feat(exam): add SAT style testing component

This commit is contained in:
shafin-r
2026-01-28 15:22:19 +06:00
parent 61b7c5220e
commit 355ca0c0c4
17 changed files with 1136 additions and 267 deletions

View File

@ -39,10 +39,10 @@ export const Home = () => {
(sheet) => sheet.user_status === "NOT_STARTED",
);
const inProgress = sheets.filter(
(sheet) => sheet.user_status === "in-progress",
(sheet) => sheet.user_status === "IN_PROGRESS",
);
const completed = sheets.filter(
(sheet) => sheet.user_status === "completed",
(sheet) => sheet.user_status === "COMPLETED",
);
setNotStartedSheets(notStarted);
@ -83,100 +83,99 @@ export const Home = () => {
};
return (
<div className="min-h-screen bg-gray-50">
<main className="flex flex-col gap-12 max-w-full mx-auto px-8 sm:px-6 lg:px-8 py-8">
<h1 className="text-4xl font-satoshi-bold tracking-tight text-gray-800 text-center">
Welcome, {user?.name || "Student"}
<main className="min-h-screen bg-gray-50 flex flex-col gap-12 max-w-full mx-auto px-8 sm:px-6 lg:px-8 py-8">
<h1 className="text-4xl font-satoshi-bold tracking-tight text-gray-800 text-center">
Welcome, {user?.name || "Student"}
</h1>
<section className="relative w-full">
<input
type="text"
placeholder="Search..."
className="font-satoshi w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
/>
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<Search size={22} color="gray" />
</div>
</section>
<section className="space-y-4">
<h1 className="font-satoshi-bold text-2xl tracking-tight">
Pick up where you left off
</h1>
<section className="relative w-full">
<input
type="text"
placeholder="Search..."
className="font-satoshi w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
/>
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<Search size={22} color="gray" />
</div>
</section>
<section className="space-y-4">
<h1 className="font-satoshi-bold text-2xl tracking-tight">
Pick up where you left off
</h1>
</section>
<section className="w-full">
<Tabs defaultValue="all" className="w-full">
<TabsList className="bg-transparent p-0 w-full">
<TabsTrigger
value="all"
className="font-satoshi-regular tracking-wide text-md rounded-none border-b-3 data-[state=active]:font-satoshi-medium data-[state=active]:border-b-purple-800 data-[state=active]:text-purple-800"
>
All
</TabsTrigger>
<TabsTrigger
value="NOT_STARTED"
className="font-satoshi-regular tracking-wide text-md rounded-none border-b-3 data-[state=active]:border-b-purple-800 data-[state=active]:text-purple-800"
>
Not Started
</TabsTrigger>
<TabsTrigger
value="COMPLETED"
className="font-satoshi-regular tracking-wide text-md rounded-none border-b-3 data-[state=active]:border-b-purple-800 data-[state=active]:text-purple-800"
>
Completed
</TabsTrigger>
</TabsList>
<TabsContent value="all" className="pt-6">
<div className="space-y-6">
{practiceSheets.length > 0 ? (
practiceSheets.map((sheet) => (
<Card key={sheet?.id} className="rounded-4xl">
<CardHeader>
<CardTitle className="font-satoshi-medium text-xl">
{sheet?.title}
</CardTitle>
<CardDescription className="font-satoshi">
{sheet?.description}
</CardDescription>
</CardHeader>
<CardContent className="flex justify-between">
<p className="font-satoshi text-gray-500">
{formatStatus(sheet?.user_status)}
</p>
<Badge
variant="secondary"
className="bg-indigo-100 text-indigo-500 font-satoshi tracking-wide"
>
{sheet?.modules_count} modules
</Badge>
</CardContent>
<CardContent>
<p className="font-satoshi text-gray-700">
{sheet?.time_limit} minutes
</p>
</CardContent>
<CardFooter>
<Button
onClick={() => handleStartPractice(sheet?.id)}
variant="outline"
className="font-satoshi rounded-3xl w-full text-lg py-6 bg-linear-to-br from-purple-500 to-purple-600 text-white"
>
Start
</Button>
</CardFooter>
</Card>
))
) : (
<div className="flex items-center justify-center py-4 rounded-full">
<h2 className="text-center font-satoshi text-lg text-gray-500">
No Practice Sheets available.
</h2>
</div>
)}
</div>
</TabsContent>
<TabsContent value="NOT_STARTED" className="pt-6">
<div className="space-y-6">
{notStartedSheets.map((sheet) => (
{inProgressSheets.length > 0 ? (
inProgressSheets.map((sheet) => (
<Card
key={sheet?.id}
className="rounded-4xl border bg-purple-50/70 border-purple-500"
>
<CardHeader>
<CardTitle className="font-satoshi-medium text-xl">
{sheet?.title}
</CardTitle>
<CardDescription className="font-satoshi">
{sheet?.description}
</CardDescription>
</CardHeader>
<CardContent className="flex justify-between">
<p className="font-satoshi text-sm border px-2 rounded-full bg-purple-500 text-white py-1">
{formatStatus(sheet?.user_status)}
</p>
<Badge
variant="secondary"
className="bg-indigo-100 text-indigo-500 font-satoshi tracking-wide"
>
{sheet?.modules_count} modules
</Badge>
</CardContent>
<CardContent>
<p className="font-satoshi text-gray-700">
{sheet?.time_limit} minutes
</p>
</CardContent>
<CardFooter>
<Button
onClick={() => handleStartPractice(sheet?.id)}
variant="outline"
className="font-satoshi rounded-3xl w-full text-lg py-6 bg-linear-to-br from-purple-500 to-purple-600 text-white"
>
Resume
</Button>
</CardFooter>
</Card>
))
) : (
<Card className="flex items-center justify-center py-4 rounded-4xl">
<h2 className="text-center font-satoshi text-lg text-gray-800">
You don't have any practice sheets in progress. Why not start one?
</h2>
</Card>
)}
</section>
<section className="w-full">
<Tabs defaultValue="all" className="w-full">
<TabsList className="bg-transparent p-0 w-full">
<TabsTrigger
value="all"
className="font-satoshi-regular tracking-wide text-md rounded-none border-b-3 data-[state=active]:font-satoshi-medium data-[state=active]:border-b-purple-800 data-[state=active]:text-purple-800"
>
All
</TabsTrigger>
<TabsTrigger
value="NOT_STARTED"
className="font-satoshi-regular tracking-wide text-md rounded-none border-b-3 data-[state=active]:border-b-purple-800 data-[state=active]:text-purple-800"
>
Not Started
</TabsTrigger>
<TabsTrigger
value="COMPLETED"
className="font-satoshi-regular tracking-wide text-md rounded-none border-b-3 data-[state=active]:border-b-purple-800 data-[state=active]:text-purple-800"
>
Completed
</TabsTrigger>
</TabsList>
<TabsContent value="all" className="pt-6">
<div className="gap-6 flex flex-col md:grid md:grid-cols-2">
{practiceSheets.length > 0 ? (
practiceSheets.map((sheet) => (
<Card key={sheet?.id} className="rounded-4xl">
<CardHeader>
<CardTitle className="font-satoshi-medium text-xl">
@ -187,10 +186,12 @@ export const Home = () => {
</CardDescription>
</CardHeader>
<CardContent className="flex justify-between">
<p className="font-satoshi text-gray-700">Not Started</p>
<p className="font-satoshi text-gray-500">
{formatStatus(sheet?.user_status)}
</p>
<Badge
variant="secondary"
className="bg-indigo-100 text-indigo-500 font-satoshi tracking-wide "
className="bg-indigo-100 text-indigo-500 font-satoshi tracking-wide"
>
{sheet?.modules_count} modules
</Badge>
@ -202,17 +203,64 @@ export const Home = () => {
</CardContent>
<CardFooter>
<Button
onClick={() => handleStartPractice(sheet?.id)}
variant="outline"
className="font-satoshi w-full text-lg py-6 bg-linear-to-br from-purple-500 to-purple-600 rounded-3xl text-white"
className="font-satoshi rounded-3xl w-full text-lg py-6 bg-linear-to-br from-purple-500 to-purple-600 text-white"
>
Start
</Button>
</CardFooter>
</Card>
))}
</div>
</TabsContent>
<TabsContent value="COMPLETED" className="pt-6">
))
) : (
<div className="flex items-center justify-center py-4 rounded-full">
<h2 className="text-center font-satoshi text-lg text-gray-500">
No Practice Sheets available.
</h2>
</div>
)}
</div>
</TabsContent>
<TabsContent value="NOT_STARTED" className="pt-6">
<div className="gap-6 flex flex-col md:grid md:grid-cols-2">
{notStartedSheets.map((sheet) => (
<Card key={sheet?.id} className="rounded-4xl">
<CardHeader>
<CardTitle className="font-satoshi-medium text-xl">
{sheet?.title}
</CardTitle>
<CardDescription className="font-satoshi">
{sheet?.description}
</CardDescription>
</CardHeader>
<CardContent className="flex justify-between">
<p className="font-satoshi text-gray-700">Not Started</p>
<Badge
variant="secondary"
className="bg-indigo-100 text-indigo-500 font-satoshi tracking-wide "
>
{sheet?.modules_count} modules
</Badge>
</CardContent>
<CardContent>
<p className="font-satoshi text-gray-700">
{sheet?.time_limit} minutes
</p>
</CardContent>
<CardFooter>
<Button
variant="outline"
className="font-satoshi w-full text-lg py-6 bg-linear-to-br from-purple-500 to-purple-600 rounded-3xl text-white"
>
Start
</Button>
</CardFooter>
</Card>
))}
</div>
</TabsContent>
<TabsContent value="COMPLETED" className="pt-6">
<div className="gap-6 flex flex-col md:grid md:grid-cols-2">
{completedSheets.length > 0 ? (
completedSheets.map((sheet) => (
<Card key={sheet?.id} className="rounded-4xl">
@ -257,46 +305,46 @@ export const Home = () => {
</h2>
</div>
)}
</TabsContent>
</Tabs>
</div>
</TabsContent>
</Tabs>
</section>
<section className="space-y-4 ">
<h1 className="font-satoshi-bold text-2xl tracking-tight">
SAT Preparation Tips
</h1>
<section className="space-y-4 ">
<div className="flex gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Practice regularly with official SAT materials
</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Review your mistakes and learn from them
</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">Focus on your weak areas</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Take full-length practice tests
</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Get plenty of rest before the test day
</p>
</div>
</section>
<section className="w-full space-y-4"></section>
<section className="space-y-4">
<h1 className="font-satoshi-bold text-2xl tracking-tight">
SAT Preparation Tips
</h1>
<section className="space-y-4">
<div className="flex gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Practice regularly with official SAT materials
</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Review your mistakes and learn from them
</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">Focus on your weak areas</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Take full-length practice tests
</p>
</div>
<div className="flex items-center gap-2">
<CheckCircle size={24} color="#AD45FF" />
<p className="font-satoshi text-md">
Get plenty of rest before the test day
</p>
</div>
</section>
</section>
</main>
</div>
</section>
</main>
);
};