Skip to content

Commit 96e691a

Browse files
committed
feat: add filters to mobile view
1 parent 4375e8a commit 96e691a

File tree

14 files changed

+127
-119
lines changed

14 files changed

+127
-119
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ColumnFilters } from '@/components/ColumnFilters';
1+
import { ProductsFilters } from '@/components/ProductsFilters';
22
import { InlineFilters } from '@/components/InlineFilters';
33
import ProductsList from '@/components/ProductsList/ProductsList';
44
import DesktopView from '@/components/ResponsiveDesign/components/DesktopView';
@@ -10,6 +10,7 @@ import { Suspense } from 'react';
1010
import ProductsListSkeleton from './components/ProductsListSkeleton';
1111
import SortRow from './components/SortRow';
1212
import SortWrapper from './components/SortWrapper';
13+
import FiltersCard from '@/components/ProductsFilters/components/FiltersCard';
1314

1415
export async function generateMetadata(): Promise<Metadata> {
1516
const t = await getTranslations();
@@ -41,7 +42,9 @@ const Page = async () => {
4142
minWidth: 270,
4243
}}
4344
>
44-
<ColumnFilters />
45+
<FiltersCard>
46+
<ProductsFilters />
47+
</FiltersCard>
4548
</Box>
4649
<Box sx={{ flexGrow: 1 }}>
4750
<SortWrapper>

src/components/ColumnFilters/ColumnFilters.tsx

Lines changed: 0 additions & 97 deletions
This file was deleted.

src/components/ColumnFilters/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/InlineFilters/InlineFilters.tsx

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

3-
import { GetAllCategoriesQuery } from '@/graphql/types/graphql';
43
import useSearchPageParams from '@/hooks/useSearchPageParams';
54
import { sortOptions } from '@/static/sortOptions';
65
import { SearchPageParamsKeys } from '@/utils/params';
@@ -17,12 +16,11 @@ import {
1716
} from '@mui/material';
1817
import { useTranslations } from 'next-intl';
1918
import { FC, useState } from 'react';
19+
import { ProductsFilters } from '../ProductsFilters';
2020
import Dialog from '../Dialog/Dialog';
2121

22-
export interface InlineFiltersProps {
23-
categories?: NonNullable<GetAllCategoriesQuery['productCategories']>['nodes'];
24-
}
25-
const InlineFilters: FC<InlineFiltersProps> = ({ categories }) => {
22+
export interface InlineFiltersProps {}
23+
const InlineFilters: FC<InlineFiltersProps> = () => {
2624
const t = useTranslations();
2725

2826
const { sort, navigate } = useSearchPageParams();
@@ -44,8 +42,33 @@ const InlineFilters: FC<InlineFiltersProps> = ({ categories }) => {
4442

4543
const selectedSort = sortOptions.find((item) => item.key === sort);
4644

45+
const [filtersDialog, setFiltersDialog] = useState(false);
46+
47+
const onToggleFiltersDialog = () => {
48+
setFiltersDialog((prevState) => !prevState);
49+
};
50+
4751
return (
4852
<>
53+
<Dialog
54+
open={filtersDialog}
55+
onClose={onToggleFiltersDialog}
56+
title={t('products.filters.title')}
57+
buttons={[
58+
{
59+
id: 'view-products',
60+
children: t('buttons.viewProducts'),
61+
variant: 'contained',
62+
color: 'primary',
63+
size: 'large',
64+
fullWidth: true,
65+
onClick: onToggleFiltersDialog,
66+
},
67+
]}
68+
>
69+
<ProductsFilters />
70+
</Dialog>
71+
4972
<Dialog
5073
key={sort}
5174
open={sortDialog}
@@ -99,8 +122,9 @@ const InlineFilters: FC<InlineFiltersProps> = ({ categories }) => {
99122
variant="outlined"
100123
size="small"
101124
endIcon={<KeyboardArrowDownIcon />}
125+
onClick={onToggleFiltersDialog}
102126
>
103-
{t('products.filters.categories')}
127+
{t('products.filters.title')}
104128
</Button>
105129
</Box>
106130
</>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use client';
2+
3+
import { GET_ALL_CATEGORIES_QUERY } from '@/graphql/queries/categories';
4+
import { GetAllCategoriesQuery } from '@/graphql/types/graphql';
5+
import useSearchPageParams from '@/hooks/useSearchPageParams';
6+
import { SearchPageParamsKeys } from '@/utils/params';
7+
import { useQuery } from '@apollo/client';
8+
import { Divider, List, ListItemText, Switch } from '@mui/material';
9+
import { useTranslations } from 'next-intl';
10+
import { FC } from 'react';
11+
import Categories from './components/Categories';
12+
import { ListItem } from './components/ListItem';
13+
import { Title } from './components/Title';
14+
15+
export interface ProductsFiltersProps {}
16+
17+
const ProductsFilters: FC<ProductsFiltersProps> = () => {
18+
const t = useTranslations();
19+
20+
const { data: categoriesData } = useQuery<GetAllCategoriesQuery>(
21+
GET_ALL_CATEGORIES_QUERY,
22+
);
23+
24+
const categories = categoriesData?.productCategories?.nodes;
25+
26+
const { navigate, inStock } = useSearchPageParams();
27+
const handleClickOnInStock = () => {
28+
navigate(SearchPageParamsKeys.InStock, !inStock);
29+
};
30+
31+
return (
32+
<List>
33+
<ListItem disableGutters disableRipple>
34+
<ListItemText
35+
primary={<Title>{t('products.filters.categories')}</Title>}
36+
/>
37+
</ListItem>
38+
{!!categories?.length && <Categories options={categories} />}
39+
40+
<Divider />
41+
42+
<ListItem disableGutters disableRipple onClick={handleClickOnInStock}>
43+
<ListItemText
44+
primary={<Title>{t('products.filters.justInStock')}</Title>}
45+
/>
46+
<Switch checked={inStock} />
47+
</ListItem>
48+
</List>
49+
);
50+
};
51+
52+
export default ProductsFilters;

src/components/ColumnFilters/components/Categories.tsx renamed to src/components/ProductsFilters/components/Categories.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
import useSearchPageParams from '@/hooks/useSearchPageParams';
2+
import { SearchPageParamsKeys } from '@/utils/params';
23
import { ExpandLess, ExpandMore } from '@mui/icons-material';
34
import { Collapse, IconButton, List, ListItemText } from '@mui/material';
45
import { FC, MouseEventHandler, useMemo, useState } from 'react';
56
import { ProductCategoryOptions } from '../types';
67
import { ListItem } from './ListItem';
78
import { Title } from './Title';
8-
import { SearchPageParamsKeys } from '@/utils/params';
99

1010
export interface CategoriesProps {
1111
options: ProductCategoryOptions;
1212
parentId?: null | number;
1313
}
1414

15-
const allItemId = -1;
16-
17-
const Categories: FC<CategoriesProps> = ({ options, parentId = allItemId }) => {
15+
const Categories: FC<CategoriesProps> = ({ options, parentId = null }) => {
1816
const _options = useMemo(() => {
1917
return options?.filter((option) => option.parentId === parentId) ?? [];
2018
}, [options, parentId]);
@@ -68,18 +66,16 @@ const Categories: FC<CategoriesProps> = ({ options, parentId = allItemId }) => {
6866
return _options.map((option) => {
6967
const hasChildren = options?.some((child) => child.parentId === option.id);
7068

71-
const isActive =
72-
(categoryId === null && option?.id === allItemId) ||
73-
option?.id === categoryId;
69+
const isActive = option.id === categoryId;
7470

7571
return (
7672
<List
73+
sx={{
74+
pl: parentId === null ? 0 : 2,
75+
}}
7776
dense
7877
component="div"
7978
key={option.id}
80-
sx={{
81-
pl: parentId === -1 ? 0 : 2,
82-
}}
8379
disablePadding
8480
>
8581
<ListItem dense disableRipple>
@@ -97,7 +93,11 @@ const Categories: FC<CategoriesProps> = ({ options, parentId = allItemId }) => {
9793
</IconButton>
9894
)}
9995
</ListItem>
100-
<Collapse timeout="auto" in={open[option.id] ?? false} unmountOnExit>
96+
<Collapse
97+
timeout="auto"
98+
in={(isActive || open[option.id]) ?? false}
99+
unmountOnExit
100+
>
101101
<Categories
102102
options={options}
103103
parentId={option.id > 0 ? option.id : null}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Card, CardContent } from '@mui/material';
2+
import React, { FC, ReactNode } from 'react';
3+
4+
export interface FiltersCardProps {
5+
children: ReactNode;
6+
}
7+
const FiltersCard: FC<FiltersCardProps> = ({ children }) => {
8+
return (
9+
<Card
10+
variant="outlined"
11+
sx={{
12+
position: 'sticky',
13+
top: 130,
14+
}}
15+
>
16+
<CardContent>{children}</CardContent>
17+
</Card>
18+
);
19+
};
20+
21+
export default FiltersCard;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as ProductsFilters } from './ProductsFilters';

0 commit comments

Comments
 (0)