Repository navigation
Expand file tree
/
Copy pathstore.ts
More file actions
122 lines (118 loc) · 3.64 KB
/
Copy pathstore.ts
File metadata and controls
122 lines (118 loc) · 3.64 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { Product } from "./sanity.types";
export interface CartItem {
product: Product;
quantity: number;
}
interface StoreState {
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[];
// // favorite
favoriteProduct: Product[];
addToFavorite: (product: Product) => Promise<void>;
removeFromFavorite: (productId: string) => void;
resetFavorite: () => void;
}
const useStore = create<StoreState>()(
persist(
(set, get) => ({
items: [],
favoriteProduct: [],
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,
addToFavorite: (product: Product) => {
return new Promise<void>((resolve) => {
set((state: StoreState) => {
const isFavorite = state.favoriteProduct.some(
(item) => item._id === product._id
);
return {
favoriteProduct: isFavorite
? state.favoriteProduct.filter(
(item) => item._id !== product._id
)
: [...state.favoriteProduct, { ...product }],
};
});
resolve();
});
},
removeFromFavorite: (productId: string) => {
set((state: StoreState) => ({
favoriteProduct: state.favoriteProduct.filter(
(item) => item?._id !== productId
),
}));
},
resetFavorite: () => {
set({ favoriteProduct: [] });
},
}),
{
name: "cart-store",
}
)
);
export default useStore;