109 lines
4.1 KiB
TypeScript
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>
|
|
)
|
|
} |