'use client'; import { useState } from 'react'; import { sanitizeSlug, slugFieldValue } from '@/lib/journal'; import { describeCollision, pageSlugCollision, type SlugTakenBy } from '@/lib/pages'; import { useModalDialog } from '@/hooks/useModalDialog'; interface NewPageDialogProps { taken: SlugTakenBy; existingPageSlugs: string[]; creating: boolean; onCreate: (input: { title: string; slug: string; showInMenu: boolean }) => void; onClose: () => void; } /** * "+ New page" (#722): a title, the slug derived from it (editable), and * whether the page goes into the menu. v1 starts every page blank. */ export default function NewPageDialog({ taken, existingPageSlugs, creating, onCreate, onClose, }: NewPageDialogProps) { const cardRef = useModalDialog(onClose); const [title, setTitle] = useState(''); const [slug, setSlug] = useState(''); const [slugEdited, setSlugEdited] = useState(false); const [showInMenu, setShowInMenu] = useState(true); /** What the field shows: the typed slug, or the one derived from the title. */ const fieldSlug = slug || (title.trim() ? sanitizeSlug(title) : ''); /** What gets created: the typed slug finished, e.g. without a trailing "-". */ const effectiveSlug = slug ? sanitizeSlug(slug) : fieldSlug; const collision = !effectiveSlug ? null : existingPageSlugs.includes(effectiveSlug) ? `A page "${effectiveSlug}" already exists.` : (() => { const c = pageSlugCollision(effectiveSlug, taken); return c ? describeCollision(effectiveSlug, c) : null; })(); const submit = (e: React.FormEvent) => { e.preventDefault(); if (!title.trim() || !effectiveSlug || collision || creating) return; onCreate({ title: title.trim(), slug: effectiveSlug, showInMenu }); }; return (