Skip to content

Commit 7a1983e

Browse files
committed
feat: complete mobile header of search page
1 parent 6f04037 commit 7a1983e

File tree

15 files changed

+336
-285
lines changed

15 files changed

+336
-285
lines changed

src/app/[locale]/(main)/(homepage)/components/MobileHeader.tsx

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,21 @@
11
'use client';
22

3+
import ProductSearchForm from '@/components/ProductSearchForm/ProductSearchForm';
34
import useSearchPageParams from '@/hooks/useSearchPageParams';
4-
import { SearchPageParamsKeys } from '@/utils/params';
55
import { SearchOutlined } from '@mui/icons-material';
66
import { Box, Container, Stack, Typography } from '@mui/material';
77
import { grey } from '@mui/material/colors';
88
import { useTranslations } from 'next-intl';
9-
import { useState, useTransition } from 'react';
10-
import SearchDialog from './SearchDialog';
11-
import SearchSection from './SearchSection';
9+
import { useState } from 'react';
10+
import ProductSearchDialog from '@/components/ProductSearchDialog/ProductSearchDialog';
1211

1312
const MobileHeader = () => {
14-
const [isPending, startTransition] = useTransition();
15-
16-
const { navigate, q } = useSearchPageParams();
17-
1813
const [open, setOpen] = useState(false);
19-
2014
const handleToggleDialog = () => {
2115
setOpen((prevState) => !prevState);
2216
};
2317

24-
const onClickOnSearch = (q: string) => {
25-
startTransition(() => {
26-
navigate(SearchPageParamsKeys.Q, q);
27-
setOpen(false);
28-
});
29-
};
18+
const { q } = useSearchPageParams();
3019

3120
const t = useTranslations();
3221

@@ -35,13 +24,9 @@ const MobileHeader = () => {
3524
maxWidth="xl"
3625
sx={{ borderBottom: '2px solid', borderColor: 'divider' }}
3726
>
38-
<SearchDialog open={open} onClose={handleToggleDialog}>
39-
<SearchSection
40-
onClickOnBack={handleToggleDialog}
41-
onClickOnSearch={onClickOnSearch}
42-
isPending={isPending}
43-
/>
44-
</SearchDialog>
27+
<ProductSearchDialog open={open} onClose={handleToggleDialog}>
28+
<ProductSearchForm onClickOnBack={handleToggleDialog} />
29+
</ProductSearchDialog>
4530
<Stack direction="row" spacing={1} alignItems="center" height={56}>
4631
<Box
4732
onClick={handleToggleDialog}
@@ -70,7 +55,7 @@ const MobileHeader = () => {
7055
pl: 1,
7156
}}
7257
>
73-
{q ? q : t('header.search.placeholder')}
58+
{q || t('header.search.placeholder')}
7459
</Typography>
7560
</Box>
7661
</Stack>

src/app/[locale]/(main)/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { GetPublishedPagesListQuery } from '@/graphql/types/graphql';
77
import { FC, ReactNode } from 'react';
88
import Wrapper from './components/Wrapper';
99
import { Stack } from '@mui/material';
10+
import TopBanner from '@/components/Header/components/TopBanner';
1011

1112
export interface LayoutProps {
1213
children: ReactNode;
@@ -29,6 +30,7 @@ const Layout: FC<LayoutProps> = async ({ children }) => {
2930

3031
return (
3132
<Stack sx={{ minHeight: '100vh' }}>
33+
<TopBanner />
3234
<MainLayoutHeader />
3335
<Wrapper>{children}</Wrapper>
3436
<Footer pages={pagesList} />

src/app/[locale]/(main)/(container)/search/page.tsx renamed to src/app/[locale]/(main)/search/page.tsx

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import { ProductsFilters } from '@/components/ProductsFilters';
21
import { InlineFilters } from '@/components/InlineFilters';
2+
import { ProductsFilters } from '@/components/ProductsFilters';
3+
import FiltersCard from '@/components/ProductsFilters/components/FiltersCard';
34
import ProductsList from '@/components/ProductsList/ProductsList';
45
import DesktopView from '@/components/ResponsiveDesign/components/DesktopView';
56
import MobileView from '@/components/ResponsiveDesign/components/MobileView';
6-
import { Box } from '@mui/material';
7+
import { Box, Container } from '@mui/material';
78
import { Metadata } from 'next';
89
import { getTranslations } from 'next-intl/server';
910
import { Suspense } from 'react';
1011
import ProductsListSkeleton from './components/ProductsListSkeleton';
1112
import SortRow from './components/SortRow';
1213
import SortWrapper from './components/SortWrapper';
13-
import FiltersCard from '@/components/ProductsFilters/components/FiltersCard';
14+
import { Header } from '@/components/Header';
1415

1516
export async function generateMetadata(): Promise<Metadata> {
1617
const t = await getTranslations();
@@ -23,40 +24,49 @@ const Page = async () => {
2324
return (
2425
<>
2526
<MobileView>
26-
<InlineFilters />
27+
<Header>
28+
<Container maxWidth="xl">
29+
<InlineFilters />
30+
</Container>
31+
</Header>
2732
<Suspense fallback={<ProductsListSkeleton />}>
28-
<ProductsList />
33+
<Container maxWidth="xl" sx={{ mt: 2 }}>
34+
<ProductsList />
35+
</Container>
2936
</Suspense>
3037
</MobileView>
3138

3239
<DesktopView>
33-
<Box
34-
sx={{
35-
display: 'flex',
36-
gap: 1,
37-
position: 'relative',
38-
}}
39-
>
40+
<Container maxWidth="xl">
4041
<Box
4142
sx={{
42-
minWidth: 270,
43+
display: 'flex',
44+
gap: 1,
45+
position: 'relative',
46+
mt: 3,
4347
}}
4448
>
45-
<FiltersCard>
46-
<ProductsFilters />
47-
</FiltersCard>
48-
</Box>
49-
<Box sx={{ flexGrow: 1 }}>
50-
<SortWrapper>
51-
<SortRow />
52-
{/* <ProductsCount value={data.products?.pageInfo.total} /> */}
53-
</SortWrapper>
49+
<Box
50+
sx={{
51+
minWidth: 270,
52+
}}
53+
>
54+
<FiltersCard>
55+
<ProductsFilters />
56+
</FiltersCard>
57+
</Box>
58+
<Box sx={{ flexGrow: 1 }}>
59+
<SortWrapper>
60+
<SortRow />
61+
{/* <ProductsCount value={data.products?.pageInfo.total} /> */}
62+
</SortWrapper>
5463

55-
<Suspense fallback={<ProductsListSkeleton />}>
56-
<ProductsList />
57-
</Suspense>
64+
<Suspense fallback={<ProductsListSkeleton />}>
65+
<ProductsList />
66+
</Suspense>
67+
</Box>
5868
</Box>
59-
</Box>
69+
</Container>
6070
</DesktopView>
6171
</>
6272
);

src/components/Header/components/MobileHeader.tsx

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
'use client';
22

3+
import ProductSearchDialog from '@/components/ProductSearchDialog/ProductSearchDialog';
4+
import ProductSearchForm from '@/components/ProductSearchForm/ProductSearchForm';
5+
import Logo from '@/components/common/Logo';
36
import { usePathname, useRouter } from '@/navigation';
47
import { ArrowBack, Search, Share } from '@mui/icons-material';
5-
import { Box, BoxProps, IconButton, Stack, Typography } from '@mui/material';
8+
import { Box, BoxProps, IconButton, Stack } from '@mui/material';
69
import { useTranslations } from 'next-intl';
7-
import { FC } from 'react';
10+
import { FC, useState } from 'react';
811
import { toast } from 'react-hot-toast';
912

1013
export interface MobileHeaderProps extends BoxProps {
@@ -14,12 +17,17 @@ const MobileHeader: FC<MobileHeaderProps> = ({ title, ...props }) => {
1417
const router = useRouter();
1518
const pathname = usePathname();
1619
const t = useTranslations();
20+
const [open, setOpen] = useState(false);
1721

18-
if (pathname === '/') {
22+
if (pathname === '/' || pathname === '/search') {
1923
return null;
2024
}
2125

22-
const onClick = () => {
26+
const handleToggleDialog = () => {
27+
setOpen((prevState) => !prevState);
28+
};
29+
30+
const handleClickOnBack = () => {
2331
if (window?.history?.length > 1) {
2432
router.back();
2533
return;
@@ -35,33 +43,39 @@ const MobileHeader: FC<MobileHeaderProps> = ({ title, ...props }) => {
3543
};
3644

3745
return (
38-
<Box px={2} borderBottom="1px solid" borderColor="divider" {...props}>
39-
<Stack direction="row" justifyContent="space-between" alignItems="center">
40-
<Stack spacing={0.5} direction="row" py={1} alignItems="center">
41-
<IconButton size="small" onClick={onClick}>
42-
<ArrowBack
43-
sx={{
44-
transform: (theme) =>
45-
theme.direction === 'rtl' ? 'rotate(180deg)' : undefined,
46-
}}
47-
/>
48-
</IconButton>
49-
{!!title && (
50-
<Typography variant="body1" fontWeight={600}>
51-
{title}
52-
</Typography>
53-
)}
54-
</Stack>
55-
<Stack direction="row" alignItems="center">
56-
<IconButton>
57-
<Search />
58-
</IconButton>
59-
<IconButton onClick={handleClickOnShare}>
60-
<Share />
61-
</IconButton>
46+
<>
47+
<ProductSearchDialog open={open} onClose={handleToggleDialog}>
48+
<ProductSearchForm onClickOnBack={handleToggleDialog} />
49+
</ProductSearchDialog>
50+
51+
<Box px={2} borderBottom="1px solid" borderColor="divider" {...props}>
52+
<Stack
53+
direction="row"
54+
justifyContent="space-between"
55+
alignItems="center"
56+
>
57+
<Stack spacing={0.5} direction="row" py={1} alignItems="center">
58+
<IconButton size="small" onClick={handleClickOnBack}>
59+
<ArrowBack
60+
sx={{
61+
transform: (theme) =>
62+
theme.direction === 'rtl' ? 'rotate(180deg)' : undefined,
63+
}}
64+
/>
65+
</IconButton>
66+
</Stack>
67+
<Logo height={24} />
68+
<Stack direction="row" alignItems="center">
69+
<IconButton onClick={handleToggleDialog}>
70+
<Search />
71+
</IconButton>
72+
<IconButton onClick={handleClickOnShare}>
73+
<Share />
74+
</IconButton>
75+
</Stack>
6276
</Stack>
63-
</Stack>
64-
</Box>
77+
</Box>
78+
</>
6579
);
6680
};
6781

src/components/Header/components/TopBanner.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
'use client';
22

33
import { ISliderItem } from '@/components/MainSlider/types';
4+
import { GET_TOP_BANNER } from '@/graphql/queries/sliders';
5+
import { GetTopBannerQuery } from '@/graphql/types/graphql';
46
import { useAppContext } from '@/hooks/useAppContext';
7+
import { useQuery } from '@apollo/client';
58
import Image from 'next/image';
69
import { FC } from 'react';
710

8-
export interface TopBannerProps {
9-
data: ISliderItem | null;
10-
}
11-
const TopBanner: FC<TopBannerProps> = ({ data }) => {
11+
export interface TopBannerProps {}
12+
const TopBanner: FC<TopBannerProps> = () => {
1213
const { isMobile } = useAppContext();
1314

14-
if (!data) {
15+
const { data } = useQuery<GetTopBannerQuery>(GET_TOP_BANNER);
16+
17+
const _item = data?.sliderCategories?.nodes?.[0]?.sliders?.edges?.[0]?.node;
18+
19+
if (!_item?.featuredImage?.node.url) {
1520
return null;
1621
}
1722

23+
const banner: ISliderItem | null = {
24+
id: _item.id,
25+
imageUrl: _item.featuredImage?.node.url,
26+
url: _item.url,
27+
title: _item.title!,
28+
};
29+
1830
return (
1931
<Image
2032
width={2800}
2133
height={isMobile ? 35 : 60}
22-
src={data.imageUrl}
34+
src={banner.imageUrl}
2335
alt="Top Banner"
2436
style={{
2537
width: '100%',

0 commit comments

Comments
 (0)