order process completed

This commit is contained in:
ROSHAN GARG 2024-08-23 10:49:28 +05:30
parent b1e6917e2a
commit 6580f5d854
10 changed files with 446 additions and 25 deletions

View File

@ -9,6 +9,7 @@ import {
cilDescription, cilDescription,
cilDrop, cilDrop,
cilNotes, cilNotes,
cilPaperPlane,
cilPencil, cilPencil,
cilPuzzle, cilPuzzle,
cilShare, cilShare,
@ -30,6 +31,19 @@ const _nav = [
to: '/shop', to: '/shop',
icon: <CIcon icon={cilShare} customClassName="nav-icon" />, icon: <CIcon icon={cilShare} customClassName="nav-icon" />,
}, },
{
component: CNavItem,
name: 'Cart',
to: '/cart',
icon: <CIcon icon={cilShare} customClassName="nav-icon" />,
},
{
component: CNavItem,
name: 'Orders Placed',
to: '/orders-placed',
icon: <CIcon icon={cilPaperPlane} customClassName="nav-icon" />,
},
// { // {
// component: CNavItem, // component: CNavItem,
// name: 'Orders', // name: 'Orders',

View File

@ -134,11 +134,11 @@ const AppHeader = () => {
</li> */} </li> */}
<AppHeaderDropdown /> <AppHeaderDropdown />
<CNavLink to="/cart" as={NavLink}> {/* <CNavLink to="/cart" as={NavLink}>
<IconButton> <IconButton>
<ShoppingCartIcon style={{ color: 'black' }} /> <ShoppingCartIcon style={{ color: 'black' }} />
</IconButton> </IconButton>
</CNavLink> </CNavLink> */}
</CHeaderNav> </CHeaderNav>
</CContainer> </CContainer>
<CContainer className="px-4" fluid> <CContainer className="px-4" fluid>

View File

@ -2,6 +2,7 @@ import { element } from 'prop-types'
import React from 'react' import React from 'react'
import Cart from './views/pages/cart/cart' import Cart from './views/pages/cart/cart'
import OrderDetails from './views/orders/OrderDetails'
const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard')) const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard'))
const Shop = React.lazy(() => import('./views/shops/Shop')) const Shop = React.lazy(() => import('./views/shops/Shop'))
@ -15,7 +16,8 @@ const routes = [
{ path: '/', exact: true, name: 'Home' }, { path: '/', exact: true, name: 'Home' },
{ path: '/dashboard', name: 'Dashboard', element: Dashboard }, { path: '/dashboard', name: 'Dashboard', element: Dashboard },
{ path: '/shop', name: 'Shop', element: Shop }, { path: '/shop', name: 'Shop', element: Shop },
{ path: '/order', name: 'Order', element: Order }, { path: '/orders-placed', name: 'Order', element: Order },
{ path: '/orders-placed/:id', name: 'Order', element: OrderDetails },
// KYC // KYC
{ path: '/kyc', name: 'KYC', element: Kyc }, { path: '/kyc', name: 'KYC', element: Kyc },
{ path: '/kyc/details/:id', name: 'Kyc details', element: KycDetails }, { path: '/kyc/details/:id', name: 'Kyc details', element: KycDetails },

View File

@ -1,7 +1,147 @@
import React from 'react' import React, { useEffect, useState } from 'react'
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
Typography,
Skeleton,
Box,
Button,
TablePagination,
} from '@mui/material'
import Axios from '../../axios'
import { isAutheticated } from '../../auth'
import { useNavigate } from 'react-router-dom'
const Order = () => { const Order = () => {
return <div>Order</div> const [orders, setOrders] = useState([])
const [loading, setLoading] = useState(true)
const [page, setPage] = useState(0)
const [rowsPerPage, setRowsPerPage] = useState(5)
const [totalOrders, setTotalOrders] = useState(0)
const token = isAutheticated()
const navigate = useNavigate()
const formatAMPM = (date) => {
var hours = new Date(date).getHours()
var minutes = new Date(date).getMinutes()
var ampm = hours >= 12 ? 'PM' : 'AM'
hours = hours % 12
hours = hours ? hours : 12 // the hour '0' should be '12'
minutes = minutes < 10 ? '0' + minutes : minutes
var strTime = hours + ':' + minutes + ' ' + ampm
return strTime
}
useEffect(() => {
// Fetch orders from the API with pagination
const fetchOrders = async () => {
try {
const response = await Axios.get('/api/get-placed-order-pd', {
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
params: {
page: page + 1, // page number for API (usually starts from 1)
limit: rowsPerPage, // number of rows per page
},
})
setOrders(response.data.plcaedOrders)
setTotalOrders(response.data.totalOrders) // Ensure the API returns the total count of orders
} catch (error) {
console.error('Error fetching orders:', error)
} finally {
setLoading(false)
}
}
fetchOrders()
}, [page, rowsPerPage])
const handleChangePage = (event, newPage) => {
setPage(newPage)
}
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10))
setPage(0) // Reset page to 0 when rows per page changes
}
return (
<Box>
<Typography variant="h4" mb={2} textAlign={'center'}>
Order placed list
</Typography>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>Order ID</TableCell>
<TableCell>Order Date</TableCell>
<TableCell>Items</TableCell>
<TableCell>Order Value</TableCell>
<TableCell>Status</TableCell>
<TableCell>Action</TableCell>
</TableRow>
</TableHead>
<TableBody>
{loading ? (
Array.from(new Array(rowsPerPage)).map((_, index) => (
<TableRow key={index}>
<TableCell colSpan={6}>
<Skeleton height={40} />
</TableCell>
</TableRow>
))
) : orders.length > 0 ? (
orders.map((order) => (
<TableRow key={order._id}>
<TableCell>{order.uniqueId}</TableCell>
<TableCell>
{new Date(`${order?.createdAt}`).toDateString()}
<span> , {`${formatAMPM(order?.createdAt)}`}</span>
</TableCell>
<TableCell>{order.orderItem.length}</TableCell>
<TableCell>{order.grandTotal.toFixed(2)}</TableCell>
<TableCell>{order.status}</TableCell>
<TableCell>
<Button
variant="contained"
color="primary"
onClick={() => navigate(`/orders-placed/${order._id}`)}
>
View
</Button>
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={6} align="center">
<Typography variant="body1">Data not found</Typography>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={totalOrders} // Total number of orders
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableContainer>
</Box>
)
} }
export default Order export default Order

View File

@ -0,0 +1,206 @@
import React, { useEffect, useState } from 'react'
import {
Box,
Button,
Grid,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
} from '@mui/material'
import axios from 'axios' // Make sure you have axios installed
import { useNavigate, useParams } from 'react-router-dom'
import Axios from '../../axios'
const OrderDetails = () => {
const [order, setOrder] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const navigate = useNavigate()
const { id } = useParams() // Assuming order ID is passed as a route parameter
useEffect(() => {
const fetchOrderDetails = async () => {
try {
const response = await Axios.get(`/api/get-single-placed-order-pd/${id}`) // Adjust API endpoint as needed
setOrder(response.data.singleOrder)
console.log(response)
setLoading(false)
} catch (err) {
setError(err.return_msg)
setLoading(false)
}
}
fetchOrderDetails()
}, [id])
if (loading) {
return <Typography>Loading...</Typography>
}
if (error) {
return <Typography>Error: {error}</Typography>
}
if (!order) {
return <Typography>No data found</Typography>
}
const {
uniqueId,
billTo,
shipTo,
paymentMode,
orderItem,
subtotal,
gstTotal,
grandTotal,
statusHistory, // Assume this is an array of status objects
} = order
console.log(statusHistory)
return (
<Box>
{/* Order Details Section */}
<Box sx={{ my: '2rem', background: '#fff', padding: '1rem', borderRadius: '0.8rem' }}>
<Box display="flex" justifyContent="space-between" alignItems="center" mb={2}>
<Typography variant="h4" sx={{ flexGrow: 1, textAlign: 'center' }}>
Order ID: {uniqueId}
</Typography>
<Button color="primary" onClick={() => navigate('/orders-placed')} variant="contained">
Back
</Button>
</Box>
<Grid container spacing={2}>
<Grid item sm={6} md={6} lg={6}>
<Typography variant="h5" sx={{ mb: '0.5rem' }}>
Bill Address
</Typography>
<Typography sx={{ mb: '0.5rem' }}>{billTo}</Typography>
</Grid>
<Grid item sm={6} md={6} lg={6}>
<Typography variant="h5" sx={{ mb: '0.5rem' }}>
Ship Address
</Typography>
<Typography sx={{ mb: '0.5rem' }}>{shipTo}</Typography>
</Grid>
<Grid item sm={6} md={6} lg={6}>
<Typography variant="h5" sx={{ mb: '0.5rem' }}>
Payment Mode: <strong>{paymentMode}</strong>
</Typography>
</Grid>
</Grid>
</Box>
{/* Order Items Table */}
<Box my={8}>
<Grid container spacing={5}>
<Grid item xs={12}>
<Box>
<TableContainer
component={Paper}
elevation={0}
sx={{ borderBottom: '1.5px solid #CFCFD5', borderRadius: 0 }}
>
<Table sx={{ minWidth: 650 }} size="large">
<TableHead>
<TableRow>
<TableCell>Product</TableCell>
<TableCell>SKU</TableCell>
<TableCell>Quantity</TableCell>
<TableCell>Price</TableCell>
<TableCell>GST</TableCell>
<TableCell>Subtotal</TableCell>
</TableRow>
</TableHead>
<TableBody>
{order.orderItem.map((row, index) => {
const gstAmount = (row.productId.price * row.productId.GST) / 100
return (
<TableRow
key={index}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell>
<Box sx={{ display: 'flex' }}>
<Box>
<Typography fontWeight={600}>{row.productId.name}</Typography>
</Box>
</Box>
</TableCell>
<TableCell>{row.productId.SKU}</TableCell>
<TableCell>{row.quantity}</TableCell>
<TableCell>{row.productId.price}</TableCell>
<TableCell>{gstAmount}</TableCell>
<TableCell>{row.productId.price * row.quantity}</TableCell>
</TableRow>
)
})}
<TableRow>
<TableCell colSpan={5} />
<TableCell>
Subtotal:<strong> {subtotal}</strong>
</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={5} />
<TableCell>
Total GST:<strong> {gstTotal} </strong>
</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={5} />
<TableCell>
Grand Total: <strong> {grandTotal}</strong>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</Box>
</Grid>
</Grid>
</Box>
{/* Status History Table */}
{statusHistory.length > 0 && (
<Box mt={8}>
<Typography variant="h5" sx={{ mb: '1rem' }}>
Status History
</Typography>
<TableContainer
component={Paper}
elevation={0}
sx={{ borderBottom: '1.5px solid #CFCFD5', borderRadius: '0.8rem' }}
>
<Table sx={{ minWidth: 650 }} size="large">
<TableHead>
<TableRow>
<TableCell>Status</TableCell>
<TableCell>Timestamp</TableCell>
</TableRow>
</TableHead>
<TableBody>
{statusHistory.map((status, index) => (
<TableRow key={index}>
<TableCell>{status.status}</TableCell>
<TableCell>{new Date(status.timestamp).toLocaleString()}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Box>
)}
</Box>
)
}
export default OrderDetails

View File

@ -14,6 +14,7 @@ import ReviewOrder from './reviewOrder'
import OrderConfirmation from './orderConfirmation' import OrderConfirmation from './orderConfirmation'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { import {
clearCart,
loadCart, loadCart,
selectCartItemCount, selectCartItemCount,
selectCartItems, selectCartItems,
@ -103,6 +104,7 @@ const styles = {
const Cart = () => { const Cart = () => {
const [shipTo, setShipTo] = useState('') const [shipTo, setShipTo] = useState('')
const [billTo, setBillTo] = useState('') const [billTo, setBillTo] = useState('')
const dispatch = useDispatch()
const [paymentMode, setPaymentMode] = useState('') const [paymentMode, setPaymentMode] = useState('')
const cartItems = useSelector(selectCartItems) const cartItems = useSelector(selectCartItems)
const totalItemCount = useSelector(selectCartItemCount) const totalItemCount = useSelector(selectCartItemCount)
@ -110,6 +112,12 @@ const Cart = () => {
const [value, setValue] = useState(0) const [value, setValue] = useState(0)
const handleTabChange = (event, newValue) => { const handleTabChange = (event, newValue) => {
console.log(newValue) console.log(newValue)
if (value === 3 && newValue !== 3) {
setPaymentMode('')
setBillTo('')
setShipTo('')
dispatch(clearCart())
}
if (newValue === 1 && cartItems.length === 0) { if (newValue === 1 && cartItems.length === 0) {
Swal.fire('Cart is emplty ,can not move to next screen pls add items to cart ') Swal.fire('Cart is emplty ,can not move to next screen pls add items to cart ')
return return
@ -133,7 +141,7 @@ const Cart = () => {
// } // }
// setValue(1) // setValue(1)
// } // }
const orderId = '#F5SD67G' const [orderId, setOrderId] = useState(null)
// const [cartItem, setCartItem] = useState([ // const [cartItem, setCartItem] = useState([
// { // {
// product: { // product: {
@ -166,12 +174,6 @@ const Cart = () => {
// subtotal: 150, // subtotal: 150,
// }, // },
// ]) // ])
const dispatch = useDispatch()
// Load the cart items from local storage when the component mounts
useEffect(() => {
dispatch(loadCart())
}, [])
return ( return (
<Container> <Container>
@ -225,6 +227,7 @@ const Cart = () => {
shipTo={shipTo} shipTo={shipTo}
paymentMode={paymentMode} paymentMode={paymentMode}
orderId={orderId} orderId={orderId}
setOrderId={setOrderId}
cartItem={cartItems} cartItem={cartItems}
handleTabChange={handleTabChange} handleTabChange={handleTabChange}
/> />

View File

@ -21,7 +21,7 @@ const OrderConfirmation = ({ orderId, billTo, shipTo, paymentMode, cartItem }) =
// Calculate total GST for the entire cart // Calculate total GST for the entire cart
const totalGST = cartItem.reduce((acc, item) => { const totalGST = cartItem.reduce((acc, item) => {
// console.log(item) // console.log(item)
const gstAmount = (item.price * item.GST.tax) / 100 const gstAmount = (item.price * item.GST) / 100
return acc + gstAmount * item.count return acc + gstAmount * item.count
}, 0) }, 0)
return ( return (
@ -65,7 +65,7 @@ const OrderConfirmation = ({ orderId, billTo, shipTo, paymentMode, cartItem }) =
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell>Product</TableCell> <TableCell>Product</TableCell>
<TableCell>HSN</TableCell> <TableCell>SKU</TableCell>
<TableCell>Quantity</TableCell> <TableCell>Quantity</TableCell>
<TableCell>Price</TableCell> <TableCell>Price</TableCell>
<TableCell>GST</TableCell> <TableCell>GST</TableCell>
@ -74,7 +74,7 @@ const OrderConfirmation = ({ orderId, billTo, shipTo, paymentMode, cartItem }) =
</TableHead> </TableHead>
<TableBody> <TableBody>
{cartItem.map((row, index) => { {cartItem.map((row, index) => {
const gstAmount = (row.price * row.GST.tax) / 100 const gstAmount = (row.price * row.GST) / 100
return ( return (
<TableRow <TableRow

View File

@ -13,18 +13,70 @@ import {
Typography, Typography,
} from '@mui/material' } from '@mui/material'
import React from 'react' import React from 'react'
import { useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { selectCartSubtotal } from '../../../redux-store/CartStore/ducs' import { clearCart, selectCartSubtotal } from '../../../redux-store/CartStore/ducs'
import Axios from '../../../axios'
import { isAutheticated } from '../../../auth'
import Swal from 'sweetalert2'
const ReviewOrder = ({ orderId, billTo, shipTo, paymentMode, cartItem, handleTabChange }) => { const ReviewOrder = ({
orderId,
billTo,
shipTo,
paymentMode,
cartItem,
handleTabChange,
setOrderId,
}) => {
const subtotal = useSelector(selectCartSubtotal) const subtotal = useSelector(selectCartSubtotal)
const token = isAutheticated()
const dispatch = useDispatch()
// Calculate total GST for the entire cart // Calculate total GST for the entire cart
const totalGST = cartItem.reduce((acc, item) => { const totalGST = cartItem.reduce((acc, item) => {
// console.log(item) // console.log(item)
const gstAmount = (item.price * item.GST.tax) / 100 const gstAmount = (item.price * item.GST) / 100
return acc + gstAmount * item.count return acc + gstAmount * item.count
}, 0) }, 0)
const handleConfirmOrder = async (e) => {
e.preventDefault()
if (!billTo || !shipTo || !paymentMode || !cartItem || !subtotal || !totalGST) {
Swal.fire('All fields are required ')
}
try {
const res = await Axios.post(
'/api/order-place',
{
billTo,
shipTo,
paymentMode,
grandTotal: subtotal + totalGST,
gstTotal: totalGST,
subtotal: subtotal,
orderItems: cartItem,
},
{
headers: {
'Access-Control-Allow-Origin': '*',
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
},
)
console.log(res)
if (res.status === 201) {
setOrderId(res?.data?.placedOrder?.uniqueId)
console.log(res)
Swal.fire('Success!', 'Your order has been placed successfully.', 'success')
handleTabChange(e, 3)
}
} catch (error) {
Swal.fire('Something went wrong', error.message, 'error')
}
}
return ( return (
<Box> <Box>
<Box sx={{ my: '2rem', background: '#fff', padding: '1rem', borderRadius: '0.8rem' }}> <Box sx={{ my: '2rem', background: '#fff', padding: '1rem', borderRadius: '0.8rem' }}>
@ -62,7 +114,7 @@ const ReviewOrder = ({ orderId, billTo, shipTo, paymentMode, cartItem, handleTab
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell>Product</TableCell> <TableCell>Product</TableCell>
<TableCell>HSN</TableCell> <TableCell>SKU</TableCell>
<TableCell>Quantity</TableCell> <TableCell>Quantity</TableCell>
<TableCell>Price</TableCell> <TableCell>Price</TableCell>
<TableCell>GST</TableCell> <TableCell>GST</TableCell>
@ -71,7 +123,7 @@ const ReviewOrder = ({ orderId, billTo, shipTo, paymentMode, cartItem, handleTab
</TableHead> </TableHead>
<TableBody> <TableBody>
{cartItem.map((row, index) => { {cartItem.map((row, index) => {
const gstAmount = (row.price * row.GST.tax) / 100 const gstAmount = (row.price * row.GST) / 100
return ( return (
<TableRow <TableRow
@ -127,7 +179,7 @@ const ReviewOrder = ({ orderId, billTo, shipTo, paymentMode, cartItem, handleTab
<Button variant="contained" color="primary" onClick={(e) => handleTabChange(e, 0)}> <Button variant="contained" color="primary" onClick={(e) => handleTabChange(e, 0)}>
Update Order Update Order
</Button> </Button>
<Button variant="contained" color="success" onClick={(e) => handleTabChange(e, 3)}> <Button variant="contained" color="success" onClick={handleConfirmOrder}>
Confirm Order Confirm Order
</Button> </Button>
</Box> </Box>

View File

@ -36,7 +36,7 @@ const ShoppingCart = ({ handleTabChange }) => {
// Calculate total GST for the entire cart // Calculate total GST for the entire cart
const totalGST = cartItems.reduce((acc, item) => { const totalGST = cartItems.reduce((acc, item) => {
// console.log(item) // console.log(item)
const gstAmount = (item.price * item.GST.tax) / 100 const gstAmount = (item.price * item.GST) / 100
return acc + gstAmount * item.count return acc + gstAmount * item.count
}, 0) }, 0)
@ -68,7 +68,7 @@ const ShoppingCart = ({ handleTabChange }) => {
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell>Product</TableCell> <TableCell>Product</TableCell>
<TableCell>HSN</TableCell> <TableCell>SKU</TableCell>
<TableCell>Quantity</TableCell> <TableCell>Quantity</TableCell>
<TableCell>Price</TableCell> <TableCell>Price</TableCell>
<TableCell>GST</TableCell> <TableCell>GST</TableCell>
@ -77,7 +77,7 @@ const ShoppingCart = ({ handleTabChange }) => {
</TableHead> </TableHead>
<TableBody> <TableBody>
{cartItems.map((row, index) => { {cartItems.map((row, index) => {
const gstAmount = (row.price * row.GST.tax) / 100 const gstAmount = (row.price * row.GST) / 100
return ( return (
<TableRow <TableRow

View File

@ -19,10 +19,13 @@ import { cilLockLocked, cilUser } from '@coreui/icons'
// import axios from 'axios' // import axios from 'axios'
import Axios from '../../../axios' import Axios from '../../../axios'
import Swal from 'sweetalert2' import Swal from 'sweetalert2'
import { clearCart } from '../../../redux-store/CartStore/ducs'
import { useDispatch } from 'react-redux'
const Login = () => { const Login = () => {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [validForm, setValidForm] = useState(false) const [validForm, setValidForm] = useState(false)
const dispatch = useDispatch()
const navigate = useNavigate() const navigate = useNavigate()
const [auth, setAuth] = useState({ const [auth, setAuth] = useState({
email: '', email: '',
@ -101,6 +104,7 @@ const Login = () => {
console.log(res) console.log(res)
if (res.data.success === true && res.data.user.role === 'principal-Distributor') { if (res.data.success === true && res.data.user.role === 'principal-Distributor') {
localStorage.setItem('authToken', res.data.token) localStorage.setItem('authToken', res.data.token)
dispatch(clearCart())
navigate('/dashboard') navigate('/dashboard')
setLoading(false) setLoading(false)
Swal.fire('success', 'logged in successfully ', 'success') Swal.fire('success', 'logged in successfully ', 'success')