From 9edf6ac79455a792fe0f8433d36ed0170d7d5c7c Mon Sep 17 00:00:00 2001 From: Hikmet Date: Wed, 8 Jul 2026 11:38:15 +0300 Subject: [PATCH] fix: support async searchParams for Next.js 16 and bypass locking for admin users --- src/app/api/ads/[id]/route.ts | 3 ++- src/app/api/ads/search/route.ts | 3 ++- src/app/dashboard/ads/page.tsx | 12 +++++++----- src/app/dashboard/stores/page.tsx | 7 ++++--- src/lib/locked-response.ts | 4 ++-- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/app/api/ads/[id]/route.ts b/src/app/api/ads/[id]/route.ts index 96aa82a..c7d03d7 100644 --- a/src/app/api/ads/[id]/route.ts +++ b/src/app/api/ads/[id]/route.ts @@ -14,5 +14,6 @@ export async function GET(_: Request, context: { params: Promise<{ id: string }> }); if (!ad) return NextResponse.json({ error: "NOT_FOUND" }, { status: 404 }); const plan = planFromUser(user as any); - return NextResponse.json({ data: maskAdForPlan(ad as any, plan?.code) }); + const isAdmin = user.role === "ADMIN"; + return NextResponse.json({ data: maskAdForPlan(ad as any, plan?.code, isAdmin) }); } diff --git a/src/app/api/ads/search/route.ts b/src/app/api/ads/search/route.ts index ed0c2cc..95b7edd 100644 --- a/src/app/api/ads/search/route.ts +++ b/src/app/api/ads/search/route.ts @@ -79,7 +79,8 @@ export async function GET(req: Request) { thumbnailUrl: ad.creatives[0]?.thumbnailUrl || ad.creatives[0]?.url, isSaved: savedIds.has(ad.id) }, - plan?.code + plan?.code, + user.role === "ADMIN" ) ); diff --git a/src/app/dashboard/ads/page.tsx b/src/app/dashboard/ads/page.tsx index 0c87132..34b329a 100644 --- a/src/app/dashboard/ads/page.tsx +++ b/src/app/dashboard/ads/page.tsx @@ -6,18 +6,20 @@ import { maskAdForPlan } from "@/lib/locked-response"; import { planFromUser } from "@/lib/plans"; import { Card } from "@/components/ui/card"; -export default async function AdsPage({ searchParams }: { searchParams: Record }) { +export default async function AdsPage({ searchParams }: { searchParams: Promise> }) { const user = await requireUser(); const plan = planFromUser(user as any); - const q = searchParams.q?.trim(); - const niche = searchParams.niche; - const mediaType = searchParams.mediaType; + const resolvedSearchParams = await searchParams; + const q = resolvedSearchParams.q?.trim(); + const niche = resolvedSearchParams.niche; + const mediaType = resolvedSearchParams.mediaType; const where: Prisma.AdWhereInput = {}; if (q) where.OR = [{ primaryText: { contains: q, mode: "insensitive" } }, { headline: { contains: q, mode: "insensitive" } }, { brandPage: { name: { contains: q, mode: "insensitive" } } }]; if (niche) where.niche = niche; if (mediaType) where.mediaType = mediaType as any; const ads = await prisma.ad.findMany({ where, include: { brandPage: true, creatives: { take: 1 }, savedBy: { where: { userId: user.id } } }, orderBy: { rankPercentile: "asc" }, take: 48 }); - const masked = ads.map((ad) => maskAdForPlan({ ...ad, isSaved: ad.savedBy.length > 0 }, plan?.code)); + const isAdmin = user.role === "ADMIN"; + const masked = ads.map((ad) => maskAdForPlan({ ...ad, isSaved: ad.savedBy.length > 0 }, plan?.code, isAdmin)); return (
diff --git a/src/app/dashboard/stores/page.tsx b/src/app/dashboard/stores/page.tsx index 367102c..ab1432f 100644 --- a/src/app/dashboard/stores/page.tsx +++ b/src/app/dashboard/stores/page.tsx @@ -4,10 +4,11 @@ import { prisma } from "@/lib/db"; import { requireUser } from "@/lib/auth/current-user"; import { Card } from "@/components/ui/card"; -export default async function StoresPage({ searchParams }: { searchParams: Record }) { +export default async function StoresPage({ searchParams }: { searchParams: Promise> }) { await requireUser(); - const q = searchParams.q?.trim(); - const niche = searchParams.niche; + const resolvedSearchParams = await searchParams; + const q = resolvedSearchParams.q?.trim(); + const niche = resolvedSearchParams.niche; const where: Prisma.StoreWhereInput = {}; if (q) where.OR = [{ name: { contains: q, mode: "insensitive" } }, { domain: { contains: q, mode: "insensitive" } }]; if (niche) where.niche = niche; diff --git a/src/lib/locked-response.ts b/src/lib/locked-response.ts index 8b5f64f..6290598 100644 --- a/src/lib/locked-response.ts +++ b/src/lib/locked-response.ts @@ -1,7 +1,7 @@ import { PlanCode } from "@prisma/client"; -export function maskAdForPlan>(ad: T, planCode?: PlanCode): T & { isLocked: boolean } { - if (planCode && planCode !== "FREE") return { ...ad, isLocked: false }; +export function maskAdForPlan>(ad: T, planCode?: PlanCode, bypassLock?: boolean): T & { isLocked: boolean } { + if (bypassLock || (planCode && planCode !== "FREE")) return { ...ad, isLocked: false }; return { ...ad, primaryText: ad.primaryText ? `${String(ad.primaryText).slice(0, 90)}...` : null,