-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstore.ts
87 lines (83 loc) Β· 2.57 KB
/
store.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { Product } from "./sanity.types";
export interface CartItem {
product: Product;
quantity: number;
}
interface CartState {
items: CartItem[];
addItem: (product: Product) => void;
removeItem: (productId: string) => void;
deleteCartProduct: (productId: string) => void;
resetCart: () => void;
getTotalPrice: () => number;
getSubtotalPrice: () => number;
getItemCount: (productId: string) => number;
getGroupedItems: () => CartItem[];
}
const useCartStore = create<CartState>()(
persist(
(set, get) => ({
items: [],
addItem: (product) =>
set((state) => {
const existingItem = state.items.find(
(item) => item.product._id === product._id
);
if (existingItem) {
return {
items: state.items.map((item) =>
item.product._id === product._id
? { ...item, quantity: item.quantity + 1 }
: item
),
};
} else {
return { items: [...state.items, { product, quantity: 1 }] };
}
}),
removeItem: (productId) =>
set((state) => ({
items: state.items.reduce((acc, item) => {
if (item.product._id === productId) {
if (item.quantity > 1) {
acc.push({ ...item, quantity: item.quantity - 1 });
}
} else {
acc.push(item);
}
return acc;
}, [] as CartItem[]),
})),
deleteCartProduct: (productId) =>
set((state) => ({
items: state.items.filter(
({ product }) => product?._id !== productId
),
})),
resetCart: () => set({ items: [] }),
getTotalPrice: () => {
return get().items.reduce(
(total, item) => total + (item.product.price ?? 0) * item.quantity,
0
);
},
getSubtotalPrice: () => {
return get().items.reduce((total, item) => {
const price = item.product.price ?? 0;
const discount = ((item.product.discount ?? 0) * price) / 100;
const discountedPrice = price + discount;
return total + discountedPrice * item.quantity;
}, 0);
},
getItemCount: (productId) => {
const item = get().items.find((item) => item.product._id === productId);
return item ? item.quantity : 0;
},
getGroupedItems: () => get().items,
}),
{ name: "cart-store" }
)
);
export default useCartStore;