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/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/TitleBanner.tsx b/src/components/TitleBanner.tsx index 1e4085c..45a5234 100644 --- a/src/components/TitleBanner.tsx +++ b/src/components/TitleBanner.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'next-i18next'; -import { Box, Typography, styled } from '@mui/material'; +import { Box, Typography, styled, useMediaQuery } from '@mui/material'; import Image from 'next/image'; import ZkLogoDark from '~/assets/icons/zkLogoDark.svg'; @@ -24,12 +24,16 @@ export const TitleBanner = () => { const TitleBox = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + const isMobile = useMediaQuery('(max-width:600px)'); return { - display: 'flex', + display: isMobile ? 'grid' : 'flex', + gridTemplateColumns: isMobile ? 'auto 1fr' : 'none', alignItems: 'center', alignSelf: 'flex-start', gap: currentTheme.gap, + justifyContent: isMobile ? 'start' : 'center', + textAlign: isMobile ? 'left' : 'center', }; }); @@ -44,9 +48,14 @@ const Bold = styled('span')({ fontWeight: 700, }); -const Subtitle = styled(Typography)(() => ({ - fontSize: '3rem', - fontWeight: 700, - lineHeight: '4rem', - letterSpacing: '-0.03em', -})); +const Subtitle = styled(Typography)(() => { + const isMobile = useMediaQuery('(max-width:600px)'); + + return { + fontSize: '3rem', + fontWeight: 700, + lineHeight: '4rem', + letterSpacing: '-0.03em', + gridColumn: isMobile ? 'span 2' : 'auto', + }; +}); diff --git a/src/containers/ChainDetail/ChainMetadata.tsx b/src/containers/ChainDetail/ChainMetadata.tsx index 432b607..2d64a1a 100644 --- a/src/containers/ChainDetail/ChainMetadata.tsx +++ b/src/containers/ChainDetail/ChainMetadata.tsx @@ -1,4 +1,4 @@ -import { Avatar, Box, Button, Typography, styled } from '@mui/material'; +import { Avatar, Box, Button, Typography, styled, useMediaQuery } from '@mui/material'; import { useTranslation } from 'next-i18next'; import Image from 'next/image'; @@ -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, @@ -100,8 +101,10 @@ const MetadataContainer = styled(Box)(() => { }); const FirstRow = styled(Box)(() => { + const isMobile = useMediaQuery('(max-width:600px)'); + return { - display: 'flex', + display: isMobile ? 'grid' : 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '1.5rem 1rem', @@ -110,8 +113,14 @@ const FirstRow = styled(Box)(() => { const SecondRow = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + const isMobile = useMediaQuery('(max-width:600px)'); + return { - display: 'flex', + display: isMobile ? 'grid' : 'flex', + alignItems: 'center', + justifyContent: isMobile ? 'space-between' : 'flex-start', + gap: currentTheme.gap, + gridTemplateColumns: isMobile ? 'repeat(2, 1fr)' : 'none', width: '100%', borderTop: currentTheme.border, }; @@ -127,6 +136,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 +156,7 @@ const MetadataButton = styled(Button)(() => { const AddNetworkBtn = styled(Button)(() => { const { currentTheme } = useCustomTheme(); + return { background: currentTheme.primary[500], borderRadius: currentTheme.borderRadius, @@ -175,16 +186,21 @@ const WebIcon = styled(Image)({ const ButtonsContainer = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + const isMobile = useMediaQuery('(max-width:600px)'); + return { - display: 'flex', + display: isMobile ? 'grid' : 'flex', alignItems: 'center', - justifyContent: 'flex-end', + justifyContent: isMobile ? 'space-between' : 'flex-end', gap: currentTheme.gap, + gridTemplateColumns: isMobile ? 'repeat(2, 1fr)' : 'none', + marginTop: isMobile ? '1rem' : 0, }; }); export const ChainName = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '1.5rem', fontWeight: 700, @@ -195,6 +211,7 @@ export const ChainName = styled(Box)(() => { export const ChainId = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '1rem', fontWeight: 400, @@ -205,6 +222,7 @@ export const ChainId = styled(Box)(() => { export const ChainIdValue = styled('span')(() => { const { currentTheme } = useCustomTheme(); + return { color: currentTheme.textPrimary, }; @@ -212,6 +230,7 @@ export const ChainIdValue = styled('span')(() => { const MetadataItem = styled(Box)(() => { const { currentTheme } = useCustomTheme(); + return { display: 'flex', alignItems: 'center', @@ -227,6 +246,7 @@ const MetadataItem = styled(Box)(() => { const Label = styled(Typography)(() => { const { currentTheme } = useCustomTheme(); + return { fontSize: '0.875rem', lineHeight: '1.25rem', @@ -237,6 +257,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 ef23c86..9c26059 100644 --- a/src/containers/ChainDetail/index.tsx +++ b/src/containers/ChainDetail/index.tsx @@ -8,8 +8,11 @@ import { Breadcrumb } from '~/components'; export const ChainDetail = () => { return ( - - + + + + + ); diff --git a/src/containers/Header/DesktopHeader.tsx b/src/containers/Header/DesktopHeader.tsx new file mode 100644 index 0000000..d4bf2b2 --- /dev/null +++ b/src/containers/Header/DesktopHeader.tsx @@ -0,0 +1,46 @@ +import { useTranslation } from 'next-i18next'; +import Image from 'next/image'; + +import { StyledHeader, LogoContainer, Logo, SIconButton } from '~/containers'; +import { HeaderProps } from '.'; + +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 ( + + + + + + + + + + {theme === 'dark' ? light mode : dark mode} + + + + ); +}; diff --git a/src/containers/Header/MobileHeader.tsx b/src/containers/Header/MobileHeader.tsx new file mode 100644 index 0000000..1f93333 --- /dev/null +++ b/src/containers/Header/MobileHeader.tsx @@ -0,0 +1,128 @@ +import React from 'react'; +import { styled } from '@mui/material/styles'; +import { Box, IconButton, Drawer, List, ListItem } from '@mui/material'; +import MenuIcon from '@mui/icons-material/Menu'; +import { useTranslation } from 'next-i18next'; +import Image from 'next/image'; + +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 { BasicSelect, Gas, Icon } from '~/components'; +import { useCustomTheme } from '~/hooks'; +import SearchDark from '~/assets/icons/searchDark.svg'; +import SearchLight from '~/assets/icons/searchLight.svg'; + +interface MobileHeaderProps { + theme: string; + goToHome: () => void; + handleChangeLanguage: (value: string) => void; + localesMap: Record; + changeTheme: () => void; +} + +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 ( + + + + + + + + + + + + + + + + + + + + + + + + {theme === 'dark' ? ( + light mode + ) : ( + dark mode + )} + + + + + + + ); +}; + +export default MobileHeader; + +// Styled components +const StyledHeader = styled('header')({ + display: 'flex', + height: '5.5rem', + padding: '1rem', + alignItems: 'center', + justifyContent: 'space-between', + width: '100%', +}); + +const LogoContainer = styled(Box)({ + display: 'flex', + alignItems: 'center', + height: '100%', + flexShrink: 0, +}); + +const Logo = styled(Image)({ + width: '10rem', + height: 'auto', +}); + +const IconsContainer = styled(Box)({ + display: 'flex', + alignItems: 'center', + gap: '1rem', +}); + +const SearchIconButton = styled(IconButton)({ + padding: 0, +}); + +const SIconButton = styled(IconButton)(() => { + const { currentTheme } = useCustomTheme(); + return { + color: `${currentTheme.textPrimary}`, + backgroundColor: `${currentTheme.backgroundSecondary}`, + borderRadius: `${currentTheme.borderRadius}`, + padding: '1rem', + width: '3.5rem', + height: '3.5rem', + }; +}); + +const DrawerContent = styled(Box)({ + width: '250px', + padding: '1rem', +}); diff --git a/src/containers/Header/index.tsx b/src/containers/Header/index.tsx index c347bc4..65bb97d 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 { 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; + 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,32 +47,30 @@ export const Header = () => { changeLanguage(locale); }; - const handleLogoClick = () => { + const goToHome = () => { router.push('/'); }; - return ( - - - - - - - - - - {theme === 'dark' ? light mode : dark mode} - - - + return isMobile ? ( + + ) : ( + ); }; -const StyledHeader = styled('header')({ +export const StyledHeader = styled('header')({ display: 'flex', height: '5.5rem', padding: '1rem', @@ -76,20 +79,20 @@ const StyledHeader = styled('header')({ 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}`,