"use client"; import { startTransition, useState } from "react"; import { useRouter } from "next/navigation"; import type { Locale } from "@/lib/i18n"; import type { CrosswordRequest } from "@/lib/types"; const DEFAULTS = { topic: "transport", difficulty: "medium", initialWordCount: 19, themedFillCount: 10, targetEmptyRatio: 0.1667, seed: 2, lexiconFile: "lexicon_it_curated_llm_aggressive.json", }; type CrosswordConfigFormProps = { locale: Locale; dict: { topic: string; difficulty: string; initialWords: string; themedFillCount: string; targetEmptyRatio: string; seed: string; lexiconFile: string; submit: string; submitting: string; note: string; }; }; export function CrosswordConfigForm({ locale, dict }: CrosswordConfigFormProps) { const router = useRouter(); const [topic, setTopic] = useState(DEFAULTS.topic); const [difficulty, setDifficulty] = useState(DEFAULTS.difficulty); const [initialWordCount, setInitialWordCount] = useState(DEFAULTS.initialWordCount); const [themedFillCount, setThemedFillCount] = useState(DEFAULTS.themedFillCount); const [targetEmptyRatio, setTargetEmptyRatio] = useState(DEFAULTS.targetEmptyRatio); const [seed, setSeed] = useState(DEFAULTS.seed); const [lexiconFile, setLexiconFile] = useState(DEFAULTS.lexiconFile); const [isSubmitting, setIsSubmitting] = useState(false); const [errorMessage, setErrorMessage] = useState(""); async function handleSubmit(event: React.FormEvent) { event.preventDefault(); setIsSubmitting(true); setErrorMessage(""); const requestPayload: CrosswordRequest = { schema_version: "1.0", request_id: `req-${Date.now()}`, requested_at: new Date().toISOString(), generator: { topic: topic .split(",") .map((item) => item.trim()) .filter(Boolean), difficulty, seed, initial_word_count: initialWordCount, themed_fill_count: themedFillCount, target_empty_ratio: targetEmptyRatio, diffxy: 7, time_limit_seconds: 8, max_candidates_per_word: 12, lexicon_file: lexiconFile, definitions_enabled: true, definition_style: "classic", preferred_output_language: locale, }, }; try { const response = await fetch("/api/crosswords/generate", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(requestPayload), }); if (!response.ok) { const errorPayload = await response.json().catch(() => ({})); throw new Error(errorPayload.message || "Unable to generate crossword"); } const generated = await response.json(); startTransition(() => { router.push(`/${locale}/crosswords/${generated.crossword_id}`); }); } catch (error) { setErrorMessage(error instanceof Error ? error.message : "Unexpected error"); setIsSubmitting(false); } } return (
setTopic(event.target.value)} />
setInitialWordCount(Number(event.target.value))} />
setThemedFillCount(Number(event.target.value))} />
setTargetEmptyRatio(Number(event.target.value))} />
setSeed(Number(event.target.value))} />
setLexiconFile(event.target.value)} />
{dict.note}
{errorMessage ?

{errorMessage}

: null}
); }