diff --git a/.eslintrc.js b/.eslintrc.js
index cefb7cc..6bea878 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,26 +1,26 @@
-module.exports = {
- parser: '@typescript-eslint/parser',
- extends: ['@mate-academy/eslint-config-react-typescript'],
- plugins: ['@typescript-eslint', 'react-hooks', 'prettier'],
- parserOptions: {
- ecmaVersion: 2018,
- sourceType: 'module',
- ecmaFeatures: {
- jsx: true,
- },
- },
- env: {
- browser: true,
- node: true,
- es6: true,
- jest: true,
- },
- rules: {
- 'linebreak-style': 'off',
- },
- settings: {
- react: {
- version: 'detect',
- },
- },
-};
+module.exports = {
+ parser: '@typescript-eslint/parser',
+ extends: ['@mate-academy/eslint-config-react-typescript'],
+ plugins: ['@typescript-eslint', 'react-hooks', 'prettier'],
+ parserOptions: {
+ ecmaVersion: 2018,
+ sourceType: 'module',
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ env: {
+ browser: true,
+ node: true,
+ es6: true,
+ jest: true,
+ },
+ rules: {
+ 'linebreak-style': 'off',
+ },
+ settings: {
+ react: {
+ version: 'detect',
+ },
+ },
+};
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 43bf5e1..05e0512 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -1,45 +1,45 @@
-name: Checking with lint
-
-on:
- pull_request:
- branches: [ master ]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- node-version: [14.x]
-
- steps:
- - name: Checkout repository ๐
- uses: actions/checkout@v3
-
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node-version }}
-
- - name: Cache dependencies ๐ฆ
- uses: actions/cache@v3
- with:
- path: |
- **/node_modules
- key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
-
- - name: Install dependencies ๐
- run: npm install
-
- - name: Run the lint ๐งช
- run: npm run lint
-
- - name: Build ๐ง
- run: npm run build
-
- env:
- user_name: 'github-actions[bot]'
- user_email: 'github-actions[bot]@users.noreply.github.com'
- github_token: ${{ secrets.ACTIONS_DEPLOY_ACCESS_TOKEN }}
- repository: ${{ github.repository }}
+name: Checking with lint
+
+on:
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [14.x]
+
+ steps:
+ - name: Checkout repository ๐
+ uses: actions/checkout@v3
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Cache dependencies ๐ฆ
+ uses: actions/cache@v3
+ with:
+ path: |
+ **/node_modules
+ key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
+
+ - name: Install dependencies ๐
+ run: npm install
+
+ - name: Run the lint ๐งช
+ run: npm run lint
+
+ - name: Build ๐ง
+ run: npm run build
+
+ env:
+ user_name: 'github-actions[bot]'
+ user_email: 'github-actions[bot]@users.noreply.github.com'
+ github_token: ${{ secrets.ACTIONS_DEPLOY_ACCESS_TOKEN }}
+ repository: ${{ github.repository }}
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 8689578..9a74794 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -1,51 +1,51 @@
-name: Auto deploy
-
-on:
- push:
- branches: [ master ]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- node-version: [14.x]
-
- steps:
- - name: Checkout repository ๐
- uses: actions/checkout@v3
-
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node-version }}
-
- - name: Cache dependencies ๐ฆ
- uses: actions/cache@v3
- with:
- path: |
- **/node_modules
- key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
-
- - name: Install dependencies ๐
- run: npm install
-
- - name: Run the lint ๐งช
- run: npm run lint
-
- - name: Build ๐ง
- run: npm run build
-
- - name: Deploy ๐
- run: |
- git config --global user.name $user_name
- git config --global user.email $user_email
- git remote set-url origin https://${github_token}@github.com/${repository}
- npm run deploy
- env:
- user_name: 'github-actions[bot]'
- user_email: 'github-actions[bot]@users.noreply.github.com'
- github_token: ${{ secrets.ACTIONS_DEPLOY_ACCESS_TOKEN }}
- repository: ${{ github.repository }}
+name: Auto deploy
+
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [14.x]
+
+ steps:
+ - name: Checkout repository ๐
+ uses: actions/checkout@v3
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Cache dependencies ๐ฆ
+ uses: actions/cache@v3
+ with:
+ path: |
+ **/node_modules
+ key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
+
+ - name: Install dependencies ๐
+ run: npm install
+
+ - name: Run the lint ๐งช
+ run: npm run lint
+
+ - name: Build ๐ง
+ run: npm run build
+
+ - name: Deploy ๐
+ run: |
+ git config --global user.name $user_name
+ git config --global user.email $user_email
+ git remote set-url origin https://${github_token}@github.com/${repository}
+ npm run deploy
+ env:
+ user_name: 'github-actions[bot]'
+ user_email: 'github-actions[bot]@users.noreply.github.com'
+ github_token: ${{ secrets.ACTIONS_DEPLOY_ACCESS_TOKEN }}
+ repository: ${{ github.repository }}
diff --git a/.prettierrc b/.prettierrc
index e73e0b5..e84c7e8 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,8 +1,8 @@
-{
- "printWidth": 80,
- "tabWidth": 2,
- "singleQuote": true,
- "semi": true,
- "trailingComma": "all",
- "bracketSpacing": true
-}
+{
+ "printWidth": 80,
+ "tabWidth": 2,
+ "singleQuote": true,
+ "semi": true,
+ "trailingComma": "all",
+ "bracketSpacing": true
+}
diff --git a/package-lock.json b/package-lock.json
index 01856f3..f5a937a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12054,9 +12054,9 @@
}
},
"typescript": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
- "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
+ "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
"dev": true
},
"unbox-primitive": {
diff --git a/public/icons/Buttons/Icons/ArrowLeft.svg b/public/icons/Buttons/Icons/ArrowLeft.svg
index 5a64cef..ef8650b 100644
--- a/public/icons/Buttons/Icons/ArrowLeft.svg
+++ b/public/icons/Buttons/Icons/ArrowLeft.svg
@@ -1,3 +1,3 @@
-
+
diff --git a/public/icons/Buttons/Icons/ArrowRight.svg b/public/icons/Buttons/Icons/ArrowRight.svg
index e0ec5e5..c609788 100644
--- a/public/icons/Buttons/Icons/ArrowRight.svg
+++ b/public/icons/Buttons/Icons/ArrowRight.svg
@@ -1,3 +1,3 @@
-
+
diff --git a/public/index.html b/public/index.html
index 7311733..d2de9a0 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,19 +1,19 @@
-
-
-
-
-
-
-
-
-
-
- Nice Gadgets
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ Nice Gadgets
+
+
+
+
+
+
diff --git a/src/App.scss b/src/App.scss
index a44c5a4..f87c10c 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -12,3 +12,4 @@
font-family: 'Mont', sans-serif;
scroll-behavior: smooth;
}
+
diff --git a/src/Root.tsx b/src/Root.tsx
index bd7381e..e587031 100644
--- a/src/Root.tsx
+++ b/src/Root.tsx
@@ -6,13 +6,20 @@ import {
} from 'react-router-dom';
import { App } from './App';
import { HomePage } from './modules/HomePage';
-import { PhonesPage } from './modules/PhonesPage';
+import { ProductsPage } from './modules/PhonesPage';
import { ProductDetailsPage } from './modules/ProductDetailsPage';
-import { FavoritesPage } from './modules/FavoritesPage';
import { CartPage } from './modules/CartPage';
import { NotFoundPage } from './modules/NotFoundPage';
-import { TabletsPage } from './modules/TabletsPage';
-import { AccessoriesPage } from './modules/AccessoriesPage';
+import { PageInProgress } from './modules/PageInProgress';
+import { FavoritesPage } from './modules/FavoritesPage';
+import {
+ getProductsWithSearchParams as loadPhones,
+ getProductAmount as loadPhonesAmount,
+} from './api/service';
+
+const MOBILE_TITLE = 'Mobile phones';
+// const TABLETS_TITLE = 'Tablet';
+// const ACCESSOTIES_TITLE = 'Accessories';
export const Root = () => (
@@ -22,13 +29,39 @@ export const Root = () => (
} />
} />
- } />
+
+ )}
+ />
} />
- } />
- } />
+ {/* }
+ /> */}
+ {/* }
+ /> */}
} />
} />
+ } />
} />
diff --git a/src/api/service.ts b/src/api/service.ts
index 989dff5..9f81535 100644
--- a/src/api/service.ts
+++ b/src/api/service.ts
@@ -1,39 +1,42 @@
import { axiosClient } from '../utils/axiosClient';
-import { Phone } from '../types/Phone';
-import { SortBy } from '../types/SortBy';
-import { PhoneDetail } from '../types/PhoneDetail';
+import { Categories, EndPoints, ProductsAmount } from '../types/Enums';
+import { Product, ProductDetail, QueryParams } from '../types/Product';
-export const getPhones = () => {
- return axiosClient.get('/phones');
-};
-
-export const getPhonesAmount = () => {
- return axiosClient.get('/phones/amount');
+export const getProductAmount = (category?: Categories) => {
+ return axiosClient.get(
+ `/${EndPoints.Product}/amount/${category}`,
+ );
};
-export const getPhonesWithSearchParams = (
- sortBy: SortBy,
- perPage: number,
- page: number,
+export const getProductsWithSearchParams = (
+ endPoints: EndPoints,
+ params?: QueryParams,
) => {
- return axiosClient.get(
- `/phones?sortBy=${sortBy}&perPage=${perPage}&page=${page}`,
+ const {
+ page = 1, perPage = 8, sort = 'discount', order = 'asc',
+ } = params || {};
+
+ return axiosClient.get(
+ `/${endPoints}?page=${page}&perPage=${perPage}&sort=${sort}&order=${order}`,
);
};
-export const getNewestPhones = () => {
- return axiosClient.get('/phones/new');
+export const getNewestProducts = () => {
+ return axiosClient.get(`/${EndPoints.Product}/new`);
};
-export const getPhonesWithDiscount = () => {
- return axiosClient.get('/phones/discount');
+export const getProductsWithDiscount = () => {
+ return axiosClient.get(`/${EndPoints.Product}/discount`);
};
-export const getPhoneDetail = (phoneId: string) => {
- return axiosClient.get(`/phones/${phoneId}`);
+export const getProductDetail = (endPoint: EndPoints, itemId: string) => {
+ return axiosClient.get(`/${endPoint}/${itemId}`);
};
-export const getRecommendedPhones = (phoneId: string) => {
- return axiosClient.get(`/phones/${phoneId}/recommended`);
+export const getRecommendedProducts = (
+ endPoint: EndPoints,
+ phoneId: string,
+) => {
+ return axiosClient.get(`/${endPoint}/${phoneId}/recommended`);
};
diff --git a/src/modules/AccessoriesPage/AccessoriesPage.tsx b/src/modules/AccessoriesPage/AccessoriesPage.tsx
index f3d43d0..1e0692a 100644
--- a/src/modules/AccessoriesPage/AccessoriesPage.tsx
+++ b/src/modules/AccessoriesPage/AccessoriesPage.tsx
@@ -1,7 +1,7 @@
-import './AccessoriesPage.module.scss';
-
-import React from 'react';
-
-export const AccessoriesPage: React.FC = () => {
- return Accessories Page
;
-};
+import './AccessoriesPage.module.scss';
+
+import React from 'react';
+
+export const AccessoriesPage: React.FC = () => {
+ return Accessories Page
;
+};
diff --git a/src/modules/AccessoriesPage/index.ts b/src/modules/AccessoriesPage/index.ts
index 486474a..0cc97ca 100644
--- a/src/modules/AccessoriesPage/index.ts
+++ b/src/modules/AccessoriesPage/index.ts
@@ -1 +1 @@
-export * from './AccessoriesPage';
+export * from './AccessoriesPage';
diff --git a/src/modules/CartPage/CartPage.tsx b/src/modules/CartPage/CartPage.tsx
index e5ed439..aa3cf4d 100644
--- a/src/modules/CartPage/CartPage.tsx
+++ b/src/modules/CartPage/CartPage.tsx
@@ -1,35 +1,40 @@
-import React, { useEffect, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
import cn from 'classnames';
import { CartItem } from './components/CartItem';
-import { Phone } from '../../types/Phone';
-import { getNewestPhones } from '../../api/service';
import styles from './CartPage.module.scss';
import { useAppSelector } from '../../store/hooks';
import { BackButton } from '../shared/BackButton';
+import { Modal } from './components/Modal';
export const CartPage: React.FC = () => {
- const [phones, setPhones] = useState([]);
const { isDarkTheme } = useAppSelector((state) => state.theme);
+ const { cart } = useAppSelector(state => state.cart);
+ const [isModalOpen, setModalOpen] = useState(false);
- const total = useMemo(() => {
- return phones.reduce((accumulator, phone) => accumulator + phone.price, 0);
- }, [phones]);
+ const openModal = () => {
+ setModalOpen(true);
+ };
- useEffect(() => {
- getNewestPhones()
- .then(setPhones)
- // eslint-disable-next-line
- .catch((error) => console.error('Error fetching data:', error));
- }, []);
+ const closeModal = () => {
+ setModalOpen(false);
+ };
+
+ const totalPrice = useMemo(() => {
+ return cart.reduce((acc, phone) => acc + phone.price * phone.amount, 0);
+ }, [cart]);
+
+ const totalItems = useMemo(() => {
+ return cart.reduce((acc, phone) => acc + phone.amount, 0);
+ }, [cart]);
return (
+
-
{
- {phones.map((phone) => (
-
+ {cart.map((phone) => (
+
))}
@@ -55,7 +63,7 @@ export const CartPage: React.FC = () => {
[styles.contentDark]: isDarkTheme,
})}
>
- {`$ ${total}`}
+ {`$ ${totalPrice}`}
{
[styles.amountContent__DARK]: isDarkTheme,
})}
>
- {`Total for ${phones.length} items`}
+ {`Total for ${totalItems} items`}
{
+
diff --git a/src/modules/CartPage/components/CartItem/CartItem.module.scss b/src/modules/CartPage/components/CartItem/CartItem.module.scss
index d188919..a4cf630 100644
--- a/src/modules/CartPage/components/CartItem/CartItem.module.scss
+++ b/src/modules/CartPage/components/CartItem/CartItem.module.scss
@@ -56,6 +56,7 @@
display: flex;
gap: 13px;
align-items: center;
+ cursor: pointer;
}
.content {
@@ -85,9 +86,10 @@
}
}
-.closeButton {
+.deleteButton {
border: none;
background-color: transparent;
+ cursor: pointer;
}
.changeAmountButton {
diff --git a/src/modules/CartPage/components/CartItem/CartItem.tsx b/src/modules/CartPage/components/CartItem/CartItem.tsx
index d95ea6d..2cb46f7 100644
--- a/src/modules/CartPage/components/CartItem/CartItem.tsx
+++ b/src/modules/CartPage/components/CartItem/CartItem.tsx
@@ -1,8 +1,7 @@
import React from 'react';
-
import cn from 'classnames';
-import { useAppSelector } from '../../../../store/hooks';
-import { Phone } from '../../../../types/Phone';
+import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
+import { actions as cartActions } from '../../../../store/reducers/cartSlice';
import styles from './CartItem.module.scss';
import { ReactComponent as CloseIcon }
from '../../../../static/icons/close_icon.svg';
@@ -10,14 +9,15 @@ import { ReactComponent as MinusIcon }
from '../../../../static/icons/minus_icon.svg';
import { ReactComponent as PlusIcon }
from '../../../../static/icons/plus_icon.svg';
+import { ProductWithAmount } from '../../../../types/Product';
type Props = {
- phone: Phone | null;
+ phone: ProductWithAmount;
};
export const CartItem: React.FC = ({ phone }) => {
const { isDarkTheme } = useAppSelector((state) => state.theme);
- const isMinusDisabled = true;
+ const dispatch = useAppDispatch();
const getIconColor = (isTheme: boolean, isDisabled: boolean) => {
if (isTheme) {
@@ -37,9 +37,6 @@ export const CartItem: React.FC = ({ phone }) => {
return isDisabled ? {} : styles.changeAmountButton__ACTIVE;
};
- const minusIconColor = getIconColor(isDarkTheme, isMinusDisabled);
- const minusClass = getClass(isDarkTheme, isMinusDisabled);
-
return (
= ({ phone }) => {
})}
>
- {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
-