'use client'; import { useState, useEffect } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { ScrollArea } from '@/components/ui/scroll-area'; import { CheckboxField } from '@/components/ui/checkbox-field'; import { Loader2 } from 'lucide-react'; import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '@/components/ui/select'; interface ArticleGenerationModalProps { isOpen: boolean; onClose: () => void; onGenerate: (params: ArticleGenerationParams) => void; isGenerating: boolean; } export interface ArticleGenerationParams { publisher: string[]; grade: string[]; unit: string[]; textbookVocab: string; additionalVocab: string; grammar: string[]; topic: string[]; inputArticle: string; cefr: string; // single-select: A1..C2 } // Options based on the Python entry_form.py const PUBLISHER_OPTIONS = [ '康軒', '南一', '翰林' ]; const GRADE_OPTIONS = [ '七年級上學期', '七年級下學期', '八年級上學期', '八年級下學期', '九年級上學期', '九年級下學期' ]; const UNIT_OPTIONS = [ '第一課', '第二課', '第三課', '第四課', '第五課', '第六課' ]; const GRAMMAR_OPTIONS = [ '名詞', '動詞', '形容詞', '副詞', '介系詞', '連接詞', '助詞' ]; const TOPIC_OPTIONS = [ '家庭', '學校', '運動', '食物', '動物', '旅遊', '科技', '環境', '友誼', '夢想' ]; export function ArticleGenerationModal({ isOpen, onClose, onGenerate, isGenerating }: ArticleGenerationModalProps) { const [formData, setFormData] = useState({ publisher: [], grade: [], unit: [], textbookVocab: '', additionalVocab: '', grammar: [], topic: [], inputArticle: '', cefr: '' }); // Reset form when modal opens useEffect(() => { if (isOpen) { setFormData({ publisher: [], grade: [], unit: [], textbookVocab: '', additionalVocab: '', grammar: [], topic: [], inputArticle: '', cefr: '' }); } }, [isOpen]); // Update textbook vocabulary when selections change useEffect(() => { let cancelled = false; const fetchVocab = async () => { if (formData.grade.length > 0 && formData.unit.length > 0 && formData.publisher.length > 0) { try { const res = await fetch('/api/vocab', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ publisher: formData.publisher, grade: formData.grade, unit: formData.unit, }), }); if (!res.ok) throw new Error('Failed to fetch vocab'); const data: { vocab: string[]; text: string } = await res.json(); if (!cancelled) { setFormData(prev => ({ ...prev, textbookVocab: data.text })); } } catch (e) { if (!cancelled) { setFormData(prev => ({ ...prev, textbookVocab: '' })); } } } else { if (!cancelled) { setFormData(prev => ({ ...prev, textbookVocab: '' })); } } }; fetchVocab(); return () => { cancelled = true; }; }, [formData.grade, formData.unit, formData.publisher]); const handleCheckboxChange = (field: keyof ArticleGenerationParams, value: string) => { setFormData(prev => { const currentArray = prev[field] as string[]; const newArray = currentArray.includes(value) ? currentArray.filter(item => item !== value) : [...currentArray, value]; return { ...prev, [field]: newArray }; }); }; const handleTextChange = (field: keyof ArticleGenerationParams, value: string) => { setFormData(prev => ({ ...prev, [field]: value })); }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onGenerate(formData); }; return ( 📝 Generate / Rewrite Article Configure the parameters for article generation
{/* 初始文章 */}