dramaling-vocab-learning/frontend/components/flashcards/FlashcardInfoBlock.tsx

109 lines
4.1 KiB
TypeScript

import React from 'react'
import type { Flashcard } from '@/lib/services/flashcards'
import { getPartOfSpeechDisplay, formatNextReviewDate } from '@/lib/utils/flashcardUtils'
interface FlashcardInfoBlockProps {
flashcard: Flashcard
isEditing: boolean
editedCard?: Partial<Flashcard>
onEditChange: (field: string, value: string) => void
className?: string
}
export const FlashcardInfoBlock: React.FC<FlashcardInfoBlockProps> = ({
flashcard,
isEditing,
editedCard,
onEditChange,
className = ''
}) => {
// 安全的日期格式化函數
const formatSafeDate = (dateString: string | null | undefined): string => {
console.log('🔍 日期格式化檢查:', { dateString, type: typeof dateString })
if (!dateString) return '未設定'
const date = new Date(dateString)
if (isNaN(date.getTime())) return '日期無效'
const result = date.toLocaleDateString()
console.log('✅ 日期格式化結果:', result)
return result
}
// 除錯日誌
console.log('🔍 FlashcardInfoBlock 資料檢查:', {
flashcardId: flashcard.id,
nextReviewDate: flashcard.nextReviewDate,
createdAt: flashcard.createdAt,
timesReviewed: flashcard.timesReviewed,
masteryLevel: flashcard.masteryLevel
})
return (
<div className={`bg-gray-50 rounded-lg p-4 border border-gray-200 ${className}`}>
<h3 className="font-semibold text-gray-900 mb-3 text-left"></h3>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<span className="text-gray-600">:</span>
{isEditing ? (
<select
value={editedCard?.partOfSpeech || flashcard.partOfSpeech}
onChange={(e) => onEditChange('partOfSpeech', e.target.value)}
className="ml-2 p-1 border border-gray-300 rounded text-sm focus:ring-2 focus:ring-blue-500"
>
<option value="noun"></option>
<option value="verb"></option>
<option value="adjective"></option>
<option value="adverb"></option>
<option value="preposition"></option>
<option value="conjunction"></option>
<option value="interjection"></option>
<option value="pronoun"></option>
<option value="other"></option>
</select>
) : (
<span className="ml-2 font-medium">{getPartOfSpeechDisplay(flashcard.partOfSpeech)}</span>
)}
</div>
<div>
<span className="text-gray-600">CEFR等級:</span>
{isEditing ? (
<select
value={editedCard?.cefr || flashcard.cefr}
onChange={(e) => onEditChange('cefr', e.target.value)}
className="ml-2 p-1 border border-gray-300 rounded text-sm focus:ring-2 focus:ring-blue-500"
>
<option value="A1">A1</option>
<option value="A2">A2</option>
<option value="B1">B1</option>
<option value="B2">B2</option>
<option value="C1">C1</option>
<option value="C2">C2</option>
</select>
) : (
<span className="ml-2 font-medium">{flashcard.cefr}</span>
)}
</div>
<div>
<span className="text-gray-600">:</span>
<span className="ml-2 font-medium">{formatSafeDate(flashcard.createdAt)}</span>
</div>
<div>
<span className="text-gray-600">:</span>
<span className="ml-2 font-medium">{formatSafeDate(flashcard.nextReviewDate)}</span>
</div>
<div>
<span className="text-gray-600">:</span>
<span className="ml-2 font-medium">{flashcard.timesReviewed} </span>
</div>
<div>
<span className="text-gray-600">:</span>
<span className="ml-2 font-medium">{flashcard.masteryLevel}</span>
</div>
</div>
</div>
)
}