Skip to content

Commit d517233

Browse files
committed
feat: integrate review page
1 parent c75af6e commit d517233

2 files changed

Lines changed: 57 additions & 36 deletions

File tree

frontend/app/routes/exam-room/layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useExam } from './context';
66
import { TimeRemaining } from './components/time-remaining';
77
import { Slider } from '~/components/ui/slider';
88
import { Submitting } from './components/submitting';
9+
import { Module } from '~/common/types';
910

1011
interface LayoutProps {
1112
children: ReactNode;
@@ -37,7 +38,10 @@ export function Layout({ children }: LayoutProps) {
3738
<div className="flex flex-col">
3839
<div className="flex flex-1 justify-center bg-primary min-h-[90px]">
3940
<div
40-
className={cn('grid grid-cols-3 w-5/6 items-center', (exam.duration === 0 || isCompleted) && 'grid-cols-2')}
41+
className={cn(
42+
'grid grid-cols-3 w-5/6 items-center',
43+
(isCompleted || (exam.module === Module.SPEAKING && !isReviewing)) && 'grid-cols-2'
44+
)}
4145
>
4246
<div className="flex justify-start items-center gap-4">
4347
<Link to="/section">
Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import { Section } from '~/common/types';
1+
import { Module, Section } from '~/common/types';
22
import { cn } from '~/lib/utils';
3-
import { type ReactNode } from 'react';
4-
import { Globe, TableOfContents } from 'lucide-react';
5-
import React from 'react';
3+
import { Suspense, type ReactNode } from 'react';
4+
import { TableOfContents } from 'lucide-react';
65
import listening from '../listeningicon.svg';
76
import writing from '../writingicon.svg';
87
import reading from '../readingicon.svg';
98
import speaking from '../speakingicon.svg';
10-
import globe from '../globe.svg';
119
import { useState } from 'react';
1210
import { requireAuth } from '~/common/auth';
1311
import type { Route } from './+types/review';
12+
import { client } from '~/clients/client';
13+
import { Link } from 'react-router';
14+
import dayjs from 'dayjs';
15+
import { match } from 'ts-pattern';
1416

1517
export async function loader({ request }: Route.LoaderArgs) {
1618
await requireAuth(request);
@@ -46,62 +48,75 @@ function ModuleSelector({ section, setSection }: ModuleSelectorProps) {
4648
return (
4749
<div>
4850
<div className="flex justify-center items-center gap-4">
49-
<SectionButton section={Section.FULLTEST} currentSection={section} setSection={setSection} icon={<Globe />}>
51+
{/* <SectionButton section={Section.FULLTEST} currentSection={section} setSection={setSection} icon={<Globe />}>
5052
Full Test
51-
</SectionButton>
53+
</SectionButton> */}
5254
<SectionButton
53-
section={Section.FULLTEST}
55+
section={Section.SECTIONTEST}
5456
currentSection={section}
5557
setSection={setSection}
5658
icon={<TableOfContents />}
5759
>
5860
Section Test
5961
</SectionButton>
6062
</div>
61-
<div className="flex justify-center w-[1300px] mx-auto h-[7px] bg-[#D9D9D9] mt-10 mb-10 rounded-full"></div>
63+
<div className="border border-b border-gray-200 mt-8 mb-2" />
6264
</div>
6365
);
6466
}
6567

6668
const Reviewbar = () => {
67-
const sections = [
68-
{
69-
name: 'Listening',
70-
testNumber: 1,
71-
icon: <img className="w-12 h-12" src={listening} alt="Listening" />,
72-
score: 6.5,
73-
},
74-
{ name: 'Writing', testNumber: 2, icon: <img className="w-12 h-12" src={writing} alt="Writing" />, score: 7.0 },
75-
{ name: 'Reading', testNumber: 3, icon: <img className="w-12 h-12" src={reading} alt="Reading" />, score: 8.5 },
76-
{ name: 'Speaking', testNumber: 4, icon: <img className="w-12 h-12" src={speaking} alt="Speaking" />, score: 7.5 },
77-
{ name: 'Fulltest', testNumber: 1, icon: <img className="w-12 h-12" src={globe} alt="globe" />, score: 7.5 },
78-
];
69+
const {
70+
data: { data: sections },
71+
} = client.useSuspenseQuery('get', '/question-bank/v1/sessions');
7972

80-
const maxScore = 9.0; // Max score for all sections
73+
// const sections = [
74+
// {
75+
// name: 'Listening',
76+
// testNumber: 1,
77+
// icon: <img className="w-12 h-12" src={listening} alt="Listening" />,
78+
// score: 6.5,
79+
// },
80+
// { name: 'Writing', testNumber: 2, icon: <img className="w-12 h-12" src={writing} alt="Writing" />, score: 7.0 },
81+
// { name: 'Reading', testNumber: 3, icon: <img className="w-12 h-12" src={reading} alt="Reading" />, score: 8.5 },
82+
// { name: 'Speaking', testNumber: 4, icon: <img className="w-12 h-12" src={speaking} alt="Speaking" />, score: 7.5 },
83+
// { name: 'Fulltest', testNumber: 1, icon: <img className="w-12 h-12" src={globe} alt="globe" />, score: 7.5 },
84+
// ];
85+
//
86+
// const maxScore = 9.0; // Max score for all sections
8187

8288
return (
83-
<div className="p-6 w-full mx-4">
84-
{sections.map((section) => (
89+
<div className="w-full">
90+
{sections.map((section, index) => (
8591
<div
86-
key={section.name}
92+
key={section.test.testId}
8793
className="flex items-center justify-between p-4 border rounded-lg shadow-md mb-4 bg-white transform transition-transform hover:scale-105 hover:shadow-lg"
8894
>
8995
<div className="flex items-center gap-4">
90-
<div className="text-3xl">{section.icon}</div>
96+
<div className="text-3xl">
97+
{match(section.test.module as Module)
98+
.with(Module.LISTENING, () => <img className="w-12 h-12" src={listening} alt="Listening" />)
99+
.with(Module.WRITING, () => <img className="w-12 h-12" src={writing} alt="Writing" />)
100+
.with(Module.READING, () => <img className="w-12 h-12" src={reading} alt="Reading" />)
101+
.with(Module.SPEAKING, () => <img className="w-12 h-12" src={speaking} alt="Speaking" />)
102+
.exhaustive()}
103+
</div>
91104
<div>
92105
<h2 className="text-xl font-semibold">
93-
{section.name} / Test {section.testNumber}
106+
{section.test.module} / Test {sections.length - index}
94107
</h2>
95-
<p className="text-sm text-gray-500">21 Jan 2568 10:30 A.M.</p>
108+
<p className="text-sm text-gray-500">{dayjs(section.startedAt).format('DD MMM YYYY HH:mm')}</p>
96109
</div>
97110
</div>
98111
<div className="flex items-center gap-2">
99-
<div className="rounded-full px-4 py-2 text-lg text-black" style={{ backgroundColor: '#D9D9D9' }}>
112+
{/* <div className="rounded-full px-4 py-2 text-lg text-black" style={{ backgroundColor: '#D9D9D9' }}>
100113
{section.score}/{maxScore}
101-
</div>
102-
<button className="rounded-lg px-5 py-2 text-black" style={{ backgroundColor: '#D9D9D9' }}>
103-
Review
104-
</button>
114+
</div> */}
115+
<Link to={`/test/${section.test.testId}/start`}>
116+
<button className="rounded-lg px-5 py-2 text-black" style={{ backgroundColor: '#D9D9D9' }}>
117+
Review
118+
</button>
119+
</Link>
105120
</div>
106121
</div>
107122
))}
@@ -110,11 +125,13 @@ const Reviewbar = () => {
110125
};
111126

112127
export default function QuestionBank() {
113-
const [section, setSection] = useState<Section>(Section.FULLTEST);
128+
const [section, setSection] = useState<Section>(Section.SECTIONTEST);
114129
return (
115130
<div className="flex flex-col gap-8 my-4">
116131
<ModuleSelector section={section} setSection={setSection} />
117-
<Reviewbar />
132+
<Suspense>
133+
<Reviewbar />
134+
</Suspense>
118135
</div>
119136
);
120137
}

0 commit comments

Comments
 (0)