PraxaLing / app /(app) /practice /DialoguePracticeClient.tsx
Reubencf's picture
Deploy: PraxaLing rename + HF Docker Space
16fde87
Raw
History Blame Contribute Delete
2.54 kB
"use client";
import { useState } from "react";
import type { Dialogue } from "@/lib/types/dialogue";
import type { Level } from "@/lib/languages";
import { CustomTopicCard } from "./CustomTopicCard";
import { ScenarioLibrary } from "./ScenarioLibrary";
import { DialogueResultView } from "./DialogueResultView";
import { GeneratingDialogueProgress } from "./GeneratingDialogueProgress";
export function DialoguePracticeClient({ defaultLevel }: { defaultLevel: Level }) {
const [customTopic, setCustomTopic] = useState("");
const [error, setError] = useState<string | null>(null);
const [activeScenario, setActiveScenario] = useState<string | null>(null);
const [generatedDialogue, setGeneratedDialogue] = useState<Dialogue | null>(null);
const [level, setLevel] = useState<Level>(defaultLevel);
async function generate(scenario: string, label: string) {
if (activeScenario) return;
setError(null);
setActiveScenario(label);
try {
const res = await fetch("/api/dialogues", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ scenario, level }),
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
setError(data.message || data.error || "Could not generate this dialogue.");
setActiveScenario(null);
return;
}
setGeneratedDialogue((await res.json()) as Dialogue);
} catch {
setError("Could not generate this dialogue.");
setActiveScenario(null);
}
}
function generateCustom() {
const topic = customTopic.trim();
if (!topic) {
setError("Enter a situation first.");
return;
}
generate(topic, "Custom topic");
}
if (generatedDialogue) {
return (
<DialogueResultView
dialogue={generatedDialogue}
onBack={() => {
setGeneratedDialogue(null);
setActiveScenario(null);
}}
/>
);
}
if (activeScenario) {
return <GeneratingDialogueProgress scenario={activeScenario} />;
}
return (
<section className="space-y-6">
<CustomTopicCard
level={level}
onLevelChange={setLevel}
customTopic={customTopic}
onCustomTopicChange={setCustomTopic}
onGenerate={generateCustom}
pending={activeScenario === "Custom topic"}
disabled={activeScenario !== null}
error={error}
/>
<ScenarioLibrary activeScenario={activeScenario} onGenerate={generate} />
</section>
);
}