| | import { useEffect, useState } from 'react'; |
| | import './GradingModal.css'; |
| | import type { MatchedAssistant } from '../types/index'; |
| |
|
| | interface GradingModalProps { |
| | isOpen: boolean; |
| | assistant: MatchedAssistant | null; |
| | language: string; |
| | } |
| |
|
| | const GradingModal = ({ isOpen, assistant, language }: GradingModalProps) => { |
| | const [progress, setProgress] = useState(0); |
| | const [currentStep, setCurrentStep] = useState(0); |
| |
|
| | const steps = language === 'zh-TW' ? [ |
| | '📖 讀取文章內容...', |
| | '🤖 啟動 AI 批改引擎...', |
| | '📝 分析文章結構...', |
| | '🔍 檢查文法與用詞...', |
| | '💡 生成改進建議...', |
| | '✨ 整理批改結果...', |
| | ] : [ |
| | '📖 Reading your article...', |
| | '🤖 Starting AI grading engine...', |
| | '📝 Analyzing article structure...', |
| | '🔍 Checking grammar and wording...', |
| | '💡 Generating suggestions...', |
| | '✨ Finalizing results...', |
| | ]; |
| |
|
| | useEffect(() => { |
| | if (!isOpen) { |
| | setProgress(0); |
| | setCurrentStep(0); |
| | return; |
| | } |
| |
|
| | |
| | const progressPerStep = 100 / steps.length; |
| |
|
| | |
| | const stepInterval = setInterval(() => { |
| | setCurrentStep(prev => { |
| | if (prev >= steps.length - 1) return prev; |
| | return prev + 1; |
| | }); |
| | }, 5000); |
| |
|
| | |
| | const progressInterval = setInterval(() => { |
| | setProgress(prev => { |
| | const targetProgress = (currentStep + 1) * progressPerStep; |
| | |
| | if (prev < targetProgress - 2) { |
| | return prev + 0.5 + Math.random() * 0.5; |
| | } |
| | |
| | return Math.min(prev, 95); |
| | }); |
| | }, 100); |
| |
|
| | return () => { |
| | clearInterval(progressInterval); |
| | clearInterval(stepInterval); |
| | }; |
| | }, [isOpen, steps.length, currentStep]); |
| |
|
| | if (!isOpen) return null; |
| |
|
| | return ( |
| | <div className="grading-modal-overlay"> |
| | <div className="grading-modal"> |
| | <div className="grading-modal-header"> |
| | <h2>{language === 'zh-TW' ? 'AI 批改中' : 'AI Grading in Progress'}</h2> |
| | </div> |
| | |
| | <div className="grading-modal-body"> |
| | {/* 機器人資訊 */} |
| | {assistant && ( |
| | <div className="assistant-info"> |
| | <div className="assistant-icon">🤖</div> |
| | <div className="assistant-details"> |
| | <h3>{assistant.name}</h3> |
| | <p className="assistant-subtitle"> |
| | {language === 'zh-TW' ? '專業 AI 批改助手' : 'Professional AI Grading Assistant'} |
| | </p> |
| | </div> |
| | </div> |
| | )} |
| | |
| | {/* 進度條 */} |
| | <div className="progress-section"> |
| | <div className="progress-bar-container"> |
| | <div |
| | className="progress-bar-fill" |
| | style={{ width: `${Math.min(progress, 100)}%` }} |
| | /> |
| | </div> |
| | <div className="progress-text"> |
| | {Math.round(Math.min(progress, 100))}% |
| | </div> |
| | </div> |
| | |
| | {/* 當前步驟 */} |
| | <div className="steps-section"> |
| | {steps.map((step, index) => ( |
| | <div |
| | key={index} |
| | className={`step-item ${index === currentStep ? 'active' : ''} ${index < currentStep ? 'completed' : ''}`} |
| | > |
| | {index < currentStep ? '✓' : index === currentStep ? '⏳' : '○'} {step} |
| | </div> |
| | ))} |
| | </div> |
| | |
| | {/* 提示資訊 */} |
| | <div className="grading-info"> |
| | <p className="info-text"> |
| | {language === 'zh-TW' |
| | ? '⏱️ AI 批改通常需要 30-60 秒,請耐心等待...' |
| | : '⏱️ AI grading usually takes 30-60 seconds, please wait...'} |
| | </p> |
| | <p className="info-subtitle"> |
| | {language === 'zh-TW' |
| | ? '💡 批改完成後會自動顯示詳細結果' |
| | : '💡 Results will be displayed automatically when complete'} |
| | </p> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | ); |
| | }; |
| |
|
| | export default GradingModal; |
| |
|