Skip to content

Commit 082b307

Browse files
committed
add question history management with local storage and update history modal
1 parent 30cff16 commit 082b307

File tree

5 files changed

+230
-102
lines changed

5 files changed

+230
-102
lines changed

app/page.tsx

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import SettingsModal from "@/components/modals/settings-modal"
1111
import HistoryModal from "@/components/modals/history-modal"
1212
import LoadingQuestionModal from "@/components/modals/loading-question-modal"
1313
import { useState, useEffect, useCallback } from "react"
14-
import type { Question, UserAnswer } from "@/lib/types"
14+
import type { Question, UserAnswer, QuestionHistory } from "@/lib/types"
1515
import { generateRandomQuestion } from "@/lib/data"
1616
import { useTranslation } from "@/lib/i18n"
1717
import { useToast } from "@/hooks/use-toast"
@@ -35,15 +35,49 @@ export default function Page() {
3535
const [answer, setAnswer] = useState<any>(null)
3636
const [isStreaming, setIsStreaming] = useState(false)
3737
const { toast } = useToast()
38+
const [questionHistory, setQuestionHistory] = useState<QuestionHistory[]>([])
3839

3940
const [isLoadingQuestion, setIsLoadingQuestion] = useState(true)
4041

42+
// 在组件加载时从本地存储加载历史记录
43+
useEffect(() => {
44+
const savedHistory = localStorage.getItem("questionHistory");
45+
if (savedHistory) {
46+
try {
47+
setQuestionHistory(JSON.parse(savedHistory));
48+
} catch (e) {
49+
console.error("Error parsing question history:", e);
50+
}
51+
}
52+
}, []);
53+
4154
useEffect(() => {
4255
const fetchQuestion = async () => {
4356
setIsLoadingQuestion(true);
4457
try {
4558
const question = await generateRandomQuestion();
4659
setCurrentQuestion(question);
60+
61+
// 记录新获取的问题到历史记录
62+
const newHistoryItem: QuestionHistory = {
63+
id: question.id,
64+
title: question.translations[language]?.title || question.translations.en.title,
65+
timestamp: new Date().toISOString(),
66+
answered: false,
67+
language: language,
68+
question: question
69+
};
70+
71+
setQuestionHistory(prevHistory => {
72+
// 检查是否已存在相同ID的问题
73+
const exists = prevHistory.some(item => item.id === question.id);
74+
if (!exists) {
75+
const updatedHistory = [newHistoryItem, ...prevHistory];
76+
localStorage.setItem("questionHistory", JSON.stringify(updatedHistory));
77+
return updatedHistory;
78+
}
79+
return prevHistory;
80+
});
4781
} catch (error) {
4882
console.error("Error fetching question:", error);
4983
toast({
@@ -84,14 +118,26 @@ export default function Page() {
84118
setResults(null)
85119
setIsStreaming(true)
86120

87-
88121
try {
89122
// Call OpenAI to evaluate the answer with streaming
90123
await evaluateAnswer(currentQuestion, userAnswer.content, language, (streamingResults) => {
91124
setResults(streamingResults)
92125
})
93126

94127
setIsStreaming(false)
128+
129+
// 更新历史记录中的问题状态为已回答
130+
if (currentQuestion) {
131+
setQuestionHistory(prevHistory => {
132+
const updatedHistory = prevHistory.map(item =>
133+
item.id === currentQuestion.id
134+
? { ...item, answered: true }
135+
: item
136+
);
137+
localStorage.setItem("questionHistory", JSON.stringify(updatedHistory));
138+
return updatedHistory;
139+
});
140+
}
95141
} catch (error) {
96142
console.error("Error submitting answer:", error)
97143
setIsStreaming(false)
@@ -112,6 +158,27 @@ export default function Page() {
112158
try {
113159
const question = await generateRandomQuestion();
114160
setCurrentQuestion(question);
161+
162+
// 记录新问题到历史
163+
const newHistoryItem: QuestionHistory = {
164+
id: question.id,
165+
title: question.translations[language]?.title || question.translations.en.title,
166+
timestamp: new Date().toISOString(),
167+
answered: false,
168+
language: language,
169+
question: question
170+
};
171+
172+
setQuestionHistory(prevHistory => {
173+
// 检查是否已存在相同ID的问题
174+
const exists = prevHistory.some(item => item.id === question.id);
175+
if (!exists) {
176+
const updatedHistory = [newHistoryItem, ...prevHistory];
177+
localStorage.setItem("questionHistory", JSON.stringify(updatedHistory));
178+
return updatedHistory;
179+
}
180+
return prevHistory;
181+
});
115182
} catch (error) {
116183
console.error("Error fetching next question:", error);
117184
toast({
@@ -123,7 +190,7 @@ export default function Page() {
123190
} finally {
124191
setIsLoadingQuestion(false);
125192
}
126-
}, [toast, t]);
193+
}, [toast, t, language]);
127194

128195
const onViewAnswer = () => {
129196
setConfirmationStep(0)
@@ -148,6 +215,19 @@ export default function Page() {
148215

149216
setIsStreaming(false)
150217
setIsSubmitted(true)
218+
219+
// 更新历史记录中的问题状态为已回答
220+
if (currentQuestion) {
221+
setQuestionHistory(prevHistory => {
222+
const updatedHistory = prevHistory.map(item =>
223+
item.id === currentQuestion.id
224+
? { ...item, answered: true }
225+
: item
226+
);
227+
localStorage.setItem("questionHistory", JSON.stringify(updatedHistory));
228+
return updatedHistory;
229+
});
230+
}
151231
} catch (error) {
152232
console.error("Error getting model answer:", error)
153233
setIsStreaming(false)
@@ -207,6 +287,21 @@ export default function Page() {
207287
const onCloseHistory = () => {
208288
setShowHistoryModal(false)
209289
}
290+
291+
// 从历史记录加载问题
292+
const loadQuestionFromHistory = (historyItem: QuestionHistory) => {
293+
setCurrentQuestion(historyItem.question);
294+
setUserAnswer({ content: "" });
295+
setIsSubmitted(false);
296+
setTimeRemaining(600);
297+
setShowHistoryModal(false);
298+
};
299+
300+
// 在 Page 组件中添加一个函数来清除历史记录
301+
const clearQuestionHistory = () => {
302+
localStorage.removeItem("questionHistory");
303+
setQuestionHistory([]);
304+
};
210305

211306
return (
212307
<div className="flex flex-col min-h-screen">
@@ -259,7 +354,15 @@ export default function Page() {
259354

260355
{showSettingsModal && <SettingsModal language={language} onClose={onCloseSettings} />}
261356

262-
{showHistoryModal && <HistoryModal language={language} onClose={onCloseHistory} />}
357+
{showHistoryModal && (
358+
<HistoryModal
359+
language={language}
360+
onClose={onCloseHistory}
361+
history={questionHistory}
362+
onSelectQuestion={loadQuestionFromHistory}
363+
onClearHistory={clearQuestionHistory}
364+
/>
365+
)}
263366

264367
<LoadingQuestionModal isOpen={isLoadingQuestion} />
265368
</div>

components/header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client"
22

3-
import {Globe, Settings, User} from "lucide-react"
3+
import {Globe, Settings, History} from "lucide-react"
44
import {Button} from "@/components/ui/button"
55
import {DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger} from "@/components/ui/dropdown-menu"
66
import {useTranslation} from "@/lib/i18n"
@@ -54,7 +54,7 @@ export default function Header({ language, setLanguage, onOpenSettings, onOpenHi
5454
</Button>
5555

5656
<Button variant="ghost" size="icon" className="rounded-full" onClick={onOpenHistory}>
57-
<User className="h-5 w-5" />
57+
<History className="h-5 w-5" />
5858
</Button>
5959

6060
<a href={githubRepoUrl} target="_blank" rel="noopener noreferrer" title={t("header.github")}>

0 commit comments

Comments
 (0)