diff --git a/src/_nav.js b/src/_nav.js index bcd0619..275b9d4 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -8,6 +8,7 @@ import { cilCursor, cilDescription, cilDrop, + cilFile, cilNotes, cilPaperPlane, cilPencil, @@ -43,6 +44,12 @@ const _nav = [ to: '/orders-placed', icon: , }, + { + component: CNavItem, + name: 'Product manual', + to: '/product-manual', + icon: , + }, // { // component: CNavItem, diff --git a/src/routes.js b/src/routes.js index 9ed04ac..9b69e9f 100644 --- a/src/routes.js +++ b/src/routes.js @@ -3,6 +3,8 @@ import React from 'react' import Cart from './views/pages/cart/cart' import OrderDetails from './views/orders/OrderDetails' +import ProductManual from './views/pages/productManual/productManual' +import ViewProductManual from './views/pages/productManual/viewProductManual' const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard')) const Shop = React.lazy(() => import('./views/shops/Shop')) @@ -18,9 +20,13 @@ const routes = [ { path: '/shop', name: 'Shop', element: Shop }, { path: '/orders-placed', name: 'Order', element: Order }, { path: '/orders-placed/:id', name: 'Order', element: OrderDetails }, + // KYC { path: '/kyc', name: 'KYC', element: Kyc }, { path: '/kyc/details/:id', name: 'Kyc details', element: KycDetails }, + // Product manual + { path: '/product-manual', name: 'Product Manual ', element: ProductManual }, + { path: '/product-manual/:id', name: 'Product Manual ', element: ViewProductManual }, { path: '/my-profile', name: 'Profile', element: MyProfile }, { path: '/change-password', name: 'Change password', element: ChangePassword }, diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index a194772..2f886f1 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,10 +1,80 @@ -import React from 'react' - +import { Box, Typography, Card, CardContent, Grid } from '@mui/material' +import React, { useState, useEffect } from 'react' +import Axios from '../../axios' +import AddShoppingCartIcon from '@mui/icons-material/AddShoppingCart' +import LocalShippingIcon from '@mui/icons-material/LocalShipping' +import CancelIcon from '@mui/icons-material/Cancel' +import HourglassEmptyIcon from '@mui/icons-material/HourglassEmpty' +import CheckCircleIcon from '@mui/icons-material/CheckCircle' const Dashboard = () => { + const [counts, setCounts] = useState({ + new: 0, + dispatched: 0, + cancelled: 0, + processing: 0, + delivered: 0, + }) + + // Fetch counts on component mount + useEffect(() => { + const getCounts = async () => { + try { + const res = await Axios.get('/api/get-counts-pdOrders') // Updated API endpoint + if (res.status === 200) { + console.log('res', res) + setCounts(res.data.counts) // Assuming the response is in the format { new, dispatched, cancelled, processing, delivered } + } + } catch (error) { + console.error('Failed to fetch status counts:', error) + } + } + getCounts() + }, []) + + // Define colors for different statuses + const statusColors = { + new: '#4caf50', // Green + dispatched: '#2196f3', // Blue + cancelled: '#f44336', // Red + processing: '#ff9800', // Orange + delivered: '#9c27b0', // Purple + } + const statusIcons = { + new: , + dispatched: , + cancelled: , + processing: , + delivered: , + } + return ( - <> -
Dashboard
- + + + Orders Status Summary + + + + {Object.keys(counts).map((status) => ( + + + + + + {status.charAt(0).toUpperCase() + status.slice(1)} + + + {counts[status]} + + + {statusIcons[status]} {/* Display the corresponding icon */} + + + + ))} + + ) } diff --git a/src/views/orders/Order.js b/src/views/orders/Order.js index 612160c..c75f44a 100644 --- a/src/views/orders/Order.js +++ b/src/views/orders/Order.js @@ -37,6 +37,11 @@ const Order = () => { return strTime } + // Helper function to capitalize the first letter of a string + const capitalizeFirstLetter = (string) => { + return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase() + } + useEffect(() => { // Fetch orders from the API with pagination const fetchOrders = async () => { @@ -81,13 +86,13 @@ const Order = () => { - - Order ID - Order Date - Items - Order Value - Status - Action + + Order ID + Order Date + Items + Order Value + Status + Action @@ -104,12 +109,18 @@ const Order = () => { {order.uniqueId} - {new Date(`${order?.createdAt}`).toDateString()} - , {`${formatAMPM(order?.createdAt)}`} + {new Date(order?.createdAt) + .toLocaleDateString('en-US', { + year: 'numeric', + month: 'short', + day: 'numeric', + }) + .replace(',', '')}{' '} + , {`${formatAMPM(order?.createdAt)}`} {order.orderItem.length} {order.grandTotal.toFixed(2)} - {order.status} + {capitalizeFirstLetter(order.status)}
- Product - Category - Brand - SKU - Quantity - Price - GST - Subtotal + Product + Category + Brand + SKU + Quantity + Price + GST + Subtotal diff --git a/src/views/pages/Kyc/MessageList.js b/src/views/pages/Kyc/MessageList.js index 04c166a..5844e14 100644 --- a/src/views/pages/Kyc/MessageList.js +++ b/src/views/pages/Kyc/MessageList.js @@ -12,6 +12,11 @@ const MessageList = ({ messages }) => { var strTime = hours + ':' + minutes + ' ' + ampm return strTime } + const formatDateWithoutComma = (date) => { + const dateObj = new Date(date) + const dateStr = dateObj.toDateString().split(' ') + return `${dateStr[1]} ${dateStr[2]} ${dateStr[3]}` + } return ( <> {messages.map((msg, index) => ( @@ -27,7 +32,8 @@ const MessageList = ({ messages }) => { >
{msg.user}
- {new Date(`${msg.replyDate}`).toDateString()} + {/* {new Date(`${msg.replyDate}`).toDateString()} */} + {`${formatDateWithoutComma(msg?.replyDate)}`} , {`${formatAMPM(msg?.replyDate)}`}
{msg.message}
diff --git a/src/views/pages/Kyc/kyc.js b/src/views/pages/Kyc/kyc.js index 7da5176..564c863 100644 --- a/src/views/pages/Kyc/kyc.js +++ b/src/views/pages/Kyc/kyc.js @@ -142,6 +142,7 @@ const Kyc = () => { { status: 'reject', rejectionReason, + user: 'Principal Distributer', }, { headers: { @@ -174,7 +175,16 @@ const Kyc = () => { var strTime = hours + ':' + minutes + ' ' + ampm return strTime } + const capitalizeStatus = (status) => { + return status.charAt(0).toUpperCase() + status.slice(1) + } + // Helper function to format the date + const formatDateWithoutComma = (date) => { + const dateObj = new Date(date) + const dateStr = dateObj.toDateString().split(' ') + return `${dateStr[1]} ${dateStr[2]} ${dateStr[3]}` + } return ( @@ -187,11 +197,11 @@ const Kyc = () => {
- ID - Trade Name - Created On - Status - Action + ID + Trade Name + Created On + Status + Action @@ -203,10 +213,10 @@ const Kyc = () => { {row._id} {row.trade_name} - {new Date(`${row?.createdAt}`).toDateString()} - , {`${formatAMPM(row?.createdAt)}`} + {`${formatDateWithoutComma(row?.createdAt)}`} + , {`${formatAMPM(row?.createdAt)}`} - {row.status} + {capitalizeStatus(row.status)}
- Product - Category - Brand - SKU - Quantity - Price - GST - Subtotal + Product + Category + Brand + SKU + Quantity + Price + GST + Subtotal diff --git a/src/views/pages/cart/reviewOrder.js b/src/views/pages/cart/reviewOrder.js index 4ec0243..95e2e3b 100644 --- a/src/views/pages/cart/reviewOrder.js +++ b/src/views/pages/cart/reviewOrder.js @@ -114,14 +114,14 @@ const ReviewOrder = ({
- Product - Category - Brand - SKU - Quantity - Price - GST - Subtotal + Product + Category + Brand + SKU + Quantity + Price + GST + Subtotal diff --git a/src/views/pages/cart/shopingCart.js b/src/views/pages/cart/shopingCart.js index 14647d4..211bd95 100644 --- a/src/views/pages/cart/shopingCart.js +++ b/src/views/pages/cart/shopingCart.js @@ -67,12 +67,12 @@ const ShoppingCart = ({ handleTabChange }) => {
- Product - SKU - Quantity - Price - GST - Subtotal + Product + SKU + Quantity + Price + GST + Subtotal diff --git a/src/views/pages/productManual/productManual.js b/src/views/pages/productManual/productManual.js new file mode 100644 index 0000000..9701722 --- /dev/null +++ b/src/views/pages/productManual/productManual.js @@ -0,0 +1,117 @@ +import React, { useEffect, useState, useRef } from 'react' +import Axios from '../../../axios' +import { isAutheticated } from '../../../auth' +import { + Box, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, + Button, + TextField, + CircularProgress, + Pagination, +} from '@mui/material' +import { Link } from 'react-router-dom' + +const ProductManual = () => { + const [loading, setLoading] = useState(true) + const token = isAutheticated() + const [productManuals, setProductManuals] = useState([]) + const [currentPage, setCurrentPage] = useState(1) + const [itemsPerPage, setItemsPerPage] = useState(10) + const [totalData, setTotalData] = useState(0) + const titleRef = useRef('') + + const getProductManuals = async () => { + try { + setLoading(true) + const response = await Axios.get(`/api/productmanual/getall`, { + headers: { Authorization: `Bearer ${token}` }, + params: { + page: currentPage, + show: itemsPerPage, + title: titleRef.current.value || '', + }, + }) + if (response.status === 200) { + const { productManuals, total } = response.data + setProductManuals(productManuals) + setTotalData(total) + } + } catch (error) { + console.error('Failed to fetch product manuals:', error) + } finally { + setLoading(false) + } + } + + useEffect(() => { + getProductManuals() + }, [currentPage, itemsPerPage]) + + const handleFilterChange = () => { + setCurrentPage(1) + getProductManuals() + } + + const handlePageChange = (event, page) => { + setCurrentPage(page) + } + + return ( + + {/* Filter Text Field */} + + {/* Table and Pagination */} + {loading ? ( + + ) : ( + <> + +
+ + + Name + Action + + + + {productManuals.map((manual) => ( + + {manual.title} + + + + + ))} + +
+
+ + {/* Pagination */} + + + + + )} + + ) +} + +export default ProductManual diff --git a/src/views/pages/productManual/viewProductManual.js b/src/views/pages/productManual/viewProductManual.js new file mode 100644 index 0000000..b6d689f --- /dev/null +++ b/src/views/pages/productManual/viewProductManual.js @@ -0,0 +1,107 @@ +import React, { useEffect, useState } from 'react' +import Button from '@mui/material/Button' // Updated import for MUI v5 +import { Link, useParams } from 'react-router-dom' +import Swal from 'sweetalert2' // Import SweetAlert2 +import axios from 'axios' + +import Axios from '../../../axios' +import { isAutheticated } from '../../../auth' + +const ViewProductManual = () => { + const [title, setTitle] = useState('') + const [image, setImage] = useState('') + const token = isAutheticated() + const { id } = useParams() + + const getproductmanual = async () => { + try { + const res = await Axios.get(`/api/productmanual/getone/${id}`, { + headers: { Authorization: `Bearer ${token}` }, + }) + setTitle(res?.data?.productManual?.title) + setImage(res?.data?.productManual?.product_manual) + } catch (err) { + console.error(err) + // SweetAlert2 configuration + Swal.fire({ + title: 'Error', + text: 'Unable to fetch the product manual', + icon: 'error', + confirmButtonText: 'Retry', + showCancelButton: true, + confirmButtonColor: '#d33', + cancelButtonColor: '#3085d6', + cancelButtonText: 'Cancel', + }) + } + } + + useEffect(() => { + getproductmanual() + }, []) + + return ( +
+
+
+
+
+ View Product Manual +
+
+

+
+
+ + + +
+
+
+
+
+
+
+
+

+ {title} +

+
+ {image && + (image.url.endsWith('.pdf') ? ( +