Commit bb9842bc authored by tom's avatar tom

search results page

parent e52386b8
...@@ -8,12 +8,12 @@ import PageNextJs from 'nextjs/PageNextJs'; ...@@ -8,12 +8,12 @@ import PageNextJs from 'nextjs/PageNextJs';
import LayoutSearchResults from 'ui/shared/layout/LayoutSearchResults'; import LayoutSearchResults from 'ui/shared/layout/LayoutSearchResults';
// const SearchResults = dynamic(() => import('ui/pages/SearchResults'), { ssr: false }); const SearchResults = dynamic(() => import('ui/pages/SearchResults'), { ssr: false });
const Page: NextPageWithLayout<Props> = (props: Props) => { const Page: NextPageWithLayout<Props> = (props: Props) => {
return ( return (
<PageNextJs pathname="/search-results" query={ props.query }> <PageNextJs pathname="/search-results" query={ props.query }>
{ /* <SearchResults/> */ } <SearchResults/>
</PageNextJs> </PageNextJs>
); );
}; };
......
import { Box, chakra, Table, Tbody, Tr, Th, Show, Hide } from '@chakra-ui/react'; import { Box, chakra } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type { FormEvent } from 'react'; import type { FormEvent } from 'react';
import React from 'react'; import React from 'react';
...@@ -11,20 +11,20 @@ import { useSettingsContext } from 'lib/contexts/settings'; ...@@ -11,20 +11,20 @@ import { useSettingsContext } from 'lib/contexts/settings';
import * as regexp from 'lib/regexp'; import * as regexp from 'lib/regexp';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import removeQueryParam from 'lib/router/removeQueryParam'; import removeQueryParam from 'lib/router/removeQueryParam';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { TableBody, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
import useMarketplaceApps from 'ui/marketplace/useMarketplaceApps'; import useMarketplaceApps from 'ui/marketplace/useMarketplaceApps';
import SearchResultListItem from 'ui/searchResults/SearchResultListItem'; import SearchResultListItem from 'ui/searchResults/SearchResultListItem';
import SearchResultsInput from 'ui/searchResults/SearchResultsInput'; import SearchResultsInput from 'ui/searchResults/SearchResultsInput';
import SearchResultTableItem from 'ui/searchResults/SearchResultTableItem'; import SearchResultTableItem from 'ui/searchResults/SearchResultTableItem';
import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar'; import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary'; import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
import Skeleton from 'ui/shared/chakra/Skeleton';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as Layout from 'ui/shared/layout/components'; import * as Layout from 'ui/shared/layout/components';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import Pagination from 'ui/shared/pagination/Pagination'; import Pagination from 'ui/shared/pagination/Pagination';
import type { SearchResultAppItem } from 'ui/shared/search/utils'; import type { SearchResultAppItem } from 'ui/shared/search/utils';
import Thead from 'ui/shared/TheadSticky';
import HeaderAlert from 'ui/snippets/header/HeaderAlert'; import HeaderAlert from 'ui/snippets/header/HeaderAlert';
import HeaderDesktop from 'ui/snippets/header/HeaderDesktop'; import HeaderDesktop from 'ui/snippets/header/HeaderDesktop';
import HeaderMobile from 'ui/snippets/header/HeaderMobile'; import HeaderMobile from 'ui/snippets/header/HeaderMobile';
...@@ -144,7 +144,7 @@ const SearchResultsPageContent = () => { ...@@ -144,7 +144,7 @@ const SearchResultsPageContent = () => {
return ( return (
<> <>
<Show below="lg" ssr={ false }> <Box hideFrom="lg">
{ displayedItems.map((item, index) => ( { displayedItems.map((item, index) => (
<SearchResultListItem <SearchResultListItem
key={ (isLoading ? 'placeholder_' : 'actual_') + index } key={ (isLoading ? 'placeholder_' : 'actual_') + index }
...@@ -154,18 +154,18 @@ const SearchResultsPageContent = () => { ...@@ -154,18 +154,18 @@ const SearchResultsPageContent = () => {
addressFormat={ settingsContext?.addressFormat } addressFormat={ settingsContext?.addressFormat }
/> />
)) } )) }
</Show> </Box>
<Hide below="lg" ssr={ false }> <Box hideBelow="lg">
<Table fontWeight={ 500 }> <TableRoot fontWeight={ 500 }>
<Thead top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }> <TableHeaderSticky top={ pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : 0 }>
<Tr> <TableRow>
<Th width="30%">Search result</Th> <TableColumnHeader width="30%">Search result</TableColumnHeader>
<Th width="35%"/> <TableColumnHeader width="35%"/>
<Th width="35%" pr={ 10 }/> <TableColumnHeader width="35%" pr={ 10 }/>
<Th width="150px">Category</Th> <TableColumnHeader width="150px">Category</TableColumnHeader>
</Tr> </TableRow>
</Thead> </TableHeaderSticky>
<Tbody> <TableBody>
{ displayedItems.map((item, index) => ( { displayedItems.map((item, index) => (
<SearchResultTableItem <SearchResultTableItem
key={ (isLoading ? 'placeholder_' : 'actual_') + index } key={ (isLoading ? 'placeholder_' : 'actual_') + index }
...@@ -175,9 +175,9 @@ const SearchResultsPageContent = () => { ...@@ -175,9 +175,9 @@ const SearchResultsPageContent = () => {
addressFormat={ settingsContext?.addressFormat } addressFormat={ settingsContext?.addressFormat }
/> />
)) } )) }
</Tbody> </TableBody>
</Table> </TableRoot>
</Hide> </Box>
</> </>
); );
})(); })();
...@@ -190,7 +190,7 @@ const SearchResultsPageContent = () => { ...@@ -190,7 +190,7 @@ const SearchResultsPageContent = () => {
const resultsCount = pagination.page === 1 && !data?.next_page_params ? displayedItems.length : '50+'; const resultsCount = pagination.page === 1 && !data?.next_page_params ? displayedItems.length : '50+';
const text = isLoading && pagination.page === 1 ? ( const text = isLoading && pagination.page === 1 ? (
<Skeleton h={ 6 } w="280px" borderRadius="full" mb={ pagination.isVisible ? 0 : 6 }/> <Skeleton loading h={ 6 } w="280px" borderRadius="full" mb={ pagination.isVisible ? 0 : 6 }/>
) : ( ) : (
( (
<> <>
...@@ -214,9 +214,9 @@ const SearchResultsPageContent = () => { ...@@ -214,9 +214,9 @@ const SearchResultsPageContent = () => {
return ( return (
<> <>
<Box display={{ base: 'block', lg: 'none' }}>{ text }</Box> <Box hideFrom="lg">{ text }</Box>
<ActionBar mt={{ base: 0, lg: -6 }} alignItems="center"> <ActionBar mt={{ base: 0, lg: -6 }} alignItems="center">
<Box display={{ base: 'none', lg: 'block' }}>{ text }</Box> <Box hideBelow="lg">{ text }</Box>
<Pagination { ...pagination }/> <Pagination { ...pagination }/>
</ActionBar> </ActionBar>
</> </>
......
This diff is collapsed.
This diff is collapsed.
import { PopoverTrigger, PopoverContent, PopoverBody, useDisclosure } from '@chakra-ui/react';
import { debounce } from 'es-toolkit'; import { debounce } from 'es-toolkit';
import type { FormEvent, FocusEvent } from 'react'; import type { FormEvent, FocusEvent } from 'react';
import React from 'react'; import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import { getRecentSearchKeywords } from 'lib/recentSearchKeywords'; import { getRecentSearchKeywords } from 'lib/recentSearchKeywords';
import Popover from 'ui/shared/chakra/Popover'; import { PopoverBody, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import SearchBarBackdrop from 'ui/snippets/searchBar/SearchBarBackdrop'; import SearchBarBackdrop from 'ui/snippets/searchBar/SearchBarBackdrop';
import SearchBarInput from 'ui/snippets/searchBar/SearchBarInput'; import SearchBarInput from 'ui/snippets/searchBar/SearchBarInput';
import SearchBarRecentKeywords from 'ui/snippets/searchBar/SearchBarRecentKeywords'; import SearchBarRecentKeywords from 'ui/snippets/searchBar/SearchBarRecentKeywords';
...@@ -17,7 +17,7 @@ type Props = { ...@@ -17,7 +17,7 @@ type Props = {
}; };
const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }: Props) => { const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }: Props) => {
const { isOpen, onClose, onOpen } = useDisclosure(); const { open, onClose, onOpen } = useDisclosure();
const inputRef = React.useRef<HTMLFormElement>(null); const inputRef = React.useRef<HTMLFormElement>(null);
const menuRef = React.useRef<HTMLDivElement>(null); const menuRef = React.useRef<HTMLDivElement>(null);
const menuWidth = React.useRef<number>(0); const menuWidth = React.useRef<number>(0);
...@@ -25,6 +25,10 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange } ...@@ -25,6 +25,10 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }
const recentSearchKeywords = getRecentSearchKeywords(); const recentSearchKeywords = getRecentSearchKeywords();
const handleOpenChange = React.useCallback(({ open }: { open: boolean }) => {
open && onOpen();
}, [ onOpen ]);
const handleFocus = React.useCallback(() => { const handleFocus = React.useCallback(() => {
onOpen(); onOpen();
}, [ onOpen ]); }, [ onOpen ]);
...@@ -47,7 +51,7 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange } ...@@ -47,7 +51,7 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }
inputRef.current?.querySelector('input')?.focus(); inputRef.current?.querySelector('input')?.focus();
}, [ handleSearchTermChange ]); }, [ handleSearchTermChange ]);
const menuPaddingX = isMobile ? 32 : 0; const menuPaddingX = isMobile ? 24 : 0;
const calculateMenuWidth = React.useCallback(() => { const calculateMenuWidth = React.useCallback(() => {
menuWidth.current = (inputRef.current?.getBoundingClientRect().width || 0) - menuPaddingX; menuWidth.current = (inputRef.current?.getBoundingClientRect().width || 0) - menuPaddingX;
}, [ menuPaddingX ]); }, [ menuPaddingX ]);
...@@ -68,17 +72,15 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange } ...@@ -68,17 +72,15 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }
}; };
}, [ calculateMenuWidth ]); }, [ calculateMenuWidth ]);
const isSuggestOpen = isOpen && recentSearchKeywords.length > 0 && searchTerm.trim().length === 0; const isSuggestOpen = open && recentSearchKeywords.length > 0 && searchTerm.trim().length === 0;
return ( return (
<> <>
<Popover <PopoverRoot
isOpen={ isSuggestOpen } open={ isSuggestOpen }
autoFocus={ false } autoFocus={ false }
onClose={ onClose } onOpenChange={ handleOpenChange }
placement="bottom-start" positioning={{ offset: { mainAxis: isMobile ? 0 : 8, crossAxis: isMobile ? 12 : 0 } }}
offset={ isMobile ? [ 16, -12 ] : [ 0, 8 ] }
isLazy
> >
<PopoverTrigger> <PopoverTrigger>
<SearchBarInput <SearchBarInput
...@@ -98,7 +100,7 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange } ...@@ -98,7 +100,7 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }
<SearchBarRecentKeywords onClick={ handleSearchTermChange } onClear={ onClose }/> <SearchBarRecentKeywords onClick={ handleSearchTermChange } onClear={ onClose }/>
</PopoverBody> </PopoverBody>
</PopoverContent> </PopoverContent>
</Popover> </PopoverRoot>
<SearchBarBackdrop isOpen={ isSuggestOpen }/> <SearchBarBackdrop isOpen={ isSuggestOpen }/>
</> </>
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment