dramaling-vocab-learning/frontend/components/learn/TaskListModal.tsx

129 lines
4.7 KiB
TypeScript

interface TestItem {
id: string
cardId: string
word: string
testType: string
testName: string
isCompleted: boolean
isCurrent: boolean
order: number
}
interface TaskListModalProps {
isOpen: boolean
onClose: () => void
testItems: TestItem[]
completedTests: number
totalTests: number
}
export const TaskListModal: React.FC<TaskListModalProps> = ({
isOpen,
onClose,
testItems,
completedTests,
totalTests
}) => {
if (!isOpen) return null
const progressPercentage = totalTests > 0 ? Math.round((completedTests / totalTests) * 100) : 0
const completedCount = testItems.filter(item => item.isCompleted).length
const currentCount = testItems.filter(item => item.isCurrent).length
const pendingCount = testItems.filter(item => !item.isCompleted && !item.isCurrent).length
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-xl shadow-2xl max-w-4xl w-full mx-4 max-h-[80vh] overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-gray-200">
<h2 className="text-2xl font-bold text-gray-900 flex items-center gap-2">
📚
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600 text-2xl"
>
</button>
</div>
{/* Content */}
<div className="p-6 overflow-y-auto max-h-[60vh]">
{/* 進度統計 */}
<div className="mb-6 bg-blue-50 rounded-lg p-4">
<div className="flex items-center justify-between text-sm">
<span className="text-blue-900 font-medium">
: {completedTests} / {totalTests} ({progressPercentage}%)
</span>
<div className="flex items-center gap-4 text-blue-800">
<span> : {completedCount}</span>
<span> : {currentCount}</span>
<span> : {pendingCount}</span>
</div>
</div>
<div className="mt-3 w-full bg-blue-200 rounded-full h-2">
<div
className="bg-blue-600 h-2 rounded-full transition-all"
style={{ width: `${progressPercentage}%` }}
></div>
</div>
</div>
{/* 測驗清單 */}
<div className="space-y-4">
{testItems.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
{testItems.map((item) => (
<div
key={item.id}
className={`flex items-center gap-3 p-3 rounded-lg transition-all ${
item.isCompleted
? 'bg-green-50 border border-green-200'
: item.isCurrent
? 'bg-blue-50 border border-blue-300 shadow-sm'
: 'bg-gray-50 border border-gray-200'
}`}
>
{/* 狀態圖標 */}
<span className="text-lg">
{item.isCompleted ? '✅' : item.isCurrent ? '⏳' : '⚪'}
</span>
{/* 測驗資訊 */}
<div className="flex-1">
<div className="font-medium text-sm">
{item.order}. {item.word} - {item.testName}
</div>
<div className={`text-xs ${
item.isCompleted ? 'text-green-600' :
item.isCurrent ? 'text-blue-600' : 'text-gray-500'
}`}>
{item.isCompleted ? '已完成' :
item.isCurrent ? '進行中' : '待完成'}
</div>
</div>
</div>
))}
</div>
) : (
<div className="text-center py-8 text-gray-500">
<div className="text-4xl mb-2">📚</div>
<p></p>
</div>
)}
</div>
</div>
{/* Footer */}
<div className="px-6 py-4 border-t border-gray-200 bg-gray-50">
<button
onClick={onClose}
className="w-full py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
</button>
</div>
</div>
</div>
)
}