@@ -327,6 +327,19 @@ const SearchPage: React.FC = () => {
327327 </ >
328328 ) ;
329329
330+ // check if has database/dataset matches
331+ const hasDbMatches = ! ! keywordInput && registryMatches . length > 0 ;
332+ const hasDatasetMatches = Array . isArray ( results ) && results . length > 0 ;
333+ // when backend find nothing
334+ const backendEmpty =
335+ ! Array . isArray ( results ) && ( results as any ) ?. msg === "empty output" ;
336+
337+ // show red message only if nothing matched at all
338+ const showNoResults =
339+ hasSearched &&
340+ ! loading &&
341+ ! hasDbMatches &&
342+ ( ! hasDatasetMatches || backendEmpty ) ;
330343 return (
331344 < Container
332345 maxWidth = { false }
@@ -414,8 +427,8 @@ const SearchPage: React.FC = () => {
414427 color : Colors . darkPurple ,
415428 } }
416429 >
417- Use the filters to search for datasets or subjects based on
418- metadata.
430+ Use the filters and click submit to search for datasets or
431+ subjects based on metadata.
419432 </ Typography >
420433 ) }
421434 </ Box >
@@ -523,6 +536,138 @@ const SearchPage: React.FC = () => {
523536
524537 { /* results */ }
525538 { hasSearched && (
539+ < Box mt = { 4 } >
540+ { loading ? (
541+ < Box textAlign = "center" my = { 4 } >
542+ < CircularProgress />
543+ < Typography mt = { 2 } color = "text.secondary" >
544+ Loading search results...
545+ </ Typography >
546+ </ Box >
547+ ) : (
548+ < >
549+ { /* Only show header when there are dataset hits */ }
550+ { hasDatasetMatches && (
551+ < Typography
552+ variant = "h6"
553+ sx = { { borderBottom : "1px solid lightgray" , mb : 2 } }
554+ >
555+ { `Showing ${ results . length } ${
556+ isDataset ? "Datasets" : "Subjects"
557+ } `}
558+ </ Typography >
559+ ) }
560+
561+ { /* pagination + cards (unchanged, but guard with hasDatasetMatches) */ }
562+ { hasDatasetMatches && (
563+ < >
564+ { results . length >= 50 && (
565+ < Box textAlign = "center" mt = { 2 } >
566+ < Button
567+ variant = "outlined"
568+ onClick = { handleLoadMore }
569+ sx = { {
570+ color : Colors . purple ,
571+ borderColor : Colors . purple ,
572+ "&:hover" : {
573+ transform : "scale(1.05)" ,
574+ borderColor : Colors . purple ,
575+ } ,
576+ } }
577+ >
578+ Load Extra 50 Results
579+ </ Button >
580+ </ Box >
581+ ) }
582+
583+ < Box textAlign = "center" mt = { 2 } mb = { 2 } >
584+ < Pagination
585+ count = { Math . ceil ( results . length / itemsPerPage ) }
586+ page = { page }
587+ onChange = { handlePageChange }
588+ showFirstButton
589+ showLastButton
590+ siblingCount = { 2 }
591+ sx = { {
592+ "& .MuiPagination-ul" : { justifyContent : "center" } ,
593+ "& .MuiPaginationItem-root" : {
594+ color : Colors . darkPurple ,
595+ } ,
596+ "& .MuiPaginationItem-root.Mui-selected" : {
597+ backgroundColor : Colors . purple ,
598+ color : "white" ,
599+ fontWeight : "bold" ,
600+ "&:hover" : {
601+ backgroundColor : Colors . secondaryPurple ,
602+ } ,
603+ } ,
604+ } }
605+ />
606+ </ Box >
607+
608+ { results . length > 0 &&
609+ paginatedResults . length > 0 &&
610+ paginatedResults . map ( ( item , idx ) => {
611+ try {
612+ const parsedJson = JSON . parse ( item . json ) ;
613+ const globalIndex = ( page - 1 ) * itemsPerPage + idx ;
614+
615+ const isDataset =
616+ parsedJson ?. value ?. subj &&
617+ Array . isArray ( parsedJson . value . subj ) ;
618+
619+ return isDataset ? (
620+ < DatasetCard
621+ key = { idx }
622+ index = { globalIndex }
623+ dbname = { item . dbname }
624+ dsname = { item . dsname }
625+ parsedJson = { parsedJson }
626+ onChipClick = { handleChipClick }
627+ keyword = { formData . keyword } // for keyword highlight
628+ />
629+ ) : (
630+ < SubjectCard
631+ key = { idx }
632+ index = { globalIndex }
633+ { ...item }
634+ parsedJson = { parsedJson }
635+ onChipClick = { handleChipClick }
636+ />
637+ ) ;
638+ } catch ( e ) {
639+ console . error (
640+ `Failed to parse JSON for item #${ idx } ` ,
641+ e
642+ ) ;
643+ return null ;
644+ }
645+ } ) }
646+ </ >
647+ ) }
648+
649+ { /* Single place to show the red message */ }
650+ { showNoResults && (
651+ < Typography sx = { { color : Colors . error } } >
652+ No results found based on your criteria. Please adjust the
653+ filters and try again.
654+ </ Typography >
655+ ) }
656+
657+ { hasSearched &&
658+ ! loading &&
659+ ! Array . isArray ( results ) &&
660+ results ?. msg !== "empty output" && (
661+ < Typography sx = { { color : Colors . error } } >
662+ Something went wrong. Please try again later.
663+ </ Typography >
664+ ) }
665+ </ >
666+ ) }
667+ </ Box >
668+ ) }
669+
670+ { /* {hasSearched && (
526671 <Box mt={4}>
527672 {loading ? (
528673 <Box textAlign="center" my={4}>
@@ -640,7 +785,7 @@ const SearchPage: React.FC = () => {
640785 </Typography>
641786 )}
642787 </Box>
643- ) }
788+ )} */ }
644789 </ Box >
645790
646791 { /* mobile version filters */ }
0 commit comments