'use client'; import { useState, useEffect, useTransition } from 'react'; import { WordData } from '@/zoom/logic/types'; import { fetchWordsByToneAndSyllables } from '@/actions/tones'; import { Button } from '@/components/ui/button'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; import { Label } from '@/components/ui/label'; import { Skeleton } from '@/components/ui/skeleton'; // For loading state // Helper to display tones prominently const ProminentToneDisplay = ({ wordData }: { wordData: WordData }) => { if (!wordData.prosody || !Array.isArray(wordData.prosody)) { return

No prosody data

; } return (

{wordData.spelling}

{wordData.prosody.map((p, index) => (

Syllable {index + 1}

{p.tone ?? '?'}

))}
{wordData.ipa && wordData.ipa.length > 0 && (

{wordData.ipa.map(i => i.ipa).join(' / ')}

)}
); }; export default function ToneSelectorClient({ initialWord }: { initialWord: WordData | null }) { const [currentWord, setCurrentWord] = useState(initialWord); const [syllableCount, setSyllableCount] = useState(initialWord?.syllables || 1); const [selectedTones, setSelectedTones] = useState<(number | null)[]>( initialWord?.prosody?.map(p => p.tone ?? null) || [null] ); const [isLoading, startTransition] = useTransition(); useEffect(() => { // Adjust selectedTones array length when syllableCount changes setSelectedTones(prevTones => { const newTones = Array(syllableCount).fill(null); for (let i = 0; i < Math.min(prevTones.length, syllableCount); i++) { newTones[i] = prevTones[i]; } return newTones; }); }, [syllableCount]); const handleFetchWord = () => { startTransition(async () => { const word = await fetchWordsByToneAndSyllables(syllableCount, selectedTones); setCurrentWord(word); }); }; const handleSyllableCountChange = (value: string) => { const count = parseInt(value, 10); if (!isNaN(count) && count > 0 && count <= 5) { // Max 5 syllables for simplicity setSyllableCount(count); } }; const handleToneChange = (syllableIndex: number, value: string) => { const tone = value === 'any' ? null : parseInt(value, 10); setSelectedTones(prevTones => { const newTones = [...prevTones]; newTones[syllableIndex] = tone; return newTones; }); }; const thaiTones = [ { value: '1', label: '1 (Mid)' }, { value: '2', label: '2 (Low)' }, { value: '3', label: '3 (Falling)' }, { value: '4', label: '4 (High)' }, { value: '5', label: '5 (Rising)' }, ]; return (
Thai Tone Explorer Select syllable count and tones to find Thai words.
{Array.from({ length: syllableCount }).map((_, index) => (
))}
{isLoading && !currentWord && ( )} {!isLoading && currentWord && ( Current Word {/* You can add more details from WordData here if needed, like definitions */} {currentWord.senses && currentWord.senses.length > 0 && (

Meanings:

{currentWord.senses.map((sense, sIdx) => (

{sense.pos}

{sense.senses && Array.isArray(sense.senses) && sense.senses.map((subSense, ssIdx) => ( subSense.glosses && Array.isArray(subSense.glosses) && subSense.glosses.map((gloss: string, gIdx: number) => (

- {gloss}

)) ))}
))}
)}
)} {!isLoading && !currentWord && ( No Word Found

Could not find a Thai word matching your criteria. Try different selections.

)}
); }