Skip to content

Commit

Permalink
update sort
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMelior committed Mar 25, 2024
1 parent 8248ebe commit 983ef9f
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function checkLocalstorage() {
return [];
}

export const initialState: number[] = checkLocalstorage();
const initialState: number[] = checkLocalstorage();

export const favoritesSlice = createSlice({
name: 'favorites',
Expand Down
2 changes: 1 addition & 1 deletion src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const productData: ProductDataProps[] = [
images: ['100025078688b2.webp'],
title: 'Ого! Это я недавно такие наушники купил',
creativity: 5,
filter: ['new-year'],
filter: ['year'],
characteristics: {
'Характеристика 1': 'Значение характеристики 1',
},
Expand Down
6 changes: 3 additions & 3 deletions src/shared/assets/icon/Check.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export const CheckIcon = ({
stroke={color}
stroke-dasharray='22'
strokeDashoffset={isSelected ? 44 : 66}
stroke-linecap='round'
stroke-linejoin='round'
stroke-width='1.5'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='1.5'
style={{ transition: 'stroke-dashoffset 200ms ease 0s' }}
></polyline>
</svg>
Expand Down
96 changes: 44 additions & 52 deletions src/views/ShopPage/ShopPage.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,75 @@
'use client';

import { productData } from '@/db';
import { ProductDataProps } from '@/shared/types/product';
import { Blackhole } from '@/shared/ui/Blackhole';
import { Button } from '@/shared/ui/Button';
import { Cards } from '@/shared/ui/Card';
import { NavigationPanel } from '@/widgets/NavigationPanel';
import { Sorts } from '@/widgets/Sorts';
import { getMaxPrice } from '@/widgets/Sorts/model/selector/getMaxPrice';
import { getMinPrice } from '@/widgets/Sorts/model/selector/getMinPrice';
import { getSort } from '@/widgets/Sorts/model/selector/getSort';
import { getSortSearchparams } from '@/widgets/Sorts/model/features/getSortSearchparams';
import { TopPage } from '@/widgets/TopPage';
import { Image, Textarea } from '@nextui-org/react';
import cn from 'clsx';
import { FC } from 'react';
import { useSelector } from 'react-redux';
import { FC, useMemo } from 'react';
import cls from './ShopPage.module.scss';

export const ShopPage: FC = () => {
const startPrice = useSelector(getMinPrice);
const endPrice = useSelector(getMaxPrice);
const sort = useSelector(getSort);
const { age, category, maxPrice, sex, minPrice, sorting } =
getSortSearchparams();

const filteredProductData = productData.filter(
(product: ProductDataProps) => {
/**
* Фильтрация продуктов по заданным критериям
*/
const filteredProducts = useMemo(() => {
return productData.filter(({ markets, filter }) => {
// Проверка соответствия цены критериям
const meetsPriceCriteria =
product.markets[0].price >= startPrice &&
product.markets[0].price <= endPrice;
const meetsCategoryCriteria = !sort.category.some((category) =>
product.filter.includes(category),
markets[0].price >= minPrice && markets[0].price <= maxPrice;
// Проверка соответствия категории критериям
const meetsCategoryCriteria = !category.some((cat) =>
filter.includes(cat),
);
const meetsSexCriteria = !sort.sex.some((category) =>
product.filter.includes(category),
);
const meetsAgeCriteria = !sort.age.some((category) =>
product.filter.includes(category),
);

// Проверка соответствия пола критериям
const meetsSexCriteria = !sex.some((s) => filter.includes(s));
// Проверка соответствия возраста критериям
const meetsAgeCriteria = !age.some((a) => filter.includes(a));
// Возвращаем true, если продукт соответствует всем критериям, иначе false
return (
meetsPriceCriteria &&
meetsCategoryCriteria &&
meetsSexCriteria &&
meetsAgeCriteria
);
},
);
});
}, [productData, minPrice, maxPrice, category, sex, age]);

const sortedProducts = filteredProductData.slice().sort((a, b) => {
if (sort.sorting === 'popular') {
// Сортировка по популярности (reviewCount)
if (a.markets[0].reviewCount !== b.markets[0].reviewCount) {
/**
* Сортировка отфильтрованных продуктов
*/
const sortedProducts = useMemo(() => {
return filteredProducts.slice().sort((a, b) => {
if (sorting === 'popular') {
// Сортировка по популярности (количеству отзывов)
return b.markets[0].reviewCount - a.markets[0].reviewCount;
}
} else if (sort.sorting === 'rating') {
// Сортировка по рейтингу (rating)
if (a.markets[0].rating !== b.markets[0].rating) {
} else if (sorting === 'rating') {
// Сортировка по рейтингу
return b.markets[0].rating - a.markets[0].rating;
}
} else if (sort.sorting === 'creativity') {
// Сортировка по креативности (creativity)
if (a.creativity !== b.creativity) {
} else if (sorting === 'creativity') {
// Сортировка по креативности
return b.creativity - a.creativity;
} else if (sorting === 'expensive') {
// Сортировка по убыванию цены
return b.markets[0].price - a.markets[0].price;
} else if (sorting === 'cheap') {
// Сортировка по возрастанию цены
return a.markets[0].price - b.markets[0].price;
} else if (sorting === 'new') {
// Сортировка по новизне
return productData.indexOf(b) - productData.indexOf(a); // Последние в массиве идут первыми
}
} else if (sort.sorting === 'expensive') {
// Сортировка по цене (expensive)
if (a.markets[0].price !== b.markets[0].price) {
return b.markets[0].price - a.markets[0].price; // Сортировка по убыванию
}
} else if (sort.sorting === 'cheap') {
// Сортировка по цене (cheap)
if (a.markets[0].price !== b.markets[0].price) {
return a.markets[0].price - b.markets[0].price; // Сортировка по возрастанию
}
} else if (sort.sorting === 'new') {
// Сортировка по новизне
return filteredProductData.indexOf(b) - filteredProductData.indexOf(a); // Последние в массиве идут первыми
}
return 0;
});
return 0; // Возвращаем 0, если сортировка не требуется или неизвестен тип сортировки
});
}, [filteredProducts, sorting]);

return (
<>
Expand Down
2 changes: 1 addition & 1 deletion src/widgets/Sorts/model/const/categoryButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const categoryButton: ButtonCategoryProps[] = [
{
text: '🎄 Новый год',
color: '66, 255, 153',
key: 'new-year',
key: 'year',
},
{
text: '😁 Приколы',
Expand Down
43 changes: 43 additions & 0 deletions src/widgets/Sorts/model/features/getSortSearchparams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useSearchParams } from 'next/navigation';
import { useMemo } from 'react';
import { sortInitialState } from '../slice/sortSlice';
import {
SortAge,
SortCategory,
SortSex,
SortSorting,
SortState,
} from '../types/sortType';

export const getSortSearchparams = (): SortState => {
const searchParams = useSearchParams();

return useMemo(() => {
const category =
(searchParams.get('category')?.split('-') as SortCategory[]) ??
sortInitialState.category;
const sex =
(searchParams.get('sex')?.split('-') as SortSex[]) ??
sortInitialState.sex;
const minPrice: number = searchParams.get('min')
? Number(searchParams.get('min'))
: sortInitialState.minPrice;
const maxPrice: number = searchParams.get('max')
? Number(searchParams.get('max'))
: sortInitialState.maxPrice;
const age =
(searchParams.get('age')?.split('-') as SortAge[]) ??
sortInitialState.age;
const sorting =
(searchParams.get('sorting') as SortSorting) ?? sortInitialState.sorting;

return {
category,
sex,
minPrice,
maxPrice,
age,
sorting,
};
}, [searchParams]);
};
5 changes: 0 additions & 5 deletions src/widgets/Sorts/model/selector/getMaxPrice.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/widgets/Sorts/model/selector/getMinPrice.ts

This file was deleted.

16 changes: 15 additions & 1 deletion src/widgets/Sorts/model/slice/sortSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
import { getSortSearchparams } from '../features/getSortSearchparams';
import {
SortAge,
SortCategory,
Expand All @@ -7,7 +8,7 @@ import {
SortState,
} from '../types/sortType';

export const initialState: SortState = {
export const sortInitialState = {
category: ['joke'],
sex: ['male', 'female'],
age: ['adult'],
Expand All @@ -16,6 +17,19 @@ export const initialState: SortState = {
maxPrice: 15000,
};

const initialState = (): SortState => {
const { age, category, sex, minPrice, maxPrice, sorting } =
getSortSearchparams();
return {
category: category ?? sortInitialState.category,
sex: sex ?? sortInitialState.sex,
age: age ?? sortInitialState.age,
sorting: sorting ?? sortInitialState.sorting,
minPrice: minPrice ?? sortInitialState.minPrice,
maxPrice: maxPrice ?? sortInitialState.maxPrice,
};
};

const toggleMultiple = (state: string[], action: string) => {
const index = state.indexOf(action);
if (index === -1) {
Expand Down
2 changes: 1 addition & 1 deletion src/widgets/Sorts/model/types/sortType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type SortCategory = 'birthday' | 'love' | 'new-year' | 'joke';
export type SortCategory = 'birthday' | 'love' | 'year' | 'joke';

export type SortSex = 'male' | 'female';

Expand Down
Loading

0 comments on commit 983ef9f

Please sign in to comment.