Skip to content

Commit

Permalink
feat: search results
Browse files Browse the repository at this point in the history
  • Loading branch information
0xtiti committed Aug 13, 2024
1 parent ddc3e8e commit 3a87712
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 40 deletions.
7 changes: 5 additions & 2 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"transfer": "ERC-20 Transfer",
"home": "Home",
"menu": "Menu",
"search": "Search",
"LOCKEDASSETS": {
"lockedAssets": "Locked assets",
"lockedAssetsDescription": "Locked assets in Elastic Chain Ecosystem",
Expand All @@ -20,9 +21,11 @@
"tvl": "TVL (L1)",
"type": "Type",
"search": "Search (Chain)",
"notFound": "Chain not found",
"noRPC": "No RPC",
"noMetadata": "No Metadata"
"noMetadata": "No Metadata",
"searchResults": "Search results",
"enterSearchTerm": "Enter the name or chain ID",
"notFound": "No results found"
}
},
"CHAIN": {
Expand Down
7 changes: 5 additions & 2 deletions public/locales/es/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"transfer": "Transferencia ERC-20",
"home": "Inicio",
"menu": "Menú",
"search": "Búsqueda",
"LOCKEDASSETS": {
"lockedAssets": "Activos bloqueados",
"lockedAssetsDescription": "Activos bloqueados en el ecosistema de Elastic Chain",
Expand All @@ -20,9 +21,11 @@
"tvl": "TVL (L1)",
"type": "Tipo",
"search": "Buscar (Cadena)",
"notFound": "Cadena no encontrada",
"noRPC": "Sin RPC",
"noMetadata": "Sin Metadata"
"noMetadata": "Sin Metadata",
"searchResults": "Resultados de la búsqueda",
"enterSearchTerm": "Ingrese el nombre o ID de la cadena",
"notFound": "No se encontraron resultados"
}
},
"CHAIN": {
Expand Down
11 changes: 0 additions & 11 deletions src/components/NotFound.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import CloseLight from '~/assets/icons/closeLight.svg';

export const SearchBar = () => {
const { t } = useTranslation();
const { searchTerm, setSearchTerm, setIsSearch, isSearch, handleSearchOn } = useSearchContext();
const { searchTerm, setSearchTerm, closeSearch, isSearch, navigateToSearch } = useSearchContext();
const { theme } = useCustomTheme();

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -27,7 +27,7 @@ export const SearchBar = () => {
value={searchTerm}
onChange={handleChange}
placeholder={t('HOME.DASHBOARD.search')}
onClick={handleSearchOn}
onClick={navigateToSearch}
InputProps={{
startAdornment: (
<InputAdornment position='start'>
Expand All @@ -37,7 +37,7 @@ export const SearchBar = () => {
}}
/>
{isSearch && (
<SIconButton onClick={() => setIsSearch(false)} aria-label='close-search'>
<SIconButton onClick={closeSearch} aria-label='close-search'>
<Image src={theme === 'dark' ? CloseDark : CloseLight} alt='close icon' />
</SIconButton>
)}
Expand Down
1 change: 0 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export * from './RPC';
export * from './TVL';
export * from './ChainInformation';
export * from './BasicSelect';
export * from './NotFound';
export * from './Gas';
export * from './TvlContentBox';
export * from './Breadcrumb';
Expand Down
57 changes: 48 additions & 9 deletions src/containers/Dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { useTranslation } from 'next-i18next';
import { Typography, styled } from '@mui/material';

import { NotFound, DataTable, Title } from '~/components';
import { useData, useSearchContext } from '~/hooks';
import { StyledSection } from '~/containers';
import { DataTable } from '~/components';
import { useData, useSearchContext, useCustomTheme } from '~/hooks';

export const Dashboard = () => {
const { t } = useTranslation();
const { ecosystemData } = useData();
const { searchTerm } = useSearchContext();
const { searchTerm, isSearch } = useSearchContext();

const filteredChains = ecosystemData?.zkChains.filter((chain) => {
const chainIdStr = String(chain.chainId);
const formattedSearchTerm = String(searchTerm).toLowerCase();

// Check if either chain name or chain ID matches the search term
const matchesName = chain.chainName.toLowerCase().includes(formattedSearchTerm);
const matchesId = chainIdStr.includes(formattedSearchTerm);

Expand All @@ -23,13 +22,53 @@ export const Dashboard = () => {
const availableChains = filteredChains?.length > 0;

return (
<StyledSection>
<DashboardContainer>
<header>
<Title title={t('HOME.DASHBOARD.title')} />
{!isSearch && <h2>{t('HOME.DASHBOARD.title')}</h2>}

{isSearch && availableChains && (
<>
{searchTerm ? (
<SearchLabel>{`${t(
'HOME.DASHBOARD.searchResults',
)} '${searchTerm}' (${filteredChains?.length})`}</SearchLabel>
) : (
<SearchLabel>{t('HOME.DASHBOARD.enterSearchTerm')}</SearchLabel>
)}
</>
)}
</header>

{availableChains && <DataTable chains={filteredChains} />}
{!availableChains && <NotFound text={t('HOME.DASHBOARD.notFound')} />}
</StyledSection>
{!availableChains && <SearchLabel>{t('HOME.DASHBOARD.notFound')}</SearchLabel>}
</DashboardContainer>
);
};

const DashboardContainer = styled('section')(({ theme }) => {
const { isSearch } = useSearchContext();

return {
width: '100%',
...(isSearch && {
padding: '0 7rem',
minHeight: 'calc(100vh - 11rem)',
[theme.breakpoints.down('sm')]: {
padding: '0 1rem',
},
}),
};
});

const SearchLabel = styled(Typography)(() => {
const { currentTheme } = useCustomTheme();

return {
color: currentTheme.textPrimary,
fontSize: '1rem',
fontWeight: 400,
lineHeight: '1.5rem',
textAlign: 'center',
margin: '1.5rem 0',
};
});
5 changes: 3 additions & 2 deletions src/containers/Header/MobileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Image from 'next/image';

import { StyledHeader, LogoContainer, Logo, HeaderProps } from '~/containers';
import { BasicSelect, Gas } from '~/components';
import { useCustomTheme } from '~/hooks';
import { useCustomTheme, useSearchContext } from '~/hooks';

import LogoDark from '~/assets/icons/logoDark.svg';
import LogoLight from '~/assets/icons/logoLight.svg';
Expand All @@ -26,6 +26,7 @@ export const MobileHeader = ({ theme, goToHome, handleChangeLanguage, localesMap
t,
i18n: { language },
} = useTranslation();
const { handleSearchOn } = useSearchContext();

const [drawerOpen, setDrawerOpen] = React.useState(false);

Expand All @@ -39,7 +40,7 @@ export const MobileHeader = ({ theme, goToHome, handleChangeLanguage, localesMap
<Logo src={theme === 'dark' ? LogoDark : LogoLight} alt='ZK Chain Hub' />
</LogoContainer>
<IconsContainer>
<SIconButton>
<SIconButton onClick={handleSearchOn}>
{theme === 'dark' ? (
<Image src={SearchDark} alt='search-icon' />
) : (
Expand Down
37 changes: 36 additions & 1 deletion src/pages/search/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
import { useEffect } from 'react';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { GetStaticProps } from 'next';
import { useTranslation } from 'next-i18next';

import { CustomHead } from '~/components';
import { Dashboard } from '~/containers';
import { getConfig } from '~/config';
import { useSearchContext } from '~/hooks';

const { DEFAULT_LANG, SUPPORTED_LANGUAGES } = getConfig();

const Search = () => {
return <Dashboard />;
const { t } = useTranslation();
const { setIsSearch } = useSearchContext();

useEffect(() => {
setIsSearch(true);

// Cleanup function to reset the state when the component unmounts
return () => setIsSearch(false);
}, [setIsSearch]);

return (
<>
<CustomHead title={t('HOME.search')} />
<Dashboard />
</>
);
};

export const getStaticProps: GetStaticProps = async ({ locale }) => {
const i18Config = await serverSideTranslations(locale || DEFAULT_LANG, ['common'], null, SUPPORTED_LANGUAGES);

return {
props: {
...i18Config,
},
};
};

export default Search;
35 changes: 26 additions & 9 deletions src/providers/SearchProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { createContext, useState } from 'react';
import router from 'next/router';
import { createContext, useState, useEffect, useCallback } from 'react';
import { useRouter } from 'next/router';

type ContextType = {
searchTerm: string;
setSearchTerm: (val: string) => void;

isSearch: boolean;
setIsSearch: (val: boolean) => void;

handleSearchOn: () => void;
navigateToSearch: () => void;
closeSearch: () => void;
};

interface StateProps {
Expand All @@ -20,11 +19,28 @@ export const SearchContext = createContext({} as ContextType);
export const SearchProvider = ({ children }: StateProps) => {
const [searchTerm, setSearchTerm] = useState<string>('');
const [isSearch, setIsSearch] = useState<boolean>(false);
const [previousPage, setPreviousPage] = useState<string>('');
const router = useRouter();

const handleSearchOn = () => {
setIsSearch(true);
const navigateToSearch = useCallback(() => {
setPreviousPage(router.asPath); // Save the current page before navigating to search
router.push('/search');
};
}, [router]);

const closeSearch = useCallback(() => {
if (previousPage && previousPage !== '/search') {
router.push(previousPage); // Go back to the previous page if it's not the search page
} else {
router.push('/'); // Otherwise, go to the home page
}
setIsSearch(false);
}, [previousPage, router]);

useEffect(() => {
if (!isSearch) {
setPreviousPage('');
}
}, [isSearch]);

return (
<SearchContext.Provider
Expand All @@ -33,7 +49,8 @@ export const SearchProvider = ({ children }: StateProps) => {
setSearchTerm,
isSearch,
setIsSearch,
handleSearchOn,
navigateToSearch,
closeSearch,
}}
>
{children}
Expand Down

0 comments on commit 3a87712

Please sign in to comment.