diff --git a/src/components/practice/InputArea.tsx b/src/components/practice/InputArea.tsx index a3b8c37..92c0562 100644 --- a/src/components/practice/InputArea.tsx +++ b/src/components/practice/InputArea.tsx @@ -128,6 +128,7 @@ export function InputArea({ 'w-10 h-12 text-center text-2xl font-medium', 'bg-transparent border-b-2 transition-all duration-200', 'focus:outline-none', + 'text-gray-900 dark:text-gray-100', isComposing && 'border-gray-300 dark:border-gray-600 opacity-70', !isComposing && !char && 'border-gray-400 dark:border-gray-500', !isComposing && isCorrect && 'border-green-500', diff --git a/src/pages/ProcessPracticePage.tsx b/src/pages/ProcessPracticePage.tsx index 06e14c4..1c99491 100644 --- a/src/pages/ProcessPracticePage.tsx +++ b/src/pages/ProcessPracticePage.tsx @@ -16,12 +16,32 @@ export default function ProcessPracticePage() { // 生成格子顺序 const [cellSequence] = useState(() => generateCellSequence()) + // 从 localStorage 加载答题进度 + const loadProgress = useCallback(() => { + try { + const saved = localStorage.getItem('practice-progress') + if (saved) { + const data = JSON.parse(saved) + return { + answeredCells: new Map(data.answeredCells || []), + currentCellId: data.currentCellId || cellSequence[0]?.id || null, + } + } + } catch (e) { + console.error('加载进度失败:', e) + } + return { + answeredCells: new Map(), + currentCellId: cellSequence[0]?.id || null, + } + }, [cellSequence]) + // 答题状态 const [answeredCells, setAnsweredCells] = useState>( - new Map() + () => loadProgress().answeredCells ) const [currentCellId, setCurrentCellId] = useState( - cellSequence[0]?.id || null + () => loadProgress().currentCellId ) // 输入状态 @@ -55,6 +75,21 @@ export default function ProcessPracticePage() { latestInputRef.current = userInput }, [userInput]) + // 保存答题进度到 localStorage + useEffect(() => { + try { + localStorage.setItem( + 'practice-progress', + JSON.stringify({ + answeredCells: Array.from(answeredCells.entries()), + currentCellId, + }) + ) + } catch (e) { + console.error('保存进度失败:', e) + } + }, [answeredCells, currentCellId]) + // 切换到指定格子 const switchToCell = useCallback( (cell: CellInfo) => { @@ -283,6 +318,15 @@ export default function ProcessPracticePage() { const answeredCount = answeredCells.size const totalCount = cellSequence.length + // 清除进度 + const handleClearProgress = useCallback(() => { + if (confirm('确定要清除所有答题进度吗?')) { + setAnsweredCells(new Map()) + setCurrentCellId(cellSequence[0]?.id || null) + localStorage.removeItem('practice-progress') + } + }, [cellSequence]) + return (
{/* 顶部进度条 */} @@ -292,8 +336,16 @@ export default function ProcessPracticePage() {

过程背诵练习

-
- 进度:{answeredCount} / {totalCount} +
+
+ 进度:{answeredCount} / {totalCount} +
+
@@ -341,6 +393,16 @@ export default function ProcessPracticePage() { onCompositionEnd={handleCompositionEnd} onPaste={handlePaste} /> + + {/* 提示按钮 */} +
+ +
{/* 辅助信息区域 */}