diff --git a/app/api/listings/check-slug/route.ts b/app/api/listings/check-slug/route.ts new file mode 100644 index 0000000..ee5e290 --- /dev/null +++ b/app/api/listings/check-slug/route.ts @@ -0,0 +1,18 @@ +import { NextResponse } from 'next/server'; +import { prisma } from '../../../../lib/prisma'; + +export async function GET(req: Request) { + const url = new URL(req.url); + const slug = url.searchParams.get('slug')?.trim().toLowerCase(); + + if (!slug) { + return NextResponse.json({ error: 'Missing slug' }, { status: 400 }); + } + + const existing = await prisma.listingTranslation.findFirst({ + where: { slug, listing: { removedAt: null } }, + select: { id: true }, + }); + + return NextResponse.json({ available: !existing }); +} diff --git a/app/listings/new/page.tsx b/app/listings/new/page.tsx index 1db8286..a6566fc 100644 --- a/app/listings/new/page.tsx +++ b/app/listings/new/page.tsx @@ -60,6 +60,7 @@ export default function NewListingPage() { const [isAuthed, setIsAuthed] = useState(false); const [aiResponse, setAiResponse] = useState(''); const [copyStatus, setCopyStatus] = useState<'idle' | 'copied' | 'error'>('idle'); + const [slugStatus, setSlugStatus] = useState<'idle' | 'checking' | 'available' | 'taken' | 'error'>('idle'); useEffect(() => { setCurrentLocale(uiLocale as Locale); @@ -214,6 +215,25 @@ export default function NewListingPage() { })); } + async function checkSlugAvailability() { + const value = slug.trim().toLowerCase(); + if (!value) { + setSlugStatus('idle'); + return; + } + setSlugStatus('checking'); + try { + const res = await fetch(`/api/listings/check-slug?slug=${encodeURIComponent(value)}`, { cache: 'no-store' }); + const data = await res.json(); + if (!res.ok || typeof data.available !== 'boolean') { + throw new Error('bad response'); + } + setSlugStatus(data.available ? 'available' : 'taken'); + } catch (err) { + setSlugStatus('error'); + } + } + async function onSubmit(e: React.FormEvent) { e.preventDefault(); setMessage(null); @@ -325,8 +345,14 @@ export default function NewListingPage() {