diff --git a/package-lock.json b/package-lock.json index bd8e7be..6047156 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.6.0", + "react-id-swiper": "^4.0.0", "react-redux": "^8.0.5", "react-router-dom": "^6.4.3", "react-spinners": "^0.13.6", @@ -16086,7 +16087,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -18322,6 +18322,22 @@ "react": "*" } }, + "node_modules/react-id-swiper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-id-swiper/-/react-id-swiper-4.0.0.tgz", + "integrity": "sha512-BFY8VQYgc1ECkT1Ek6MYSF8MADjWYZctdeRlMA202mjGcdjq1Bugfhg207KHTjGWKWZlY/7/nxFShqQo74RslA==", + "dependencies": { + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">= 6.11.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "swiper": ">=5.0.0" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -19021,6 +19037,74 @@ "strip-ansi": "^6.0.1" } }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -20187,6 +20271,74 @@ "node": ">= 10" } }, + "node_modules/svgo/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/svgo/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/svgo/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/swiper": { "version": "8.4.5", "resolved": "https://registry.npmjs.org/swiper/-/swiper-8.4.5.tgz", @@ -33891,8 +34043,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-hash": { "version": "3.0.0", @@ -35358,6 +35509,14 @@ "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", "requires": {} }, + "react-id-swiper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-id-swiper/-/react-id-swiper-4.0.0.tgz", + "integrity": "sha512-BFY8VQYgc1ECkT1Ek6MYSF8MADjWYZctdeRlMA202mjGcdjq1Bugfhg207KHTjGWKWZlY/7/nxFShqQo74RslA==", + "requires": { + "object-assign": "^4.1.1" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -35835,11 +35994,63 @@ "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "dev": true, "requires": { - "css-select": "*", + "css-select": "^4.1.3", "dom-converter": "^0.2.0", "htmlparser2": "^6.1.0", "lodash": "^4.17.21", "strip-ansi": "^6.0.1" + }, + "dependencies": { + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "*" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } } }, "require-directory": { @@ -36710,7 +36921,7 @@ "requires": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", - "css-select": "*", + "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", @@ -36722,6 +36933,56 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "*" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true } } }, diff --git a/package.json b/package.json index 11dd0cd..21a2e6d 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.6.0", + "react-id-swiper": "^4.0.0", "react-redux": "^8.0.5", "react-router-dom": "^6.4.3", "react-spinners": "^0.13.6", @@ -72,4 +73,4 @@ "css-select": "*" } } -} \ No newline at end of file +} diff --git a/src/components/CCTPCards.tsx b/src/components/CCTPCards.tsx index 2aacf1f..b24308c 100644 --- a/src/components/CCTPCards.tsx +++ b/src/components/CCTPCards.tsx @@ -1,22 +1,34 @@ -import React, { FC, ReactElement } from 'react' -import { FCTypes } from '../types/public.types'; +import React, { FC, ReactElement } from "react"; +import { FCTypes } from "../types/public.types"; -const CCTPCards:FC = (props):ReactElement => { - const {data} = props; +const CCTPCards: FC = (props): ReactElement => { + const { data } = props; return ( -
-
- {String(data.id)} +
+
+ {String(data.id)}
-
-

{data.title}

+
+

+ {data.title} +

-

${data.price}

+

+ ${data.price} +

- ) -} + ); +}; -export default CCTPCards \ No newline at end of file +export default CCTPCards; diff --git a/src/components/EXTPCards.tsx b/src/components/EXTPCards.tsx index 6b11ebd..99ab1e7 100644 --- a/src/components/EXTPCards.tsx +++ b/src/components/EXTPCards.tsx @@ -1,23 +1,32 @@ -import React, { FC, ReactElement } from 'react' -import { FCTypes } from '../types/public.types' +import React, { FC, ReactElement } from "react"; +import { FCTypes } from "../types/public.types"; -const EXTPCards:FC = (props):ReactElement => { - const {data} = props; +const EXTPCards: FC = (props): ReactElement => { + const { data } = props; return ( -
-
- +
+
+
-
-

{data.title}

-

${data.price}

+
+

+ {data.title} +

+

+ ${data.price} +

- ) -} + ); +}; -export default EXTPCards \ No newline at end of file +export default EXTPCards; diff --git a/src/components/FPCards.tsx b/src/components/FPCards.tsx index f7f7563..f3f6514 100644 --- a/src/components/FPCards.tsx +++ b/src/components/FPCards.tsx @@ -1,58 +1,64 @@ // Featured Products Card -import React, { FC, ReactElement } from 'react' -import { HiOutlineShoppingCart } from 'react-icons/hi'; -import { SlMagnifierAdd } from 'react-icons/sl'; +import React, { FC, ReactElement } from "react"; +import { HiOutlineShoppingCart } from "react-icons/hi"; +import { SlMagnifierAdd } from "react-icons/sl"; import { FiHeart } from "react-icons/fi"; -import { FCTypes } from '../types/public.types' +import { FCTypes } from "../types/public.types"; - -const FPCards:FC = (props):ReactElement => { - const {data} = props; +const FPCards: FC = (props): ReactElement => { + const { data } = props; return ( -
-
- {data.title} -
- - - +
+
+ {data.title} +
+ + +
- +
-
-

{data.title}

-
- { - data.colors && - data.colors?.map((color: any) => -
- ) - } +
+

+ {data.title} +

+
+ {data.colors && + data.colors?.map((color: any) => ( +
+ ))}
-

Code - {data.id}

-
- { - data.discount ? -
-

- {data.price} -

-

- {data.discount} -

-
: -

+

+ Code - {data.id} +

+
+ {data.discount ? ( +
+

{data.price}

+

{data.discount}

+
+ ) : ( +

{data.price}

- } + )}
- ) -} + ); +}; -export default FPCards \ No newline at end of file +export default FPCards; diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 0d88afc..807df65 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,66 +1,94 @@ -import React, { FC, ReactElement } from 'react' -import {AiFillInstagram} from "react-icons/ai"; -import {GrFacebookOption, GrTwitter} from "react-icons/gr"; +import React, { FC, ReactElement } from "react"; +import { AiFillInstagram } from "react-icons/ai"; +import { GrFacebookOption, GrTwitter } from "react-icons/gr"; -const Footer: FC = ():ReactElement => { +const Footer: FC = (): ReactElement => { return (
-
-
-
-
+
+
+
+
-
+
-
Customer Care
+
+ Customer Care +
    -
  • My Account
  • -
  • Discount
  • -
  • Returns
  • -
  • Orders History
  • -
  • Order Tracking
  • +
  • My Account
  • +
  • Discount
  • +
  • Returns
  • +
  • Orders History
  • +
  • Order Tracking
-
+
-
Pages
+
+ Pages +
    -
  • Browse the Shop
  • -
  • Wishlist
  • -
  • Cart
  • -
  • Sign In
  • -
  • Sign Up
  • +
  • Browse the Shop
  • +
  • Wishlist
  • +
  • Cart
  • +
  • Sign In
  • +
  • Sign Up
-
-
-

©MiladSadeghi - All Rights Reserved

-
- - - +
+
+

+ ©MiladSadeghi - All Rights Reserved +

+
+ + +
- ) -} + ); +}; -export default Footer \ No newline at end of file +export default Footer; diff --git a/src/components/LPCards.tsx b/src/components/LPCards.tsx index b9df2e0..e008982 100644 --- a/src/components/LPCards.tsx +++ b/src/components/LPCards.tsx @@ -1,36 +1,55 @@ // Featured Products Card -import React, { FC } from 'react' -import { FiHeart } from 'react-icons/fi'; -import { HiOutlineShoppingCart } from 'react-icons/hi'; -import { SlMagnifierAdd } from 'react-icons/sl'; -import { FCTypes } from '../types/public.types'; +import React, { FC } from "react"; +import { FiHeart } from "react-icons/fi"; +import { HiOutlineShoppingCart } from "react-icons/hi"; +import { SlMagnifierAdd } from "react-icons/sl"; +import { FCTypes } from "../types/public.types"; -const LPCards:FC = (props) => { - const {data} = props; +const LPCards: FC = (props) => { + const { data } = props; return ( -
-
- {data.title} -
- - - +
+
+ {data.title} +
+ + +
-
-

{data.title}

-
-

${data?.discount}

-

${data.price}

+
+

+ {data.title} +

+
+

+ ${data?.discount} +

+

+ ${data.price} +

- ) -} + ); +}; -export default LPCards \ No newline at end of file +export default LPCards; diff --git a/src/components/TCCards.tsx b/src/components/TCCards.tsx index 9512ea1..1539e78 100644 --- a/src/components/TCCards.tsx +++ b/src/components/TCCards.tsx @@ -1,21 +1,33 @@ -import React, { FC, ReactElement } from 'react' -import { FCTypes } from '../types/public.types' +import React, { FC, ReactElement } from "react"; +import { FCTypes } from "../types/public.types"; -const TCCards:FC = (props):ReactElement => { - const {data} = props; +const TCCards: FC = (props): ReactElement => { + const { data } = props; return ( -
-
- {data.title} - -
-
-
-
{data.title}
-

${data.price}

+
+
+ {data.title} + +
+
+
+
+ {data.title} +
+

${data.price}

- ) -} + ); +}; -export default TCCards \ No newline at end of file +export default TCCards; diff --git a/src/enums/public.enum.ts b/src/enums/public.enum.ts index 785ee16..84f9bef 100644 --- a/src/enums/public.enum.ts +++ b/src/enums/public.enum.ts @@ -8,4 +8,11 @@ export enum ECartSituation { First = "cart details", Second = "checkout", Third = "order complete" +} + +export enum ELatestSection { + NewArrival = "New Arrival", + BestSeller = "Best Seller", + Featured = "Featured", + SpecialOffer = "Special Offer" } \ No newline at end of file diff --git a/src/images/ellipse-unique-furniture.png b/src/images/ellipse-unique-furniture.png new file mode 100644 index 0000000..7b39cd7 Binary files /dev/null and b/src/images/ellipse-unique-furniture.png differ diff --git a/src/redux/hook.ts b/src/redux/hook.ts index 1b9a9a6..6092949 100644 --- a/src/redux/hook.ts +++ b/src/redux/hook.ts @@ -1,5 +1,5 @@ import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import type { RootState, AppDispatch } from './store'; -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: TypedUseSelectorHook = useSelector +export const useAppDispatch: () => AppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; \ No newline at end of file diff --git a/src/redux/slices/list.ts b/src/redux/slices/list.ts index 9518e0c..2e0dbe0 100644 --- a/src/redux/slices/list.ts +++ b/src/redux/slices/list.ts @@ -1,7 +1,7 @@ import { createAsyncThunk, createSlice } from "@reduxjs/toolkit" import { ISliceInitialState, Product } from "../../types/IProducts.interface"; -export const getRegularList = createAsyncThunk("product/regularList", async ({products, search}: {products: any, search: any}) => { +export const getRegularList = createAsyncThunk("product/regularList", async ({ products, search }: { products: any, search: any }) => { const filteredProducts = products.filter((product: Product) => product.title.toLowerCase().includes(search.toLowerCase())) return filteredProducts }) @@ -41,6 +41,6 @@ const productRegularList = createSlice({ }, }) -export const {lowest, highest, regular} = productRegularList.actions; +export const { lowest, highest, regular } = productRegularList.actions; export default productRegularList.reducer; \ No newline at end of file diff --git a/src/redux/slices/user.ts b/src/redux/slices/user.ts index ae423f8..981dbe4 100644 --- a/src/redux/slices/user.ts +++ b/src/redux/slices/user.ts @@ -1,9 +1,11 @@ import { createAsyncThunk, createSlice } from "@reduxjs/toolkit" import { doc, getDoc, updateDoc } from "firebase/firestore"; import { toast } from "react-toastify"; +import { createNonNullChain } from "typescript"; import { ECartSituation } from "../../enums/public.enum"; import { fireStoreDB } from "../../helper/firebase.config"; import { getCart } from "../../helper/firebase.data"; +import { IUserSlice } from "../../types/user.types"; export const getWishlist = createAsyncThunk("user/getWishlist", async (uid: string) => { @@ -44,14 +46,13 @@ export const removeCartItem = createAsyncThunk("user/removeCartItem", async ({ u } }) -const initialState = { +const initialState: IUserSlice = { userName: null, isLoggedIn: false, guest: false, - uid: null, + uid: "", wishlist: [], cart: [], - wishlistLoading: true, cartSituation: ECartSituation.First } @@ -114,14 +115,11 @@ const userSlice = createSlice({ }, extraReducers(builder) { builder.addCase(getWishlist.pending, (state) => { - state.wishlistLoading = true; }) builder.addCase(getWishlist.fulfilled, (state, action) => { state.wishlist = action.payload; - state.wishlistLoading = false; }) builder.addCase(getWishlist.rejected, (state, action) => { - state.wishlistLoading = false; toast.error("Please refresh the page") }) builder.addCase(clearUserCart.fulfilled, (state, action: any) => { diff --git a/src/routes/About.tsx b/src/routes/About.tsx index b7436f0..444c84d 100644 --- a/src/routes/About.tsx +++ b/src/routes/About.tsx @@ -1,87 +1,133 @@ -import React, { FC, ReactElement, useState } from 'react' +import React, { FC, ReactElement, useState } from "react"; import ManagementIMG from "../images/management-about.png"; -import ShopOffers from './Home/ShopOffers'; -import { Pagination } from 'swiper'; -import { Swiper, SwiperSlide } from 'swiper/react'; +import ShopOffers from "./Home/ShopOffers"; +import { Pagination } from "swiper"; +import { Swiper, SwiperSlide } from "swiper/react"; import client1 from "../images/client-1.png"; import client2 from "../images/client-2.png"; import client3 from "../images/client-3.png"; -import 'swiper/css'; -import 'swiper/css/pagination'; -import '../styles/swipers.css'; +import "swiper/css"; +import "swiper/css/pagination"; +import "../styles/swipers.css"; const About: FC = (): ReactElement => { - const [slide, setSlide] = useState(1); + const [commentSlide, setCommentSlide] = useState(1); const clientDetails = [ { name: "Sam Bankman-Fried", - position: "Ceo At FTX" + position: "Ceo At FTX", }, { name: "Selina Gomez", - position: "Ceo At Webecy Digital" + position: "Ceo At Webecy Digital", }, { name: "Guy Gershon", - position: "Senior Technical Product Manager" - } - ] + position: "Senior Technical Product Manager", + }, + ]; return (
-
-
-

About Us

+
+
+

+ About Us +

-
-
-
-
- management +
+
+
+
+ management
-
-

Know About Our ECommerce Business, History

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mattis neque ultrices mattis aliquam, malesuada diam est. Malesuada sem tristique amet erat vitae eget dolor lobortis. Accumsan faucibus vitae lobortis quis bibendum quam.

- +
+

+ Know About Our ECommerce Business, History +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mattis + neque ultrices mattis aliquam, malesuada diam est. Malesuada sem + tristique amet erat vitae eget dolor lobortis. Accumsan faucibus + vitae lobortis quis bibendum quam. +

+
-
- +
+
-

Our Client Say!

-
- Sam Bankman-Fried - Selina Gomez - Guy Gershon +

+ Our Client Say! +

+
+ Sam Bankman-Fried + Selina Gomez + Guy Gershon
setSlide(element.activeIndex)} + onRealIndexChange={(element) => + setCommentSlide(element.activeIndex) + } pagination={{ clickable: true }} className="mySwiper about-us" > - { - clientDetails.map(client => ( - -

{client.name}

-
{client.position}
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non duis ultrices quam vel dui sollicitudin aliquet id arcu. Nam vitae a enim nunc, sed sapien egestas ac nam. Tristique ultrices dolor aliquam lacus volutpat praesent.

-
- )) - } + {clientDetails.map((client) => ( + +

+ {client.name} +

+
+ {client.position} +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non + duis ultrices quam vel dui sollicitudin aliquet id arcu. Nam + vitae a enim nunc, sed sapien egestas ac nam. Tristique + ultrices dolor aliquam lacus volutpat praesent. +

+
+ ))}
- ) -} + ); +}; -export default About \ No newline at end of file +export default About; diff --git a/src/routes/Account/SignUp.tsx b/src/routes/Account/SignUp.tsx index 60c1f32..a590689 100644 --- a/src/routes/Account/SignUp.tsx +++ b/src/routes/Account/SignUp.tsx @@ -10,7 +10,7 @@ import { toast } from "react-toastify"; import { BarLoader } from "react-spinners"; import { createUserData, getWishlistAndCart } from "../../helper/firebase.data"; import { useAppSelector } from "../../redux/hook"; -import { TCart, TUserData } from "../../types/public.types"; +import { TUserData } from "../../types/public.types"; const SignUp: FC = (): ReactElement => { const { diff --git a/src/routes/Cart/Cart.tsx b/src/routes/Cart/Cart.tsx index 1a1093d..54dbf0f 100644 --- a/src/routes/Cart/Cart.tsx +++ b/src/routes/Cart/Cart.tsx @@ -78,7 +78,9 @@ const Cart: FC = ({ className="w-[87px]" src={ product.imagesByColor - ? product.imagesByColor[product.colors[0].name][0] + ? product.imagesByColor[ + product.colors!![0].name + ][0] : product.images[0] } alt={product.title} diff --git a/src/routes/Cart/Checkout.tsx b/src/routes/Cart/Checkout.tsx index 9c49457..2d43e46 100644 --- a/src/routes/Cart/Checkout.tsx +++ b/src/routes/Cart/Checkout.tsx @@ -162,7 +162,7 @@ const Checkout: React.FC = ({ className="w-full rounded-sm" src={ product.imagesByColor - ? product.imagesByColor[product.colors[0].name][0] + ? product.imagesByColor[product.colors!![0].name][0] : product.images[0] } alt={product.title} diff --git a/src/routes/Cart/main.tsx b/src/routes/Cart/main.tsx index f431a61..3b29633 100644 --- a/src/routes/Cart/main.tsx +++ b/src/routes/Cart/main.tsx @@ -12,7 +12,7 @@ import { ECartSituation } from "../../enums/public.enum"; const CartMain = (): ReactElement => { const { uid, cart, cartSituation } = useAppSelector((state) => state.user); const { products } = useAppSelector((state) => state.product); - const [cartProducts, setCartProducts] = useState(); + const [cartProducts, setCartProducts] = useState(); useEffect(() => { if (uid && !!products.length) { @@ -28,7 +28,7 @@ const CartMain = (): ReactElement => { const totalCartPrice = (): string => { const pricesArray: any = []; - cartProducts.forEach((item1: any) => + cartProducts!.forEach((item1: any) => cart.forEach((item2: any) => { if (item1.id === item2.productID) { pricesArray.push( diff --git a/src/routes/Home/DiscountItems.tsx b/src/routes/Home/DiscountItems.tsx index 05e3db5..b376fa2 100644 --- a/src/routes/Home/DiscountItems.tsx +++ b/src/routes/Home/DiscountItems.tsx @@ -1,63 +1,86 @@ -import React, { useEffect, useState } from 'react' -import { discountSection } from '../../enums/public.enum'; -import { useAppSelector } from '../../redux/hook'; -import {BiCheck} from "react-icons/bi"; -import { Product } from '../../types/IProducts.interface'; +import React, { useEffect, useState } from "react"; +import { discountSection } from "../../enums/public.enum"; +import { useAppSelector } from "../../redux/hook"; +import { BiCheck } from "react-icons/bi"; +import { Product } from "../../types/IProducts.interface"; const DiscountItems = () => { - const [section, setSection] = useState(discountSection.WoodChair); - const {products} = useAppSelector(state => state.product); - const [discountItem, setDiscountItem] = useState([]) + const [section, setSection] = useState( + discountSection.WoodChair + ); + const { products } = useAppSelector((state) => state.product); + const [discountItem, setDiscountItem] = useState(); - function changeItem(section: string):any { - return products.filter((product: Product) => product.category === 'Discount Item' && product.section === section) + function changeItem(section: string): any { + return products.find( + (product: Product) => + product.category === "Discount Item" && product.section === section + ); } useEffect(() => { setDiscountItem(changeItem(section)); - }, [section]) + }, [section, products]); - if (!!!discountItem.length) return null + if (!discountItem) return null; return ( -
-

Discount Item

-
- { - Object.values(discountSection).map((item, index) => ( - setSection(item)} key={item} className={`mr-10 last:mr-0 text-lg font-Lato text-navy-blue ${item === section && 'DI-selected'}`}> - {item} - - )) - } +
+

+ Discount Item +

+
+ {Object.values(discountSection).map((item, index) => ( + setSection(item)} + key={item} + className={`mr-10 last:mr-0 text-lg font-Lato text-navy-blue cursor-pointer ${ + item === section && "DI-selected" + }`} + > + {item} + + ))}
-
-
-
20% Discount Of All Products
-

{discountItem[0].title}

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Eu eget feugiat habitasse nec, bibendum condimentum.

-
- { - discountItem[0]?.specifications.slice(0,4).map((item: string) => ( -
- -

{item}

-
- )) - } +
+
+
+ 20% Discount Of All Products +
+

+ {discountItem.title} +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Eu eget + feugiat habitasse nec, bibendum condimentum. +

+
+ {discountItem?.specifications.slice(0, 4).map((item: string) => ( +
+ +

{item}

+
+ ))}
-
-
- +
+
+
- ) -} + ); +}; -export default DiscountItems \ No newline at end of file +export default DiscountItems; diff --git a/src/routes/Home/Header.tsx b/src/routes/Home/Header.tsx index 3d5985f..d9b166c 100644 --- a/src/routes/Home/Header.tsx +++ b/src/routes/Home/Header.tsx @@ -1,33 +1,46 @@ -import React from 'react' -import { Swiper, SwiperSlide } from 'swiper/react'; -import { Pagination } from 'swiper'; +import React from "react"; +import { Swiper, SwiperSlide } from "swiper/react"; +import { Autoplay, Pagination } from "swiper"; -import 'swiper/css'; -import 'swiper/css/pagination'; -import '../../styles/swipers.css'; +import "swiper/css"; +import "swiper/css/pagination"; +import "../../styles/swipers.css"; const Header = () => { return ( <> - first banner + first banner - second banner + second banner - third banner + third banner - - ) -} + ); +}; -export default Header; \ No newline at end of file +export default Header; diff --git a/src/routes/Home/LatestProducts.tsx b/src/routes/Home/LatestProducts.tsx index ca0d8b3..19232b1 100644 --- a/src/routes/Home/LatestProducts.tsx +++ b/src/routes/Home/LatestProducts.tsx @@ -1,38 +1,50 @@ -import React, { useEffect, useState } from 'react' -import LPCards from '../../components/LPCards'; -import { useAppSelector } from '../../redux/hook'; -import { Product } from '../../types/IProducts.interface'; +import React, { useEffect, useState } from "react"; +import LPCards from "../../components/LPCards"; +import { ELatestSection } from "../../enums/public.enum"; +import { useAppSelector } from "../../redux/hook"; +import { Product } from "../../types/IProducts.interface"; const LatestProducts = () => { - - const [section, setSection] = useState("New Arrival"); - const sections = ["New Arrival", "Best Seller", "Featured", "Special Offer"]; - const {products: Products} = useAppSelector(state => state.product); + const [section, setSection] = useState( + ELatestSection.NewArrival + ); + const { products: Products } = useAppSelector((state) => state.product); const [latestProducts, setLatestProducts] = useState([]); useEffect(() => { - const products: Product[] = Products.filter((product:Product) => product.category === "Leatest Products" && product.section === section); + const products: Product[] = Products.filter( + (product: Product) => + product.category === "Leatest Products" && product.section === section + ); setLatestProducts(products); - }, [section, Products]) + }, [section, Products]); if (latestProducts.length === 0) return null; return ( -
-

Latest Products

-
- {sections.map((item, index) => ( -

setSection(item)} className={`${item === section && '!text-pink-cc border-b-[1px] border-pink-cc'} mr-14 text-navy-blue last:mr-0 cursor-pointer `} key={index}>{item}

+
+

+ Latest Products +

+
+ {Object.values(ELatestSection).map((item: any, index: number) => ( +

setSection(item)} + className={`${ + item === section && "!text-pink-cc border-b-[1px] border-pink-cc" + } mr-14 text-navy-blue last:mr-0 cursor-pointer `} + key={index} + > + {item} +

))}
-
- { - latestProducts.map((product:Product) => - - ) - } +
+ {latestProducts.map((product: Product) => ( + + ))}
- ) -} + ); +}; -export default LatestProducts; \ No newline at end of file +export default LatestProducts; diff --git a/src/routes/Home/TopCategories.tsx b/src/routes/Home/TopCategories.tsx index b4065d6..ac4e89b 100644 --- a/src/routes/Home/TopCategories.tsx +++ b/src/routes/Home/TopCategories.tsx @@ -1,27 +1,31 @@ -import React, { useEffect, useState } from 'react' -import { Pagination } from 'swiper'; -import { SwiperSlide, Swiper } from 'swiper/react'; -import { useAppSelector } from '../../redux/hook'; -import { Product } from '../../types/IProducts.interface'; -import TCCards from '../../components/TCCards'; +import React, { useEffect, useState } from "react"; +import { Pagination } from "swiper"; +import { SwiperSlide, Swiper } from "swiper/react"; +import { useAppSelector } from "../../redux/hook"; +import { Product } from "../../types/IProducts.interface"; +import TCCards from "../../components/TCCards"; -import 'swiper/css'; -import 'swiper/css/pagination'; -import '../../styles/swipers.css'; +import "swiper/css"; +import "swiper/css/pagination"; +import "../../styles/swipers.css"; const TopCategories = () => { - - const {products: Products} = useAppSelector(state => state.product); + const { products: Products } = useAppSelector((state) => state.product); const [topCategories, setTopCategories] = useState([]); useEffect(() => { - const products: Product[] = Products.filter((product:Product) => product.category === "Featured Products"); + const products: Product[] = Products.filter( + (product: Product) => product.category === "Featured Products" + ); setTopCategories(products); - }, [Products]) + }, [Products]); return ( -
-

Top Categories

+
+

+ Top Categories +

+ { pagination={{ clickable: true }} className="mySwiper top-categories px-2" > - { - topCategories.map((product:Product) => ( - - - - )) - } + {topCategories.map((product: Product) => ( + + + + ))}
- ) -} + ); +}; -export default TopCategories \ No newline at end of file +export default TopCategories; diff --git a/src/routes/Home/UniqueFurniture.tsx b/src/routes/Home/UniqueFurniture.tsx index 2c3c6dd..78f5f5f 100644 --- a/src/routes/Home/UniqueFurniture.tsx +++ b/src/routes/Home/UniqueFurniture.tsx @@ -1,44 +1,66 @@ -import React from 'react' -import { useAppSelector } from '../../redux/hook'; -import { Product } from '../../types/IProducts.interface'; +import React from "react"; +import { useAppSelector } from "../../redux/hook"; +import { Product } from "../../types/IProducts.interface"; +import BGImg from "../../images/ellipse-unique-furniture.png"; const UniqueFurniture = () => { - const {products} = useAppSelector(state => state.product); - const uniqueFurniture: any = products.find((product: Product) => product.id === "09346776"); + const { products } = useAppSelector((state) => state.product); + const uniqueFurniture: any = products.find( + (product: Product) => product.id === "09346776" + ); - if (uniqueFurniture === undefined) return null + if (uniqueFurniture === undefined) return null; return ( -
-
-
-
- {uniqueFurniture.title} +
+
+
+
+ + {uniqueFurniture.title}
-
-

Unique Features Of leatest & Trending Poducts

-
    -
  • +
    +

    + Unique Features Of leatest & Trending Poducts +

    +
      +
    • {uniqueFurniture.specifications[0]}
    • -
    • +
    • {uniqueFurniture.specifications[1]}
    • -
    • +
    • {uniqueFurniture.specifications[2]}
    -
    - -
    -

    {uniqueFurniture.title}

    -

    ${uniqueFurniture.price}

    +
    + +
    +

    + {uniqueFurniture.title} +

    +

    + ${uniqueFurniture.price} +

- ) -} + ); +}; -export default UniqueFurniture; \ No newline at end of file +export default UniqueFurniture; diff --git a/src/routes/Products/ProductDetails.tsx b/src/routes/Products/ProductDetails.tsx index d626145..0bafb00 100644 --- a/src/routes/Products/ProductDetails.tsx +++ b/src/routes/Products/ProductDetails.tsx @@ -16,7 +16,7 @@ import { } from "../../helper/firebase.data"; import Loader from "../../helper/Loader"; import { useAppDispatch, useAppSelector } from "../../redux/hook"; -import { Product } from "../../types/IProducts.interface"; +import { Product, TProductDetailsStars } from "../../types/IProducts.interface"; const ProductDetails: FC = (): ReactElement | null => { const { id } = useParams(); @@ -28,12 +28,12 @@ const ProductDetails: FC = (): ReactElement | null => { const { products: Products } = useAppSelector((state) => state.product); const [productDetails, setProductDetails] = useState(); - const [stars, setStars] = useState({ + const [stars, setStars] = useState({ star: 0, count: 0, }); - const [toggleState, setToggleState] = useState(1); - const [mainImageIndex, setMainImageIndex] = useState(0); + const [toggleState, setToggleState] = useState(1); + const [mainImageIndex, setMainImageIndex] = useState(0); const toggleTab = (index: number) => { setToggleState(index); @@ -89,7 +89,7 @@ const ProductDetails: FC = (): ReactElement | null => {
{productDetails.imagesByColor ? productDetails.imagesByColor[ - productDetails.colors[0].name + productDetails.colors!![0].name ].map((image: string, index: number) => ( { className="rounded-sm" key={ productDetails.imagesByColor[ - productDetails.colors[0].name + productDetails.colors!![0].name ][0] } src={ productDetails.imagesByColor[ - productDetails.colors[0].name + productDetails.colors!![0].name ][mainImageIndex] } alt={productDetails.title} diff --git a/src/routes/Products/ProductsList.tsx b/src/routes/Products/ProductsList.tsx index ef731a4..05b5c7a 100644 --- a/src/routes/Products/ProductsList.tsx +++ b/src/routes/Products/ProductsList.tsx @@ -1,148 +1,212 @@ -import React, { useEffect, useRef, useState } from 'react' -import { FiHeart } from 'react-icons/fi'; -import { HiOutlineShoppingCart } from 'react-icons/hi'; -import { SlMagnifierAdd } from 'react-icons/sl'; -import { Link, useSearchParams } from 'react-router-dom'; -import Loader from '../../helper/Loader'; -import { useAppDispatch, useAppSelector } from '../../redux/hook'; -import { getRegularList, highest, lowest, regular } from '../../redux/slices/list'; -import { Product } from '../../types/IProducts.interface'; -import { TProductListSort } from '../../types/public.types'; +import React, { useEffect, useRef, useState } from "react"; +import { FiHeart } from "react-icons/fi"; +import { HiOutlineShoppingCart } from "react-icons/hi"; +import { SlMagnifierAdd } from "react-icons/sl"; +import { Link, useSearchParams } from "react-router-dom"; +import Loader from "../../helper/Loader"; +import { useAppDispatch, useAppSelector } from "../../redux/hook"; +import { + getRegularList, + highest, + lowest, + regular, +} from "../../redux/slices/list"; +import { Product } from "../../types/IProducts.interface"; +import { TProductListSort } from "../../types/public.types"; const ProductsList = () => { const [searchParams, setSearchParams] = useSearchParams(); - const {loading : productsLoading, products} = useAppSelector(state => state.product); - const [searchText, setSearchText] = useState(""); - const [sort, setSort] = useState("regular") - const {loading: listedLoading, listedProduct} = useAppSelector(state => state.list); + const { loading: productsLoading, products } = useAppSelector( + (state) => state.product + ); + const [searchText, setSearchText] = useState(""); + const [sort, setSort] = useState("regular"); + const { loading: listedLoading, listedProduct } = useAppSelector( + (state) => state.list + ); const dispatch = useAppDispatch(); - const isMount1 = useRef(false) - const isMount2 = useRef(false) + const isMount1 = useRef(false); + const isMount2 = useRef(false); useEffect(() => { if (!productsLoading && !!products.length) { if (searchParams.get("search")) { - setSearchText(() => searchParams.get("search")); + setSearchText(() => String(searchParams.get("search"))); } else { - dispatch(getRegularList({products, search: ""})) + dispatch(getRegularList({ products, search: "" })); } } - }, [products]) - + }, [products]); useEffect(() => { if (isMount1.current) { - dispatch(getRegularList({products, search: searchText})); + dispatch(getRegularList({ products, search: searchText })); searchParams.set("search", searchText); setSearchParams(searchParams); - document.title = `Hekto - ${searchText}` - setSort('regular'); + document.title = `Hekto - ${searchText}`; + setSort("regular"); } else { - isMount1.current = true + isMount1.current = true; } - }, [searchText]) + }, [searchText]); useEffect(() => { if (isMount2.current) { if (sort === "lowest") { - dispatch(lowest(listedProduct)) + dispatch(lowest(listedProduct)); } else if (sort === "highest") { - dispatch(highest(listedProduct)) - } else if (sort === 'regular') { - dispatch(regular(products)) + dispatch(highest(listedProduct)); + } else if (sort === "regular") { + dispatch(regular(products)); } } else { isMount2.current = true; } - }, [sort]) + }, [sort]); const changeHandler = (query: TProductListSort) => { - setSort(() => query) - } + setSort(() => query); + }; - if (productsLoading || !!!products.length) return + if (productsLoading || !!!products.length) return ; return (
-
-
-

Product List

+
+
+

+ Product List +

-
+
-
-
Furniture Ecommerce
-
-

Sort By:

- changeHandler(e.target.value)} + > - setSearchText(e.target.value)} /> + setSearchText(e.target.value)} + />
-
- { - listedLoading ? - ( - - ): - ( - listedProduct.map((product: Product) => -
-
+
+ {listedLoading ? ( + + ) : ( + listedProduct.map((product: Product) => ( +
+
- - +
-
-
- {product.title} - { - product.colors && - ( -
- {product.colors.map((item: any) => -
-
-
-

{item.name}

- -
+
+
+ + {product.title} + + {product.colors && ( +
+ {product.colors.map((item: any) => ( +
+
+
+

+ {item.name} +

+ + +
- )} -
- ) - } +
+ ))} +
+ )}
-
-

${product.discount}

-

${product.price}

+
+

+ ${product.discount} +

+

+ ${product.price} +

-
- - +
+ + - +
- ) - ) - } + )) + )}
- ) -} + ); +}; -export default ProductsList \ No newline at end of file +export default ProductsList; diff --git a/src/routes/Wishlist.tsx b/src/routes/Wishlist.tsx index d275025..7fa961d 100644 --- a/src/routes/Wishlist.tsx +++ b/src/routes/Wishlist.tsx @@ -91,7 +91,7 @@ const Wishlist = () => { className="w-[150px]" src={ product.imagesByColor - ? product.imagesByColor[product.colors[0].name][0] + ? product.imagesByColor[product.colors!![0].name][0] : product.images[0] } alt={product.title} diff --git a/src/types/IProducts.interface.ts b/src/types/IProducts.interface.ts index e504a4c..55bbb4c 100644 --- a/src/types/IProducts.interface.ts +++ b/src/types/IProducts.interface.ts @@ -1,20 +1,17 @@ type ProductColors = { - [key: string]: { - name: string; - color: string; - } + name: string; + color: string; } type ProductImagesByColor = { - [key: string]: string[] + [name: string]: string[] } - export type Product = { category: string; - colors?: any, + colors?: ProductColors[], id: string; - imagesByColor?: any, + imagesByColor?: ProductImagesByColor, price: string; specifications: string[], title: string; @@ -29,4 +26,9 @@ export interface ISliceInitialState { products?: Product[], error: any, listedProduct?: Product[], +} + +export type TProductDetailsStars = { + star: number, + count: number } \ No newline at end of file diff --git a/src/types/user.types.ts b/src/types/user.types.ts new file mode 100644 index 0000000..97e28dc --- /dev/null +++ b/src/types/user.types.ts @@ -0,0 +1,28 @@ +import { ECartSituation } from "../enums/public.enum"; +import { Product } from "./IProducts.interface"; + +export type TCart = { + productID: string; + quantity: number +}; + +export type TUserData = { + wishlist: string[], + cart: TCart[] +} + +export interface ICartProps { + cartProducts: Product[], + cart: TCart[], + totalCartPrice: string +} + +export interface IUserSlice { + userName: string | null, + isLoggedIn: boolean, + guest: boolean, + uid: string, + wishlist: string[], + cart: TCart[], + cartSituation: ECartSituation +} \ No newline at end of file