feat: grid layout, global claim/qty toggles, admin access link, swaddle image
- Public wishlist now renders as responsive 3-col grid instead of list - Subtitle supports line breaks (whitespace-pre-line) - claimingEnabled and showQuantity moved to global site settings (not per-item); toggled in admin Configurações panel; claim API enforces server-side - Admin dashboard shows admin access link with copy button - Settings API exposes and persists the two new boolean settings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { and, eq, ne, sql } from 'drizzle-orm';
|
||||
import { db, wishlistItems, wishlists, itemClaims, guests } from '@/lib/db';
|
||||
import { db, wishlistItems, wishlists, itemClaims, guests, settings } from '@/lib/db';
|
||||
import { getGuestFromRequest } from '@/lib/auth/tokens';
|
||||
|
||||
export async function POST(
|
||||
@@ -26,6 +26,11 @@ export async function POST(
|
||||
if (wl.length === 0) return NextResponse.json({ error: 'Wishlist not found' }, { status: 404 });
|
||||
if (!wl[0].isPublic) return NextResponse.json({ error: 'This wishlist is private' }, { status: 403 });
|
||||
|
||||
const claimingSetting = await db.select().from(settings).where(eq(settings.key, 'claimingEnabled')).limit(1);
|
||||
if (claimingSetting[0]?.value === 'false') {
|
||||
return NextResponse.json({ error: 'Reservas desativadas' }, { status: 403 });
|
||||
}
|
||||
|
||||
// Atomically check remaining quantity and upsert the claim inside a synchronous
|
||||
// transaction to prevent race conditions (better-sqlite3 is synchronous).
|
||||
type TxResult = { ok: true } | { ok: false; remaining: number };
|
||||
|
||||
Reference in New Issue
Block a user