1- import { useCallback , useMemo , useState , useEffect } from "react" ;
1+ import { useCallback , useEffect , useMemo , useState } from "react" ;
22import { useLocation , useNavigate } from "react-router-dom" ;
3- import type { HeritageSearchParams } from "../../../../domain/types" ;
3+ import type {
4+ Category ,
5+ HeritageSearchParams ,
6+ IdSortOption ,
7+ SearchValues ,
8+ StudyRegion ,
9+ } from "../../../../domain/types" ;
410import {
511 parseHeritageSearchParams ,
612 serializeHeritageSearchParams ,
7- } from "../mapper/search-heritages.params.ts" ;
8- import { HeritageSubHeader } from "@features/top/components/HeritageSubHeader.tsx" ;
9- import type { SearchValues } from "@features/top/components/HeritageSearchForm.tsx" ;
13+ } from "../mapper/search-heritages.params" ;
14+ import { DEFAULT_HERITAGE_SEARCH_PARAMS as SEARCH_PARAMS } from "../mapper/search-heritage.types" ;
15+ import { HeritageSubHeader } from "@features/top/components/HeritageSubHeader" ;
16+
17+ const DEFAULT_TOP_PER_PAGE = 30 ;
18+ const DEFAULT_ORDER : IdSortOption = "asc" ;
19+
20+ const toStudyRegionOrNull = ( value : StudyRegion | "" ) : StudyRegion | null =>
21+ value === "" ? null : value ;
22+
23+ const toCategoryOrNull = ( value : Category | "" ) : Category | null => ( value === "" ? null : value ) ;
1024
1125const toSearchYearOrNull = ( value : string ) : number | null => {
1226 const trimmed = value . trim ( ) ;
@@ -16,71 +30,40 @@ const toSearchYearOrNull = (value: string): number | null => {
1630 return Math . floor ( parsed ) ;
1731} ;
1832
19- /** Determine whether any valid search condition exists */
20- const hasSearchParams = ( params : HeritageSearchParams ) : boolean =>
21- params . search_query !== null ||
22- params . region !== null ||
23- params . category !== null ||
24- params . year_inscribed_from !== null ||
25- params . year_inscribed_to !== null ;
33+ const toSearchValues = ( params : HeritageSearchParams ) : SearchValues => ( {
34+ region : params . region ?? "" ,
35+ category : params . category ?? "" ,
36+ keyword : params . search_query ?? "" ,
37+ yearInscribedFrom : params . year_inscribed_from !== null ? String ( params . year_inscribed_from ) : "" ,
38+ yearInscribedTo : params . year_inscribed_to !== null ? String ( params . year_inscribed_to ) : "" ,
39+ } ) ;
2640
27- type Props = {
28- /** Notify the parent which API should be used: list or search */
29- onApiModeChange ?: ( isSearch : boolean ) => void ;
30- } ;
31-
32- export function SearchHeritageFormContainer ( { onApiModeChange } : Props ) {
41+ export function SearchHeritageFormContainer ( ) {
3342 const location = useLocation ( ) ;
3443 const navigate = useNavigate ( ) ;
3544
36- const params : HeritageSearchParams = useMemo (
37- ( ) => parseHeritageSearchParams ( location . search ) ,
38- [ location . search ] ,
39- ) ;
40-
41- // If any search parameter exists, we consider it as "search mode". Otherwise, it's "list mode".
42- const isSearchMode = useMemo ( ( ) => hasSearchParams ( params ) , [ params ] ) ;
43-
44- useEffect ( ( ) => {
45- onApiModeChange ?.( isSearchMode ) ;
46- } , [ isSearchMode , onApiModeChange ] ) ;
47-
48- // If no search condition exists on the results page, redirect to the list page.
49- useEffect ( ( ) => {
50- if ( ! isSearchMode && location . pathname === "/heritages/results" ) {
51- navigate ( { pathname : "/heritages" , search : location . search } , { replace : true } ) ;
52- }
53- } , [ isSearchMode , location . pathname , location . search , navigate ] ) ;
54-
55- const valueFromUrl : SearchValues = useMemo (
56- ( ) => ( {
57- region : params . region ?? "" ,
58- category : params . category ?? "" ,
59- keyword : params . search_query ?? "" ,
60- yearInscribedFrom :
61- params . year_inscribed_from !== null ? String ( params . year_inscribed_from ) : "" ,
62- yearInscribedTo : params . year_inscribed_to !== null ? String ( params . year_inscribed_to ) : "" ,
63- } ) ,
64- [
65- params . region ,
66- params . category ,
67- params . search_query ,
68- params . year_inscribed_from ,
69- params . year_inscribed_to ,
70- ] ,
71- ) ;
45+ const params : HeritageSearchParams = useMemo ( ( ) => {
46+ const parsed = parseHeritageSearchParams ( location . search ) ;
47+ return {
48+ ...SEARCH_PARAMS ,
49+ ...parsed ,
50+ current_page : parsed . current_page ?? 1 ,
51+ per_page : parsed . per_page ?? DEFAULT_TOP_PER_PAGE ,
52+ order : parsed . order ?? DEFAULT_ORDER ,
53+ } ;
54+ } , [ location . search ] ) ;
7255
73- const [ draft , setDraft ] = useState < SearchValues > ( valueFromUrl ) ;
56+ const [ draft , setDraft ] = useState < SearchValues > ( ( ) => toSearchValues ( params ) ) ;
7457
7558 useEffect ( ( ) => {
76- setDraft ( valueFromUrl ) ;
77- } , [ valueFromUrl ] ) ;
59+ setDraft ( toSearchValues ( params ) ) ;
60+ } , [ params ] ) ;
7861
79- const onChange = useCallback ( ( next : SearchValues ) => {
62+ const handleChange = useCallback ( ( next : SearchValues ) => {
8063 setDraft ( next ) ;
8164 } , [ ] ) ;
8265
83- const onSubmit = useCallback (
66+ const handleSubmit = useCallback (
8467 ( query : Partial < SearchValues > ) => {
8568 const merged : SearchValues = {
8669 region : query . region ?? draft . region ,
@@ -91,20 +74,24 @@ export function SearchHeritageFormContainer({ onApiModeChange }: Props) {
9174 } ;
9275
9376 const nextParams : HeritageSearchParams = {
94- ...params ,
95- region : ( merged . region . trim ( ) || null ) as HeritageSearchParams [ "region" ] ,
96- category : ( merged . category . trim ( ) || null ) as HeritageSearchParams [ "category" ] ,
97- search_query : merged . keyword . trim ( ) || null ,
77+ ...SEARCH_PARAMS ,
78+ search_query : merged . keyword . trim ( ) === "" ? null : merged . keyword . trim ( ) ,
79+ region : toStudyRegionOrNull ( merged . region ) ,
80+ category : toCategoryOrNull ( merged . category ) ,
9881 year_inscribed_from : toSearchYearOrNull ( merged . yearInscribedFrom ) ,
9982 year_inscribed_to : toSearchYearOrNull ( merged . yearInscribedTo ) ,
10083 current_page : 1 ,
84+ per_page : params . per_page ?? DEFAULT_TOP_PER_PAGE ,
85+ order : params . order ?? DEFAULT_ORDER ,
86+ country : null ,
10187 } ;
10288
10389 const search = serializeHeritageSearchParams ( nextParams ) ;
104- navigate ( { pathname : location . pathname , search } , { replace : false } ) ;
90+ navigate ( { pathname : "/heritages/results" , search } , { replace : false } ) ;
91+ setDraft ( merged ) ;
10592 } ,
106- [ navigate , location . pathname , params , draft ] ,
93+ [ draft , navigate , params . per_page , params . order ] ,
10794 ) ;
10895
109- return < HeritageSubHeader value = { draft } onChange = { onChange } onSubmit = { onSubmit } /> ;
96+ return < HeritageSubHeader value = { draft } onChange = { handleChange } onSubmit = { handleSubmit } /> ;
11097}
0 commit comments