Skip to content

Commit d175e31

Browse files
committed
fix : refactored sidebar file into sidebarbutton and sidebarsection for reusability
1 parent 8fbc2d4 commit d175e31

3 files changed

Lines changed: 93 additions & 65 deletions

File tree

src/components/SideBar.tsx

Lines changed: 15 additions & 65 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,
@@ -49,24 +45,6 @@ function SideBar({
4945
handleDeselectAll: () => void;
5046
handleDownloadSelected: () => void;
5147
}) {
52-
const Button: React.FC<{
53-
onClick: () => void;
54-
selected?: boolean;
55-
className?: string;
56-
children: React.ReactNode;
57-
}> = ({ onClick, selected = false, className, children }) => (
58-
<div
59-
onClick={onClick}
60-
className={`cursor-pointer rounded-full border-2 px-2 py-1 font-play text-xs font-semibold ${
61-
selected
62-
? "border-[#B2B8FF] bg-[#B2B8FF] text-black dark:border-[#434dba] dark:bg-[#434dba] dark:text-white"
63-
: "border-black hover:bg-[#B2B8FF] hover:text-black dark:border-white dark:hover:border-[#434dba] dark:hover:bg-[#434dba] dark:hover:text-white"
64-
} ${className ?? ""}`}
65-
>
66-
{children}
67-
</div>
68-
);
69-
7048
const exams =
7149
filterOptions?.unique_exams.map((exam) => ({ label: exam, value: exam })) ?? [];
7250
const slots =
@@ -140,20 +118,18 @@ function SideBar({
140118

141119
return (
142120
<div className="no-scrollbar fixed sticky top-0 h-[100vh] flex-col items-baseline overflow-y-auto border-r-2 border-[#36266d] bg-[#f3f5ff] pt-[10px] dark:bg-[#070114] md:flex">
143-
{/* Header */}
144121
<div className="flex w-full items-center justify-between border-b-2 border-[#36266d] px-[10px] py-4">
145122
<div className="flex items-center gap-1">
146123
<Filter size={24} />
147124
<div className="font-play text-xl font-bold">Filters</div>
148125
</div>
149-
<Button onClick={() => handleApplyFilters([], [], [], [], [], false)}>
126+
<SidebarButton onClick={() => handleApplyFilters([], [], [], [], [], false)}>
150127
Reset Filters
151-
</Button>
128+
</SidebarButton>
152129
</div>
153130

154-
{/* Answer Key Toggle */}
155131
<div className="flex w-full items-center justify-between border-b-2 border-[#36266d] px-[10px] py-4">
156-
<Button
132+
<SidebarButton
157133
selected={selectedAnswerKeyIncluded}
158134
onClick={() =>
159135
handleApplyFilters(
@@ -167,49 +143,23 @@ function SideBar({
167143
}
168144
>
169145
Answer Key Available
170-
</Button>
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-
<Button onClick={handleSelectAll}>Select All</Button>
176-
<Button onClick={handleDeselectAll}>Deselect All</Button>
177-
<Button onClick={handleDownloadAll}>Download Selected</Button>
150+
<SidebarButton onClick={handleSelectAll}>Select All</SidebarButton>
151+
<SidebarButton onClick={handleDeselectAll}>Deselect All</SidebarButton>
152+
<SidebarButton onClick={handleDownloadAll}>Download Selected</SidebarButton>
178153
</div>
179154

180-
{/* Filters */}
181155
{filtersForSidebar.map((section) => (
182-
<div
156+
<SidebarSection
183157
key={section.label}
184-
className="flex w-full flex-col items-baseline justify-between border-b-2 border-[#36266d] px-[10px]"
185-
>
186-
<Accordion className="w-full" type="single" collapsible>
187-
<AccordionItem className="border-none no-underline" value="item-1">
188-
<AccordionTrigger className="w-full no-underline">
189-
<div className="font-play text-sm no-underline">{section.label}</div>
190-
</AccordionTrigger>
191-
<AccordionContent>
192-
<div className="my-2 flex w-full flex-wrap items-center">
193-
{section.data.map((item) => (
194-
<Button
195-
key={item.value}
196-
selected={section.selected.includes(item.value)}
197-
onClick={() => {
198-
const newValues = section.selected.includes(item.value)
199-
? section.selected.filter((v) => v !== item.value)
200-
: [...section.selected, item.value];
201-
section.updater(newValues);
202-
}}
203-
className="mb-2 mr-2"
204-
>
205-
{item.label}
206-
</Button>
207-
))}
208-
</div>
209-
</AccordionContent>
210-
</AccordionItem>
211-
</Accordion>
212-
</div>
158+
label={section.label}
159+
data={section.data}
160+
selected={section.selected}
161+
updater={section.updater}
162+
/>
213163
))}
214164
</div>
215165
);

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)