diff --git a/design/icons/beer.png b/design/icons/beer.png new file mode 100644 index 0000000..943c588 Binary files /dev/null and b/design/icons/beer.png differ diff --git a/design/icons/cder.png b/design/icons/cder.png new file mode 100644 index 0000000..81edf6f Binary files /dev/null and b/design/icons/cder.png differ diff --git a/design/icons/champage.png b/design/icons/champage.png new file mode 100644 index 0000000..6224e21 Binary files /dev/null and b/design/icons/champage.png differ diff --git a/design/icons/coffee.png b/design/icons/coffee.png new file mode 100644 index 0000000..37e25e0 Binary files /dev/null and b/design/icons/coffee.png differ diff --git a/design/icons/cola.png b/design/icons/cola.png new file mode 100644 index 0000000..6208957 Binary files /dev/null and b/design/icons/cola.png differ diff --git a/design/icons/index.ts b/design/icons/index.ts new file mode 100644 index 0000000..25d4c1a --- /dev/null +++ b/design/icons/index.ts @@ -0,0 +1,8 @@ +import ico1 from './beer.png'; +import ico2 from './cder.png'; +import ico3 from './champage.png'; +import ico4 from './coffee.png'; +import ico5 from './cola.png'; +import ico6 from './mineral-water.png'; + +export const imageIcons = [ico3, ico4, ico5, ico1, ico2, ico6]; diff --git a/design/icons/mineral-water.png b/design/icons/mineral-water.png new file mode 100644 index 0000000..133a607 Binary files /dev/null and b/design/icons/mineral-water.png differ diff --git a/package-lock.json b/package-lock.json index aa18674..b75646f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "axios": "^1.3.4", "eslint": "8.35.0", "eslint-config-next": "13.2.3", + "js-sha1": "^0.6.0", "lodash": "^4.17.21", "next": "13.2.3", "next-redux-wrapper": "^8.1.0", @@ -5092,6 +5093,11 @@ "url": "https://opencollective.com/js-sdsl" } }, + "node_modules/js-sha1": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/js-sha1/-/js-sha1-0.6.0.tgz", + "integrity": "sha512-01gwBFreYydzmU9BmZxpVk6svJJHrVxEN3IOiGl6VO93bVKYETJ0sIth6DASI6mIFdt7NmfX9UiByRzsYHGU9w==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -13520,6 +13526,11 @@ "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==" }, + "js-sha1": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/js-sha1/-/js-sha1-0.6.0.tgz", + "integrity": "sha512-01gwBFreYydzmU9BmZxpVk6svJJHrVxEN3IOiGl6VO93bVKYETJ0sIth6DASI6mIFdt7NmfX9UiByRzsYHGU9w==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 09064dd..6fd5945 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "axios": "^1.3.4", "eslint": "8.35.0", "eslint-config-next": "13.2.3", + "js-sha1": "^0.6.0", "lodash": "^4.17.21", "next": "13.2.3", "next-redux-wrapper": "^8.1.0", diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 725e2a0..c9d2dab 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -3,11 +3,20 @@ import Header from './header/Header'; import DrawCategory from '../ui/drawer/DrawCategory'; import { CategoryService } from '@/services/Server/ServerCategory'; +import styled from 'styled-components'; interface ILayout { children?: React.ReactNode; } +const Main = styled.main` + width: 100%; +`; + +const Section = styled.section` + display: flex; +`; + // TODO: change categories variable to object like {data, changeData, loading, error} or set 'em to redux storage const Layout: React.FC = ({ children }) => { @@ -30,11 +39,11 @@ const Layout: React.FC = ({ children }) => { // TODO: create recurcive function for fetching data return ( -
+
-
{children}
-
+
{children}
+
); }; diff --git a/src/components/layout/header/Header.tsx b/src/components/layout/header/Header.tsx index c30edf2..8686c26 100644 --- a/src/components/layout/header/Header.tsx +++ b/src/components/layout/header/Header.tsx @@ -33,8 +33,6 @@ const Wrapper = styled.div` `; const Header = () => { - console.log(window.innerWidth); - return ( diff --git a/src/components/layout/header/Logo.tsx b/src/components/layout/header/Logo.tsx index 8ec3c3d..1720690 100644 --- a/src/components/layout/header/Logo.tsx +++ b/src/components/layout/header/Logo.tsx @@ -31,7 +31,7 @@ const Logo = () => { onClick={() => toggleUpperDrawer(!user.upperDrawer)} /> -

Оболонь Маркет

+

Маркет

); diff --git a/src/components/screen/category/Category.tsx b/src/components/screen/category/Category.tsx index f584a5e..9752737 100644 --- a/src/components/screen/category/Category.tsx +++ b/src/components/screen/category/Category.tsx @@ -1,18 +1,19 @@ import Card from '@/components/ui/card/Card'; import CardLoader from '@/components/ui/card/CardLoader'; -import List from '@/components/ui/list/List'; import Pagination from '@/components/ui/pagination/Pagination'; import Refinements from '@/components/ui/refinements/Refinements'; import { useActions } from '@/hooks/useActions'; import { useTypedSelector } from '@/hooks/useTypedSelector'; -import { AmazonProduct } from '@/services/Amazon/AmazonProduct'; import { ProductService } from '@/services/Server/ServerProduct'; import { IProduct } from '@/types/product.interface'; -import { IAmazonProductsByCategory } from '@/types/products.interface'; import { Empty, Select } from 'antd'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; +import sortByValue from './utils/sort'; +import filterByValue from './utils/filter'; +import { TFilter } from '@/store/product/product.types'; + const Wrapper = styled.div` display: flex; padding: 20px; @@ -55,8 +56,10 @@ const SortWrapper = styled.div` } `; +type TData = IProduct & TFilter & { strength: string[]; capacity: string[] }; + interface ICategory { - data: IAmazonProductsByCategory; + data: TData[]; categoryId: string; } @@ -75,10 +78,7 @@ const Category: React.FC = ({ data, categoryId }) => { const [categoryResults, setCategoryResults] = useState(data); const [loading, setLoading] = useState(false); const [refinements, setRefinements] = useState({}); - - const sort = useTypedSelector((state) => state.product.sort); const filter = useTypedSelector((state) => state.product.filter); - const { setSort } = useActions(); useEffect(() => { (async () => { @@ -87,140 +87,22 @@ const Category: React.FC = ({ data, categoryId }) => { })(); }, []); - // React query status working - - // const fetchByParameters = async (page: number, sort?: string) => { - // window.scrollTo(0, 0); - // setLoading(true); - // const data = await AmazonProduct.getByCategoryId(categoryId, page, sort); - // if (data) { - // setCategoryResults(data); - // } - // setLoading(false); - // }; + useEffect(() => { + setCategoryResults(filterByValue(data, filter)); + }, [filter]); const handleChange = (value: string) => { - setSort({ type: value.type }); - - console.log(value); - - switch (value) { - case 'by_title_a': - setCategoryResults( - data.sort((a, b) => { - if (a.title > b.title) return 1; - if (a.title < b.title) return -1; - return 0; - }) - ); - break; - case 'by_title_z': - setCategoryResults( - data.sort((a, b) => { - if (a.title > b.title) return -1; - if (a.title < b.title) return 1; - return 0; - }) - ); - break; - case 'by_cost_l': - setCategoryResults( - data.sort((a, b) => { - const costA = a.discount ? a.cost - a.discount * a.cost : a.cost; - const costB = b.discount ? b.cost - b.discount * b.cost : b.cost; - - if (costA > costB) return -1; - if (costA < costB) return 1; - return 0; - }) - ); - break; - case 'by_cost_h': - setCategoryResults( - data.sort((a, b) => { - const costA = a.discount ? a.cost - a.discount * a.cost : a.cost; - const costB = b.discount ? b.cost - b.discount * b.cost : b.cost; - - if (costA > costB) return 1; - if (costA < costB) return -1; - return 0; - }) - ); - break; - case 'by_discount': - setCategoryResults( - data.sort((a, b) => { - if (a.discount > b.discount) return -1; - if (a.discount < b.discount) return 1; - return 0; - }) - ); - break; - case 'by_new': - setCategoryResults( - data.sort((a, b) => { - if (a.isNew) return -1; - if (!a.isNew) return 1; - return 0; - }) - ); - break; - - default: - break; - } + const sorted = sortByValue(data, value); + setCategoryResults([...sorted]); }; - useEffect(() => { - setCategoryResults(data); - }, [data]); - - useEffect(() => { - console.log(JSON.stringify(filter)); - - if ( - JSON.stringify(filter) !== - '{"brand":[],"capacities":[],"kind":[],"manufacturer":[],"packing":[],"strengths":[]}' - ) { - const products = categoryResults.filter((product) => { - const isBrand = filter.brand.some( - (brand) => product.brand[0] === brand - ); - const isKind = filter.kind.some((kind) => product.kind[0] === kind); - const isManufacturer = filter.manufacturer.some( - (manufacturer) => product.manufacturer[0] === manufacturer - ); - const isStrength = filter.strengths.some( - (strength) => product.strength[0] === strength - ); - const isCapacity = filter.capacities.some( - (capacity) => product.capacity[0] === capacity - ); - const isPacking = filter.packing.some( - (packing) => product.packing[0] === packing - ); - return ( - isBrand || - isKind || - isManufacturer || - isStrength || - isCapacity || - isPacking - ); - }); - setCategoryResults(products); - } else setCategoryResults(data); - }, [filter]); - return ( - {/* */} -

Відсортувати:

+ + +
); diff --git a/src/pages/global-error.tsx b/src/pages/global-error.tsx new file mode 100644 index 0000000..6579ca2 --- /dev/null +++ b/src/pages/global-error.tsx @@ -0,0 +1,26 @@ +import styled from 'styled-components'; + +export const Wrapper = styled.div` + display: flex; + align-items: center; + justify-content: center; + + height: 350px; + width: 100%; + + p { + font-size: 16pt; + font-style: italic; + font-weight: bold; + } +`; + +const Error = () => { + return ( + +

Occur some unknown error

+
+ ); +}; + +export default Error; diff --git a/src/pages/product/[slug].tsx b/src/pages/product/[slug].tsx index d537dd8..f884ba0 100644 --- a/src/pages/product/[slug].tsx +++ b/src/pages/product/[slug].tsx @@ -1,15 +1,9 @@ import React from 'react'; import MetaLayout from '@/components/layout/MetaLayout'; import Product from '@/components/screen/product/Product'; -// import { AmazonProduct } from '@/services/Amazon/AmazonProduct'; -import { IAmazonProductById } from '@/types/products.interface'; import { GetServerSideProps } from 'next'; import { ProductService } from '@/services/Server/ServerProduct'; -import { - IAttribute, - IAttributesResponse, - IProduct, -} from '@/types/product.interface'; +import { IAttributesResponse, IProduct } from '@/types/product.interface'; export const getServerSideProps: GetServerSideProps = async (context) => { const slug = context.params?.slug as string; diff --git a/src/pages/user/index.tsx b/src/pages/user/index.tsx index 133c08a..c0d349e 100644 --- a/src/pages/user/index.tsx +++ b/src/pages/user/index.tsx @@ -1,14 +1,5 @@ import React from 'react'; import MetaLayout from '@/components/layout/MetaLayout'; -import Product from '@/components/screen/product/Product'; -// import { AmazonProduct } from '@/services/Amazon/AmazonProduct'; -import { GetServerSideProps } from 'next'; -import { ProductService } from '@/services/Server/ServerProduct'; -import { - IAttribute, - IAttributesResponse, - IProduct, -} from '@/types/product.interface'; import User from '@/components/screen/user/User'; const UserPage = () => { diff --git a/src/services/Server/ServerProduct.ts b/src/services/Server/ServerProduct.ts index c607f14..c63e90b 100644 --- a/src/services/Server/ServerProduct.ts +++ b/src/services/Server/ServerProduct.ts @@ -41,9 +41,12 @@ export const ProductService = { async getProductsByCategory({ id }: { id: string }) { try { - const { data } = await serverApi.post(`${PRODUCT}/category`, { - id: id, - }); + const { data } = await serverApi.post<{ id: string }>( + `${PRODUCT}/category`, + { + id: id, + } + ); return data; } catch (error) {} diff --git a/src/services/Server/SeverUser.ts b/src/services/Server/SeverUser.ts index b97bdf4..2e52ee2 100644 --- a/src/services/Server/SeverUser.ts +++ b/src/services/Server/SeverUser.ts @@ -67,4 +67,17 @@ export const UserService = { return data; } catch (error) {} }, + + // Liqpay + + async getLiqpayData(obj: any) { + try { + const { data } = await serverApiClient.post( + `${USER}/liqpay/data`, + obj + ); + + return data; + } catch (error) {} + }, }; diff --git a/src/store/product/product.slice.ts b/src/store/product/product.slice.ts index 38a8999..5da18bc 100644 --- a/src/store/product/product.slice.ts +++ b/src/store/product/product.slice.ts @@ -2,6 +2,15 @@ import { PayloadAction, createSlice } from '@reduxjs/toolkit'; import { IProductInitialState } from './product.types'; +const filterInitial = { + brand: [], + capacities: [], + kind: [], + manufacturer: [], + packing: [], + strengths: [], +}; + const initialState: IProductInitialState = { sort: {}, filter: { @@ -31,7 +40,7 @@ export const productSlice = createSlice({ reset: (state) => { state.sort = {}; - state.filter = {}; + state.filter = filterInitial; }, }, }); diff --git a/src/store/product/product.types.ts b/src/store/product/product.types.ts index 91615dc..988704c 100644 --- a/src/store/product/product.types.ts +++ b/src/store/product/product.types.ts @@ -1,11 +1,11 @@ -export interface IFilter { +export type TFilter = { brand: string[]; kind: string[]; capacities: string[]; strengths: string[]; manufacturer: string[]; packing: string[]; -} +}; export interface ISort { type: @@ -19,5 +19,5 @@ export interface ISort { export interface IProductInitialState { sort: ISort | {}; - filter: IFilter | {}; + filter: TFilter; } diff --git a/src/types/product.interface.ts b/src/types/product.interface.ts index 2f2997c..fab0114 100644 --- a/src/types/product.interface.ts +++ b/src/types/product.interface.ts @@ -1,27 +1,27 @@ -export interface IProduct { - _id: string; - code: string; - title: string; - description: string; - picture: string; - cost: number; - discount: number; - isNew: boolean; - inStockQuantity: 5; - category: string[]; - __v: number; -} - export interface IAttribute { _id: string; value: string; } -export interface IAttributesResponse { +export type IAttributesResponse = { brand: IAttribute[]; capacity: IAttribute[]; strength: IAttribute[]; kind: IAttribute[]; manufacturer: IAttribute[]; packing: IAttribute[]; -} +}; + +export type IProduct = { + _id: string; + code: string; + title: string; + description: string; + picture: string; + cost: number; + discount: number; + isNew: boolean; + inStockQuantity: 5; + category: string[]; + __v: number; +};