diff --git a/components/Card.tsx b/components/Card.tsx index 8cd337b..1905720 100644 --- a/components/Card.tsx +++ b/components/Card.tsx @@ -2,13 +2,21 @@ import Link from "next/link"; import Image from "next/image"; import styles from '../styles/Card.module.css'; import { ProductType } from "../utils/types"; +import {useState} from 'react'; const Card = ({product}:{product:ProductType}) => { + const handleImage = ()=>{ + if(!product.images[0].includes('http')){ + return + } + return + } + return (
- + {handleImage()}
{product.category.name}
diff --git a/components/Cart.tsx b/components/Cart.tsx index bb00064..20b17c0 100644 --- a/components/Cart.tsx +++ b/components/Cart.tsx @@ -3,6 +3,10 @@ import styles from '../styles/Cart.module.css'; import { useAppSelector } from "../utils/hooks"; import Link from 'next/link'; import useOutsideAlerter from '../hooks/useOutsideAlerter'; +import { useRouter } from 'next/router'; +import { useAppDispatch } from '../utils/hooks'; +import { ProductType } from '../utils/types'; +import { updateCartThunk } from '../utils/thunk'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faCartShopping } from "@fortawesome/free-solid-svg-icons" @@ -13,30 +17,47 @@ export const Cart = () => { const numOfItems = cartProducts?.reduce((prev,current)=>prev+current.quantity,0); const totalPrice = cartProducts?.reduce((prev,current)=>prev+(Math.floor(current.price*current.quantity)),0); + const router = useRouter(); + const dispatch = useAppDispatch(); + const ref = useRef(null); const [clickedOutside] = useOutsideAlerter(ref); useEffect(()=>{setOpened(false)},[clickedOutside]); + const addProductQuantity = (product:ProductType)=>{ + dispatch(updateCartThunk({item:product})); + } + const subtractProductQuantity = (product:ProductType)=>{ + dispatch(updateCartThunk({item:product,subtruct:true})); + } + + const navigateToProduct = (id:number)=>{ + router.push('/products/'+id); + setOpened(false); + } return ( -
+
setOpened(prev=>!prev)}> {numOfItems}
{/* */} {opened && -
setOpened(false)}> +

Products:

{cartProducts && cartProducts.map(product => - -
- {product.title} - {product.title}: {Math.floor(product.price * product.quantity)}$ +
+ {product.title}navigateToProduct(product.id)}/> +
+ navigateToProduct(product.id)}>{product.title} + Total: {Math.floor(product.price * product.quantity)}$ +
+ {product.quantity} +
- )} - Checkout +
}
) } diff --git a/next.config.js b/next.config.js index 3376e3c..b02eea1 100644 --- a/next.config.js +++ b/next.config.js @@ -3,7 +3,7 @@ const nextConfig = { reactStrictMode: false, swcMinify: true, images: { - domains: ['fakestoreapi.com','api.escuelajs.co','api.lorem.space','placeimg.com'], + domains: ['ih1.redbubble.net','api.escuelajs.co','api.lorem.space','placeimg.com'], }, } diff --git a/pages/index.tsx b/pages/index.tsx index a5ddb87..6920ba4 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -8,7 +8,7 @@ import { updateProducts } from '../utils/products.slice' import Card from '../components/Card' export const getServerSideProps:GetServerSideProps = async () => { - const products = await (await fetch('https://api.escuelajs.co/api/v1/products?offset=1&limit=9')).json(); + const products = await (await fetch('https://api.escuelajs.co/api/v1/products?offset=1&limit=30')).json(); const categories = await (await fetch('https://api.escuelajs.co/api/v1/categories')).json(); return { props:{products,categories} diff --git a/pages/products/[id].tsx b/pages/products/[id].tsx index 2170185..3582c04 100644 --- a/pages/products/[id].tsx +++ b/pages/products/[id].tsx @@ -29,7 +29,7 @@ export const Product:NextPage<{product?:ProductType}> = ({product}) => { const dispatch = useAppDispatch(); const user = useAppSelector(state=>state.userDetails.user); const onAddToCartHandler = (product:ProductType) => { - dispatch(updateCartThunk(product)); + dispatch(updateCartThunk({item:product})); } return( diff --git a/public/blob-haikei (1).svg b/public/blob-haikei (1).svg deleted file mode 100644 index 9807547..0000000 --- a/public/blob-haikei (1).svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/blob-haikei.svg b/public/blob-haikei.svg deleted file mode 100644 index 3f34240..0000000 --- a/public/blob-haikei.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/circle-scatter-haikei.svg b/public/circle-scatter-haikei.svg deleted file mode 100644 index c144a85..0000000 --- a/public/circle-scatter-haikei.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/leone-venter-mTkXSSScrzw-unsplash.jpg b/public/leone-venter-mTkXSSScrzw-unsplash.jpg deleted file mode 100644 index ce8ff33..0000000 Binary files a/public/leone-venter-mTkXSSScrzw-unsplash.jpg and /dev/null differ diff --git a/public/paul-earle-wVjd0eWNqI8-unsplash.jpg b/public/paul-earle-wVjd0eWNqI8-unsplash.jpg deleted file mode 100644 index 5141ae6..0000000 Binary files a/public/paul-earle-wVjd0eWNqI8-unsplash.jpg and /dev/null differ diff --git a/public/product_placeholder.jpg b/public/product_placeholder.jpg new file mode 100644 index 0000000..81b225a Binary files /dev/null and b/public/product_placeholder.jpg differ diff --git a/styles/Cart.module.css b/styles/Cart.module.css index 453593c..468354c 100644 --- a/styles/Cart.module.css +++ b/styles/Cart.module.css @@ -21,6 +21,7 @@ /* background-color: #555; */ padding: 5px; /* border: 5px solid #333; */ + margin-bottom: 10px; } .cartItem img { @@ -29,16 +30,32 @@ .cartItemTitle { font-weight: bold; + display: block; +} +.cartItemTotal { + font-size: 0.9rem; } .cartItemQuantity { - display: inline-block; + display: flex; + align-items: center; + justify-content: center; background-color: #333; - border-radius: 50%; + border-radius: 10px; + font-size: 1rem; + width: 3rem; + height: 2rem; + color: #fff; +} + +.checkoutButton { + background: #333; + color: #fff; + padding: 0.5rem 1rem; + border-radius: 30px; + border: none; font-size: 1rem; - width: 30px; - height: 30px; - line-height: 30px; + cursor: pointer; } @keyframes enter { diff --git a/utils/thunk.ts b/utils/thunk.ts index e3f445e..a3b261a 100644 --- a/utils/thunk.ts +++ b/utils/thunk.ts @@ -4,8 +4,18 @@ import { ProductType } from "./types"; import {createAsyncThunk} from '@reduxjs/toolkit'; import { RootState } from "./store"; -export const updateCartThunk = createAsyncThunk('updateCartThunk',async (item:ProductType,{getState})=>{ - const state = getState(); +type Props = { + item:ProductType, + subtruct?:boolean +} +type ThunkApi = { + state:RootState +} +export const updateCartThunk = createAsyncThunk + +('updateCartThunk',async (props,thunkApi)=>{ + const {item,subtruct} = props; + const state = thunkApi.getState(); let isExist = -1; const oldCart = state.userDetails.cart ? [...state.userDetails.cart]: []; let newCart; @@ -13,9 +23,14 @@ export const updateCartThunk = createAsyncThunk0){ + newCart = [updatedProduct,...oldCart]; + }else{ + newCart = [...oldCart]; + } }else{ newCart = [{...item,quantity:1},...oldCart]; }