Skip to content

Commit 51c619e

Browse files
Merge pull request #23 from bhagirathpaliyal/Order
added basic order functionality
2 parents d390390 + 86ff4a1 commit 51c619e

File tree

12 files changed

+244
-42
lines changed

12 files changed

+244
-42
lines changed

src/App.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { setUser } from "./components/store/feature/authSlice";
1717
import { UserTypeSelector } from './components/UserTypeSelecctor';
1818
import { UserTypeSelectorLogin } from './components/UserTypeSelecctorLogin';
1919
import AddProducts from './components/AddProducts';
20+
import Order from './components/Order/Order';
2021

2122

2223
function App() {
@@ -46,8 +47,9 @@ useEffect(()=>{
4647
<Route path="/Products/Electronics" element={<Electronics />} />
4748
</Route>
4849
<Route path="/cart" element={<Cart />} />
49-
<Route path="/AddProducts" element={<AddProducts />} />
5050

51+
<Route path="/AddProducts" element={<AddProducts />} />
52+
<Route path="/Order" element={<Order />} />
5153
</Routes>
5254
</div>
5355
</BrowserRouter>

src/components/AllProducts.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ const skeleton=[1,2,3,4,5,6,7,8,9,10,11,12]
1616

1717
useEffect(() => {
1818
if (user) {
19+
1920
dispatch(fetchProduct(user.uid))
2021
.finally(() => setLoading(false));
2122
}
2223
}, [user, dispatch]);
23-
24+
console.log(product)
2425
return (
2526
<div className="bg-secondary flex flex-col pt-[50px]">
2627

@@ -36,7 +37,7 @@ const skeleton=[1,2,3,4,5,6,7,8,9,10,11,12]
3637
<div className="flex flex-wrap gap-[20px] justify-center">
3738
{product.length > 0 ? (
3839
product.slice(0, 100).map((item, index) => (
39-
<Item key={index} reference={item.productRef} index={index + 20} data={item} name={item.merchant.name} />
40+
<Item key={index} reference={item.productRef} index={index + 20} data={item} name={item.merchant?.name} />
4041
))
4142
) : (
4243

src/components/Cart.jsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React, { useEffect, useState } from 'react';
22
import { useSelector, useDispatch } from 'react-redux';
33
import { fetchCartItems } from './store/feature/cartSlice';
4-
import Item from './Item';
5-
import Loader from 'react-js-loader';
4+
import Item from './Item';
65
import ItemSkeleton from './ItemSkeleton';
76

87

@@ -20,7 +19,7 @@ const skeleton=[1,2,3,4,5,6,7,8,9,10,11,12];
2019
.finally(() => setLoading(false));
2120
}
2221
}, [user, dispatch]);
23-
22+
console.log(cartItems)
2423
return (
2524
<div className='mt-[66px] flex flex-col gap-4 items-center'>
2625
<h2>Your Cart</h2>
@@ -37,7 +36,7 @@ const skeleton=[1,2,3,4,5,6,7,8,9,10,11,12];
3736
<div className='flex flex-wrap gap-[20px] justify-center '>
3837
{cartItems.length > 0 ? (
3938
cartItems.map((item, index) => (
40-
<Item key={index} index={index + 20} data={item} isCart={true} />
39+
<Item key={index} index={index + 20} data={item} isCart={true} />
4140
))
4241
) : (
4342
<p>Your cart is empty.</p>

src/components/Item.jsx

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,71 @@ import { useDispatch, useSelector } from "react-redux";
33
import { addToCart } from "./store/feature/cartSlice";
44
import { LazyLoadImage } from "react-lazy-load-image-component";
55
import { Button } from "@mui/material";
6+
import { createOrder } from "./store/feature/orderSlice";
67

7-
function Item(prop){
8-
const user = useSelector((state) => {
9-
return state.auth.user
10-
});
11-
const products = useSelector((state) => state.product.items);
8+
function Item(prop) {
9+
const user = useSelector((state) => {
10+
return state.auth.user;
11+
});
12+
const products = useSelector((state) => state.product.items);
1213

13-
const dispatch =useDispatch()
14-
console.log(window.location.href.includes('Cart'))
15-
return(
16-
<div key={prop.index} className="flex flex-col gap-[10px] border-[2px] border-solid border-brown-900 w-[200px] bg-secondary rounded-[6px] overflow-hidden p-[10px] relative">
17-
<div><LazyLoadImage src={prop.data?.image ? prop.data?.image:`https://picsum.photos/id/${prop.index}/200/300`} alt="Image" className='bg-cover w-full h-[200px] rounded-[6px]'/></div>
18-
<div className=' flex flex-col h-[100%] justify-between'>
14+
const dispatch = useDispatch();
1915

20-
<h2 className='text-[12px] md:text-[15px] font-medium'>{prop.data?.name}</h2>
21-
<p className="text-[12px] md:text-[15px] font-medium">{prop?.name}</p>
22-
<h2 className='text-[12px] md:text-[15px]font-bold '>Price : {prop.data?.price }</h2>
23-
24-
{ !user?.isMerchant && !prop.isCart ?<Button onClick={()=>{dispatch(addToCart({userId: user.uid,productRef: prop.reference}))}} >Add To Cart</Button>:''}
16+
return (
17+
<div
18+
className="flex flex-col gap-[10px] border-[2px] border-solid border-brown-900 w-[200px] bg-secondary rounded-[6px] overflow-hidden p-[10px] relative"
19+
>
20+
<div>
21+
<LazyLoadImage
22+
src={
23+
prop.data?.image
24+
? prop.data?.image
25+
: `https://picsum.photos/id/${prop.index}/200/300`
26+
}
27+
alt="Image"
28+
className="bg-cover w-full h-[200px] rounded-[6px]"
29+
/>
30+
</div>
31+
<div className=" flex flex-col h-[100%] justify-between">
32+
<h2 className="text-[12px] md:text-[15px] font-medium">
33+
{prop.data?.name}
34+
</h2>
35+
<p className="text-[12px] md:text-[15px] font-medium">{prop?.name}</p>
36+
<h2 className="text-[12px] md:text-[15px] ">
37+
Price : <span className="font-medium ">{prop.data?.price}</span>{" "}
38+
</h2>
2539

26-
27-
</div>
28-
29-
30-
</div>
31-
)
40+
{!user?.isMerchant && !prop.isCart ? (
41+
<Button
42+
variant="contained"
43+
onClick={() => {
44+
dispatch(
45+
addToCart({ userId: user.uid, productRef: prop.reference })
46+
);
47+
}}
48+
>
49+
Add To Cart
50+
</Button>
51+
) : (
52+
""
53+
)}
54+
55+
{prop.isCart && (
56+
<Button
57+
variant="contained"
58+
onClick={() => {
59+
console.log(prop.data.ref)
60+
dispatch(
61+
createOrder({ userId: user.uid , merchantId: prop.data.merchantId , productRef:prop.data.productRef})
62+
);
63+
}}
64+
>
65+
Buy Now
66+
</Button>
67+
)}
68+
</div>
69+
</div>
70+
);
3271
}
3372

34-
export default Item;
73+
export default Item;

src/components/Order/Order.jsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { useSelector, useDispatch } from 'react-redux';
3+
import { fetchOrder } from '../store/feature/orderSlice';
4+
import Item from '../Item';
5+
import ItemSkeleton from '../ItemSkeleton';
6+
import OrderCard from './OrderCard';
7+
8+
9+
const Order = () => {
10+
const [loading, setLoading] = useState(true);
11+
12+
const user = useSelector((state) => state.auth.user);
13+
const dispatch = useDispatch();
14+
const orderItems = useSelector((state) => state.order.items);
15+
const skeleton=[1,2,3,4,5,6,7,8,9,10,11,12];
16+
useEffect(() => {
17+
if (user) {
18+
dispatch(fetchOrder())
19+
.finally(() => setLoading(false));
20+
}
21+
}, [user, dispatch]);
22+
console.log(orderItems)
23+
return (
24+
<div className='mt-[66px] flex flex-col gap-4 items-center'>
25+
<h2>Your order</h2>
26+
27+
{loading ? (
28+
<div className=' flex gap-[20px] flex-wrap mx-[50px]'>
29+
{ skeleton.map((data,index) => (
30+
<ItemSkeleton key={index}/>
31+
))}
32+
</div>
33+
) : (
34+
<>
35+
36+
<div className='flex flex-wrap gap-[20px] justify-center '>
37+
{orderItems.length > 0 ? (
38+
orderItems.map((item, index) => (
39+
item.user.email === user.email && ( <OrderCard key={index} data={item
40+
} />)
41+
))
42+
) : (
43+
<p>Your order is empty.</p>
44+
)}
45+
</div>
46+
</>
47+
)}
48+
</div>
49+
);
50+
};
51+
52+
export default Order;

src/components/Order/OrderCard.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react'
2+
3+
const OrderCard = (prop) => {
4+
return (
5+
<div className='border p-5 rounded-[10px]'>
6+
<h4>OrderId : <span>{prop.data.orderId}</span></h4>
7+
<p>Product Name : <span>{prop.data.orderedProducts.name}</span></p>
8+
<p>Product Price : <span>{prop.data.orderedProducts.Price}</span></p>
9+
<p>Merchant Name : <span>{prop.data.merchant?.name}</span></p>
10+
11+
</div>
12+
)
13+
}
14+
15+
export default OrderCard

src/components/Profile.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ const Profile = () => {
2828
</div>
2929

3030
<h1>{user?.email}</h1>
31+
32+
<Link to={"/Order"}>
33+
{" "}
34+
<Button
35+
36+
color="inherit"
37+
variant="outlined"
38+
>
39+
Your Order
40+
</Button>
41+
</Link>
42+
3143
<Link to={"/Login"}>
3244
{" "}
3345
<Button
@@ -39,6 +51,8 @@ const Profile = () => {
3951
sign out
4052
</Button>
4153
</Link>
54+
55+
4256
</div>
4357
</div>
4458
);

src/components/store/feature/cartSlice.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ import { collection, setDoc, doc, getDoc, addDoc, updateDoc, arrayUnion, getDocs
77
export const fetchCartItems = createAsyncThunk(
88
'cart/fetchCartItems',
99
async (userId) => {
10-
// const cartRef = db.collection('users').doc(userId);
10+
1111
const cartRef = doc(db,'users',userId);
1212

1313
const userObj = await getDoc(cartRef);
14-
// const doc = await cartRef.get();
1514
const cart=userObj.data().cart ;
1615
const cartitem = [];
1716
for (const item of cart) {
1817
const productDoc = await getDoc(item)
19-
const productData = productDoc.data()
20-
cartitem.push(productData)
18+
const productData = await productDoc.data()
19+
cartitem.push({
20+
...productData,
21+
productRef: productDoc.ref
22+
})
2123
}
2224

2325
return cartitem;
@@ -28,9 +30,9 @@ export const addToCart = createAsyncThunk(
2830
'cart/addToCart',
2931
async ({ userId ,productRef}, { getState }) => {
3032
const cartRef = doc(db, "users", userId);
31-
const docc = await getDoc(cartRef);
33+
3234
await updateDoc(cartRef, {
33-
cart: arrayUnion(doc(db, productRef)),
35+
cart: arrayUnion(productRef),
3436
});
3537
}
3638
);
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
3+
import { db } from '../../../context/firebase';
4+
import { collection, setDoc, doc, getDoc, addDoc, updateDoc, arrayUnion, getDocs } from "firebase/firestore";
5+
6+
7+
8+
export const fetchOrder = createAsyncThunk(
9+
'order/fetchOrder',
10+
async () => {
11+
const orderRef = collection(db,'orders');
12+
13+
const docs = await getDocs(orderRef);
14+
const orders = []
15+
for (const item of docs.docs) {
16+
const mainData = await item.data()
17+
const merchantData = await getDoc(mainData.merchantId)
18+
const userData = await getDoc(mainData.userId)
19+
const orderProduct = await getDoc(mainData.productRef)
20+
21+
orders.push({orderedProducts: await orderProduct.data(),
22+
merchant: await merchantData.data(),
23+
user: await userData.data(),
24+
orderId: item.ref.id
25+
26+
})
27+
}
28+
return orders;
29+
}
30+
);
31+
32+
export const createOrder = createAsyncThunk(
33+
'order/createOrder',
34+
async ({ userId,merchantId , productRef }, { getState }) => {
35+
const ordersCollection = collection(db, "orders");
36+
await addDoc(ordersCollection, {
37+
userId:doc(db, "users", userId) ,
38+
merchantId,
39+
productRef
40+
41+
});
42+
}
43+
);
44+
45+
const orderSlice = createSlice({
46+
name: 'order',
47+
initialState: {
48+
items: [],
49+
status: 'idle',
50+
},
51+
reducers: {},
52+
extraReducers: (builder) => {
53+
builder
54+
.addCase(fetchOrder.fulfilled, (state, action) => {
55+
state.items = action.payload;
56+
})
57+
.addCase(fetchOrder.pending, (state, action) => {
58+
// state.items = action.payload;
59+
})
60+
.addCase(fetchOrder.rejected, (state, action) => {
61+
//state.items = action.payload;
62+
console.log(action)
63+
})
64+
.addCase(createOrder.fulfilled, (state, action) => {
65+
// state.items.push(action.payload);
66+
})
67+
// .addCase(createOrder.pending, (state, action) => {
68+
// console.log(action)
69+
// })
70+
.addCase(createOrder.rejected, (state, action) => {
71+
console.log(action)
72+
});
73+
},
74+
});
75+
76+
export default orderSlice.reducer;

src/components/store/feature/productSlice.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { collection, setDoc, doc, getDoc, addDoc, updateDoc, arrayUnion, getDocs
77

88
export const fetchProduct = createAsyncThunk(
99
'product/fetchProduct',
10-
async (userId) => {
10+
async () => {
1111
const productRef = collection(db,'products');
1212

1313
const docs = await getDocs(productRef);
@@ -17,7 +17,7 @@ export const fetchProduct = createAsyncThunk(
1717
const merchantData = await getDoc(mainData.merchantId)
1818
products.push({...mainData,
1919
merchant: await merchantData.data(),
20-
productRef: item.ref.path
20+
productRef: item.ref
2121
})
2222
}
2323
return products;

0 commit comments

Comments
 (0)