diff --git a/frontend/bun.lockb b/frontend/bun.lockb index 0878d98..9a62962 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/package.json b/frontend/package.json index f1098f5..7b77491 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,6 +28,7 @@ "react-icons": "^5.3.0", "react-redux": "^9.1.2", "redux": "^5.0.1", + "redux-persist": "^6.0.0", "resend": "^3.5.0", "sass": "^1.80.5", "sharp": "^0.33.5", diff --git a/frontend/src/app/redux/CartReducer.ts b/frontend/src/app/redux/CartReducer.ts index f377c89..91b8e17 100644 --- a/frontend/src/app/redux/CartReducer.ts +++ b/frontend/src/app/redux/CartReducer.ts @@ -1,4 +1,4 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; export interface Product { id: number; @@ -18,7 +18,7 @@ export const cartSlice = createSlice({ name: "cart", initialState, reducers: { - addToCart: (state: any, action: any) => { + addToCart: (state: any, action: PayloadAction) => { const item = state.products.find((p:Product) => p.id === action.payload.id); if(item) { item.quantity += action.payload.quantity; @@ -31,10 +31,12 @@ export const cartSlice = createSlice({ }, resetCart: (state) => { state.products = []; - } + }, }, }); export const { addToCart, removeFromCart, resetCart } = cartSlice.actions; -export default cartSlice.reducer; \ No newline at end of file +export default cartSlice.reducer; + +export const dynamic = 'force-dynamic' \ No newline at end of file diff --git a/frontend/src/components/CartTab/CartTab.css b/frontend/src/components/CartTab/CartTab.css index ea050d5..2829781 100644 --- a/frontend/src/components/CartTab/CartTab.css +++ b/frontend/src/components/CartTab/CartTab.css @@ -1,6 +1,5 @@ .cart{ z-index: 999; - background-color: white; -webkit-box-shadow: 0px 0px 7px -5px rgba(0,0,0,0.5); box-shadow: 0px 0px 7px -5px rgba(0,0,0,0.5); diff --git a/frontend/src/components/CartTab/CartTab.tsx b/frontend/src/components/CartTab/CartTab.tsx index 581193b..fad6f26 100644 --- a/frontend/src/components/CartTab/CartTab.tsx +++ b/frontend/src/components/CartTab/CartTab.tsx @@ -4,18 +4,27 @@ import Image from "next/image"; import { MdDeleteOutline } from "react-icons/md"; import { Button } from "@/components/ui/button"; import "./CartTab.css"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; import type { RootState } from "@/lib/Store"; - +import { removeFromCart } from "@/app/redux/CartReducer"; import type { Product } from "@/app/redux/CartReducer"; const CartTab = () => { const cartItems = true; + const dispatch = useDispatch(); // get the products from the cart const products = useSelector((state: RootState) => state.cart.products); + const totalPrice = () => { + let total = 0; + products?.forEach((item: Product) => { + total += item.price * item.quantity; + }); + return total.toFixed(2); + }; + // const data = [ // { // id: 1, @@ -39,30 +48,32 @@ const CartTab = () => { // }, // ]; return ( -
+
{products?.map((item: Product) => ( -
-
- item picture +
+
+
+ item picture +
+
+

{item.title}

+ {/*

{item.desc?.substring(0, 100)}

*/} +
{item.quantity} x ${item.price}
+
+ dispatch(removeFromCart(item.id))} />
-
-

{item.title}

-

{item.desc?.substring(0, 100)}

-
{item.quantity} x ${item.price}
+
+ SUBTOTAL + ${totalPrice()}
-
))} -
- SUBTOTAL - $123 -
{/* Reset Cart */}
diff --git a/frontend/src/components/Navbar/Navbar.tsx b/frontend/src/components/Navbar/Navbar.tsx index 8733c9d..915b340 100644 --- a/frontend/src/components/Navbar/Navbar.tsx +++ b/frontend/src/components/Navbar/Navbar.tsx @@ -5,6 +5,10 @@ import { useMediaQuery } from "@/util/useMediaQuery"; import { FiShoppingCart } from "react-icons/fi"; import Image from "next/image"; import CartTab from "@/components/CartTab/CartTab"; +import { useSelector } from "react-redux"; +import type { RootState } from "@/lib/Store"; +import Products from "@/app/products/page"; +import type { Product } from "@/app/redux/CartReducer"; const navMotion = { visible: { @@ -30,8 +34,11 @@ export default function Nav() { const matches = useMediaQuery("(min-width: 1280px)"); // console.log(matches); + // get the products from the cart + const products = useSelector((state: RootState) => state.cart.products); + return ( -
diff --git a/frontend/src/lib/Store.ts b/frontend/src/lib/Store.ts index 982f88f..fd7ce64 100644 --- a/frontend/src/lib/Store.ts +++ b/frontend/src/lib/Store.ts @@ -1,6 +1,16 @@ import { configureStore } from '@reduxjs/toolkit' import counterReducer from '@/app/redux/slice' import cartReducer from '@/app/redux/CartReducer' +import { persistReducer, persistStore } from 'redux-persist' +import storage from 'redux-persist/lib/storage' + +const persistConfig = { + key: 'cart', + storage, +} + +const persistedReducer = persistReducer(persistConfig, cartReducer) + export const makeStore = () => { return configureStore({ reducer: { @@ -9,6 +19,8 @@ export const makeStore = () => { }) } +export const persistor = persistStore(makeStore()); + // Infer the type of makeStore export type AppStore = ReturnType // Infer the `RootState` and `AppDispatch` types from the store itself