akarshanxyz 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,49 +1,382 @@
|
|
|
1
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Provider, useDispatch, useSelector } from "react-redux";
|
|
3
|
+
import { configureStore, createSlice } from "@reduxjs/toolkit";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const initialState = {
|
|
6
|
-
products: [
|
|
7
|
-
{
|
|
8
|
-
id: 1,
|
|
9
|
-
title: "Handmade Vase",
|
|
10
|
-
price: 800,
|
|
11
|
-
stock: 5,
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
id: 2,
|
|
15
|
-
title: "Wooden Craft",
|
|
16
|
-
price: 1200,
|
|
17
|
-
stock: 3,
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
};
|
|
5
|
+
/* ================= PRODUCT SLICE ================= */
|
|
21
6
|
|
|
22
7
|
const productSlice = createSlice({
|
|
23
8
|
name: "products",
|
|
24
|
-
initialState
|
|
9
|
+
initialState: {
|
|
10
|
+
products: [
|
|
11
|
+
{
|
|
12
|
+
id: 1,
|
|
13
|
+
title: "Handmade Vase",
|
|
14
|
+
price: 800,
|
|
15
|
+
stock: 5,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 2,
|
|
19
|
+
title: "Wooden Craft",
|
|
20
|
+
price: 1200,
|
|
21
|
+
stock: 3,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
25
|
reducers: {
|
|
26
26
|
decreaseStock: (state, action) => {
|
|
27
27
|
const product = state.products.find(
|
|
28
|
-
(
|
|
28
|
+
(p) => p.id === action.payload
|
|
29
29
|
);
|
|
30
30
|
|
|
31
31
|
if (product && product.stock > 0) {
|
|
32
|
-
product.stock
|
|
32
|
+
product.stock--;
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
|
|
36
36
|
increaseStock: (state, action) => {
|
|
37
37
|
const product = state.products.find(
|
|
38
|
-
(
|
|
38
|
+
(p) => p.id === action.payload
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
if (product) {
|
|
42
|
-
product.stock
|
|
42
|
+
product.stock++;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/* ================= CART SLICE ================= */
|
|
49
|
+
|
|
50
|
+
const cartSlice = createSlice({
|
|
51
|
+
name: "cart",
|
|
52
|
+
initialState: {
|
|
53
|
+
cartItems: [],
|
|
54
|
+
totalPrice: 0,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
reducers: {
|
|
58
|
+
addToCart: (state, action) => {
|
|
59
|
+
const product = action.payload;
|
|
60
|
+
|
|
61
|
+
const existingItem = state.cartItems.find(
|
|
62
|
+
(item) => item.id === product.id
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (existingItem) {
|
|
66
|
+
existingItem.quantity++;
|
|
67
|
+
} else {
|
|
68
|
+
state.cartItems.push({
|
|
69
|
+
id: product.id,
|
|
70
|
+
title: product.title,
|
|
71
|
+
price: product.price,
|
|
72
|
+
quantity: 1,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
state.totalPrice += product.price;
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
removeFromCart: (state, action) => {
|
|
80
|
+
const productId = action.payload;
|
|
81
|
+
|
|
82
|
+
const item = state.cartItems.find(
|
|
83
|
+
(item) => item.id === productId
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
if (!item) return;
|
|
87
|
+
|
|
88
|
+
state.totalPrice -= item.price;
|
|
89
|
+
|
|
90
|
+
if (item.quantity > 1) {
|
|
91
|
+
item.quantity--;
|
|
92
|
+
} else {
|
|
93
|
+
state.cartItems = state.cartItems.filter(
|
|
94
|
+
(i) => i.id !== productId
|
|
95
|
+
);
|
|
43
96
|
}
|
|
44
97
|
},
|
|
98
|
+
|
|
99
|
+
deleteItem: (state, action) => {
|
|
100
|
+
const productId = action.payload;
|
|
101
|
+
|
|
102
|
+
const item = state.cartItems.find(
|
|
103
|
+
(i) => i.id === productId
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
if (!item) return;
|
|
107
|
+
|
|
108
|
+
state.totalPrice -=
|
|
109
|
+
item.price * item.quantity;
|
|
110
|
+
|
|
111
|
+
state.cartItems = state.cartItems.filter(
|
|
112
|
+
(i) => i.id !== productId
|
|
113
|
+
);
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
clearCart: (state) => {
|
|
117
|
+
state.cartItems = [];
|
|
118
|
+
state.totalPrice = 0;
|
|
119
|
+
},
|
|
45
120
|
},
|
|
46
121
|
});
|
|
47
122
|
|
|
48
|
-
|
|
49
|
-
|
|
123
|
+
/* ================= USER SLICE ================= */
|
|
124
|
+
|
|
125
|
+
const userSlice = createSlice({
|
|
126
|
+
name: "user",
|
|
127
|
+
|
|
128
|
+
initialState: {
|
|
129
|
+
user: {
|
|
130
|
+
name: "Sakshi",
|
|
131
|
+
isLoggedIn: true,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
reducers: {
|
|
136
|
+
login: (state, action) => {
|
|
137
|
+
state.user = {
|
|
138
|
+
name: action.payload,
|
|
139
|
+
isLoggedIn: true,
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
logout: (state) => {
|
|
144
|
+
state.user = {
|
|
145
|
+
name: "",
|
|
146
|
+
isLoggedIn: false,
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
/* ================= STORE ================= */
|
|
153
|
+
|
|
154
|
+
const store = configureStore({
|
|
155
|
+
reducer: {
|
|
156
|
+
productReducer: productSlice.reducer,
|
|
157
|
+
cartReducer: cartSlice.reducer,
|
|
158
|
+
userReducer: userSlice.reducer,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const {
|
|
163
|
+
decreaseStock,
|
|
164
|
+
increaseStock,
|
|
165
|
+
} = productSlice.actions;
|
|
166
|
+
|
|
167
|
+
const {
|
|
168
|
+
addToCart,
|
|
169
|
+
removeFromCart,
|
|
170
|
+
deleteItem,
|
|
171
|
+
clearCart,
|
|
172
|
+
} = cartSlice.actions;
|
|
173
|
+
|
|
174
|
+
const {
|
|
175
|
+
login,
|
|
176
|
+
logout,
|
|
177
|
+
} = userSlice.actions;
|
|
178
|
+
|
|
179
|
+
/* ================= SHOP COMPONENT ================= */
|
|
180
|
+
|
|
181
|
+
function Shop() {
|
|
182
|
+
const dispatch = useDispatch();
|
|
183
|
+
|
|
184
|
+
const products = useSelector(
|
|
185
|
+
(state) => state.productReducer.products
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const cartItems = useSelector(
|
|
189
|
+
(state) => state.cartReducer.cartItems
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const totalPrice = useSelector(
|
|
193
|
+
(state) => state.cartReducer.totalPrice
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const user = useSelector(
|
|
197
|
+
(state) => state.userReducer.user
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const handleAddToCart = (product) => {
|
|
201
|
+
if (product.stock === 0) {
|
|
202
|
+
alert("Out of Stock");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
dispatch(addToCart(product));
|
|
207
|
+
dispatch(decreaseStock(product.id));
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const handleRemoveFromCart = (id) => {
|
|
211
|
+
dispatch(removeFromCart(id));
|
|
212
|
+
dispatch(increaseStock(id));
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const handleDelete = (item) => {
|
|
216
|
+
for (let i = 0; i < item.quantity; i++) {
|
|
217
|
+
dispatch(increaseStock(item.id));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
dispatch(deleteItem(item.id));
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<div style={{ padding: "20px" }}>
|
|
225
|
+
<h1>Mini E-Commerce App</h1>
|
|
226
|
+
|
|
227
|
+
{/* USER SECTION */}
|
|
228
|
+
|
|
229
|
+
<div
|
|
230
|
+
style={{
|
|
231
|
+
border: "1px solid black",
|
|
232
|
+
padding: "10px",
|
|
233
|
+
marginBottom: "20px",
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
<h2>User Section</h2>
|
|
237
|
+
|
|
238
|
+
{user.isLoggedIn ? (
|
|
239
|
+
<>
|
|
240
|
+
<p>
|
|
241
|
+
Logged In As:
|
|
242
|
+
<strong> {user.name}</strong>
|
|
243
|
+
</p>
|
|
244
|
+
|
|
245
|
+
<button
|
|
246
|
+
onClick={() =>
|
|
247
|
+
dispatch(logout())
|
|
248
|
+
}
|
|
249
|
+
>
|
|
250
|
+
Logout
|
|
251
|
+
</button>
|
|
252
|
+
</>
|
|
253
|
+
) : (
|
|
254
|
+
<>
|
|
255
|
+
<p>User Not Logged In</p>
|
|
256
|
+
|
|
257
|
+
<button
|
|
258
|
+
onClick={() =>
|
|
259
|
+
dispatch(login("Sakshi"))
|
|
260
|
+
}
|
|
261
|
+
>
|
|
262
|
+
Login
|
|
263
|
+
</button>
|
|
264
|
+
</>
|
|
265
|
+
)}
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
{/* PRODUCTS */}
|
|
269
|
+
|
|
270
|
+
<div
|
|
271
|
+
style={{
|
|
272
|
+
border: "1px solid black",
|
|
273
|
+
padding: "10px",
|
|
274
|
+
marginBottom: "20px",
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
<h2>Products</h2>
|
|
278
|
+
|
|
279
|
+
{products.map((product) => (
|
|
280
|
+
<div
|
|
281
|
+
key={product.id}
|
|
282
|
+
style={{
|
|
283
|
+
border: "1px solid gray",
|
|
284
|
+
padding: "10px",
|
|
285
|
+
marginBottom: "10px",
|
|
286
|
+
}}
|
|
287
|
+
>
|
|
288
|
+
<h3>{product.title}</h3>
|
|
289
|
+
|
|
290
|
+
<p>Price: ₹{product.price}</p>
|
|
291
|
+
|
|
292
|
+
<p>Stock: {product.stock}</p>
|
|
293
|
+
|
|
294
|
+
<button
|
|
295
|
+
disabled={product.stock === 0}
|
|
296
|
+
onClick={() =>
|
|
297
|
+
handleAddToCart(product)
|
|
298
|
+
}
|
|
299
|
+
>
|
|
300
|
+
Add To Cart
|
|
301
|
+
</button>
|
|
302
|
+
</div>
|
|
303
|
+
))}
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
{/* CART */}
|
|
307
|
+
|
|
308
|
+
<div
|
|
309
|
+
style={{
|
|
310
|
+
border: "1px solid black",
|
|
311
|
+
padding: "10px",
|
|
312
|
+
}}
|
|
313
|
+
>
|
|
314
|
+
<h2>Cart</h2>
|
|
315
|
+
|
|
316
|
+
{cartItems.length === 0 ? (
|
|
317
|
+
<p>Cart is Empty</p>
|
|
318
|
+
) : (
|
|
319
|
+
cartItems.map((item) => (
|
|
320
|
+
<div
|
|
321
|
+
key={item.id}
|
|
322
|
+
style={{
|
|
323
|
+
border: "1px solid gray",
|
|
324
|
+
marginBottom: "10px",
|
|
325
|
+
padding: "10px",
|
|
326
|
+
}}
|
|
327
|
+
>
|
|
328
|
+
<h3>{item.title}</h3>
|
|
329
|
+
|
|
330
|
+
<p>Price: ₹{item.price}</p>
|
|
331
|
+
|
|
332
|
+
<p>
|
|
333
|
+
Quantity: {item.quantity}
|
|
334
|
+
</p>
|
|
335
|
+
|
|
336
|
+
<button
|
|
337
|
+
onClick={() =>
|
|
338
|
+
handleRemoveFromCart(
|
|
339
|
+
item.id
|
|
340
|
+
)
|
|
341
|
+
}
|
|
342
|
+
>
|
|
343
|
+
Remove One
|
|
344
|
+
</button>
|
|
345
|
+
|
|
346
|
+
<button
|
|
347
|
+
style={{
|
|
348
|
+
marginLeft: "10px",
|
|
349
|
+
}}
|
|
350
|
+
onClick={() =>
|
|
351
|
+
handleDelete(item)
|
|
352
|
+
}
|
|
353
|
+
>
|
|
354
|
+
Delete Item
|
|
355
|
+
</button>
|
|
356
|
+
</div>
|
|
357
|
+
))
|
|
358
|
+
)}
|
|
359
|
+
|
|
360
|
+
<h3>Total Price: ₹{totalPrice}</h3>
|
|
361
|
+
|
|
362
|
+
<button
|
|
363
|
+
onClick={() =>
|
|
364
|
+
dispatch(clearCart())
|
|
365
|
+
}
|
|
366
|
+
>
|
|
367
|
+
Clear Cart
|
|
368
|
+
</button>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* ================= APP ================= */
|
|
375
|
+
|
|
376
|
+
export default function App() {
|
|
377
|
+
return (
|
|
378
|
+
<Provider store={store}>
|
|
379
|
+
<Shop />
|
|
380
|
+
</Provider>
|
|
381
|
+
);
|
|
382
|
+
}
|
package/package.json
CHANGED
|
File without changes
|