Skip to content

Commit 9c661d5

Browse files
Merge pull request #320 from shikhar-sahay/prod
Fixed issue #263
2 parents 0122dd1 + d175e31 commit 9c661d5

3 files changed

Lines changed: 107 additions & 99 deletions

File tree

src/components/SideBar.tsx

Lines changed: 29 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@
33
import React from "react";
44
import { Filter } from "lucide-react";
55
import { type Filters, type IPaper } from "@/interface";
6-
import {
7-
Accordion,
8-
AccordionContent,
9-
AccordionItem,
10-
AccordionTrigger,
11-
} from "@/components/ui/accordion";
6+
import SidebarButton from "./SidebarButton";
7+
import SidebarSection from "./SidebarSection";
128

139
function SideBar({
1410
selectedExams,
@@ -43,27 +39,18 @@ function SideBar({
4339
years: string[],
4440
campus: string[],
4541
semester: string[],
46-
anskey: boolean,
42+
anskey: boolean
4743
) => void;
4844
handleSelectAll: () => void;
4945
handleDeselectAll: () => void;
5046
handleDownloadSelected: () => void;
5147
}) {
5248
const exams =
53-
filterOptions?.unique_exams.map((exam) => ({
54-
label: exam,
55-
value: exam,
56-
})) ?? [];
49+
filterOptions?.unique_exams.map((exam) => ({ label: exam, value: exam })) ?? [];
5750
const slots =
58-
filterOptions?.unique_slots.map((slot) => ({
59-
label: slot,
60-
value: slot,
61-
})) ?? [];
51+
filterOptions?.unique_slots.map((slot) => ({ label: slot, value: slot })) ?? [];
6252
const years =
63-
filterOptions?.unique_years.map((year) => ({
64-
label: year,
65-
value: year,
66-
})) ?? [];
53+
filterOptions?.unique_years.map((year) => ({ label: year, value: year })) ?? [];
6754
const semesters =
6855
filterOptions?.unique_semesters.map((semester) => ({
6956
label: semester,
@@ -82,7 +69,7 @@ function SideBar({
8269
selectedYears,
8370
selectedCampuses,
8471
selectedSemesters,
85-
selectedAnswerKeyIncluded,
72+
selectedAnswerKeyIncluded
8673
),
8774
},
8875
{
@@ -96,7 +83,7 @@ function SideBar({
9683
selectedYears,
9784
selectedCampuses,
9885
selectedSemesters,
99-
selectedAnswerKeyIncluded,
86+
selectedAnswerKeyIncluded
10087
),
10188
},
10289
{
@@ -110,7 +97,7 @@ function SideBar({
11097
newVal,
11198
selectedCampuses,
11299
selectedSemesters,
113-
selectedAnswerKeyIncluded,
100+
selectedAnswerKeyIncluded
114101
),
115102
},
116103
{
@@ -124,7 +111,7 @@ function SideBar({
124111
selectedYears,
125112
selectedCampuses,
126113
newVal,
127-
selectedAnswerKeyIncluded,
114+
selectedAnswerKeyIncluded
128115
),
129116
},
130117
];
@@ -136,100 +123,43 @@ function SideBar({
136123
<Filter size={24} />
137124
<div className="font-play text-xl font-bold">Filters</div>
138125
</div>
139-
<div className="flex flex-col">
140-
<div
141-
className="cursor-pointer rounded-full border-2 border-black px-2 py-1 font-play text-xs font-semibold hover:bg-slate-800 hover:text-white dark:border-[#434dba] dark:hover:border-white dark:hover:bg-slate-900"
142-
onClick={() => {
143-
handleApplyFilters([], [], [], [], [], false);
144-
}}
145-
>
146-
Reset Filters
147-
</div>
148-
</div>
126+
<SidebarButton onClick={() => handleApplyFilters([], [], [], [], [], false)}>
127+
Reset Filters
128+
</SidebarButton>
149129
</div>
150130

151131
<div className="flex w-full items-center justify-between border-b-2 border-[#36266d] px-[10px] py-4">
152-
<div
153-
onClick={() => {
132+
<SidebarButton
133+
selected={selectedAnswerKeyIncluded}
134+
onClick={() =>
154135
handleApplyFilters(
155136
selectedExams,
156137
selectedSlots,
157138
selectedYears,
158139
selectedCampuses,
159140
selectedSemesters,
160-
!selectedAnswerKeyIncluded,
161-
);
162-
}}
163-
className={`flex cursor-pointer rounded-full border-2 border-black px-2 py-1 font-play text-xs font-semibold hover:bg-slate-800 hover:text-white ${
164-
selectedAnswerKeyIncluded
165-
? "border-[#B2B8FF] bg-[#B2B8FF] hover:border-black hover:bg-[#B2B8FF] dark:border-[#434dba] dark:bg-[#434dba] dark:hover:border-[white] dark:hover:bg-[#434dba]"
166-
: "bg-none hover:bg-[#B2B8FF] dark:border-white dark:hover:border-[#434dba]"
167-
}`}
141+
!selectedAnswerKeyIncluded
142+
)
143+
}
168144
>
169145
Answer Key Available
170-
</div>
146+
</SidebarButton>
171147
</div>
172148

173-
{/* Select/Deselect/Download All Buttons */}
174149
<div className="flex w-full flex-wrap justify-between gap-2 border-b-2 border-[#36266d] px-[10px] py-4">
175-
<div
176-
onClick={handleSelectAll}
177-
className="cursor-pointer rounded-full border-2 border-black px-2 py-1 font-play text-xs font-semibold hover:bg-[#B2B8FF] hover:text-black dark:border-white dark:hover:border-[#434dba] dark:hover:bg-[#434dba] dark:hover:text-white"
178-
>
179-
Select All
180-
</div>
181-
<div
182-
onClick={handleDeselectAll}
183-
className="cursor-pointer rounded-full border-2 border-black px-2 py-1 font-play text-xs font-semibold hover:bg-[#B2B8FF] hover:text-black dark:border-white dark:hover:border-[#434dba] dark:hover:bg-[#434dba] dark:hover:text-white"
184-
>
185-
Deselect All
186-
</div>
187-
<div
188-
onClick={handleDownloadAll}
189-
className="cursor-pointer rounded-full border-2 border-black px-2 py-1 font-play text-xs font-semibold hover:bg-[#B2B8FF] hover:text-black dark:border-white dark:hover:border-[#434dba] dark:hover:bg-[#434dba] dark:hover:text-white"
190-
>
191-
Download Selected
192-
</div>
150+
<SidebarButton onClick={handleSelectAll}>Select All</SidebarButton>
151+
<SidebarButton onClick={handleDeselectAll}>Deselect All</SidebarButton>
152+
<SidebarButton onClick={handleDownloadAll}>Download Selected</SidebarButton>
193153
</div>
194154

195-
{/* Filters */}
196155
{filtersForSidebar.map((section) => (
197-
<div
156+
<SidebarSection
198157
key={section.label}
199-
className="flex w-full flex-col items-baseline justify-between border-b-2 border-[#36266d] px-[10px]"
200-
>
201-
<Accordion className="w-full" type="single" collapsible>
202-
<AccordionItem className="border-none no-underline" value="item-1">
203-
<AccordionTrigger className="w-full no-underline">
204-
<div className="font-play text-sm no-underline">
205-
{section.label}
206-
</div>
207-
</AccordionTrigger>
208-
<AccordionContent>
209-
<div className="my-2 flex w-full flex-wrap items-center">
210-
{section.data.map((item) => (
211-
<div
212-
key={item.value}
213-
onClick={() => {
214-
const newValues = section.selected.includes(item.value)
215-
? section.selected.filter((v) => v !== item.value)
216-
: [...section.selected, item.value];
217-
section.updater(newValues);
218-
}}
219-
className={`mb-2 mr-2 flex h-fit cursor-pointer items-center rounded-full border-2 border-black px-2 py-1 font-play text-xs font-semibold hover:bg-slate-800 hover:text-white ${
220-
section.selected.includes(item.value)
221-
? "border-[#B2B8FF] bg-[#B2B8FF] dark:border-[#434dba] dark:bg-[#434dba]"
222-
: "bg-none dark:border-white"
223-
}`}
224-
>
225-
{item.label}
226-
</div>
227-
))}
228-
</div>
229-
</AccordionContent>
230-
</AccordionItem>
231-
</Accordion>
232-
</div>
158+
label={section.label}
159+
data={section.data}
160+
selected={section.selected}
161+
updater={section.updater}
162+
/>
233163
))}
234164
</div>
235165
);

src/components/SidebarButton.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use client";
2+
3+
import React from "react";
4+
5+
const SidebarButton: React.FC<{
6+
onClick: () => void;
7+
selected?: boolean;
8+
className?: string;
9+
children: React.ReactNode;
10+
}> = ({ onClick, selected = false, className, children }) => (
11+
<div
12+
onClick={onClick}
13+
className={`cursor-pointer rounded-full border-2 px-2 py-1 font-play text-xs font-semibold ${
14+
selected
15+
? "border-[#B2B8FF] bg-[#B2B8FF] text-black dark:border-[#434dba] dark:bg-[#434dba] dark:text-white"
16+
: "border-black hover:bg-[#B2B8FF] hover:text-black dark:border-white dark:hover:border-[#434dba] dark:hover:bg-[#434dba] dark:hover:text-white"
17+
} ${className ?? ""}`}
18+
>
19+
{children}
20+
</div>
21+
);
22+
23+
export default SidebarButton;

src/components/SidebarSection.tsx

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"use client";
2+
3+
import React from "react";
4+
import {
5+
Accordion,
6+
AccordionContent,
7+
AccordionItem,
8+
AccordionTrigger,
9+
} from "@/components/ui/accordion";
10+
import SidebarButton from "./SidebarButton";
11+
12+
interface SidebarSectionProps {
13+
label: string;
14+
data: { label: string; value: string }[];
15+
selected: string[];
16+
updater: (newVal: string[]) => void;
17+
}
18+
19+
const SidebarSection: React.FC<SidebarSectionProps> = ({
20+
label,
21+
data,
22+
selected,
23+
updater,
24+
}) => (
25+
<div className="flex w-full flex-col items-baseline justify-between border-b-2 border-[#36266d] px-[10px]">
26+
<Accordion className="w-full" type="single" collapsible>
27+
<AccordionItem className="border-none no-underline" value="item-1">
28+
<AccordionTrigger className="w-full no-underline">
29+
<div className="font-play text-sm no-underline">{label}</div>
30+
</AccordionTrigger>
31+
<AccordionContent>
32+
<div className="my-2 flex w-full flex-wrap items-center">
33+
{data.map((item) => (
34+
<SidebarButton
35+
key={item.value}
36+
selected={selected.includes(item.value)}
37+
onClick={() => {
38+
const newValues = selected.includes(item.value)
39+
? selected.filter((v) => v !== item.value)
40+
: [...selected, item.value];
41+
updater(newValues);
42+
}}
43+
className="mb-2 mr-2"
44+
>
45+
{item.label}
46+
</SidebarButton>
47+
))}
48+
</div>
49+
</AccordionContent>
50+
</AccordionItem>
51+
</Accordion>
52+
</div>
53+
);
54+
55+
export default SidebarSection;

0 commit comments

Comments
 (0)