@@ -15,10 +15,12 @@ import { IUpcomingPaper } from "@/interface";
1515function 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 >
0 commit comments