fix: 修復學習頁面到期詞卡載入問題
- 移除API調用中的date參數,使用後端預設邏輯 - 修復日期篩選過於嚴格導致可學習詞卡被過濾問題 - 添加詳細調試日誌,便於追蹤API調用和數據轉換 - 後端現在返回所有需要復習的詞卡(到期、逾期、新詞卡) - 學習頁面現在能正確載入5張可復習詞卡 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
6c83316467
commit
d19fa34556
|
|
@ -111,13 +111,16 @@ export default function LearnPage() {
|
||||||
const loadDueCards = async () => {
|
const loadDueCards = async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoadingCard(true)
|
setIsLoadingCard(true)
|
||||||
|
console.log('🔍 開始載入到期詞卡...');
|
||||||
|
|
||||||
// 完全使用後端API數據
|
// 完全使用後端API數據
|
||||||
const apiResult = await flashcardsService.getDueFlashcards(50);
|
const apiResult = await flashcardsService.getDueFlashcards(50);
|
||||||
|
console.log('📡 API回應結果:', apiResult);
|
||||||
|
|
||||||
if (apiResult.success && apiResult.data && apiResult.data.length > 0) {
|
if (apiResult.success && apiResult.data && apiResult.data.length > 0) {
|
||||||
const cardsToUse = apiResult.data;
|
const cardsToUse = apiResult.data;
|
||||||
console.log('載入後端API數據:', cardsToUse.length, '張詞卡');
|
console.log('✅ 載入後端API數據成功:', cardsToUse.length, '張詞卡');
|
||||||
|
console.log('📋 詞卡列表:', cardsToUse.map(c => c.word));
|
||||||
|
|
||||||
setDueCards(cardsToUse);
|
setDueCards(cardsToUse);
|
||||||
|
|
||||||
|
|
@ -131,19 +134,25 @@ export default function LearnPage() {
|
||||||
setMode(selectedMode);
|
setMode(selectedMode);
|
||||||
setIsAutoSelecting(false);
|
setIsAutoSelecting(false);
|
||||||
|
|
||||||
console.log(`初始載入: ${firstCard.word}, 選擇模式: ${selectedMode}`);
|
console.log(`🎯 初始載入: ${firstCard.word}, 選擇模式: ${selectedMode}`);
|
||||||
} else {
|
} else {
|
||||||
// 沒有到期詞卡
|
// 沒有到期詞卡
|
||||||
console.log('沒有到期的詞卡');
|
console.log('❌ API回應:', {
|
||||||
|
success: apiResult.success,
|
||||||
|
dataExists: !!apiResult.data,
|
||||||
|
dataLength: apiResult.data?.length,
|
||||||
|
error: apiResult.error
|
||||||
|
});
|
||||||
setDueCards([]);
|
setDueCards([]);
|
||||||
setCurrentCard(null);
|
setCurrentCard(null);
|
||||||
setShowNoDueCards(true);
|
setShowNoDueCards(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('載入到期詞卡失敗:', error);
|
console.error('💥 載入到期詞卡失敗:', error);
|
||||||
setDueCards([]);
|
setDueCards([]);
|
||||||
setCurrentCard(null);
|
setCurrentCard(null);
|
||||||
|
setShowNoDueCards(true);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoadingCard(false);
|
setIsLoadingCard(false);
|
||||||
}
|
}
|
||||||
|
|
@ -799,6 +808,39 @@ export default function LearnPage() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 當前選擇突出顯示 */}
|
||||||
|
<div className="bg-gradient-to-r from-blue-50 to-blue-100 rounded-lg p-3 mb-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
{currentCard && (() => {
|
||||||
|
const userCEFR = localStorage.getItem('userEnglishLevel') || 'A2';
|
||||||
|
const wordCEFR = currentCard.difficultyLevel || 'A2';
|
||||||
|
const context = getCurrentContext(userCEFR, wordCEFR);
|
||||||
|
const contextData = generateContextTable(userCEFR, wordCEFR).find(c => c.isCurrent);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<span className="text-blue-800 font-medium">
|
||||||
|
當前情境: {contextData?.icon} {context}
|
||||||
|
</span>
|
||||||
|
<div className="text-blue-600 text-xs mt-1">
|
||||||
|
可用題型: {contextData?.reviewTypes.join(' | ')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
<div className="text-blue-800 text-right">
|
||||||
|
<div className="text-xs">系統已選擇</div>
|
||||||
|
<div className="font-medium flex items-center gap-1">
|
||||||
|
<span>{getModeIcon(mode)}</span>
|
||||||
|
<span>{getModeLabel(mode)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* 完整四情境對照表 */}
|
{/* 完整四情境對照表 */}
|
||||||
<div className="bg-white rounded-lg p-4">
|
<div className="bg-white rounded-lg p-4">
|
||||||
|
|
|
||||||
|
|
@ -179,8 +179,19 @@ class FlashcardsService {
|
||||||
|
|
||||||
async getDueFlashcards(limit = 50): Promise<ApiResponse<Flashcard[]>> {
|
async getDueFlashcards(limit = 50): Promise<ApiResponse<Flashcard[]>> {
|
||||||
try {
|
try {
|
||||||
const today = new Date().toISOString().split('T')[0];
|
console.log('🚀 API調用開始:', `/flashcards/due?limit=${limit}`);
|
||||||
const response = await this.makeRequest<{ success: boolean; data: any[]; count: number }>(`/flashcards/due?date=${today}&limit=${limit}`);
|
|
||||||
|
const response = await this.makeRequest<{ success: boolean; data: any[]; count: number }>(`/flashcards/due?limit=${limit}`);
|
||||||
|
console.log('🔍 makeRequest回應:', response);
|
||||||
|
console.log('📊 response.data類型:', typeof response.data, '長度:', response.data?.length);
|
||||||
|
|
||||||
|
if (!response.data || !Array.isArray(response.data)) {
|
||||||
|
console.log('❌ response.data不是數組:', response.data);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: 'Invalid response data format',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 轉換後端格式為前端期望格式
|
// 轉換後端格式為前端期望格式
|
||||||
const flashcards = response.data.map((card: any) => ({
|
const flashcards = response.data.map((card: any) => ({
|
||||||
|
|
@ -213,12 +224,14 @@ class FlashcardsService {
|
||||||
primaryImageUrl: card.primaryImageUrl
|
primaryImageUrl: card.primaryImageUrl
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
console.log('✅ 數據轉換完成:', flashcards.length, '張詞卡');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: flashcards
|
data: flashcards
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('API request failed, using fallback:', error);
|
console.error('💥 API request failed:', error);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: error instanceof Error ? error.message : 'Failed to get due flashcards',
|
error: error instanceof Error ? error.message : 'Failed to get due flashcards',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue