diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 2036b17..dd53656 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -5,6 +5,7 @@ "gasPrice": "L1 Gas Price", "transfer": "ERC-20 Transfer", "home": "Home", + "menu": "Menu", "LOCKEDASSETS": { "lockedAssets": "Locked assets", "lockedAssetsDescription": "Locked assets in Elastic Chain Ecosystem", diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 43ba616..d91f19c 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -5,6 +5,7 @@ "gasPrice": "Precio del gas L1", "transfer": "Transferencia ERC-20", "home": "Inicio", + "menu": "MenĂº", "LOCKEDASSETS": { "lockedAssets": "Activos bloqueados", "lockedAssetsDescription": "Activos bloqueados en el ecosistema de Elastic Chain", diff --git a/src/assets/icons/closeDark.svg b/src/assets/icons/closeDark.svg new file mode 100644 index 0000000..4e97a27 --- /dev/null +++ b/src/assets/icons/closeDark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/closeLight.svg b/src/assets/icons/closeLight.svg new file mode 100644 index 0000000..ce94ec5 --- /dev/null +++ b/src/assets/icons/closeLight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/menuDark.svg b/src/assets/icons/menuDark.svg new file mode 100644 index 0000000..924c523 --- /dev/null +++ b/src/assets/icons/menuDark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/menuLight.svg b/src/assets/icons/menuLight.svg new file mode 100644 index 0000000..092832c --- /dev/null +++ b/src/assets/icons/menuLight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Breadcrumb.tsx b/src/components/Breadcrumb.tsx index bf3f456..4a8bb3f 100644 --- a/src/components/Breadcrumb.tsx +++ b/src/components/Breadcrumb.tsx @@ -53,6 +53,7 @@ export const Breadcrumb = ({ isChain }: BreadcrumbProps) => { const BreadcrumbNav = styled('nav')({ display: 'flex', alignItems: 'center', + marginBottom: '1.5rem', }); const BreadcrumbLink = styled(Link)(() => { diff --git a/src/components/ChainInformation.tsx b/src/components/ChainInformation.tsx index c047222..275fe6b 100644 --- a/src/components/ChainInformation.tsx +++ b/src/components/ChainInformation.tsx @@ -99,14 +99,19 @@ export const ChainInformation = () => { ); }; -export const DataContainer = styled(Box)(() => { +export const DataContainer = styled(Box)(({ theme: muiTheme }) => { const { currentTheme, theme } = useCustomTheme(); + return { background: theme === 'dark' ? currentTheme.backgroundTertiary : currentTheme.backgroundSecondary, borderRadius: currentTheme.borderRadius, border: currentTheme.border, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', + + [muiTheme.breakpoints.down('sm')]: { + gridTemplateColumns: 'repeat(1, 1fr)', + }, }; }); diff --git a/src/components/FeeParams.tsx b/src/components/FeeParams.tsx index 8ee4896..107df71 100644 --- a/src/components/FeeParams.tsx +++ b/src/components/FeeParams.tsx @@ -17,7 +17,7 @@ export const FeeParams = () => { const { chainData } = useData(); return ( - <> +
{t('CHAIN.FEEPARAMS.title')} { alt='max-icon' /> - +
); }; diff --git a/src/components/Table.tsx b/src/components/Table.tsx index ac78dca..ba59ada 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -78,7 +78,7 @@ export const DataTable = ({ chains }: TableProps) => { export const STableContainer = styled(TableContainer)(() => { const { currentTheme } = useCustomTheme(); return { - width: '75rem', + width: '100%', borderRadius: currentTheme.borderRadius, border: currentTheme.border, overflow: 'hidden', diff --git a/src/components/TitleBanner.tsx b/src/components/TitleBanner.tsx index 1e4085c..b683a75 100644 --- a/src/components/TitleBanner.tsx +++ b/src/components/TitleBanner.tsx @@ -22,7 +22,7 @@ export const TitleBanner = () => { ); }; -const TitleBox = styled(Box)(() => { +const TitleBox = styled(Box)(({ theme }) => { const { currentTheme } = useCustomTheme(); return { @@ -30,6 +30,14 @@ const TitleBox = styled(Box)(() => { alignItems: 'center', alignSelf: 'flex-start', gap: currentTheme.gap, + justifyContent: 'center', + textAlign: 'center', + [theme.breakpoints.down('sm')]: { + display: 'grid', + gridTemplateColumns: 'auto 1fr', + justifyContent: 'start', + textAlign: 'left', + }, }; }); @@ -44,9 +52,15 @@ const Bold = styled('span')({ fontWeight: 700, }); -const Subtitle = styled(Typography)(() => ({ - fontSize: '3rem', - fontWeight: 700, - lineHeight: '4rem', - letterSpacing: '-0.03em', -})); +const Subtitle = styled(Typography)(({ theme }) => { + return { + fontSize: '3rem', + fontWeight: 700, + lineHeight: '4rem', + letterSpacing: '-0.03em', + gridColumn: 'auto', + [theme.breakpoints.down('sm')]: { + gridColumn: 'span 2', + }, + }; +}); diff --git a/src/components/TotalValueLocked.tsx b/src/components/TotalValueLocked.tsx index c8496fb..3af36b2 100644 --- a/src/components/TotalValueLocked.tsx +++ b/src/components/TotalValueLocked.tsx @@ -1,4 +1,4 @@ -import { Box, Typography, Grid, styled } from '@mui/material'; +import { Box, Typography, Grid, styled, useMediaQuery, useTheme } from '@mui/material'; import { useTranslation } from 'next-i18next'; import { TvlData } from '~/types'; import { TvlContentBox } from '~/components'; @@ -9,17 +9,78 @@ interface TotalValueLockedProps { } export const TotalValueLocked = ({ tvl }: TotalValueLockedProps) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('sm')); + + return ( + <> + {isMobile && } + {!isMobile && } + + ); +}; + +const MobileTvlContainer = ({ tvl }: TotalValueLockedProps) => { + const { t } = useTranslation(); + + const renderTvlContent = ( + data: TvlData, + index: number, + height: string, + xs: number, + smallCard?: boolean, + isLast?: boolean, + ) => ( + + + + + + ); + + return ( + + {/* First item: full width */} + {renderTvlContent(tvl[0], 0, '12rem', 12)} + + {/* Second item: full width, half height */} + {renderTvlContent(tvl[1], 1, '6rem', 12)} + + {/* Third and Fourth items: half width each */} + + {renderTvlContent(tvl[2], 2, '6rem', 6)} + {renderTvlContent(tvl[3], 3, '6rem', 6)} + + + {/* Fifth item: half width */} + + {renderTvlContent(tvl[4], 4, '5rem', 6, true, true)} + + {/* Sixth item: two-thirds width + others remaining */} + + {renderTvlContent(tvl[5], 5, '5rem', 9, true, true)} + + + + {t('HOME.LOCKEDASSETS.others')} + + + + + + + ); +}; + +const DesktopTvlContainer = ({ tvl }: TotalValueLockedProps) => { const { t } = useTranslation(); - /** - * Renders the TVL content within a grid container. - * @param data - The TVL data. - * @param index - The index of the item in the array. - * @param height - The height of the container. - * @param xs - The grid size for the container. - * @param smallCard - Whether the card is small or not. - * @param isLast - Whether the card is the last one or not. - */ const renderTvlContent = ( data: TvlData, index: number, @@ -43,18 +104,23 @@ export const TotalValueLocked = ({ tvl }: TotalValueLockedProps) => { return ( + {/* First item: full width */} {renderTvlContent(tvl[0], 0, '12rem', 12)} + {/* Second item: half width */} {renderTvlContent(tvl[1], 1, '12rem', 6)} + {/* Third and fourth items: one-third width each*/} {tvl.slice(2, 4).map((data, index) => renderTvlContent(data, index + 2, '12rem', 4, true))} + {/* Fifth item: one-third width and half height */} {renderTvlContent(tvl[4], 4, '5.85rem', 6, true)} + {/* Sixth item: three-fourths width and halft height + others remaining width same height*/} {renderTvlContent(tvl[5], 5, '5.85rem', 9, true, true)} @@ -74,7 +140,7 @@ export const TotalValueLocked = ({ tvl }: TotalValueLockedProps) => { const TvlContainer = styled(Grid)({ display: 'flex', flexWrap: 'wrap', - width: '75rem', + alignItems: 'flex-start', }); interface GridContainerProps { diff --git a/src/components/TvlContentBox.tsx b/src/components/TvlContentBox.tsx index 0350fc6..bdb29ea 100644 --- a/src/components/TvlContentBox.tsx +++ b/src/components/TvlContentBox.tsx @@ -16,12 +16,12 @@ export const TvlContentBox = ({ avatar, token, total, tokenName, isLast }: TvlCo - {tokenName} - {token} + {tokenName} + {token} - {formatDataNumber(total, 0, true)} + {formatDataNumber(total, 0, true)} ); }; @@ -33,6 +33,7 @@ const ContentBox = styled(Box)({ alignItems: 'flex-start', zIndex: 1, width: '100%', + height: '100%', }); const TopBox = styled(Box)(() => { @@ -54,32 +55,32 @@ const TokenLogo = styled(Avatar)(({ isLast }) => ({ })); const TvlAmount = styled(Typography)(({ isLast }) => ({ - fontSize: `${isLast ? '0.85rem' : '1rem'}`, + fontSize: `${isLast ? '0.75rem' : '0.875rem'}`, fontWeight: 400, })); const TextBox = styled(Box)(() => { - const { currentTheme } = useCustomTheme(); return { display: 'flex', alignItems: 'center', flexWrap: 'wrap', - gap: currentTheme.gap, }; }); -const TokenName = styled(Typography)({ - fontSize: '0.85rem', +const TokenName = styled(Typography)(({ isLast }) => ({ + fontSize: `${isLast ? '0.75rem' : '0.875rem'}`, fontWeight: 400, whiteSpace: 'nowrap', -}); + margin: '0', +})); -const TokenTicker = styled(Typography)(() => { +const TokenTicker = styled(Typography)(({ isLast }) => { const { currentTheme } = useCustomTheme(); return { - fontSize: '0.85rem', + fontSize: `${isLast ? '0.75rem' : '0.875rem'}`, fontWeight: 400, color: currentTheme.textSecondary, whiteSpace: 'nowrap', + margin: '0', }; }); diff --git a/src/containers/ChainDetail/ChainMetadata.tsx b/src/containers/ChainDetail/ChainMetadata.tsx index 432b607..0f070a1 100644 --- a/src/containers/ChainDetail/ChainMetadata.tsx +++ b/src/containers/ChainDetail/ChainMetadata.tsx @@ -92,6 +92,7 @@ export const ChainMetadata = () => { const MetadataContainer = styled(Box)(() => { const { currentTheme, theme } = useCustomTheme(); + return { background: theme === 'dark' ? currentTheme.backgroundTertiary : currentTheme.backgroundSecondary, borderRadius: currentTheme.borderRadius, @@ -99,21 +100,31 @@ const MetadataContainer = styled(Box)(() => { }; }); -const FirstRow = styled(Box)(() => { - return { - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - padding: '1.5rem 1rem', - }; -}); +const FirstRow = styled(Box)(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + padding: '1.5rem 1rem', + [theme.breakpoints.down('sm')]: { + display: 'grid', + }, +})); -const SecondRow = styled(Box)(() => { +const SecondRow = styled(Box)(({ theme }) => { const { currentTheme } = useCustomTheme(); + return { display: 'flex', + alignItems: 'center', + justifyContent: 'flex-start', + gap: currentTheme.gap, width: '100%', borderTop: currentTheme.border, + [theme.breakpoints.down('sm')]: { + display: 'grid', + justifyContent: 'space-between', + gridTemplateColumns: 'repeat(2, 1fr)', + }, }; }); @@ -127,6 +138,7 @@ const ChainIdentity = styled(Box)(() => { const MetadataButton = styled(Button)(() => { const { currentTheme, theme } = useCustomTheme(); + return { background: theme === 'dark' ? currentTheme.backgroundSecondary : currentTheme.backgroundTertiary, borderRadius: currentTheme.borderRadius, @@ -146,6 +158,7 @@ const MetadataButton = styled(Button)(() => { const AddNetworkBtn = styled(Button)(() => { const { currentTheme } = useCustomTheme(); + return { background: currentTheme.primary[500], borderRadius: currentTheme.borderRadius, @@ -173,18 +186,27 @@ const WebIcon = styled(Image)({ height: '1.25rem', }); -const ButtonsContainer = styled(Box)(() => { +const ButtonsContainer = styled(Box)(({ theme }) => { const { currentTheme } = useCustomTheme(); + return { display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: currentTheme.gap, + marginTop: 0, + [theme.breakpoints.down('sm')]: { + display: 'grid', + justifyContent: 'space-between', + gridTemplateColumns: 'repeat(2, 1fr)', + marginTop: '1rem', + }, }; }); export const ChainName = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '1.5rem', fontWeight: 700, @@ -195,6 +217,7 @@ export const ChainName = styled(Box)(() => { export const ChainId = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '1rem', fontWeight: 400, @@ -205,6 +228,7 @@ export const ChainId = styled(Box)(() => { export const ChainIdValue = styled('span')(() => { const { currentTheme } = useCustomTheme(); + return { color: currentTheme.textPrimary, }; @@ -212,6 +236,7 @@ export const ChainIdValue = styled('span')(() => { const MetadataItem = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + return { display: 'flex', alignItems: 'center', @@ -227,6 +252,7 @@ const MetadataItem = styled(Box)(() => { const Label = styled(Typography)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '0.875rem', lineHeight: '1.25rem', @@ -237,6 +263,7 @@ const Label = styled(Typography)(() => { const Value = styled(Typography)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '1rem', lineHeight: '1.5rem', diff --git a/src/containers/ChainDetail/index.tsx b/src/containers/ChainDetail/index.tsx index b9bc8c6..0ea1ca7 100644 --- a/src/containers/ChainDetail/index.tsx +++ b/src/containers/ChainDetail/index.tsx @@ -7,20 +7,26 @@ import { Breadcrumb } from '~/components'; export const ChainDetail = () => { return ( - - + + + + + ); }; -const ChainContainer = styled(Box)(() => { - return { - width: '85%', - display: 'flex', - flexDirection: 'column', - gap: '4rem', - marginTop: '4rem', - marginBottom: '4rem', - }; -}); +export const ChainContainer = styled(Box)(({ theme }) => ({ + width: '100%', + padding: '0 7rem', + display: 'flex', + flexDirection: 'column', + gap: '4rem', + marginTop: '4rem', + marginBottom: '4rem', + + [theme.breakpoints.down('sm')]: { + padding: '0 1rem', + }, +})); diff --git a/src/containers/Dashboard/index.tsx b/src/containers/Dashboard/index.tsx index a84cddb..e95f29f 100644 --- a/src/containers/Dashboard/index.tsx +++ b/src/containers/Dashboard/index.tsx @@ -2,6 +2,7 @@ import { useTranslation } from 'next-i18next'; import { NotFound, DataTable, Title } from '~/components'; import { useData, useStateContext } from '~/hooks'; +import { StyledSection } from '~/containers'; export const Dashboard = () => { const { t } = useTranslation(); @@ -22,13 +23,13 @@ export const Dashboard = () => { const availableChains = filteredChains?.length > 0; return ( -
+
</header> {availableChains && <DataTable chains={filteredChains} />} {!availableChains && <NotFound text={t('HOME.DASHBOARD.notFound')} />} - </section> + </StyledSection> ); }; diff --git a/src/containers/Footer/index.tsx b/src/containers/Footer/index.tsx index 3713eb7..53c2447 100644 --- a/src/containers/Footer/index.tsx +++ b/src/containers/Footer/index.tsx @@ -40,16 +40,22 @@ export const Footer = () => { ); }; -const FooterContainer = styled('footer')(() => { +export const FooterContainer = styled('footer')(({ theme }) => { const { currentTheme } = useCustomTheme(); return { display: 'flex', - height: '5.5rem', padding: currentTheme.padding, alignItems: 'center', justifyContent: 'space-between', width: '100%', + gap: '0', + + [theme.breakpoints.down('sm')]: { + display: 'grid', + justifyContent: 'center', + gap: '2rem', + }, }; }); diff --git a/src/containers/Header/DesktopHeader.tsx b/src/containers/Header/DesktopHeader.tsx new file mode 100644 index 0000000..baca6b5 --- /dev/null +++ b/src/containers/Header/DesktopHeader.tsx @@ -0,0 +1,45 @@ +import { useTranslation } from 'next-i18next'; +import Image from 'next/image'; + +import { StyledHeader, LogoContainer, Logo, SIconButton, HeaderProps } from '~/containers'; +import { BasicSelect, SearchBar, Gas, SBox } from '~/components'; + +import LogoDark from '~/assets/icons/logoDark.svg'; +import LogoLight from '~/assets/icons/logoLight.svg'; +import LightMode from '~/assets/icons/lightMode.svg'; +import DarkMode from '~/assets/icons/darkMode.svg'; + +interface DesktopHeaderProps extends HeaderProps {} + +export const DesktopHeader = ({ + theme, + goToHome, + handleChangeLanguage, + localesMap, + changeTheme, +}: DesktopHeaderProps) => { + const { + t, + i18n: { language }, + } = useTranslation(); + + return ( + <StyledHeader> + <LogoContainer onClick={goToHome} role='button' aria-label='Navigate to home'> + <Logo src={theme === 'dark' ? LogoDark : LogoLight} alt='ZK Chain Hub' /> + </LogoContainer> + <SBox> + <Gas /> + <SearchBar /> + <BasicSelect + value={t(`LOCALES.${language}`)} + setValue={handleChangeLanguage} + list={Object.values(localesMap)} + /> + <SIconButton onClick={changeTheme}> + {theme === 'dark' ? <Image src={LightMode} alt='light mode' /> : <Image src={DarkMode} alt='dark mode' />} + </SIconButton> + </SBox> + </StyledHeader> + ); +}; diff --git a/src/containers/Header/MobileHeader.tsx b/src/containers/Header/MobileHeader.tsx new file mode 100644 index 0000000..0faed2a --- /dev/null +++ b/src/containers/Header/MobileHeader.tsx @@ -0,0 +1,136 @@ +import React from 'react'; +import { styled } from '@mui/material/styles'; +import { Box, IconButton, Drawer, List, ListItem, Typography } from '@mui/material'; +import { useTranslation } from 'next-i18next'; +import Image from 'next/image'; + +import { StyledHeader, LogoContainer, Logo, HeaderProps } from '~/containers'; +import { BasicSelect, Gas } from '~/components'; +import { useCustomTheme } from '~/hooks'; + +import LogoDark from '~/assets/icons/logoDark.svg'; +import LogoLight from '~/assets/icons/logoLight.svg'; +import LightMode from '~/assets/icons/lightMode.svg'; +import DarkMode from '~/assets/icons/darkMode.svg'; +import SearchDark from '~/assets/icons/searchDark.svg'; +import SearchLight from '~/assets/icons/searchLight.svg'; +import MenuDark from '~/assets/icons/menuDark.svg'; +import MenuLight from '~/assets/icons/menuLight.svg'; +import CloseDark from '~/assets/icons/closeDark.svg'; +import CloseLight from '~/assets/icons/closeLight.svg'; + +interface MobileHeaderProps extends HeaderProps {} + +export const MobileHeader = ({ theme, goToHome, handleChangeLanguage, localesMap, changeTheme }: MobileHeaderProps) => { + const { + t, + i18n: { language }, + } = useTranslation(); + + const [drawerOpen, setDrawerOpen] = React.useState(false); + + const toggleDrawer = (open: boolean) => () => { + setDrawerOpen(open); + }; + + return ( + <StyledHeader> + <LogoContainer onClick={goToHome} role='button' aria-label='Navigate to home'> + <Logo src={theme === 'dark' ? LogoDark : LogoLight} alt='ZK Chain Hub' /> + </LogoContainer> + <IconsContainer> + <SIconButton> + {theme === 'dark' ? ( + <Image src={SearchDark} alt='search-icon' /> + ) : ( + <Image src={SearchLight} alt='search-icon' /> + )} + </SIconButton> + <SIconButton onClick={toggleDrawer(true)}> + {theme === 'dark' ? <Image src={MenuDark} alt='menu-icon' /> : <Image src={MenuLight} alt='menu-icon' />} + </SIconButton> + </IconsContainer> + <Menu anchor='right' open={drawerOpen} onClose={toggleDrawer(false)}> + <DrawerContent> + <DrawerHeader> + <Typography>{t('HOME.menu')}</Typography> + <SIconButton onClick={toggleDrawer(false)} aria-label='close menu'> + <Image src={theme === 'dark' ? CloseDark : CloseLight} alt='close icon' /> + </SIconButton> + </DrawerHeader> + <List> + <ListItem> + <Gas /> + </ListItem> + <ListItem> + <BasicSelect + value={t(`LOCALES.${language}`)} + setValue={handleChangeLanguage} + list={Object.values(localesMap)} + /> + </ListItem> + <ListItem> + <SIconButton onClick={changeTheme}> + {theme === 'dark' ? ( + <Image src={LightMode} alt='light mode' /> + ) : ( + <Image src={DarkMode} alt='dark mode' /> + )} + </SIconButton> + </ListItem> + </List> + </DrawerContent> + </Menu> + </StyledHeader> + ); +}; + +export default MobileHeader; + +const IconsContainer = styled(Box)(() => { + const { currentTheme } = useCustomTheme(); + return { + display: 'flex', + alignItems: 'center', + gap: currentTheme.gap, + }; +}); + +const SIconButton = styled(IconButton)(() => { + const { currentTheme } = useCustomTheme(); + return { + color: currentTheme.textPrimary, + backgroundColor: currentTheme.backgroundSecondary, + borderRadius: currentTheme.borderRadius, + padding: currentTheme.padding, + width: '3.5rem', + height: '3.5rem', + }; +}); + +const Menu = styled(Drawer)(() => { + return { + width: '100%', + }; +}); + +const DrawerContent = styled(Box)(() => { + const { currentTheme } = useCustomTheme(); + return { + width: '100%', + height: '100%', + backgroundColor: currentTheme.backgroundPrimary, + padding: currentTheme.padding, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + }; +}); + +const DrawerHeader = styled(Box)(() => ({ + width: '100%', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + boxSizing: 'border-box', +})); diff --git a/src/containers/Header/index.tsx b/src/containers/Header/index.tsx index c347bc4..6c0d101 100644 --- a/src/containers/Header/index.tsx +++ b/src/containers/Header/index.tsx @@ -1,28 +1,33 @@ import { styled } from '@mui/material/styles'; -import { IconButton, Box } from '@mui/material'; +import { IconButton, Box, useMediaQuery } from '@mui/material'; import { useRouter } from 'next/router'; import { useTranslation } from 'next-i18next'; import Image from 'next/image'; -import { BasicSelect, SearchBar, Gas, SBox } from '~/components'; -import { useCustomTheme } from '~/hooks/useContext/useTheme'; +import { useCustomTheme } from '~/hooks'; import { getConfig } from '~/config'; - -import LogoDark from '~/assets/icons/logoDark.svg'; -import LogoLight from '~/assets/icons/logoLight.svg'; -import LightMode from '~/assets/icons/lightMode.svg'; -import DarkMode from '~/assets/icons/darkMode.svg'; +import { MobileHeader } from './MobileHeader'; +import { DesktopHeader } from './DesktopHeader'; const { DEFAULT_LANG } = getConfig(); +export interface HeaderProps { + theme: 'light' | 'dark'; + goToHome: () => void; + handleChangeLanguage: (value: string) => void; + localesMap: Record<string, string>; + changeTheme: () => void; +} + export const Header = () => { const { changeTheme, theme } = useCustomTheme(); const { t, - i18n: { changeLanguage, language }, + i18n: { changeLanguage }, } = useTranslation(); const router = useRouter(); const { locales, pathname, query } = router; + const isMobile = useMediaQuery('(max-width:600px)'); const localesMap = locales ? Object.fromEntries(locales.map((locale) => [locale, t(`LOCALES.${locale}`)])) : {}; @@ -42,61 +47,66 @@ export const Header = () => { changeLanguage(locale); }; - const handleLogoClick = () => { + const goToHome = () => { router.push('/'); }; return ( - <StyledHeader> - <LogoContainer onClick={handleLogoClick} role='button' aria-label='Navigate to home'> - <Logo src={theme === 'dark' ? LogoDark : LogoLight} alt='ZK Chain Hub' /> - </LogoContainer> - <SBox> - <Gas /> - <SearchBar /> - <BasicSelect - value={t(`LOCALES.${language}`)} - setValue={handleChangeLanguage} - list={Object.values(localesMap)} + <> + {isMobile && ( + <MobileHeader + theme={theme} + goToHome={goToHome} + handleChangeLanguage={handleChangeLanguage} + localesMap={localesMap} + changeTheme={changeTheme} /> - <SIconButton onClick={changeTheme}> - {theme === 'dark' ? <Image src={LightMode} alt='light mode' /> : <Image src={DarkMode} alt='dark mode' />} - </SIconButton> - </SBox> - </StyledHeader> + )} + {!isMobile && ( + <DesktopHeader + theme={theme} + goToHome={goToHome} + handleChangeLanguage={handleChangeLanguage} + localesMap={localesMap} + changeTheme={changeTheme} + /> + )} + </> ); }; -const StyledHeader = styled('header')({ - display: 'flex', - height: '5.5rem', - padding: '1rem', - alignItems: 'center', - justifyContent: 'space-between', - width: '100%', +export const StyledHeader = styled('header')(() => { + const { currentTheme } = useCustomTheme(); + return { + display: 'flex', + padding: currentTheme.padding, + alignItems: 'center', + justifyContent: 'space-between', + width: '100%', + }; }); -const LogoContainer = styled(Box)({ +export const LogoContainer = styled(Box)({ display: 'flex', alignItems: 'center', height: '100%', flexShrink: 0, }); -const Logo = styled(Image)({ +export const Logo = styled(Image)({ width: '13rem', height: 'auto', maxHeight: '100%', }); -const SIconButton = styled(IconButton)(() => { +export const SIconButton = styled(IconButton)(() => { const { currentTheme } = useCustomTheme(); return { - color: `${currentTheme.textPrimary}`, - backgroundColor: `${currentTheme.backgroundSecondary}`, - borderRadius: `${currentTheme.borderRadius}`, - padding: '1rem', - gap: '0.5rem', + color: currentTheme.textPrimary, + backgroundColor: currentTheme.backgroundSecondary, + borderRadius: currentTheme.borderRadius, + padding: currentTheme.padding, + gap: currentTheme.gap, width: '3.5rem', height: '3.5rem', }; diff --git a/src/containers/Landing/index.tsx b/src/containers/Landing/index.tsx index 77b3c3e..9039dd4 100644 --- a/src/containers/Landing/index.tsx +++ b/src/containers/Landing/index.tsx @@ -13,14 +13,17 @@ export const Landing = () => { ); }; -const LandingContainer = styled('main')({ +const LandingContainer = styled('main')(({ theme }) => ({ display: 'flex', flexDirection: 'column', - padding: '0 8rem', + padding: '0 7rem', alignItems: 'center', justifyContent: 'center', width: '100%', gap: '4rem', marginTop: '4rem', marginBottom: '4rem', -}); + [theme.breakpoints.down('sm')]: { + padding: '0 1rem', + }, +})); diff --git a/src/containers/Layout/index.tsx b/src/containers/Layout/index.tsx index 70c923f..503069f 100644 --- a/src/containers/Layout/index.tsx +++ b/src/containers/Layout/index.tsx @@ -1,5 +1,5 @@ import { ReactNode, FunctionComponent } from 'react'; -import { Box, styled } from '@mui/material'; +import { Box } from '@mui/material'; import { Header, Footer } from '~/containers'; interface AppLayoutProps { @@ -11,17 +11,10 @@ const AppLayout: FunctionComponent<AppLayoutProps> = (props) => { return ( <> <Header /> - <Container>{children}</Container> - + <Box>{children}</Box> <Footer /> </> ); }; -const Container = styled(Box)(() => { - return { - width: '85%', - }; -}); - export { AppLayout }; diff --git a/src/containers/LockedAssets/index.tsx b/src/containers/LockedAssets/index.tsx index 35c681e..8459a2f 100644 --- a/src/containers/LockedAssets/index.tsx +++ b/src/containers/LockedAssets/index.tsx @@ -10,7 +10,7 @@ export const LockedAssets = () => { const { ecosystemData, totalL1TVL } = useData(); return ( - <section> + <StyledSection> {ecosystemData && ( <> <LockedAssetsContainer> @@ -23,10 +23,14 @@ export const LockedAssets = () => { <TotalValueLocked tvl={ecosystemData.l1Tvl} /> </> )} - </section> + </StyledSection> ); }; +export const StyledSection = styled('section')(() => ({ + width: '100%', +})); + const LockedAssetsContainer = styled(Box)(() => ({ display: 'flex', justifyContent: 'space-between', diff --git a/src/pages/layout.tsx b/src/pages/layout.tsx index d88bf38..c3b9ce9 100644 --- a/src/pages/layout.tsx +++ b/src/pages/layout.tsx @@ -12,12 +12,6 @@ export default function Layout({ children }: { children: React.ReactNode }) { <p>This website requires JavaScript to function properly.</p> </NoScriptMessage> - {/* TODO: remove when responsive is done */} - <ResponsiveDisclaimer> - <p> - This website is not yet optimized for mobile devices. Please use a desktop browser for the best experience. - </p> - </ResponsiveDisclaimer> <Header /> {children} <Footer /> @@ -51,20 +45,3 @@ const NoScriptMessage = styled('noscript')(() => { }, }; }); - -const ResponsiveDisclaimer = styled('div')(() => { - return { - display: 'none', - margin: '0 auto', - textAlign: 'start', - fontSize: '1.6rem', - padding: '1rem 0.8rem 1rem', - '@media (max-width: 600px)': { - display: 'block', - }, - p: { - padding: '1rem 0', - margin: 0, - }, - }; -});