@@ -10,6 +10,7 @@ import React, {
1010} from "react" ;
1111import { useRouter , useSearchParams , usePathname } from "next/navigation" ;
1212import { startTransition } from "react" ;
13+ import { SearchResult , SearchResponse } from "@/services/api" ;
1314
1415export interface SearchSettings {
1516 query : string ; // Immediate query for UI binding
@@ -26,8 +27,16 @@ export interface SearchSettings {
2627 similarUid : string | null ;
2728}
2829
30+ interface CachedSearchResults {
31+ results : SearchResult [ ] ;
32+ totalHits : number ;
33+ aggregations : Record < string , any > ;
34+ searchKey : string ; // Key that identifies this search
35+ }
36+
2937interface SearchContextType {
3038 searchSettings : SearchSettings ;
39+ cachedResults : CachedSearchResults | null ;
3140 updateQuery : ( query : string ) => void ; // For immediate input updates
3241 updateSearchSettings : (
3342 settings : Partial < Omit < SearchSettings , "query" | "debouncedQuery" > >
@@ -44,6 +53,9 @@ interface SearchContextType {
4453 paginationStrategy ?: "filter" | "offset" | "trust_estimate" ;
4554 selectedCategory ?: string | null ;
4655 } ) => void ;
56+ setCachedResults : ( results : SearchResponse | null , searchKey : string ) => void ;
57+ getCachedResults : ( searchKey : string ) => CachedSearchResults | null ;
58+ clearCachedResults : ( ) => void ;
4759}
4860
4961const defaultSearchSettings : SearchSettings = {
@@ -64,6 +76,7 @@ const defaultSearchSettings: SearchSettings = {
6476// Default context value for SSR - no-op functions that don't throw errors
6577const defaultSearchContext : SearchContextType = {
6678 searchSettings : defaultSearchSettings ,
79+ cachedResults : null ,
6780 updateQuery : ( ) => {
6881 console . warn ( "Search not available on server" ) ;
6982 } ,
@@ -76,6 +89,13 @@ const defaultSearchContext: SearchContextType = {
7689 loadSearchFromSaved : ( ) => {
7790 console . warn ( "Search not available on server" ) ;
7891 } ,
92+ setCachedResults : ( ) => {
93+ console . warn ( "Search not available on server" ) ;
94+ } ,
95+ getCachedResults : ( ) => null ,
96+ clearCachedResults : ( ) => {
97+ console . warn ( "Search not available on server" ) ;
98+ } ,
7999} ;
80100
81101const SearchContext = createContext < SearchContextType > ( defaultSearchContext ) ;
@@ -318,6 +338,24 @@ function urlToSearchSettings(
318338 } ;
319339}
320340
341+ // Helper function to generate a search key from search settings
342+ function generateSearchKey ( settings : SearchSettings , resourceType ?: string | null ) : string {
343+ const parts = [
344+ settings . debouncedQuery || "" ,
345+ JSON . stringify ( settings . selectedFilters ) ,
346+ settings . useSearch2 ? "1" : "0" ,
347+ settings . hybridWeight . toString ( ) ,
348+ settings . maxDistance . toString ( ) ,
349+ settings . maxDistanceMode ,
350+ settings . directMatchWeight . toString ( ) ,
351+ settings . paginationStrategy ,
352+ settings . selectedCategory || "" ,
353+ resourceType || "" ,
354+ settings . similarUid || "" ,
355+ ] ;
356+ return parts . join ( "|" ) ;
357+ }
358+
321359export function SearchProvider ( { children } : { children : React . ReactNode } ) {
322360 const router = useRouter ( ) ;
323361 const pathname = usePathname ( ) ;
@@ -336,6 +374,7 @@ export function SearchProvider({ children }: { children: React.ReactNode }) {
336374 }
337375 return defaultSearchSettings ;
338376 } ) ;
377+ const [ cachedResults , setCachedResultsState ] = useState < CachedSearchResults | null > ( null ) ;
339378 const [ isRestoringFromNavigation , setIsRestoringFromNavigation ] =
340379 useState ( false ) ;
341380 const isInitialMount = useRef ( true ) ;
@@ -577,21 +616,55 @@ export function SearchProvider({ children }: { children: React.ReactNode }) {
577616 [ ]
578617 ) ;
579618
619+ // Store cached results
620+ const setCachedResults = useCallback ( ( results : SearchResponse | null , searchKey : string ) => {
621+ if ( results ) {
622+ setCachedResultsState ( {
623+ results : results . results || [ ] ,
624+ totalHits : results . num_hits || 0 ,
625+ aggregations : results . aggregations || { } ,
626+ searchKey,
627+ } ) ;
628+ } else {
629+ setCachedResultsState ( null ) ;
630+ }
631+ } , [ ] ) ;
632+
633+ // Get cached results if they match the current search
634+ const getCachedResults = useCallback ( ( searchKey : string ) : CachedSearchResults | null => {
635+ if ( cachedResults && cachedResults . searchKey === searchKey ) {
636+ return cachedResults ;
637+ }
638+ return null ;
639+ } , [ cachedResults ] ) ;
640+
641+ // Clear cached results
642+ const clearCachedResults = useCallback ( ( ) => {
643+ setCachedResultsState ( null ) ;
644+ } , [ ] ) ;
645+
580646 return (
581647 < SearchContext . Provider
582648 value = { {
583649 searchSettings,
650+ cachedResults,
584651 updateQuery,
585652 updateSearchSettings,
586653 resetSearchSettings,
587654 loadSearchFromSaved,
655+ setCachedResults,
656+ getCachedResults,
657+ clearCachedResults,
588658 } }
589659 >
590660 { children }
591661 </ SearchContext . Provider >
592662 ) ;
593663}
594664
665+ // Export the helper function for use in components
666+ export { generateSearchKey } ;
667+
595668export function useSearch ( ) {
596669 const context = useContext ( SearchContext ) ;
597670 return context ;
0 commit comments