update flash card, test
This commit is contained in:
82
src/features/toeic/components/ToeicTestList.tsx
Normal file
82
src/features/toeic/components/ToeicTestList.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { fetchTests } from '@/features/toeic/api/test-list-api'
|
||||
|
||||
export function ToeicTestList() {
|
||||
const navigate = useNavigate()
|
||||
const { data: tests = [], isLoading, error } = useQuery({
|
||||
queryKey: ['tests'],
|
||||
queryFn: fetchTests,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="px-6 py-8 max-w-6xl mx-auto page-enter">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-3xl font-extrabold text-slate-800 mb-2">Đề Thi TOEIC</h1>
|
||||
<p className="text-slate-500">Chọn đề thi để bắt đầu luyện tập hoặc thi thử toàn bộ.</p>
|
||||
</div>
|
||||
|
||||
{isLoading && (
|
||||
<div className="grid grid-cols-2 lg:grid-cols-3 gap-5">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<div key={i} className="bg-white rounded-2xl border border-slate-200 p-5 animate-pulse h-44" />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<div className="bg-red-50 border border-red-100 rounded-2xl p-6 text-red-600 text-sm">
|
||||
Không thể tải danh sách đề thi. Vui lòng thử lại.
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isLoading && !error && tests.length === 0 && (
|
||||
<div className="text-center py-20 text-slate-400">
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 48 }}>library_books</span>
|
||||
<p className="mt-3 font-medium">Chưa có đề thi nào. Dữ liệu đang được cập nhật.</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{tests.length > 0 && (
|
||||
<div className="grid grid-cols-2 lg:grid-cols-3 gap-5">
|
||||
{tests.map((test) => (
|
||||
<div
|
||||
key={test.id}
|
||||
className="bg-white rounded-2xl border border-slate-200 p-5 flex flex-col shadow-sm hover:-translate-y-1 hover:shadow-md transition-all duration-200"
|
||||
>
|
||||
{/* Category badge */}
|
||||
{test.categoryName && (
|
||||
<span className="self-start text-xs font-bold px-2.5 py-1 rounded-full bg-blue-50 text-blue-600 border border-blue-100 mb-3">
|
||||
{test.categoryName}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<h3 className="font-extrabold text-lg text-slate-800 mb-1 leading-snug">{test.title}</h3>
|
||||
{test.description && (
|
||||
<p className="text-xs text-slate-400 mb-3 line-clamp-2">{test.description}</p>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-3 text-xs text-slate-500 mt-auto mb-4">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>list_alt</span>
|
||||
{test.totalQuestions} câu
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>timer</span>
|
||||
{test.durationMinutes} phút
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => navigate({ to: '/toeic/$testId', params: { testId: String(test.id) } })}
|
||||
className="w-full py-2.5 bg-blue-600 text-white rounded-xl text-sm font-semibold hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
Bắt đầu
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user