Skip to content

Commit 4d7f332

Browse files
authored
Merge pull request #377 from karannfr/prod
2 parents 09d99d7 + 2d60188 commit 4d7f332

5 files changed

Lines changed: 99 additions & 32 deletions

File tree

pnpm-lock.yaml

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/Searchbar/pinned-searchbar.tsx

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ import { IUpcomingPaper } from "@/interface";
1515
function PinnedSearchBar({
1616
initialSubjects,
1717
setDisplayPapers,
18+
displayPapers,
1819
filtersNotPulled,
1920
}: {
2021
initialSubjects: ICourseWithCount[];
2122
setDisplayPapers: React.Dispatch<React.SetStateAction<IUpcomingPaper[]>>;
23+
displayPapers : IUpcomingPaper[];
2224
filtersNotPulled?: () => void;
2325
}) {
2426
const router = useRouter();
@@ -31,7 +33,7 @@ function PinnedSearchBar({
3133
const [fuzzy, setFuzzy] = useState(
3234
() => new Fuse<ICourseWithCount>([], { keys: ["name"], threshold: 0.3 }),
3335
);
34-
36+
const [highlightedIndex, setHighlightedIndex] = useState<number>(-1);
3537
useEffect(() => {
3638
if (initialSubjects && initialSubjects.length > 0) {
3739
setFuzzy(new Fuse(initialSubjects, { keys: ["name"], threshold: 0.3 }));
@@ -88,24 +90,31 @@ function PinnedSearchBar({
8890
};
8991
}, []);
9092

91-
const handlePinToggle = () => {
93+
const handlePinToggle = (searchTextOverride? : string) => {
9294
const current = !pinned;
9395
setPinned(current);
94-
96+
const subject : string = (searchTextOverride ?? searchText).toString().trim();
9597
if (
96-
searchText.trim() === "" ||
97-
!initialSubjects.find((s) => s.name === searchText)
98+
subject.trim() === "" ||
99+
!initialSubjects.find((s) => s.name === subject)
98100
) {
99101
return;
100102
}
101103

102104
const saved = JSON.parse(
103105
localStorage.getItem("userSubjects") ?? "[]",
104106
) as string[];
105-
const updated = current
106-
? [...new Set([...saved, searchText])]
107-
: saved.filter((s) => s !== searchText);
108-
107+
108+
let updated: string[] = [];
109+
110+
if (saved.includes(subject)) {
111+
updated = saved.filter((s) => s !== subject);
112+
setPinned(false);
113+
} else {
114+
updated = [...new Set([...saved, subject])];
115+
setPinned(true);
116+
}
117+
109118

110119
if (updated.length === 0) {
111120
setShowControls(false);
@@ -116,18 +125,17 @@ function PinnedSearchBar({
116125
localStorage.setItem("userSubjects", JSON.stringify(updated));
117126

118127
setDisplayPapers((prev) => {
119-
if (current) {
120-
if (!prev.find((paper) => paper.subject === searchText)) {
121-
return [...prev, { subject: searchText, slots: [] }];
122-
}
123-
return prev;
128+
const isAlreadyPinned = prev.find((paper) => paper.subject === subject);
129+
if (!isAlreadyPinned) {
130+
return [...prev, { subject, slots: [] }];
124131
} else {
125-
return prev.filter((paper) => paper.subject !== searchText);
132+
return prev.filter((paper) => paper.subject !== subject);
126133
}
127134
});
128135

129136
setSearchText("");
130137
setPinned(false);
138+
setHighlightedIndex(-1);
131139
};
132140

133141
useEffect(() => {
@@ -186,6 +194,24 @@ function PinnedSearchBar({
186194
className={`text-md w-full rounded-lg bg-[#B2B8FF] px-4 py-6 pr-10 font-play tracking-wider text-black shadow-sm ring-0 placeholder:text-black focus:outline-none focus:ring-0 dark:bg-[#7480FF66] dark:text-white placeholder:dark:text-white ${
187195
suggestions.length > 0 ? "rounded-b-none" : ""
188196
}`}
197+
onKeyDown={(e) => {
198+
if(suggestions.length == 0 && searchText.trim() == "") return;
199+
if(e.key == 'ArrowDown'){
200+
e.preventDefault();
201+
setHighlightedIndex((curr) => (curr + 1) % suggestions.length);
202+
}
203+
else if(e.key == 'ArrowUp'){
204+
e.preventDefault();
205+
setHighlightedIndex((curr) => (curr - 1 + suggestions.length) % suggestions.length);
206+
}
207+
else if(e.key == 'Enter'){
208+
e.preventDefault();
209+
if(suggestions.length > 0 && highlightedIndex >=0 && suggestions[highlightedIndex] != undefined){
210+
handlePinToggle(suggestions[highlightedIndex]);
211+
setSuggestions([]);
212+
}
213+
}
214+
}}
189215
/>
190216
<div className="absolute inset-y-0 right-3 flex items-center">
191217
<Search className="h-5 w-5 text-black dark:text-white" />
@@ -202,7 +228,10 @@ function PinnedSearchBar({
202228
<li
203229
key={index}
204230
onClick={() => handleSelectSuggestion(suggestion)}
205-
className="cursor-pointer truncate p-2 hover:bg-gray-100 dark:hover:bg-gray-800"
231+
className={`flex cursor-pointer items-center rounded p-2
232+
${index === highlightedIndex
233+
? "bg-gray-200 dark:bg-gray-800"
234+
: "hover:bg-gray-200 dark:hover:bg-gray-800"}`}
206235
>
207236
{suggestion}
208237
</li>

src/components/Searchbar/searchbar-child.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function SearchBarChild({
2121
const [fuzzy, setFuzzy] = useState(
2222
() => new Fuse<ICourseWithCount>([], { keys: ["name"], threshold: 0.3 }),
2323
);
24+
const [highlightedIndex, setHighlightedIndex] = useState<number>(-1);
2425

2526
useEffect(() => {
2627
if (initialSubjects && initialSubjects.length > 0) {
@@ -47,9 +48,10 @@ function SearchBarChild({
4748

4849
const handleSelectSuggestion = (suggestion: ICourseWithCount) => {
4950
router.push(`/catalogue?subject=${encodeURIComponent(suggestion.name)}`);
50-
setSearchText(suggestion.name);
51+
setSearchText("");
5152
setSuggestions([]);
5253
filtersNotPulled?.();
54+
setHighlightedIndex(-1);
5355
};
5456

5557
const handleClickOutside = (event: MouseEvent) => {
@@ -86,6 +88,38 @@ function SearchBarChild({
8688
onChange={handleSearchChange}
8789
placeholder="Search by subject..."
8890
className={`text-md rounded-lg bg-[#B2B8FF] px-4 py-6 pr-10 font-play tracking-wider text-black shadow-sm ring-0 placeholder:text-black focus:outline-none focus:ring-0 dark:bg-[#7480FF66] dark:text-white placeholder:dark:text-white ${suggestions.length > 0 ? "rounded-b-none" : ""}`}
91+
onKeyDown={(e) => {
92+
if (suggestions.length === 0) return;
93+
if (e.key === "ArrowDown") {
94+
e.preventDefault();
95+
setHighlightedIndex((prev) => (prev + 1) % suggestions.length);
96+
} else if (e.key === "ArrowUp") {
97+
e.preventDefault();
98+
setHighlightedIndex((prev) => (prev - 1 + suggestions.length) % suggestions.length);
99+
} else if (e.key === "Enter") {
100+
e.preventDefault();
101+
if (highlightedIndex >= 0 && highlightedIndex < suggestions.length && suggestions[highlightedIndex] !== undefined) {
102+
handleSelectSuggestion(suggestions[highlightedIndex]);
103+
} else {
104+
router.push(`/catalogue?subject=${encodeURIComponent(searchText)}`);
105+
setSuggestions([]);
106+
}
107+
} else if (e.key === "Tab") {
108+
e.preventDefault();
109+
if(highlightedIndex == -1){
110+
if (suggestions.length > 0 && suggestions[0] != undefined) {
111+
setSearchText(suggestions[0].name || "");
112+
setSuggestions([]);
113+
}
114+
}else{
115+
if (highlightedIndex >= 0 && highlightedIndex < suggestions.length && suggestions[highlightedIndex] !== undefined) {
116+
setSearchText(suggestions[highlightedIndex].name || "");
117+
setHighlightedIndex(-1);
118+
setSuggestions([]);
119+
}
120+
}
121+
}
122+
}}
89123
/>
90124
<button
91125
type="submit"
@@ -100,12 +134,15 @@ function SearchBarChild({
100134
className={`absolute z-20 w-full max-w-xl overflow-y-auto rounded-md rounded-t-none border border-t-0 bg-white text-center shadow-lg dark:bg-[#303771] md:mx-0`}
101135
style={{ maxHeight: "400px" }}
102136
>
103-
{suggestions.map((suggestion) => (
137+
{suggestions.map((suggestion : ICourseWithCount, index) => (
104138
<li
105139
key={suggestion._id}
106140
onClick={() => handleSelectSuggestion(suggestion)}
107-
className="flex cursor-pointer items-center rounded p-2 hover:bg-gray-100 dark:hover:bg-gray-800"
108-
>
141+
className={`flex cursor-pointer items-center rounded p-2
142+
${index === highlightedIndex
143+
? "bg-gray-200 dark:bg-gray-800"
144+
: "hover:bg-gray-200 dark:hover:bg-gray-800"}`}
145+
>
109146
<div
110147
id="paper_count"
111148
className="mr-4 flex h-8 w-8 items-center justify-center rounded-md bg-[#171720] text-xs font-semibold text-white"

src/components/Searchbar/searchbar.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ import { type IUpcomingPaper } from "@/interface";
88

99
export default function SearchBar({
1010
type = "default",
11+
displayPapers,
1112
setDisplayPapers,
1213
}: {
1314
type?: "default" | "pinned",
15+
displayPapers?:IUpcomingPaper[]
1416
setDisplayPapers?: React.Dispatch<React.SetStateAction<IUpcomingPaper[]>>
1517
}) {
1618
const { courses, loading, error, refetch } = useCourses();
1719

18-
return type === "pinned" && setDisplayPapers !== undefined ? (
19-
<PinnedSearchBar initialSubjects={courses} setDisplayPapers={setDisplayPapers} />
20+
return type === "pinned" && setDisplayPapers !== undefined && displayPapers !== undefined ? (
21+
<PinnedSearchBar initialSubjects={courses} setDisplayPapers={setDisplayPapers} displayPapers={displayPapers} />
2022
) : (
2123
<SearchBarChild initialSubjects={courses} />
2224
);

src/components/ui/PinnedModal.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const PinnedModal = ({triggerName = "Pin Subjects", page = "Navbar"} : {triggerN
9898
<DialogTitle className="font-normal">
9999
<div className="my-3 flex w-full flex-col items-center gap-2 text-sm">
100100
<div className="w-full">
101-
<SearchBar type="pinned" setDisplayPapers={setDisplayPapers}/>
101+
<SearchBar type="pinned" setDisplayPapers={setDisplayPapers} displayPapers={displayPapers}/>
102102
</div>
103103
</div>
104104
<div className="mt-4">
@@ -118,7 +118,6 @@ const PinnedModal = ({triggerName = "Pin Subjects", page = "Navbar"} : {triggerN
118118
Unpin
119119
<PinOff size={16}/>
120120
</div>
121-
122121
</button>
123122
</div>
124123
))

0 commit comments

Comments
 (0)