blogs,salescoordinator,settings and product managment fixed
This commit is contained in:
parent
24ffc61fa0
commit
67928e0cb7
@ -44,7 +44,7 @@
|
|||||||
"@mui/material": "^5.11.12",
|
"@mui/material": "^5.11.12",
|
||||||
"@reduxjs/toolkit": "^1.9.2",
|
"@reduxjs/toolkit": "^1.9.2",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.3.3",
|
||||||
"chart.js": "^4.4.2",
|
"chart.js": "^4.4.2",
|
||||||
"country-state-city": "^3.2.1",
|
"country-state-city": "^3.2.1",
|
||||||
"draft-js": "^0.11.7",
|
"draft-js": "^0.11.7",
|
||||||
@ -56,7 +56,7 @@
|
|||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"react": "18.0.0",
|
"react": "18.0.0",
|
||||||
"react-bootstrap": "^2.7.0",
|
"react-bootstrap": "^2.10.4",
|
||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
"react-datepicker": "^4.25.0",
|
"react-datepicker": "^4.25.0",
|
||||||
"react-dom": "^18.0.0",
|
"react-dom": "^18.0.0",
|
||||||
|
284
src/_nav.js
284
src/_nav.js
@ -46,58 +46,6 @@ const _nav = [
|
|||||||
group: "Customers",
|
group: "Customers",
|
||||||
},
|
},
|
||||||
|
|
||||||
// {
|
|
||||||
// component: CNavGroup,
|
|
||||||
// name: "Charts",
|
|
||||||
// icon: <CIcon icon={cilCat} customClassName="nav-icon" />,
|
|
||||||
// group: "",
|
|
||||||
|
|
||||||
// items: [
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "new user day wise",
|
|
||||||
// icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
|
||||||
// to: "/new-user-day-wise",
|
|
||||||
// group: "Charts",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Revenue By Product",
|
|
||||||
// icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
|
||||||
// to: "/revenue-by-product",
|
|
||||||
// group: "Charts",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Revenue By State",
|
|
||||||
// icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
|
||||||
// to: "/revenue-by-state",
|
|
||||||
// group: "Charts",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Revenue By City",
|
|
||||||
// icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
|
||||||
// to: "/revenue-by-city",
|
|
||||||
// group: "Charts",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Orders (Day Wise)",
|
|
||||||
// icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
|
||||||
// to: "/orders-day-wise",
|
|
||||||
// group: "Charts",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Revenue (Day Wise)",
|
|
||||||
// icon: <CIcon icon={cilTennisBall} customClassName="nav-icon" />,
|
|
||||||
// to: "/revenue-day-wise",
|
|
||||||
// group: "Charts",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
|
|
||||||
{
|
{
|
||||||
component: CNavGroup,
|
component: CNavGroup,
|
||||||
name: "Product Management",
|
name: "Product Management",
|
||||||
@ -121,84 +69,84 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: "VAT",
|
name: "GST",
|
||||||
icon: <CIcon icon={cilTablet} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilTablet} customClassName="nav-icon" />,
|
||||||
to: "/vat",
|
to: "/tax",
|
||||||
group: "Product Management",
|
group: "Product Management",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavItem,
|
component: CNavItem,
|
||||||
name: "Patients",
|
name: "SalesCoOrdinator",
|
||||||
icon: <CIcon icon={cilUser} customClassName="nav-icon" />,
|
icon: <CIcon icon={cilUser} customClassName="nav-icon" />,
|
||||||
to: "/patients",
|
to: "/salescoordinators",
|
||||||
group: "Patients",
|
group: "SalesCoOrdinator",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavGroup,
|
||||||
|
name: "Orders",
|
||||||
|
icon: <CIcon icon={cilCart} customClassName="nav-icon" />,
|
||||||
|
group: "",
|
||||||
|
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "New",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/orders/new",
|
||||||
|
group: "Orders",
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// component: CNavGroup,
|
|
||||||
// name: "Orders",
|
|
||||||
// icon: <CIcon icon={cilCart} customClassName="nav-icon" />,
|
|
||||||
// group: "",
|
|
||||||
|
|
||||||
// items: [
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
// component: CNavItem,
|
||||||
// name: "New",
|
// name: "Paid",
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
// to: "/orders/new",
|
// to: "/orders/returned",
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// // {
|
|
||||||
// // component: CNavItem,
|
|
||||||
// // name: "Paid",
|
|
||||||
// // icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// // to: "/orders/returned",
|
|
||||||
// // },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Processing",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/orders/processing",
|
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Dispatched",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/orders/dispatched",
|
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Delivered",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/orders/delivered",
|
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Cancelled",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/orders/cancelled",
|
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "In Store Cash Orders",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/inStoreCashOrders/new",
|
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "In Store QRCode Orders",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/InStoreQRCodeOrders/new",
|
|
||||||
// group: "Orders",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
// },
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Processing",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/orders/processing",
|
||||||
|
group: "Orders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Dispatched",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/orders/dispatched",
|
||||||
|
group: "Orders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Delivered",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/orders/delivered",
|
||||||
|
group: "Orders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Cancelled",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/orders/cancelled",
|
||||||
|
group: "Orders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "In Store Cash Orders",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/inStoreCashOrders/new",
|
||||||
|
group: "Orders",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "In Store QRCode Orders",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/InStoreQRCodeOrders/new",
|
||||||
|
group: "Orders",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: CNavGroup,
|
component: CNavGroup,
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
@ -206,41 +154,6 @@ const _nav = [
|
|||||||
group: "",
|
group: "",
|
||||||
|
|
||||||
items: [
|
items: [
|
||||||
{
|
|
||||||
component: CNavItem,
|
|
||||||
name: "Banner",
|
|
||||||
icon: <CIcon icon={cilImage} customClassName="nav-icon" />,
|
|
||||||
to: "/banner",
|
|
||||||
group: "Settings",
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Register Image",
|
|
||||||
// icon: <CIcon icon={cilImage} customClassName="nav-icon" />,
|
|
||||||
// to: "/registerImage",
|
|
||||||
// group: "Settings",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Login Image",
|
|
||||||
// icon: <CIcon icon={cilImage} customClassName="nav-icon" />,
|
|
||||||
// to: "/loginImage",
|
|
||||||
// group: "Settings",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Shop Page Image",
|
|
||||||
// icon: <CIcon icon={cilImage} customClassName="nav-icon" />,
|
|
||||||
// to: "/shopImage",
|
|
||||||
// group: "Settings",
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
component: CNavItem,
|
|
||||||
name: "Web Images",
|
|
||||||
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
to: "/web_images",
|
|
||||||
group: "Settings",
|
|
||||||
},
|
|
||||||
// {
|
// {
|
||||||
// component: CNavItem,
|
// component: CNavItem,
|
||||||
// name: "Testimonials",
|
// name: "Testimonials",
|
||||||
@ -248,13 +161,6 @@ const _nav = [
|
|||||||
// to: "/testimonials",
|
// to: "/testimonials",
|
||||||
// group: "Website Related",
|
// group: "Website Related",
|
||||||
// },
|
// },
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Contact Requests",
|
|
||||||
// icon: <CIcon icon={cilContact} customClassName="nav-icon" />,
|
|
||||||
// to: "/contact/request",
|
|
||||||
// group: "Website Related",
|
|
||||||
// },
|
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// component: CNavItem,
|
// component: CNavItem,
|
||||||
@ -314,13 +220,6 @@ const _nav = [
|
|||||||
to: "/copyright/message",
|
to: "/copyright/message",
|
||||||
group: "Settings",
|
group: "Settings",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: CNavItem,
|
|
||||||
name: "Home",
|
|
||||||
icon: <CIcon icon={cilFeaturedPlaylist} customClassName="nav-icon" />,
|
|
||||||
to: "/home",
|
|
||||||
group: "Settings",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
@ -358,43 +257,14 @@ const _nav = [
|
|||||||
// ],
|
// ],
|
||||||
// },
|
// },
|
||||||
// //Affiliate end
|
// //Affiliate end
|
||||||
// {
|
//Blog start
|
||||||
// component: CNavGroup,
|
{
|
||||||
// name: "Customer Service",
|
component: CNavItem,
|
||||||
// icon: <CIcon icon={cilClipboard} customClassName="nav-icon" />,
|
name: "Blog",
|
||||||
// group: "",
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/blogs",
|
||||||
// items: [
|
group: "Blog",
|
||||||
// {
|
},
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Customer Support",
|
|
||||||
// icon: <CIcon icon={cilAlarm} customClassName="nav-icon" />,
|
|
||||||
// to: "/support/request",
|
|
||||||
// group: "Customer Service",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Contact Requests",
|
|
||||||
// icon: <CIcon icon={cilUser} customClassName="nav-icon" />,
|
|
||||||
// to: "/contact/request",
|
|
||||||
// group: "Customer Service",
|
|
||||||
// },
|
|
||||||
// // {
|
|
||||||
// // component: CNavItem,
|
|
||||||
// // name: "Email CMS",
|
|
||||||
// // icon: <CIcon icon={cilLocationPin} customClassName="nav-icon" />,
|
|
||||||
// // to: "/email-cms",
|
|
||||||
// // },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// //Blog start
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Blog",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/blogs",
|
|
||||||
// group: "Blog",
|
|
||||||
// },
|
|
||||||
// // Employee
|
// // Employee
|
||||||
// {
|
// {
|
||||||
// component: CNavItem,
|
// component: CNavItem,
|
||||||
@ -403,14 +273,6 @@ const _nav = [
|
|||||||
// to: "/employee",
|
// to: "/employee",
|
||||||
// group: "Employees & Access",
|
// group: "Employees & Access",
|
||||||
// },
|
// },
|
||||||
// //Point of Sale start
|
|
||||||
// {
|
|
||||||
// component: CNavItem,
|
|
||||||
// name: "Point of Sale",
|
|
||||||
// icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
|
||||||
// to: "/pos",
|
|
||||||
// group: "Point of Sale",
|
|
||||||
// },
|
|
||||||
// {
|
// {
|
||||||
// component: CNavGroup,
|
// component: CNavGroup,
|
||||||
// name: "Blog",
|
// name: "Blog",
|
||||||
|
@ -3,6 +3,7 @@ import "bootstrap/dist/css/bootstrap.min.css";
|
|||||||
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
|
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
|
||||||
import "react-app-polyfill/stable";
|
import "react-app-polyfill/stable";
|
||||||
import "core-js";
|
import "core-js";
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
262
src/routes.js
262
src/routes.js
@ -22,7 +22,6 @@ import Socialmedia from "./views/configuration/Socialmedia.js";
|
|||||||
import Address from "./views/configuration/Address.js";
|
import Address from "./views/configuration/Address.js";
|
||||||
import Logo from "./views/configuration/Logo.js";
|
import Logo from "./views/configuration/Logo.js";
|
||||||
import Login from "./views/pages/login/Login";
|
import Login from "./views/pages/login/Login";
|
||||||
import Web_Images from "./views/configuration/Web_Images";
|
|
||||||
|
|
||||||
// Appointments
|
// Appointments
|
||||||
import Appointments from "./views/Appointments/Appointments";
|
import Appointments from "./views/Appointments/Appointments";
|
||||||
@ -42,7 +41,6 @@ import DispatchedOrders from "./views/orders/DispatchedOrders.js";
|
|||||||
import DeliveredOrders from "./views/orders/DeliveredOrders.js";
|
import DeliveredOrders from "./views/orders/DeliveredOrders.js";
|
||||||
import CancelledOrders from "./views/orders/CancelledOrders.js";
|
import CancelledOrders from "./views/orders/CancelledOrders.js";
|
||||||
import ReturnedOrders from "./views/orders/ReturnedOrders.js";
|
import ReturnedOrders from "./views/orders/ReturnedOrders.js";
|
||||||
import ViewOdr from "./views/orders/ViewOdr";
|
|
||||||
import AddOrder from "./views/orders/AddOrder";
|
import AddOrder from "./views/orders/AddOrder";
|
||||||
//Taxes
|
//Taxes
|
||||||
import Tax from "./views/configuration/tax/Tax";
|
import Tax from "./views/configuration/tax/Tax";
|
||||||
@ -57,8 +55,6 @@ import AddInformations from "./views/Informations/AddInformations";
|
|||||||
|
|
||||||
import ApplicationName from "./views/configuration/ApplicationName";
|
import ApplicationName from "./views/configuration/ApplicationName";
|
||||||
import CopyrightMessage from "./views/configuration/CopyrightMessage";
|
import CopyrightMessage from "./views/configuration/CopyrightMessage";
|
||||||
import ContactRequests from "./views/ContactRequests/ContactRequests";
|
|
||||||
import AddContactRequest from "./views/ContactRequests/AddContactRequest";
|
|
||||||
|
|
||||||
import AddSeoRequest from "./views/seo/AddSeoRequest";
|
import AddSeoRequest from "./views/seo/AddSeoRequest";
|
||||||
|
|
||||||
@ -97,10 +93,8 @@ import EditAboutUs from "./views/Content/editAboutUs";
|
|||||||
// import AddUserAddress from "./views/customerDetails/addUserAddress";
|
// import AddUserAddress from "./views/customerDetails/addUserAddress";
|
||||||
import viewDetails from "./views/customerDetails/viewDetails";
|
import viewDetails from "./views/customerDetails/viewDetails";
|
||||||
import Design from "./views/Design/design";
|
import Design from "./views/Design/design";
|
||||||
import Banners from "./views/Banner/banner";
|
|
||||||
import RegisterImage from "./views/Images/RegisterImage";
|
import RegisterImage from "./views/Images/RegisterImage";
|
||||||
import LoginImage from "./views/Images/LoginImage";
|
import LoginImage from "./views/Images/LoginImage";
|
||||||
import ShopImage from "./views/Images/ShopImage";
|
|
||||||
//Affiliate
|
//Affiliate
|
||||||
import Coupons from "./views/Affiliate/Coupons";
|
import Coupons from "./views/Affiliate/Coupons";
|
||||||
import Affiliates from "./views/Affiliate/Affiliates";
|
import Affiliates from "./views/Affiliate/Affiliates";
|
||||||
@ -111,10 +105,6 @@ import EditCoupon from "./views/Affiliate/EditCoupon";
|
|||||||
import PayAffiliate from "./views/Affiliate/PayAffiliate";
|
import PayAffiliate from "./views/Affiliate/PayAffiliate";
|
||||||
import AffiliateHistory from "./views/Affiliate/AffiliateHistory";
|
import AffiliateHistory from "./views/Affiliate/AffiliateHistory";
|
||||||
import CouponHistory from "./views/Affiliate/CouponHistory";
|
import CouponHistory from "./views/Affiliate/CouponHistory";
|
||||||
import SupportRequest from "./views/CustomerSupport/SupportRequest";
|
|
||||||
import SupportReply from "./views/CustomerSupport/SupportReply";
|
|
||||||
import SupportRequestClosed from "./views/CustomerSupport/SupportRequestClosed";
|
|
||||||
import CloseRequestView from "./views/CustomerSupport/CloseRequestView";
|
|
||||||
import EditTestimonial from "./views/Testimonials/EditTestimonial";
|
import EditTestimonial from "./views/Testimonials/EditTestimonial";
|
||||||
//Blogs
|
//Blogs
|
||||||
import Blogs from "./views/Blog/Blogs";
|
import Blogs from "./views/Blog/Blogs";
|
||||||
@ -122,37 +112,22 @@ import CreateBlog from "./views/Blog/CreateBlog";
|
|||||||
import users from "./views/Users/users";
|
import users from "./views/Users/users";
|
||||||
import UpdateBlog from "./views/Blog/EditBlog";
|
import UpdateBlog from "./views/Blog/EditBlog";
|
||||||
import ViewBlog from "./views/Blog/ViewBlog";
|
import ViewBlog from "./views/Blog/ViewBlog";
|
||||||
import Home from "./views/Home/home";
|
|
||||||
import EditPanel1 from "./views/Home/editPanel1";
|
|
||||||
import EditPanel2 from "./views/Home/editPanel2";
|
|
||||||
import EditPanel3 from "./views/Home/editPanel3";
|
|
||||||
import Editpanel4 from "./views/Home/editPanel4";
|
|
||||||
import CustomerTable from "./views/customerDetails/customerTable";
|
import CustomerTable from "./views/customerDetails/customerTable";
|
||||||
import SingleUserAllDetails from "./views/customerDetails/singleUserAllDetails";
|
import SingleUserAllDetails from "./views/customerDetails/singleUserAllDetails";
|
||||||
import Charts from "./views/Charts/RevenueCharts";
|
|
||||||
import UserCharts from "./views/Charts/UserChart";
|
|
||||||
import ProductrevenueCharts from "./views/Charts/ProductRevenue";
|
|
||||||
import StateRevenueCharts from "./views/Charts/Staterevenue";
|
|
||||||
import CityRevenueCharts from "./views/Charts/CityRevenue";
|
|
||||||
import { element } from "prop-types";
|
import { element } from "prop-types";
|
||||||
import OrderdayChart from "./views/Charts/OrderDaywise";
|
|
||||||
import RevenueCharts from "./views/Charts/RevenueCharts";
|
|
||||||
import AddCustomer from "./views/customerDetails/addCustomer";
|
import AddCustomer from "./views/customerDetails/addCustomer";
|
||||||
import Pos from "./views/PointOfSale/Pos";
|
|
||||||
import InStoreCashOrders from "./views/orders/InStoreCashOrders";
|
import InStoreCashOrders from "./views/orders/InStoreCashOrders";
|
||||||
import POSViewOrders from "./views/orders/POSViewOrders";
|
|
||||||
import InStoreQRCodeOrders from "./views/orders/InStoreQRCodeOrders";
|
import InStoreQRCodeOrders from "./views/orders/InStoreQRCodeOrders";
|
||||||
import EmailCms from "./views/CustomerSupport/EmailCMS/EmailCms";
|
|
||||||
import RegistrationEmail from "./views/CustomerSupport/EmailCMS/RegistrationEmail";
|
|
||||||
import Employee from "./views/EmployeeAccess/Employee";
|
import Employee from "./views/EmployeeAccess/Employee";
|
||||||
import AddEmployee from "./views/EmployeeAccess/addEmployee";
|
import AddEmployee from "./views/EmployeeAccess/addEmployee";
|
||||||
import EditEmployee from "./views/EmployeeAccess/editEmployee";
|
import EditEmployee from "./views/EmployeeAccess/editEmployee";
|
||||||
import ExportToExcel from "./views/exportExcel";
|
|
||||||
import Currency from "./views/configuration/Currency";
|
import Currency from "./views/configuration/Currency";
|
||||||
import Patient from "./views/Patients/Patient";
|
import SalesCoOrdinator from "./views/SalesCoOrdinators/SalesCoOrdinator";
|
||||||
import ViewPatient from "./views/Patients/ViewPatient";
|
import EditSalesCoOrdinator from "./views/SalesCoOrdinators/EditSalesCoOrdinator";
|
||||||
|
import AddSalesCoOrdinator from "./views/SalesCoOrdinators/AddSalesCoOrdinator";
|
||||||
const routes = [
|
const routes = [
|
||||||
// { path: "/", exact: true, name: "Home", navName: "" },
|
|
||||||
//dashboard
|
//dashboard
|
||||||
|
|
||||||
{ path: "/dashboard", name: "Dashboard", element: Dashboard, navName: "" },
|
{ path: "/dashboard", name: "Dashboard", element: Dashboard, navName: "" },
|
||||||
@ -169,44 +144,6 @@ const routes = [
|
|||||||
navName: "",
|
navName: "",
|
||||||
},
|
},
|
||||||
// { path: '/profile', name: 'Profile', element: Profile },
|
// { path: '/profile', name: 'Profile', element: Profile },
|
||||||
//------------------Charts Routes------------------------------------
|
|
||||||
{
|
|
||||||
path: "/new-user-day-wise",
|
|
||||||
name: "new user day wise",
|
|
||||||
element: UserCharts,
|
|
||||||
navName: "Charts",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/revenue-by-product",
|
|
||||||
name: "Revenue By Product",
|
|
||||||
element: ProductrevenueCharts,
|
|
||||||
navName: "Charts",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/revenue-by-state",
|
|
||||||
name: "Revenue By State",
|
|
||||||
element: StateRevenueCharts,
|
|
||||||
navName: "Charts",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/revenue-by-city",
|
|
||||||
name: "Revenue By City",
|
|
||||||
element: CityRevenueCharts,
|
|
||||||
navName: "Charts",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/orders-day-wise",
|
|
||||||
name: "Orders (Day Wise)",
|
|
||||||
element: OrderdayChart,
|
|
||||||
navName: "Charts",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/revenue-day-wise",
|
|
||||||
name: "Revenue (Day Wise)",
|
|
||||||
element: RevenueCharts,
|
|
||||||
navName: "Charts",
|
|
||||||
},
|
|
||||||
//------------------ End Charts Routes------------------------------------
|
|
||||||
//-----------------------Product Management Routes------------------------------------------------
|
//-----------------------Product Management Routes------------------------------------------------
|
||||||
{
|
{
|
||||||
path: "/products",
|
path: "/products",
|
||||||
@ -240,20 +177,26 @@ const routes = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "//patient/view/:id",
|
path: "/salescoordinator/edit/:id",
|
||||||
name: "View Patient",
|
name: "Edit SalesCoOrdinator",
|
||||||
element: ViewPatient,
|
element: EditSalesCoOrdinator,
|
||||||
navName: "Patients",
|
navName: "SalesCoOrdinators",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/patients",
|
path: "/salescoordinators",
|
||||||
name: "Patients",
|
name: "SalesCoOrdinators",
|
||||||
element: Patient,
|
element: SalesCoOrdinator,
|
||||||
navName: "Patients",
|
navName: "SalesCoOrdinators",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/salescoordinator/add",
|
||||||
|
name: "Add SalesCoOrdinators",
|
||||||
|
element: AddSalesCoOrdinator,
|
||||||
|
navName: "SalesCoOrdinators",
|
||||||
},
|
},
|
||||||
//Gst tax
|
//Gst tax
|
||||||
{
|
{
|
||||||
path: "/vat",
|
path: "/tax",
|
||||||
name: "Tax Rates",
|
name: "Tax Rates",
|
||||||
element: Tax,
|
element: Tax,
|
||||||
navName: "Product Management",
|
navName: "Product Management",
|
||||||
@ -383,70 +326,11 @@ const routes = [
|
|||||||
// },
|
// },
|
||||||
|
|
||||||
// { path: '/franchisee/view/:id', name: 'view franchisee', element: ViewFra },
|
// { path: '/franchisee/view/:id', name: 'view franchisee', element: ViewFra },
|
||||||
//Contact Requests
|
|
||||||
// ----------------Customer Service Routes-------------------------------
|
|
||||||
{
|
|
||||||
path: "/contact/request",
|
|
||||||
name: "Customer Service",
|
|
||||||
element: ContactRequests,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/contact/request/new",
|
|
||||||
name: "Customer Service",
|
|
||||||
element: AddContactRequest,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
//Support Requests
|
|
||||||
{
|
|
||||||
path: "/email-cms",
|
|
||||||
name: "CustomerSupport Requests",
|
|
||||||
element: EmailCms,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/email-cms/registration-email",
|
|
||||||
name: "CustomerSupport Requests",
|
|
||||||
element: RegistrationEmail,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
path: "/support/request",
|
|
||||||
name: "Customer Service",
|
|
||||||
element: SupportRequest,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/support/request/closed",
|
|
||||||
name: "Customer Service",
|
|
||||||
element: SupportRequestClosed,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/support/request/closed/:ticketID",
|
|
||||||
name: "Customer Service",
|
|
||||||
element: CloseRequestView,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/support/request/reply/:ticketID",
|
|
||||||
name: "Customer Service",
|
|
||||||
element: SupportReply,
|
|
||||||
navName: "Customer Service",
|
|
||||||
},
|
|
||||||
// ---------------- End Customer Service Routes-------------------------------
|
|
||||||
|
|
||||||
// { path: '/complaint/view/:id', name: 'view Complain', element: ViewComplaint },
|
// { path: '/complaint/view/:id', name: 'view Complain', element: ViewComplaint },
|
||||||
//Complaints
|
//Complaints
|
||||||
|
|
||||||
//-------------------------------website related routes----------------------------------
|
//-------------------------------website related routes----------------------------------
|
||||||
{
|
|
||||||
path: "/banner",
|
|
||||||
name: "Banners",
|
|
||||||
element: Banners,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/registerImage",
|
path: "/registerImage",
|
||||||
name: "RegisterImage",
|
name: "RegisterImage",
|
||||||
@ -454,24 +338,12 @@ const routes = [
|
|||||||
navName: "Website Related",
|
navName: "Website Related",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
path: "/web_images",
|
|
||||||
name: "Web Images",
|
|
||||||
element: Web_Images,
|
|
||||||
navName: "Settings",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/loginImage",
|
path: "/loginImage",
|
||||||
name: "LoginImage",
|
name: "LoginImage",
|
||||||
element: LoginImage,
|
element: LoginImage,
|
||||||
navName: "Website Related",
|
navName: "Website Related",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/shopImage",
|
|
||||||
name: "ShopImage",
|
|
||||||
element: ShopImage,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/testimonials",
|
path: "/testimonials",
|
||||||
name: "Testimonials",
|
name: "Testimonials",
|
||||||
@ -547,47 +419,8 @@ const routes = [
|
|||||||
element: EditAboutUs,
|
element: EditAboutUs,
|
||||||
navName: "Website Related",
|
navName: "Website Related",
|
||||||
},
|
},
|
||||||
// Home Pannel website
|
|
||||||
{
|
|
||||||
path: "/home",
|
|
||||||
name: "Home",
|
|
||||||
element: Home,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home/panel-1",
|
|
||||||
name: "EditPanel1",
|
|
||||||
element: EditPanel1,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home/panel-2",
|
|
||||||
name: "EditPanel2",
|
|
||||||
element: EditPanel2,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home/panel-3",
|
|
||||||
name: "EditPanel3",
|
|
||||||
element: EditPanel3,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/home/panel-4",
|
|
||||||
name: "EditPanel4",
|
|
||||||
element: Editpanel4,
|
|
||||||
navName: "Website Related",
|
|
||||||
},
|
|
||||||
//-------------------------------End website related routes----------------------------------
|
//-------------------------------End website related routes----------------------------------
|
||||||
|
|
||||||
//informations
|
|
||||||
// { path: "/informations", name: "Informations", element: Informations },
|
|
||||||
// {
|
|
||||||
// path: "/information/new",
|
|
||||||
// name: "Add Informations",
|
|
||||||
// element: AddInformations,
|
|
||||||
// },
|
|
||||||
|
|
||||||
//--------------Order Management Routes---------------------------------------
|
//--------------Order Management Routes---------------------------------------
|
||||||
{
|
{
|
||||||
path: "/orders/new",
|
path: "/orders/new",
|
||||||
@ -656,12 +489,6 @@ const routes = [
|
|||||||
element: InStoreQRCodeOrders,
|
element: InStoreQRCodeOrders,
|
||||||
navName: "Orders",
|
navName: "Orders",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/inStoreOrders/:status/:id",
|
|
||||||
name: "View In Store Cash Orders",
|
|
||||||
element: POSViewOrders,
|
|
||||||
navName: "Orders",
|
|
||||||
},
|
|
||||||
//-------------- End Order Management Routes---------------------------------------
|
//-------------- End Order Management Routes---------------------------------------
|
||||||
|
|
||||||
//----------Point of sale orders Routes-----------------------
|
//----------Point of sale orders Routes-----------------------
|
||||||
@ -670,37 +497,6 @@ const routes = [
|
|||||||
|
|
||||||
//------------settings------------------------//
|
//------------settings------------------------//
|
||||||
|
|
||||||
// { path: "/policies", name: "Policies", element: Policies },
|
|
||||||
|
|
||||||
// { path: "/purpose", name: "Purpose", element: Purpose },
|
|
||||||
// { path: "/purpose/add", name: "Add Purpose", element: AddPurpose },
|
|
||||||
// //languge
|
|
||||||
|
|
||||||
// { path: "/languages", name: "languages", element: Languages },
|
|
||||||
// { path: "/language/add", name: "Add languages", element: AddLanguage },
|
|
||||||
// { path: "/language/edit/:id", name: "Edit languages", element: EditLanguage },
|
|
||||||
//business Type
|
|
||||||
|
|
||||||
// { path: "/business_type", name: "business", element: BusinessType },
|
|
||||||
// {
|
|
||||||
// path: "/business_type/add",
|
|
||||||
// name: "Add business",
|
|
||||||
// element: AddBusinessType,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: "/business_type/edit/:id",
|
|
||||||
// name: "Edit business",
|
|
||||||
// element: EditBusinessType,
|
|
||||||
// },
|
|
||||||
|
|
||||||
//purpose
|
|
||||||
|
|
||||||
// { path: "/purpose", name: "purpose", element: Purpose },
|
|
||||||
// { path: "/purpose/add", name: "Add purpose", element: AddPurpose },
|
|
||||||
// { path: "/purpose/edit/:id", name: "Edit purpose", element: EditPurpose },
|
|
||||||
|
|
||||||
//languge
|
|
||||||
|
|
||||||
//-----------------Configuration Routes-----------------------------------
|
//-----------------Configuration Routes-----------------------------------
|
||||||
{
|
{
|
||||||
path: "/socialmedia",
|
path: "/socialmedia",
|
||||||
@ -834,24 +630,6 @@ const routes = [
|
|||||||
element: EditEmployee,
|
element: EditEmployee,
|
||||||
navName: "Employees & Access",
|
navName: "Employees & Access",
|
||||||
},
|
},
|
||||||
// ------------------------ End Employee Routes-----------------------
|
|
||||||
|
|
||||||
//---------Point of Sale Section Routes------------------------
|
|
||||||
{
|
|
||||||
path: "/pos",
|
|
||||||
name: "Point of Sale",
|
|
||||||
element: Pos,
|
|
||||||
navName: "Point of Sale",
|
|
||||||
},
|
|
||||||
|
|
||||||
// Export to excel
|
|
||||||
{
|
|
||||||
path: "/exp",
|
|
||||||
name: "Point of Sale",
|
|
||||||
element: ExportToExcel,
|
|
||||||
navName: "Point of Sale",
|
|
||||||
},
|
|
||||||
//--------- End Point of Sale Section Routes------------------------
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
@ -1,707 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Box,
|
|
||||||
IconButton,
|
|
||||||
Modal,
|
|
||||||
Pagination,
|
|
||||||
TextField,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
|
||||||
import { ClipLoader } from "react-spinners";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
position: "absolute",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
width: 400,
|
|
||||||
bgcolor: "background.paper",
|
|
||||||
borderRadius: "0.5rem",
|
|
||||||
boxShadow: 24,
|
|
||||||
width: "500px",
|
|
||||||
};
|
|
||||||
|
|
||||||
const Banners = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [updating, setUpdating] = useState(true); // for loading state
|
|
||||||
// const [isUpdate, setIsUpdate] = useState(false); // for edit state
|
|
||||||
const [saveLoding, setSaveLoading] = useState(true);
|
|
||||||
const [edit, setEdit] = useState(false);
|
|
||||||
const [bannerName, setBannerName] = useState("");
|
|
||||||
const [bannerImage, setBannerImage] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [bannerId, setBannerId] = useState("");
|
|
||||||
const [banner, setBanner] = useState([]);
|
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
|
||||||
const [page, setPage] = useState(1);
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [olderBannerName, setOlderBaannerName] = useState("");
|
|
||||||
const [olderImage, setOlderImage] = useState("");
|
|
||||||
|
|
||||||
const handleOpen = () => setOpen(true);
|
|
||||||
const handleClose = () => {
|
|
||||||
setOpen(false);
|
|
||||||
// setUpdating(false);
|
|
||||||
setEdit(false);
|
|
||||||
|
|
||||||
setBannerName("");
|
|
||||||
setBannerId("");
|
|
||||||
setOlderImage("");
|
|
||||||
setBannerImage("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const getBanner = async () => {
|
|
||||||
try {
|
|
||||||
const response = await axios.get("/api/banner/getBanners", {
|
|
||||||
// headers: {
|
|
||||||
// Authorization: `Bearer ${token}`,
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status === 200) {
|
|
||||||
setBanner(response?.data?.banners);
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: " please login to access the resource ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getBanner();
|
|
||||||
}, []);
|
|
||||||
// }, [token, banner]);
|
|
||||||
|
|
||||||
const handleEditClick = (_id, bannerName, bannerImage) => {
|
|
||||||
setOpen(true);
|
|
||||||
setOlderImage(bannerImage);
|
|
||||||
setBannerName(bannerName);
|
|
||||||
setBannerId(_id);
|
|
||||||
setOlderBaannerName(bannerName);
|
|
||||||
setEdit(true);
|
|
||||||
// setUpdating(false);
|
|
||||||
};
|
|
||||||
const bannerNamesArray = [];
|
|
||||||
const setBannerNamesArray = () => {
|
|
||||||
banner &&
|
|
||||||
banner.map((banner) => {
|
|
||||||
bannerNamesArray.push(banner.bannerName.toLowerCase());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
setBannerNamesArray();
|
|
||||||
|
|
||||||
const handleUpdate = () => {
|
|
||||||
const filteredArrayNames = bannerNamesArray.filter(
|
|
||||||
(item) => item !== olderBannerName.toLowerCase()
|
|
||||||
);
|
|
||||||
console.log(filteredArrayNames, "filter");
|
|
||||||
const bannerExits = filteredArrayNames.includes(bannerName.toLowerCase());
|
|
||||||
if (bannerExits) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Banner already exists ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bannerName || (!bannerImage && !olderImage)) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please fill all the required fields!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setUpdating(false);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("bannerName", bannerName);
|
|
||||||
|
|
||||||
formData.append("bannerImage", bannerImage);
|
|
||||||
|
|
||||||
formData.append("olderImage", JSON.stringify(olderImage));
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/banner/update/${bannerId}`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
// setUpdating(true);
|
|
||||||
// setIsUpdate(false);
|
|
||||||
handleClose();
|
|
||||||
setBannerId("");
|
|
||||||
setBannerName("");
|
|
||||||
setBannerImage("");
|
|
||||||
setOlderImage("");
|
|
||||||
setUpdating(true);
|
|
||||||
setEdit(false);
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "The banner was updated successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
// getCategories(); // Refresh the category list after updating
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "Sorry, please try again",
|
|
||||||
text: err,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
setUpdating(true);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (_id) => {
|
|
||||||
swal({
|
|
||||||
title: "Are you sure?",
|
|
||||||
icon: "error",
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Yes", value: true },
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.delete(`/api/banner/delete/${_id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "The banner was deleted successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
// getCategories(); // Refresh the category list after deleting
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "",
|
|
||||||
text: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveBanner = async () => {
|
|
||||||
const bannerExits = bannerNamesArray.includes(bannerName.toLowerCase());
|
|
||||||
if (bannerExits) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Banner Already exits.",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!bannerName || !bannerImage) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please fill all the required fields!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSaveLoading(false);
|
|
||||||
setLoading(true);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("bannerName", bannerName);
|
|
||||||
formData.append("bannerImage", bannerImage);
|
|
||||||
|
|
||||||
axios
|
|
||||||
.post("/api/banner/add", formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/formdata",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status === 201) {
|
|
||||||
setOpen(false);
|
|
||||||
setLoading(false);
|
|
||||||
setSaveLoading(true);
|
|
||||||
setBannerName("");
|
|
||||||
setBannerImage("");
|
|
||||||
setOlderImage("");
|
|
||||||
swal({
|
|
||||||
title: "Added",
|
|
||||||
text: "New Banner added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
// getCategories(); // Refresh the category list after adding
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setSaveLoading(true);
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: "something went wrong",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const getPageCount = () => {
|
|
||||||
return Math.max(1, Math.ceil(banner.length / itemPerPage));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files[0];
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
if (allowedTypes.includes(files.type)) {
|
|
||||||
setBannerImage(files);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const handeldeleteImage = () => {
|
|
||||||
setBannerImage("");
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Banners
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={handleOpen}
|
|
||||||
// onClick={() => {
|
|
||||||
// navigate("/testimonial/new", { replace: true });
|
|
||||||
// }}
|
|
||||||
>
|
|
||||||
Add New Banner
|
|
||||||
</Button>
|
|
||||||
<Modal
|
|
||||||
open={open}
|
|
||||||
onClose={handleClose}
|
|
||||||
aria-labelledby="modal-modal-title"
|
|
||||||
aria-describedby="modal-modal-description"
|
|
||||||
>
|
|
||||||
<Box sx={style}>
|
|
||||||
<Box p={2} display={"flex"}>
|
|
||||||
<Typography
|
|
||||||
id="modal-modal-title"
|
|
||||||
variant="body"
|
|
||||||
component="h2"
|
|
||||||
flex={1}
|
|
||||||
>
|
|
||||||
Banner Name
|
|
||||||
</Typography>
|
|
||||||
<IconButton onClick={() => handleClose()}>
|
|
||||||
<CloseIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
<hr />
|
|
||||||
<TextField
|
|
||||||
placeholder="Banner name"
|
|
||||||
value={bannerName}
|
|
||||||
fullWidth
|
|
||||||
inputProps={{
|
|
||||||
maxLength: 25,
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
onChange={(e) =>
|
|
||||||
setBannerName(
|
|
||||||
e.target.value.charAt(0).toUpperCase() +
|
|
||||||
e.target.value.slice(1)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{bannerName ? (
|
|
||||||
<>
|
|
||||||
<small className="charLeft mt-2 ml-3 fst-italic">
|
|
||||||
{25 - bannerName.length} characters left
|
|
||||||
</small>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Box
|
|
||||||
style={{
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "140px",
|
|
||||||
height: "140px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
{bannerImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={URL.createObjectURL(bannerImage)}
|
|
||||||
alt="bannerImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => handeldeleteImage()}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{olderImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={olderImage?.secure_url}
|
|
||||||
alt="bannerImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => setOlderImage("")}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<p className="pt-1 pl-2 text-secondary">
|
|
||||||
Upload jpg, jpeg and png only*
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Box
|
|
||||||
p={2}
|
|
||||||
display={"flex"}
|
|
||||||
justifyContent={"right"}
|
|
||||||
// width={"500px"}
|
|
||||||
>
|
|
||||||
{!edit && (
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSaveBanner()}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<ClipLoader loading={!saveLoding} size={18} />
|
|
||||||
{saveLoding && "Save"}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{edit && (
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
onClick={() => handleUpdate()}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<ClipLoader loading={!updating} size={18} />
|
|
||||||
{updating && "update"}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "black",
|
|
||||||
marginRight: "1rem",
|
|
||||||
background: "grey",
|
|
||||||
}}
|
|
||||||
onClick={() => setOpen(false)}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-sm-12 col-md-12">
|
|
||||||
<div className="dataTables_length">
|
|
||||||
<label className="w-100">
|
|
||||||
Show
|
|
||||||
<select
|
|
||||||
style={{ width: "10%" }}
|
|
||||||
onChange={(e) => setItemPerPage(e.target.value)}
|
|
||||||
className="
|
|
||||||
select-w
|
|
||||||
custom-select custom-select-sm
|
|
||||||
form-control form-control-sm
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: "1px solid" }}
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
className="thead-info"
|
|
||||||
style={{ background: "rgb(140, 213, 213)" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<th> Image</th>
|
|
||||||
|
|
||||||
<th> Banner Name</th>
|
|
||||||
|
|
||||||
<th>Action</th>
|
|
||||||
<th>Dimension</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{!loading && banner.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="6">
|
|
||||||
<h5>No Data Available</h5>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="6">
|
|
||||||
Loading...
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : (
|
|
||||||
banner &&
|
|
||||||
banner
|
|
||||||
.slice(
|
|
||||||
(`${page}` - 1) * itemPerPage,
|
|
||||||
`${page}` * itemPerPage
|
|
||||||
)
|
|
||||||
.map((item, i) => (
|
|
||||||
<tr key={i}>
|
|
||||||
<td>
|
|
||||||
<img
|
|
||||||
className="me-2"
|
|
||||||
src={item?.bannerImage?.secure_url}
|
|
||||||
width="40"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<h5>{} </h5>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<h5>{item.bannerName} </h5>
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
onClick={() =>
|
|
||||||
handleEditClick(
|
|
||||||
item._id,
|
|
||||||
item.bannerName,
|
|
||||||
item.bannerImage
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
background: "red",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
onClick={() => handleDelete(item._id)}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
<td>1600 x 900 pixels</td>
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style={{ display: "flex", justifyContent: "right" }}>
|
|
||||||
<Pagination
|
|
||||||
style={{ margin: "2rem" }}
|
|
||||||
variant="outlined"
|
|
||||||
size="large"
|
|
||||||
count={getPageCount()}
|
|
||||||
color="primary"
|
|
||||||
onChange={(event, value) => setPage(value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Banners;
|
|
@ -1,200 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Bar } from "react-chartjs-2";
|
|
||||||
import {
|
|
||||||
Chart as ChartJS,
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
ChartJS.register(
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend
|
|
||||||
);
|
|
||||||
|
|
||||||
const CityRevenueCharts = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [ordersData, setOrdersData] = useState([]);
|
|
||||||
const [filteredOrders, setFilteredOrders] = useState([]);
|
|
||||||
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
|
|
||||||
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getOrder() {
|
|
||||||
axios
|
|
||||||
.get(`/api/order/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setOrdersData(res.data.order);
|
|
||||||
// console.log(res.data.order);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getOrder();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Filter orders based on selected year and month
|
|
||||||
const filtered = ordersData.filter((order) => {
|
|
||||||
const createdAt = new Date(order.createdAt);
|
|
||||||
return (
|
|
||||||
createdAt.getFullYear() === selectedYear &&
|
|
||||||
createdAt.getMonth() + 1 === selectedMonth
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// Sort filtered orders by date in ascending order
|
|
||||||
filtered.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.createdAt);
|
|
||||||
const dateB = new Date(b.createdAt);
|
|
||||||
return dateA - dateB;
|
|
||||||
});
|
|
||||||
setFilteredOrders(filtered);
|
|
||||||
}, [ordersData, selectedYear, selectedMonth]); // Update filtered orders when orders data, year, or month changes
|
|
||||||
|
|
||||||
const uniquecity = [
|
|
||||||
...new Set(
|
|
||||||
filteredOrders.map((item) => item.shippingInfo.city)
|
|
||||||
),
|
|
||||||
];
|
|
||||||
// console.log(uniquecity);
|
|
||||||
// console.log(filteredOrders);
|
|
||||||
// Prepare data for chart
|
|
||||||
const data = {
|
|
||||||
labels: uniquecity, // Use unique product names as labels
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Total Amount",
|
|
||||||
data: uniquecity.map((city) => {
|
|
||||||
// Sum total amounts for each date
|
|
||||||
return filteredOrders
|
|
||||||
.filter((order) => order.shippingInfo.city.includes(city))
|
|
||||||
.reduce((total, order) => total + order.total_amount, 0);
|
|
||||||
}),
|
|
||||||
backgroundColor: "rgba(43, 63, 229, 0.8)",
|
|
||||||
borderRadius: 5,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Revenue Chart",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "City",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Total Amount",
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1, // Adjust step size as needed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert month number to string
|
|
||||||
const monthToString = (monthNumber) => {
|
|
||||||
const months = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
return months[monthNumber - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine the lowest year found in the ordersData
|
|
||||||
const lowestYear = Math.min(
|
|
||||||
...ordersData.map((order) => new Date(order.createdAt).getFullYear())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate an array of years from the lowest year to the current year
|
|
||||||
const years = Array.from(
|
|
||||||
{ length: new Date().getFullYear() - lowestYear + 1 },
|
|
||||||
(_, index) => lowestYear + index
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{ display: "flex" }}>
|
|
||||||
<div style={{ marginRight: "20px" }}>
|
|
||||||
<label htmlFor="year">Select Year:</label>
|
|
||||||
<select
|
|
||||||
id="year"
|
|
||||||
value={selectedYear}
|
|
||||||
onChange={(e) => setSelectedYear(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{years.map((year) => (
|
|
||||||
<option key={year} value={year}>
|
|
||||||
{year}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="month">Select Month:</label>
|
|
||||||
<select
|
|
||||||
id="month"
|
|
||||||
value={selectedMonth}
|
|
||||||
onChange={(e) => setSelectedMonth(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{[...Array(12).keys()].map((month) => (
|
|
||||||
<option key={month + 1} value={month + 1}>
|
|
||||||
{monthToString(month + 1)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ textAlign: "center" }}>
|
|
||||||
{filteredOrders.length === 0 ? (
|
|
||||||
<p>No data available</p>
|
|
||||||
) : (
|
|
||||||
<div style={{ height: "75vh" }}>
|
|
||||||
<Bar data={data} options={options} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CityRevenueCharts;
|
|
@ -1,195 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Bar } from "react-chartjs-2";
|
|
||||||
import {
|
|
||||||
Chart as ChartJS,
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
ChartJS.register(
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend
|
|
||||||
);
|
|
||||||
|
|
||||||
const OrderdayChart = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [ordersData, setOrdersData] = useState([]);
|
|
||||||
const [filteredOrders, setFilteredOrders] = useState([]);
|
|
||||||
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
|
|
||||||
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getOrder() {
|
|
||||||
axios
|
|
||||||
.get(`/api/order/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setOrdersData(res.data.order);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getOrder();
|
|
||||||
}, [token]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Filter orders based on selected year and month
|
|
||||||
const filtered = ordersData.filter((order) => {
|
|
||||||
const createdAt = new Date(order.createdAt);
|
|
||||||
return (
|
|
||||||
createdAt.getFullYear() === selectedYear &&
|
|
||||||
createdAt.getMonth() + 1 === selectedMonth
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// Sort filtered orders by date in ascending order
|
|
||||||
filtered.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.createdAt);
|
|
||||||
const dateB = new Date(b.createdAt);
|
|
||||||
return dateA - dateB;
|
|
||||||
});
|
|
||||||
setFilteredOrders(filtered);
|
|
||||||
}, [ordersData, selectedYear, selectedMonth]); // Update filtered orders when orders data, year, or month changes
|
|
||||||
|
|
||||||
// Extract unique dates from filtered orders
|
|
||||||
const uniqueDates = Array.from(
|
|
||||||
new Set(filteredOrders.map((order) => order.createdAt.split("T")[0]))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Prepare data for chart
|
|
||||||
const data = {
|
|
||||||
labels: uniqueDates,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Total Orders",
|
|
||||||
data: uniqueDates.map((date) => {
|
|
||||||
// Count total orders for each date
|
|
||||||
return filteredOrders.filter((order) => order.createdAt.includes(date)).length;
|
|
||||||
}),
|
|
||||||
backgroundColor: "rgba(43, 63, 229, 0.8)",
|
|
||||||
borderRadius: 5,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Revenue Order",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Date",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Orders",
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1, // Adjust step size as needed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert month number to string
|
|
||||||
const monthToString = (monthNumber) => {
|
|
||||||
const months = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
return months[monthNumber - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine the lowest year found in the ordersData
|
|
||||||
const lowestYear = Math.min(
|
|
||||||
...ordersData.map((order) => new Date(order.createdAt).getFullYear())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate an array of years from the lowest year to the current year
|
|
||||||
const years = Array.from(
|
|
||||||
{ length: new Date().getFullYear() - lowestYear + 1 },
|
|
||||||
(_, index) => lowestYear + index
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{ display: "flex"}}>
|
|
||||||
<div style={{ marginRight: "20px" }}>
|
|
||||||
<label htmlFor="year">Select Year:</label>
|
|
||||||
<select
|
|
||||||
id="year"
|
|
||||||
value={selectedYear}
|
|
||||||
onChange={(e) => setSelectedYear(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{years.map((year) => (
|
|
||||||
<option key={year} value={year}>
|
|
||||||
{year}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="month">Select Month:</label>
|
|
||||||
<select
|
|
||||||
id="month"
|
|
||||||
value={selectedMonth}
|
|
||||||
onChange={(e) => setSelectedMonth(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{[...Array(12).keys()].map((month) => (
|
|
||||||
<option key={month + 1} value={month + 1}>
|
|
||||||
{monthToString(month + 1)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ textAlign: "center" }}>
|
|
||||||
{filteredOrders.length === 0 ? (
|
|
||||||
<p>No data available</p>
|
|
||||||
) : (
|
|
||||||
<div style={{height:"75vh"}}>
|
|
||||||
<Bar data={data} options={options} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default OrderdayChart;
|
|
@ -1,213 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Bar } from "react-chartjs-2";
|
|
||||||
import {
|
|
||||||
Chart as ChartJS,
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
ChartJS.register(
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend
|
|
||||||
);
|
|
||||||
|
|
||||||
const ProductrevenueCharts = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [ordersData, setOrdersData] = useState([]);
|
|
||||||
const [filteredOrders, setFilteredOrders] = useState([]);
|
|
||||||
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
|
|
||||||
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getOrder() {
|
|
||||||
axios
|
|
||||||
.get(`/api/order/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setOrdersData(res.data.order);
|
|
||||||
// console.log(res.data.order);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getOrder();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Filter orders based on selected year and month
|
|
||||||
const filtered = ordersData.filter((order) => {
|
|
||||||
const createdAt = new Date(order.createdAt);
|
|
||||||
return (
|
|
||||||
createdAt.getFullYear() === selectedYear &&
|
|
||||||
createdAt.getMonth() + 1 === selectedMonth
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// Sort filtered orders by date in ascending order
|
|
||||||
filtered.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.createdAt);
|
|
||||||
const dateB = new Date(b.createdAt);
|
|
||||||
return dateA - dateB;
|
|
||||||
});
|
|
||||||
setFilteredOrders(filtered);
|
|
||||||
}, [ordersData, selectedYear, selectedMonth]); // Update filtered orders when orders data, year, or month changes
|
|
||||||
|
|
||||||
// Extract unique products from filtered orders
|
|
||||||
const uniqueProducts = [
|
|
||||||
...new Set(
|
|
||||||
filteredOrders.flatMap((order) =>
|
|
||||||
order.orderItems.map((item) => item.name)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
];
|
|
||||||
// console.log(uniqueProducts);
|
|
||||||
// console.log(filteredOrders);
|
|
||||||
// Prepare data for chart
|
|
||||||
const data = {
|
|
||||||
labels: uniqueProducts, // Use unique product names as labels
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Total Amount",
|
|
||||||
data: uniqueProducts.map((product) =>
|
|
||||||
filteredOrders.reduce((total, order) => {
|
|
||||||
// Find the order item for the current product
|
|
||||||
const orderItem = order.orderItems.find(
|
|
||||||
(item) => item.name === product
|
|
||||||
);
|
|
||||||
if (orderItem) {
|
|
||||||
// If the order item exists, add its total amount to the total for this product
|
|
||||||
return total + orderItem.
|
|
||||||
product_Subtotal;
|
|
||||||
} else {
|
|
||||||
// If the order item does not exist, return the current total
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
}, 0)
|
|
||||||
),
|
|
||||||
backgroundColor: "rgba(43, 63, 229, 0.8)",
|
|
||||||
borderRadius: 5,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Revenue Chart",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Product",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Total Amount",
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1, // Adjust step size as needed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert month number to string
|
|
||||||
const monthToString = (monthNumber) => {
|
|
||||||
const months = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
return months[monthNumber - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine the lowest year found in the ordersData
|
|
||||||
const lowestYear = Math.min(
|
|
||||||
...ordersData.map((order) => new Date(order.createdAt).getFullYear())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate an array of years from the lowest year to the current year
|
|
||||||
const years = Array.from(
|
|
||||||
{ length: new Date().getFullYear() - lowestYear + 1 },
|
|
||||||
(_, index) => lowestYear + index
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{ display: "flex" }}>
|
|
||||||
<div style={{ marginRight: "20px" }}>
|
|
||||||
<label htmlFor="year">Select Year:</label>
|
|
||||||
<select
|
|
||||||
id="year"
|
|
||||||
value={selectedYear}
|
|
||||||
onChange={(e) => setSelectedYear(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{years.map((year) => (
|
|
||||||
<option key={year} value={year}>
|
|
||||||
{year}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="month">Select Month:</label>
|
|
||||||
<select
|
|
||||||
id="month"
|
|
||||||
value={selectedMonth}
|
|
||||||
onChange={(e) => setSelectedMonth(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{[...Array(12).keys()].map((month) => (
|
|
||||||
<option key={month + 1} value={month + 1}>
|
|
||||||
{monthToString(month + 1)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ textAlign: "center" }}>
|
|
||||||
{filteredOrders.length === 0 ? (
|
|
||||||
<p>No data available</p>
|
|
||||||
) : (
|
|
||||||
<div style={{ height: "75vh" }}>
|
|
||||||
<Bar data={data} options={options} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProductrevenueCharts;
|
|
@ -1,199 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Bar } from "react-chartjs-2";
|
|
||||||
import {
|
|
||||||
Chart as ChartJS,
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
ChartJS.register(
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend
|
|
||||||
);
|
|
||||||
|
|
||||||
const RevenueCharts = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [ordersData, setOrdersData] = useState([]);
|
|
||||||
const [filteredOrders, setFilteredOrders] = useState([]);
|
|
||||||
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
|
|
||||||
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getOrder() {
|
|
||||||
axios
|
|
||||||
.get(`/api/order/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setOrdersData(res.data.order);
|
|
||||||
// console.log(res.data.order);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getOrder();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Filter orders based on selected year and month
|
|
||||||
const filtered = ordersData.filter((order) => {
|
|
||||||
const createdAt = new Date(order.createdAt);
|
|
||||||
return (
|
|
||||||
createdAt.getFullYear() === selectedYear &&
|
|
||||||
createdAt.getMonth() + 1 === selectedMonth
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// Sort filtered orders by date in ascending order
|
|
||||||
filtered.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.createdAt);
|
|
||||||
const dateB = new Date(b.createdAt);
|
|
||||||
return dateA - dateB;
|
|
||||||
});
|
|
||||||
setFilteredOrders(filtered);
|
|
||||||
}, [ordersData, selectedYear, selectedMonth]); // Update filtered orders when orders data, year, or month changes
|
|
||||||
|
|
||||||
// Extract unique dates from filtered orders
|
|
||||||
const uniqueDates = Array.from(
|
|
||||||
new Set(filteredOrders.map((order) => order.createdAt.split("T")[0]))
|
|
||||||
);
|
|
||||||
// console.log(uniqueDates);
|
|
||||||
// console.log(filteredOrders);
|
|
||||||
// Prepare data for chart
|
|
||||||
const data = {
|
|
||||||
labels: uniqueDates,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Total Amount",
|
|
||||||
data: uniqueDates.map((date) => {
|
|
||||||
// Sum total amounts for each date
|
|
||||||
return filteredOrders
|
|
||||||
.filter((order) => order.createdAt.includes(date))
|
|
||||||
.reduce((total, order) => total + order.total_amount, 0);
|
|
||||||
}),
|
|
||||||
backgroundColor: "rgba(43, 63, 229, 0.8)",
|
|
||||||
borderRadius: 5,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Revenue Chart",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Date",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Total Amount",
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1000, // Adjust step size as needed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert month number to string
|
|
||||||
const monthToString = (monthNumber) => {
|
|
||||||
const months = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
return months[monthNumber - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine the lowest year found in the ordersData
|
|
||||||
const lowestYear = Math.min(
|
|
||||||
...ordersData.map((order) => new Date(order.createdAt).getFullYear())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate an array of years from the lowest year to the current year
|
|
||||||
const years = Array.from(
|
|
||||||
{ length: new Date().getFullYear() - lowestYear + 1 },
|
|
||||||
(_, index) => lowestYear + index
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{ display: "flex" }}>
|
|
||||||
<div style={{ marginRight: "20px" }}>
|
|
||||||
<label htmlFor="year">Select Year:</label>
|
|
||||||
<select
|
|
||||||
id="year"
|
|
||||||
value={selectedYear}
|
|
||||||
onChange={(e) => setSelectedYear(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{years.map((year) => (
|
|
||||||
<option key={year} value={year}>
|
|
||||||
{year}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="month">Select Month:</label>
|
|
||||||
<select
|
|
||||||
id="month"
|
|
||||||
value={selectedMonth}
|
|
||||||
onChange={(e) => setSelectedMonth(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{[...Array(12).keys()].map((month) => (
|
|
||||||
<option key={month + 1} value={month + 1}>
|
|
||||||
{monthToString(month + 1)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ textAlign: "center" }}>
|
|
||||||
{filteredOrders.length === 0 ? (
|
|
||||||
<p>No data available</p>
|
|
||||||
) : (
|
|
||||||
<div style={{ height: "75vh" }}>
|
|
||||||
<Bar data={data} options={options} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RevenueCharts;
|
|
@ -1,200 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Bar } from "react-chartjs-2";
|
|
||||||
import {
|
|
||||||
Chart as ChartJS,
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
ChartJS.register(
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend
|
|
||||||
);
|
|
||||||
|
|
||||||
const StateRevenueCharts = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [ordersData, setOrdersData] = useState([]);
|
|
||||||
const [filteredOrders, setFilteredOrders] = useState([]);
|
|
||||||
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
|
|
||||||
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getOrder() {
|
|
||||||
axios
|
|
||||||
.get(`/api/order/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setOrdersData(res.data.order);
|
|
||||||
// console.log(res.data.order);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getOrder();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Filter orders based on selected year and month
|
|
||||||
const filtered = ordersData.filter((order) => {
|
|
||||||
const createdAt = new Date(order.createdAt);
|
|
||||||
return (
|
|
||||||
createdAt.getFullYear() === selectedYear &&
|
|
||||||
createdAt.getMonth() + 1 === selectedMonth
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// Sort filtered orders by date in ascending order
|
|
||||||
filtered.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.createdAt);
|
|
||||||
const dateB = new Date(b.createdAt);
|
|
||||||
return dateA - dateB;
|
|
||||||
});
|
|
||||||
setFilteredOrders(filtered);
|
|
||||||
}, [ordersData, selectedYear, selectedMonth]); // Update filtered orders when orders data, year, or month changes
|
|
||||||
|
|
||||||
const uniquestate = [
|
|
||||||
...new Set(
|
|
||||||
filteredOrders.map((item) => item.shippingInfo.state)
|
|
||||||
),
|
|
||||||
];
|
|
||||||
// console.log(uniquestate);
|
|
||||||
// console.log(filteredOrders);
|
|
||||||
// Prepare data for chart
|
|
||||||
const data = {
|
|
||||||
labels: uniquestate, // Use unique product names as labels
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Total Amount",
|
|
||||||
data: uniquestate.map((state) => {
|
|
||||||
// Sum total amounts for each date
|
|
||||||
return filteredOrders
|
|
||||||
.filter((order) => order.shippingInfo.state.includes(state))
|
|
||||||
.reduce((total, order) => total + order.total_amount, 0);
|
|
||||||
}),
|
|
||||||
backgroundColor: "rgba(43, 63, 229, 0.8)",
|
|
||||||
borderRadius: 5,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Revenue Chart",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "State",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Total Amount",
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1, // Adjust step size as needed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert month number to string
|
|
||||||
const monthToString = (monthNumber) => {
|
|
||||||
const months = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
return months[monthNumber - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine the lowest year found in the ordersData
|
|
||||||
const lowestYear = Math.min(
|
|
||||||
...ordersData.map((order) => new Date(order.createdAt).getFullYear())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate an array of years from the lowest year to the current year
|
|
||||||
const years = Array.from(
|
|
||||||
{ length: new Date().getFullYear() - lowestYear + 1 },
|
|
||||||
(_, index) => lowestYear + index
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{ display: "flex" }}>
|
|
||||||
<div style={{ marginRight: "20px" }}>
|
|
||||||
<label htmlFor="year">Select Year:</label>
|
|
||||||
<select
|
|
||||||
id="year"
|
|
||||||
value={selectedYear}
|
|
||||||
onChange={(e) => setSelectedYear(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{years.map((year) => (
|
|
||||||
<option key={year} value={year}>
|
|
||||||
{year}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="month">Select Month:</label>
|
|
||||||
<select
|
|
||||||
id="month"
|
|
||||||
value={selectedMonth}
|
|
||||||
onChange={(e) => setSelectedMonth(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{[...Array(12).keys()].map((month) => (
|
|
||||||
<option key={month + 1} value={month + 1}>
|
|
||||||
{monthToString(month + 1)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ textAlign: "center" }}>
|
|
||||||
{filteredOrders.length === 0 ? (
|
|
||||||
<p>No data available</p>
|
|
||||||
) : (
|
|
||||||
<div style={{ height: "75vh" }}>
|
|
||||||
<Bar data={data} options={options} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default StateRevenueCharts;
|
|
@ -1,200 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Bar } from "react-chartjs-2";
|
|
||||||
import {
|
|
||||||
Chart as ChartJS,
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js";
|
|
||||||
|
|
||||||
ChartJS.register(
|
|
||||||
CategoryScale,
|
|
||||||
LinearScale,
|
|
||||||
BarElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend
|
|
||||||
);
|
|
||||||
|
|
||||||
const UserCharts = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [userData, setUsers] = useState([]);
|
|
||||||
const [filteredUsers, setfilteredUsers] = useState([]);
|
|
||||||
const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
|
|
||||||
const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function getOrder() {
|
|
||||||
axios
|
|
||||||
.get(`/api/v1/admin/users`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setUsers(res.data.users);
|
|
||||||
// console.log(res.data.users);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getOrder();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Filter orders based on selected year and month
|
|
||||||
const filtered = userData.filter((order) => {
|
|
||||||
const createdAt = new Date(order.createdAt);
|
|
||||||
return (
|
|
||||||
createdAt.getFullYear() === selectedYear &&
|
|
||||||
createdAt.getMonth() + 1 === selectedMonth
|
|
||||||
);
|
|
||||||
});
|
|
||||||
// Sort filtered orders by date in ascending order
|
|
||||||
filtered.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.createdAt);
|
|
||||||
const dateB = new Date(b.createdAt);
|
|
||||||
return dateA - dateB;
|
|
||||||
});
|
|
||||||
setfilteredUsers(filtered);
|
|
||||||
}, [userData, selectedYear, selectedMonth]); // Update filtered orders when orders data, year, or month changes
|
|
||||||
|
|
||||||
// Extract unique dates from filtered orders
|
|
||||||
const uniqueDates = Array.from(
|
|
||||||
new Set(filteredUsers.map((order) => order.createdAt.split("T")[0]))
|
|
||||||
);
|
|
||||||
// console.log(uniqueDates);
|
|
||||||
// console.log(filteredUsers);
|
|
||||||
// Prepare data for chart
|
|
||||||
const data = {
|
|
||||||
labels: uniqueDates,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "No of Amounts",
|
|
||||||
data: uniqueDates.map((date) => {
|
|
||||||
// Sum total amounts for each date
|
|
||||||
return filteredUsers
|
|
||||||
.filter((order) => order.createdAt.includes(date))
|
|
||||||
.length;
|
|
||||||
}),
|
|
||||||
backgroundColor: "rgba(43, 63, 229, 0.8)",
|
|
||||||
borderRadius: 5,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
responsive: true,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "User Chart",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "Date",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: "No of Users",
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1, // Adjust step size as needed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert month number to string
|
|
||||||
const monthToString = (monthNumber) => {
|
|
||||||
const months = [
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
return months[monthNumber - 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Determine the lowest year found in the userData
|
|
||||||
const lowestYear = Math.min(
|
|
||||||
...userData.map((order) => new Date(order.createdAt).getFullYear())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate an array of years from the lowest year to the current year
|
|
||||||
const years = Array.from(
|
|
||||||
{ length: new Date().getFullYear() - lowestYear + 1 },
|
|
||||||
(_, index) => lowestYear + index
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{ display: "flex" }}>
|
|
||||||
<div style={{ marginRight: "20px" }}>
|
|
||||||
<label htmlFor="year">Select Year:</label>
|
|
||||||
<select
|
|
||||||
id="year"
|
|
||||||
value={selectedYear}
|
|
||||||
onChange={(e) => setSelectedYear(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{years.map((year) => (
|
|
||||||
<option key={year} value={year}>
|
|
||||||
{year}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="month">Select Month:</label>
|
|
||||||
<select
|
|
||||||
id="month"
|
|
||||||
value={selectedMonth}
|
|
||||||
onChange={(e) => setSelectedMonth(parseInt(e.target.value))}
|
|
||||||
>
|
|
||||||
{[...Array(12).keys()].map((month) => (
|
|
||||||
<option key={month + 1} value={month + 1}>
|
|
||||||
{monthToString(month + 1)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ textAlign: "center" }}>
|
|
||||||
{filteredUsers.length === 0 ? (
|
|
||||||
<p>No data available</p>
|
|
||||||
) : (
|
|
||||||
<div style={{ height: "75vh" }}>
|
|
||||||
<Bar data={data} options={options} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default UserCharts;
|
|
||||||
|
|
@ -1,221 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
// import { WebsiteURL } from '../WebsiteURL'
|
|
||||||
|
|
||||||
const AddContactRequest = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [data, setData] = useState({
|
|
||||||
name: "",
|
|
||||||
EmailOrMobile: "",
|
|
||||||
message: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
if (
|
|
||||||
data.name.trim() === "" ||
|
|
||||||
data.EmailOrMobile.trim() === "" ||
|
|
||||||
data.message.trim() === ""
|
|
||||||
) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Fill all mandatory fields",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.set("name", data.name);
|
|
||||||
formData.set("EmailOrMobile", data.EmailOrMobile);
|
|
||||||
|
|
||||||
formData.set("message", data.message);
|
|
||||||
|
|
||||||
axios
|
|
||||||
.post(`/api/contact/request/new/`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/formdata",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Added",
|
|
||||||
text: "Contact Requests added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
navigate("/contact/request", { replace: true });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoading(false);
|
|
||||||
const message = err.response?.data?.message || "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: message,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
New Contact Request
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSubmit()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{loading ? "Loading" : "Save"}
|
|
||||||
</Button>
|
|
||||||
<Link to="/contact/request">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12 col-md-12 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Name *
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="name"
|
|
||||||
value={data.name}
|
|
||||||
maxLength={25}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
/>
|
|
||||||
{data.name ? (
|
|
||||||
<>
|
|
||||||
<small className="charLeft mt-4 fst-italic">
|
|
||||||
{25 - data.name.length} characters left
|
|
||||||
</small>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}{" "}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Email/Mobile *
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="EmailOrMobile"
|
|
||||||
value={data.EmailOrMobile}
|
|
||||||
maxLength={25}
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
/>
|
|
||||||
{data.EmailOrMobile ? (
|
|
||||||
<>
|
|
||||||
<small className="charLeft mt-4 fst-italic">
|
|
||||||
{25 - data.EmailOrMobile.length} characters left
|
|
||||||
</small>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}{" "}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Message *
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="message"
|
|
||||||
rows="10"
|
|
||||||
cols="100"
|
|
||||||
value={data.message}
|
|
||||||
placeholder="your message..."
|
|
||||||
maxLength="500"
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
></textarea>
|
|
||||||
|
|
||||||
{data.message ? (
|
|
||||||
<>
|
|
||||||
<small className="charLeft mt-4 fst-italic">
|
|
||||||
{500 - data.message.length} characters left
|
|
||||||
</small>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
message *
|
|
||||||
</label>
|
|
||||||
<br />
|
|
||||||
<textarea id="w3review" name="w3review" rows="10" cols="100">
|
|
||||||
At w3schools.com you will learn how to make a website. They offer free tutorials in all web development technologies.
|
|
||||||
</textarea>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AddContactRequest;
|
|
@ -1,338 +0,0 @@
|
|||||||
|
|
||||||
import React, { useState, useEffect } from 'react'
|
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import Button from '@material-ui/core/Button'
|
|
||||||
import { useNavigate } from 'react-router-dom'
|
|
||||||
import axios from 'axios'
|
|
||||||
import { isAutheticated } from 'src/auth'
|
|
||||||
|
|
||||||
const ContactRequests = () => {
|
|
||||||
const token = isAutheticated()
|
|
||||||
const navigate = useNavigate()
|
|
||||||
const [loading, setLoading] = useState(true)
|
|
||||||
const [success, setSuccess] = useState(true)
|
|
||||||
const [ContactRequestsData, setContactRequestsData] = useState([])
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1)
|
|
||||||
const [itemPerPage, setItemPerPage] = useState(10)
|
|
||||||
const [showData, setShowData] = useState(ContactRequestsData)
|
|
||||||
|
|
||||||
const handleShowEntries = (e) => {
|
|
||||||
setCurrentPage(1)
|
|
||||||
setItemPerPage(e.target.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const getContactRequestsData = async () => {
|
|
||||||
axios
|
|
||||||
.get(`/api/contact/request/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(res.data)
|
|
||||||
setContactRequestsData(res.data?.contactRequest)
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoading(false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getContactRequestsData()
|
|
||||||
}, [success])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const loadData = () => {
|
|
||||||
const indexOfLastPost = currentPage * itemPerPage
|
|
||||||
const indexOfFirstPost = indexOfLastPost - itemPerPage
|
|
||||||
setShowData(ContactRequestsData.slice(indexOfFirstPost, indexOfLastPost))
|
|
||||||
}
|
|
||||||
loadData()
|
|
||||||
}, [currentPage, itemPerPage, ContactRequestsData])
|
|
||||||
|
|
||||||
const handleDelete = (id) => {
|
|
||||||
swal({
|
|
||||||
title: 'Are you sure?',
|
|
||||||
icon: 'error',
|
|
||||||
buttons: { Yes: { text: 'Yes', value: true }, Cancel: { text: 'Cancel', value: 'cancel' } },
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.delete(`/api/product/delete/${id}`, {
|
|
||||||
headers: {
|
|
||||||
'Access-Control-Allow-Origin': '*',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setSuccess((prev) => !prev)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: 'Warning',
|
|
||||||
text: 'Something went wrong!',
|
|
||||||
icon: 'error',
|
|
||||||
button: 'Retry',
|
|
||||||
dangerMode: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: '22px' }} className="fw-bold">
|
|
||||||
Contact Requests
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginBottom: '1rem',
|
|
||||||
textTransform: 'capitalize',
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/contact/request/new', { replace: true })
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
New Contact Requests
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-sm-12 col-md-12">
|
|
||||||
<div className="dataTables_length">
|
|
||||||
<label className="w-100">
|
|
||||||
Show
|
|
||||||
<select
|
|
||||||
style={{ width: '10%' }}
|
|
||||||
name=""
|
|
||||||
onChange={(e) => handleShowEntries(e)}
|
|
||||||
className="
|
|
||||||
select-w
|
|
||||||
custom-select custom-select-sm
|
|
||||||
form-control form-control-sm
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: '1px solid' }}
|
|
||||||
>
|
|
||||||
<thead className="thead-info" style={{ background: 'rgb(140, 213, 213)' }}>
|
|
||||||
<tr>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<th className="text-start">Name</th>
|
|
||||||
<th className="text-start">Email/Mobile</th>
|
|
||||||
<th className="text-start">Message</th>
|
|
||||||
|
|
||||||
|
|
||||||
<th className="text-start">Date & Time</th>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <th className="text-start">Action</th> */}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{!loading && showData.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="6">
|
|
||||||
<h5>No Data Available</h5>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="6">
|
|
||||||
Loading...
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : (
|
|
||||||
showData.map((product, i) => {
|
|
||||||
return (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-start">{product.name}</td>
|
|
||||||
|
|
||||||
<td className="text-start">{product.EmailOrMobile}</td>
|
|
||||||
<td className="text-start">{product.message}</td>
|
|
||||||
|
|
||||||
|
|
||||||
<td className="text-start">
|
|
||||||
{new Date(product.createdAt).toLocaleString('en-IN', {
|
|
||||||
weekday: 'short',
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true,
|
|
||||||
})}
|
|
||||||
</td>
|
|
||||||
{/* <td className="text-start">
|
|
||||||
|
|
||||||
<Link to={`/product/view/${product._id}`}>
|
|
||||||
<button
|
|
||||||
style={{ color: 'white', marginRight: '1rem' }}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
View
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</td> */}
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-20">
|
|
||||||
<div className="col-sm-12 col-md-6 mb-20">
|
|
||||||
<div
|
|
||||||
className="dataTables_info"
|
|
||||||
id="datatable_info"
|
|
||||||
role="status"
|
|
||||||
aria-live="polite"
|
|
||||||
>
|
|
||||||
Showing {currentPage * itemPerPage - itemPerPage + 1} to{' '}
|
|
||||||
{Math.min(currentPage * itemPerPage, ContactRequestsData.length)} of{' '}
|
|
||||||
{ContactRequestsData.length} entries
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-sm-12 col-md-6">
|
|
||||||
<div className="d-flex">
|
|
||||||
<ul className="pagination ms-auto">
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
currentPage === 1
|
|
||||||
? 'paginate_button page-item previous disabled'
|
|
||||||
: 'paginate_button page-item previous'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev - 1)}
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(currentPage - 1 < 1) && (
|
|
||||||
<li className="paginate_button page-item">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={(e) => setCurrentPage((prev) => prev - 1)}
|
|
||||||
>
|
|
||||||
{currentPage - 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li className="paginate_button page-item active">
|
|
||||||
<span className="page-link" style={{ cursor: 'pointer' }}>
|
|
||||||
{currentPage}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
ContactRequestsData.length - 1
|
|
||||||
) && (
|
|
||||||
<li className="paginate_button page-item ">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentPage((prev) => prev + 1)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{currentPage + 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
ContactRequestsData.length - 1
|
|
||||||
)
|
|
||||||
? 'paginate_button page-item next'
|
|
||||||
: 'paginate_button page-item next disabled'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev + 1)}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ContactRequests
|
|
@ -1,207 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
// import Button from "@material-ui/core/Button";
|
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { Button, ImageList, InputLabel, ImageListItem } from "@mui/material";
|
|
||||||
import MessageList from "./MessageList";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
|
|
||||||
const CloseRequestView = () => {
|
|
||||||
// Assuming you have the following ticket details
|
|
||||||
const { ticketID } = useParams();
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
// error****************************please check
|
|
||||||
const [ticketDetails, setticketDetails] = useState(null);
|
|
||||||
|
|
||||||
// const dispatch = useDispatch();
|
|
||||||
// const tickets = useSelector((state) => state.ticket.ticket);
|
|
||||||
// useEffect(() => {
|
|
||||||
// dispatch(getTicketItem());
|
|
||||||
// }, [dispatch]);
|
|
||||||
|
|
||||||
// console.log(tickets);
|
|
||||||
// geting data from backend************
|
|
||||||
|
|
||||||
// const dispatch = useDispatch();
|
|
||||||
// const tickets = useSelector((state) => state.ticket.ticket);
|
|
||||||
// useEffect(() => {
|
|
||||||
// dispatch(getTicketItem());
|
|
||||||
// }, [dispatch]);
|
|
||||||
|
|
||||||
// console.log(tickets);
|
|
||||||
// useEffect(() => {
|
|
||||||
// const foundTicket = tickets.find((ticket) => ticket.ticketId === ticketID);
|
|
||||||
// // console.log(foundTicket);
|
|
||||||
// setticketDetails(foundTicket);
|
|
||||||
// }, [ticketID]);
|
|
||||||
// console.log(ticketID);
|
|
||||||
// *****************
|
|
||||||
// geting data from backend************
|
|
||||||
const getSupportTicketDetails = async () => {
|
|
||||||
// console.log(ticketID);
|
|
||||||
axios
|
|
||||||
.get(`/api/support/getOne/${ticketID}`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
// console.log(res?.data);
|
|
||||||
// setticketDetails(res.data?.support);
|
|
||||||
// setTicket(res.data?.support);
|
|
||||||
console.log(res.data?.support);
|
|
||||||
getuserName(res.data?.support);
|
|
||||||
// setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: "please login to access the resource or refresh the page ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
// setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// ************************************
|
|
||||||
const getuserName = async (ticket) => {
|
|
||||||
try {
|
|
||||||
const userId = ticket.addedBy;
|
|
||||||
let resp = await axios.get(`/api/v1/admin/user/${userId}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
console.log(resp?.data?.user?.name);
|
|
||||||
const userName = resp?.data?.user?.name;
|
|
||||||
const userMailId = resp?.data?.user?.email;
|
|
||||||
// console.log(userName);
|
|
||||||
// Update support ticket with user name
|
|
||||||
const ticketWithUserName = {
|
|
||||||
...ticket,
|
|
||||||
userName: userName,
|
|
||||||
userMailId: userMailId,
|
|
||||||
};
|
|
||||||
setticketDetails(ticketWithUserName);
|
|
||||||
} catch (error) {
|
|
||||||
// Handle errors
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
getSupportTicketDetails();
|
|
||||||
}, []);
|
|
||||||
// *****************
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
View Request
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
<div className="page-title-right">
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/support/request/closed", { replace: true });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12 col-md-12 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Ticket ID: {ticketDetails?.ticketId}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
User ID: {ticketDetails?.addedBy}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
User Name: {ticketDetails?.userName}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
User MailId: {ticketDetails?.userMailId}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Date and Time: {ticketDetails?.createdOn}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Subject: {ticketDetails?.subject}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Description:{" "}
|
|
||||||
{ticketDetails?.description
|
|
||||||
? ticketDetails?.description
|
|
||||||
: "No Description"}
|
|
||||||
</InputLabel>
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
{ticketDetails?.image?.length > 0 && (
|
|
||||||
<div>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Image:
|
|
||||||
</InputLabel>
|
|
||||||
<ImageList sx={{ width: 500 }} cols={3} rowHeight={164}>
|
|
||||||
{ticketDetails?.image?.map((item) => (
|
|
||||||
<ImageListItem key={item.public_id}>
|
|
||||||
<img
|
|
||||||
srcSet={`${item.url}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`}
|
|
||||||
src={`${item.url}?w=164&h=164&fit=crop&auto=format`}
|
|
||||||
alt={item.title || "No image"}
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</ImageListItem>
|
|
||||||
))}
|
|
||||||
</ImageList>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
{ticketDetails && (
|
|
||||||
<MessageList messages={ticketDetails?.message} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* *************** */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CloseRequestView;
|
|
@ -1,111 +0,0 @@
|
|||||||
import {
|
|
||||||
Button,
|
|
||||||
Paper,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import React from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
|
|
||||||
export default function EmailCms() {
|
|
||||||
const pages = [
|
|
||||||
{
|
|
||||||
name: "New user registration",
|
|
||||||
action: "Edit",
|
|
||||||
path: "/email-cms/registration-email",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Forgot Password",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Change Password Notification ",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "New Order",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Order - Processing",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Order - Dispatched",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Order - Delivered",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Order - Cancelled",
|
|
||||||
action: "Edit",
|
|
||||||
path: "#",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<Typography variant="h6" fontWeight={"bold"}>
|
|
||||||
Email CMS
|
|
||||||
</Typography>
|
|
||||||
<TableContainer component={Paper}>
|
|
||||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell style={{ fontWeight: "bold" }}>Page</TableCell>
|
|
||||||
<TableCell style={{ fontWeight: "bold" }} align="right">
|
|
||||||
Action
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{pages.map((row) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.name}
|
|
||||||
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
|
|
||||||
>
|
|
||||||
<TableCell component="th" scope="row">
|
|
||||||
{row.name}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right">
|
|
||||||
{" "}
|
|
||||||
<Link to={row.path}>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-info btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mt-1
|
|
||||||
mx-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{row.action}
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,207 +0,0 @@
|
|||||||
import { Typography } from "@material-ui/core";
|
|
||||||
import { Box, Button } from "@mui/material";
|
|
||||||
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import ReactrichTextEditor from "../../Content/reactrichTextEditor";
|
|
||||||
import ReactQuill from "react-quill";
|
|
||||||
import "react-quill/dist/quill.snow.css";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { useNavigate, useNavigation } from "react-router-dom";
|
|
||||||
|
|
||||||
// const TOOLBAR_OPTIONS = [
|
|
||||||
// [{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
||||||
// [{ font: [] }],
|
|
||||||
// [{ list: "ordered" }, { list: "bullet" }],
|
|
||||||
// ["bold", "italic", "underline", "strike"],
|
|
||||||
// [{ color: [] }, { background: [] }],
|
|
||||||
// [{ align: [] }],
|
|
||||||
// [{ script: "super" }, { script: "sub" }],
|
|
||||||
// ["undo", "redo"],
|
|
||||||
// ];
|
|
||||||
|
|
||||||
export default function RegistrationEmail() {
|
|
||||||
const [title, setTitle] = useState("Registration Email");
|
|
||||||
const [welcomemsg, setWelcomeMsg] = useState("");
|
|
||||||
const [welcomemsgforDescription, setWelcomeMsgForDescription] = useState("");
|
|
||||||
|
|
||||||
const [subject, setSubject] = useState("");
|
|
||||||
const [description, setDescription] = useState("");
|
|
||||||
const [content, setContent] = useState("");
|
|
||||||
const [added, setAdded] = useState(false);
|
|
||||||
const [olderContent, setOlderContent] = useState("");
|
|
||||||
const [id, setId] = useState(null);
|
|
||||||
|
|
||||||
const token = isAutheticated();
|
|
||||||
|
|
||||||
const getTermsAndConditions = async () => {
|
|
||||||
const response = await axios.get("/api/get-email-data", {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (response.status === 200) {
|
|
||||||
if (response.data?.registerEmaildata.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.log(response);
|
|
||||||
// setContent(response?.data?.registerEmaildata[0]?.termsAndContionContent);
|
|
||||||
// setOlderContent(
|
|
||||||
// response?.data?.registerEmaildata[0]?.termsAndContionContent
|
|
||||||
// );
|
|
||||||
setSubject(response?.data?.registerEmaildata[0]?.subject);
|
|
||||||
setDescription(response?.data?.registerEmaildata[0]?.description);
|
|
||||||
setId(response?.data?.registerEmaildata[0]?._id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const addTermsandConditions = async () => {
|
|
||||||
const response = await axios.post(
|
|
||||||
"/api/register-email",
|
|
||||||
{ subject: subject, description: description },
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (response.status == 200) {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: response?.data?.message,
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const handleCancelClick = () => {
|
|
||||||
setAdded(!added);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveClick = async () => {
|
|
||||||
// if (id === null) {
|
|
||||||
await addTermsandConditions();
|
|
||||||
setAdded(true);
|
|
||||||
// } else {
|
|
||||||
// await updateContent();
|
|
||||||
// setAdded(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Reload terms and conditions
|
|
||||||
// await getTermsAndConditions();
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
// addTermsandConditions();
|
|
||||||
getTermsAndConditions();
|
|
||||||
}, [added]);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div style={{ display: "flex" }}>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={handleSaveClick}
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={handleCancelClick}
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Box style={{ background: "#FFFFFF", color: "black", padding: "1rem" }}>
|
|
||||||
{/* <TextField
|
|
||||||
type="text"
|
|
||||||
value={title}
|
|
||||||
onChange={(e) => setTitle(e.target.value)}
|
|
||||||
variant="outlined"
|
|
||||||
size="small"
|
|
||||||
fullWidth
|
|
||||||
/> */}
|
|
||||||
<Typography
|
|
||||||
style={{ margin: "0.5rem 0rem", fontWeight: "bold" }}
|
|
||||||
variant="h6"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Email Confiramtion:{" "}
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="welcomeMsg" className="form-label">
|
|
||||||
Welcome Message*
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
style={{ width: "300px" }}
|
|
||||||
id="welcomeMsg"
|
|
||||||
placeholder="Eg: Welcome to "
|
|
||||||
value={welcomemsg}
|
|
||||||
onChange={(e) => setWelcomeMsg(e.target.value)}
|
|
||||||
/>
|
|
||||||
<h6 style={{ fontWeight: "bold", marginTop: "1rem" }}>
|
|
||||||
App Name : Cheminova
|
|
||||||
</h6>
|
|
||||||
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Subject*
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="title"
|
|
||||||
value={subject}
|
|
||||||
onChange={(e) => setSubject(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="welcomeMsgforDes" className="form-label">
|
|
||||||
Welcome Message for Description*
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
style={{ width: "300px" }}
|
|
||||||
id="welcomeMsgforDes"
|
|
||||||
placeholder="Eg: Welcome to "
|
|
||||||
value={welcomemsgforDescription}
|
|
||||||
onChange={(e) => setWelcomeMsgForDescription(e.target.value)}
|
|
||||||
/>
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Description *
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="description"
|
|
||||||
rows="10"
|
|
||||||
cols="100"
|
|
||||||
value={description}
|
|
||||||
placeholder="your message..."
|
|
||||||
onChange={(e) => setDescription(e.target.value)}
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { Paper } from '@material-ui/core';
|
|
||||||
|
|
||||||
const MessageList = ({ messages }) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{messages.map((msg, index) => (
|
|
||||||
<div key={index} style={{ marginBottom: '10px' }}>
|
|
||||||
<Paper
|
|
||||||
elevation={3}
|
|
||||||
style={{
|
|
||||||
padding: '10px',
|
|
||||||
backgroundColor: msg.user === 'user' ? 'white' : 'lightgray',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ fontWeight: 'bold', marginBottom: '5px' }}>
|
|
||||||
{msg.user === 'user' ? 'User' : 'Admin'}
|
|
||||||
</div>
|
|
||||||
<div style={{ fontWeight: 'bold', marginBottom: '5px' }}>
|
|
||||||
{msg.replyDate}
|
|
||||||
</div>
|
|
||||||
<div>{msg.message}</div>
|
|
||||||
</Paper>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MessageList;
|
|
||||||
|
|
@ -1,346 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
// import Button from "@material-ui/core/Button";
|
|
||||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { Button, ImageList, InputLabel, ImageListItem } from "@mui/material";
|
|
||||||
import MessageList from "./MessageList";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
|
|
||||||
import toast from "react-hot-toast";
|
|
||||||
const SupportReply = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [data, setData] = useState({
|
|
||||||
user: "admin",
|
|
||||||
replyDate: "",
|
|
||||||
message: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }));
|
|
||||||
};
|
|
||||||
const options = {
|
|
||||||
weekday: "short", // Abbreviated weekday (e.g., "Tue")
|
|
||||||
day: "numeric", // Numeric day (e.g., "5")
|
|
||||||
month: "short", // Abbreviated month (e.g., "Mar")
|
|
||||||
year: "numeric", // Numeric year (e.g., "2024")
|
|
||||||
hour: "numeric", // Numeric hour (e.g., "10")
|
|
||||||
minute: "2-digit", // Two-digit minute (e.g., "27")
|
|
||||||
hour12: true, // Use 12-hour clock (true/false)
|
|
||||||
};
|
|
||||||
|
|
||||||
const { ticketID } = useParams();
|
|
||||||
|
|
||||||
|
|
||||||
const [ticketDetails, setticketDetails] = useState(null);
|
|
||||||
const [fetchData, setFetchData] = useState(false);
|
|
||||||
|
|
||||||
const getSupportTicketDetails = async () => {
|
|
||||||
// console.log(ticketID);
|
|
||||||
axios
|
|
||||||
.get(`/api/support/getOne/${ticketID}`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
// console.log(res?.data);
|
|
||||||
// setticketDetails(res.data?.support);
|
|
||||||
// setTicket(res.data?.support);
|
|
||||||
console.log(res.data?.support);
|
|
||||||
getuserName(res.data?.support);
|
|
||||||
// setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: "please login to access the resource or refresh the page ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
// setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// ************************************
|
|
||||||
// updating message in backend************
|
|
||||||
const handleSubmit = () => {
|
|
||||||
if (data.message.trim() === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Fill all mandatory fields",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
const formData = {
|
|
||||||
message: data.message,
|
|
||||||
replyDate: new Date().toLocaleString("en-US", options),
|
|
||||||
user: "admin",
|
|
||||||
};
|
|
||||||
axios
|
|
||||||
.patch(
|
|
||||||
`/api/support/update/${ticketID}`,
|
|
||||||
{
|
|
||||||
message: formData,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
toast.success("Message Sent successfully!");
|
|
||||||
setLoading(false);
|
|
||||||
setData({ message: "" });
|
|
||||||
setFetchData(true);
|
|
||||||
navigate("/support/request", { replace: true });
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
swal({
|
|
||||||
title: "Error",
|
|
||||||
text: "Something went wrong",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// ************************************
|
|
||||||
const getuserName = async (ticket) => {
|
|
||||||
try {
|
|
||||||
const userId = ticket.addedBy;
|
|
||||||
let resp = await axios.get(`/api/v1/admin/user/${userId}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
console.log(resp?.data?.user?.name);
|
|
||||||
const userName = resp?.data?.user?.name;
|
|
||||||
const userMailId = resp?.data?.user?.email;
|
|
||||||
// console.log(userName);
|
|
||||||
// Update support ticket with user name
|
|
||||||
const ticketWithUserName = {
|
|
||||||
...ticket,
|
|
||||||
userName: userName,
|
|
||||||
userMailId: userMailId,
|
|
||||||
};
|
|
||||||
setticketDetails(ticketWithUserName);
|
|
||||||
} catch (error) {
|
|
||||||
// Handle errors
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
getSupportTicketDetails();
|
|
||||||
setFetchData(false);
|
|
||||||
}, [fetchData]);
|
|
||||||
|
|
||||||
// ************************************
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Support Chat
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
<div className="page-title-right">
|
|
||||||
{/* <Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSubmit()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{loading ? "Loading" : "Submit"}
|
|
||||||
</Button> */}
|
|
||||||
{/* <Button
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Are you sure you want to go back?",
|
|
||||||
icon: "error",
|
|
||||||
buttons: ["No", "Yes"], // Specify the buttons array
|
|
||||||
dangerMode: true,
|
|
||||||
}).then((value) => {
|
|
||||||
if (value) {
|
|
||||||
navigate("/support/request", { replace: true });
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12 col-md-12 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Ticket ID: {ticketDetails?.ticketId}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
User ID: {ticketDetails?.addedBy}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
User Name: {ticketDetails?.userName}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
User MailId: {ticketDetails?.userMailId}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Date and Time: {ticketDetails?.createdOn}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Subject: {ticketDetails?.subject}
|
|
||||||
</InputLabel>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Description:{" "}
|
|
||||||
{ticketDetails?.description
|
|
||||||
? ticketDetails?.description
|
|
||||||
: "No Description"}
|
|
||||||
</InputLabel>
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
{ticketDetails?.image?.length > 0 && (
|
|
||||||
<div>
|
|
||||||
<InputLabel htmlFor="name" sx={{ mt: 1, mb: 2 }}>
|
|
||||||
Image:
|
|
||||||
</InputLabel>
|
|
||||||
<ImageList sx={{ width: 500 }} cols={3} rowHeight={164}>
|
|
||||||
{ticketDetails?.image?.map((item) => (
|
|
||||||
<ImageListItem key={item.public_id}>
|
|
||||||
<img
|
|
||||||
srcSet={`${item.url}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`}
|
|
||||||
src={`${item.url}?w=164&h=164&fit=crop&auto=format`}
|
|
||||||
alt={item.title || "No image"}
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</ImageListItem>
|
|
||||||
))}
|
|
||||||
</ImageList>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
{ticketDetails && (
|
|
||||||
<MessageList messages={ticketDetails?.message} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Message *
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="message"
|
|
||||||
rows="10"
|
|
||||||
cols="100"
|
|
||||||
value={data.message}
|
|
||||||
placeholder="your message..."
|
|
||||||
maxLength="500"
|
|
||||||
onChange={(e) => handleChange(e)}
|
|
||||||
></textarea>
|
|
||||||
|
|
||||||
{data.message ? (
|
|
||||||
<>
|
|
||||||
<small className="charLeft mt-4 fst-italic">
|
|
||||||
{500 - data.message.length} characters left
|
|
||||||
</small>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSubmit()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{loading ? "Loading" : "Submit"}
|
|
||||||
</Button>
|
|
||||||
{/* <Link to="/support/request"> */}
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Are you sure you want to go back?",
|
|
||||||
icon: "error",
|
|
||||||
buttons: ["No", "Yes"], // Specify the buttons array
|
|
||||||
dangerMode: true,
|
|
||||||
}).then((value) => {
|
|
||||||
if (value) {
|
|
||||||
navigate("/support/request", { replace: true });
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
{/* </Link> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SupportReply;
|
|
@ -1,428 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
|
|
||||||
import { CircularProgress, TextField } from "@material-ui/core";
|
|
||||||
import { cilSearch } from "@coreui/icons";
|
|
||||||
import CIcon from "@coreui/icons-react";
|
|
||||||
import Fuse from "fuse.js";
|
|
||||||
const SupportRequest = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [SupportRequestsData, setSupportRequestsData] = useState([]);
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
|
||||||
const [showData, setShowData] = useState(SupportRequestsData);
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (searchTerm !== "") {
|
|
||||||
let searchedResult = [];
|
|
||||||
searchedResult = SupportRequestsData.filter((item) =>
|
|
||||||
item.ticketId.toString().includes(searchTerm)
|
|
||||||
);
|
|
||||||
|
|
||||||
setShowData(searchedResult);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getSupportTicketsData();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}, [searchTerm]);
|
|
||||||
|
|
||||||
const handleShowEntries = (e) => {
|
|
||||||
setCurrentPage(1);
|
|
||||||
setItemPerPage(e.target.value);
|
|
||||||
};
|
|
||||||
const getSupportTicketsData = async () => {
|
|
||||||
axios
|
|
||||||
.get(`/api/support/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
|
|
||||||
setSupportRequestsData(
|
|
||||||
res.data?.support.filter((ticket) => ticket.status === "Open")
|
|
||||||
);
|
|
||||||
// setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: "please login to access the resource or refresh the page ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
React.useEffect(() => {
|
|
||||||
setLoading(true);
|
|
||||||
getSupportTicketsData();
|
|
||||||
}, [token]);
|
|
||||||
const statusupdate = (ticketId) => {
|
|
||||||
axios
|
|
||||||
.patch(
|
|
||||||
`/api/support/update/${ticketId}`,
|
|
||||||
{
|
|
||||||
status: "Close",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Success",
|
|
||||||
text: "Ticket Closed Successfully",
|
|
||||||
icon: "success",
|
|
||||||
button: "Close",
|
|
||||||
});
|
|
||||||
getSupportTicketsData();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
swal({
|
|
||||||
title: "Error",
|
|
||||||
text: "Something went wrong",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// const loadData = () => {
|
|
||||||
const indexOfLastPost = currentPage * itemPerPage;
|
|
||||||
const indexOfFirstPost = indexOfLastPost - itemPerPage;
|
|
||||||
setShowData(SupportRequestsData.slice(indexOfFirstPost, indexOfLastPost));
|
|
||||||
setLoading(false);
|
|
||||||
// };
|
|
||||||
// loadData();
|
|
||||||
}, [currentPage, itemPerPage, SupportRequestsData]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Customer Support Requests
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div
|
|
||||||
className="card-body
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div className="d-flex align-items-center">
|
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-sm-12 col-md-12">
|
|
||||||
<div className="dataTables_length">
|
|
||||||
<label className="w-auto">
|
|
||||||
Show
|
|
||||||
<select
|
|
||||||
style={{ width: "50px" }}
|
|
||||||
name=""
|
|
||||||
onChange={(e) => handleShowEntries(e)}
|
|
||||||
className="select-w custom-select custom-select-sm form-control form-control-sm"
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="ml-2 mt-2">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/support/request`, {
|
|
||||||
replace: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Open Requests
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/support/request/closed`, {
|
|
||||||
replace: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Close Requests
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{/* ********* */}
|
|
||||||
<div className="ml-5 mt-2">
|
|
||||||
<TextField
|
|
||||||
type="text"
|
|
||||||
placeholder="Search by Ticket ID"
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
|
||||||
/>
|
|
||||||
<CIcon
|
|
||||||
icon={cilSearch}
|
|
||||||
size="xl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/* ********** */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: "1px solid" }}
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
className="thead-info"
|
|
||||||
style={{ background: "rgb(140, 213, 213)" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<th className="text-start">Ticket ID</th>
|
|
||||||
<th className="text-start">Subject</th>
|
|
||||||
<th className="text-start">Created On</th>
|
|
||||||
<th className="text-start">Last Reply</th>
|
|
||||||
<th className="text-start">Status</th>
|
|
||||||
<th
|
|
||||||
className="text-start"
|
|
||||||
style={{ paddingLeft: "15px" }}
|
|
||||||
>
|
|
||||||
Action
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{!loading && showData.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="6">
|
|
||||||
<h5>No Open Tickets Available</h5>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="6">
|
|
||||||
{/* Loading... */}
|
|
||||||
<CircularProgress />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : (
|
|
||||||
showData.map((ticket, i) => {
|
|
||||||
return (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-start">{ticket.ticketId}</td>
|
|
||||||
<td className="text-start">{ticket.subject}</td>
|
|
||||||
<td className="text-start">{ticket.createdOn}</td>
|
|
||||||
<td className="text-start">{ticket.lastreply}</td>
|
|
||||||
<td className="text-start">{ticket.status}</td>
|
|
||||||
<td className="text-start">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(
|
|
||||||
`/support/request/reply/${ticket.ticketId}`,
|
|
||||||
{
|
|
||||||
replace: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Reply
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
color: "red",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Are you sure you want to Close This Ticket?",
|
|
||||||
icon: "error",
|
|
||||||
buttons: ["No", "Yes"],
|
|
||||||
dangerMode: true,
|
|
||||||
}).then((value) => {
|
|
||||||
if (value) {
|
|
||||||
statusupdate(ticket.ticketId);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);})
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-20">
|
|
||||||
<div className="col-sm-12 col-md-6 mb-20">
|
|
||||||
<div
|
|
||||||
className="dataTables_info"
|
|
||||||
id="datatable_info"
|
|
||||||
role="status"
|
|
||||||
aria-live="polite"
|
|
||||||
>
|
|
||||||
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
|
|
||||||
{Math.min(
|
|
||||||
currentPage * itemPerPage,
|
|
||||||
SupportRequestsData.length
|
|
||||||
)}{" "}
|
|
||||||
of {SupportRequestsData.length} entries
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-sm-12 col-md-6">
|
|
||||||
<div className="d-flex">
|
|
||||||
<ul className="pagination ms-auto">
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
currentPage === 1
|
|
||||||
? "paginate_button page-item previous disabled"
|
|
||||||
: "paginate_button page-item previous"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev - 1)}
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(currentPage - 1 < 1) && (
|
|
||||||
<li className="paginate_button page-item">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={(e) =>
|
|
||||||
setCurrentPage((prev) => prev - 1)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{currentPage - 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li className="paginate_button page-item active">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
>
|
|
||||||
{currentPage}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
SupportRequestsData.length - 1
|
|
||||||
) && (
|
|
||||||
<li className="paginate_button page-item ">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentPage((prev) => prev + 1);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{currentPage + 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
SupportRequestsData.length - 1
|
|
||||||
)
|
|
||||||
? "paginate_button page-item next"
|
|
||||||
: "paginate_button page-item next disabled"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev + 1)}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SupportRequest;
|
|
@ -1,379 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import { CircularProgress, TextField } from "@material-ui/core";
|
|
||||||
import { cilSearch } from "@coreui/icons";
|
|
||||||
import CIcon from "@coreui/icons-react";
|
|
||||||
import Fuse from "fuse.js";
|
|
||||||
const SupportRequestClosed = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [success, setSuccess] = useState(true);
|
|
||||||
const [status, setStatus] = useState("");
|
|
||||||
const [SupportRequestsData, setSupportRequestsData] = useState([]);
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
|
||||||
const [showData, setShowData] = useState(SupportRequestsData);
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (searchTerm !== "") {
|
|
||||||
let searchedResult = [];
|
|
||||||
searchedResult = SupportRequestsData.filter((item) =>
|
|
||||||
item.ticketId.toString().includes(searchTerm)
|
|
||||||
);
|
|
||||||
|
|
||||||
setShowData(searchedResult);
|
|
||||||
} else {
|
|
||||||
getSupportTicketsData();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}, [searchTerm]);
|
|
||||||
|
|
||||||
const handleShowEntries = (e) => {
|
|
||||||
setCurrentPage(1);
|
|
||||||
setItemPerPage(e.target.value);
|
|
||||||
};
|
|
||||||
const [ticketsData, setticketsData] = React.useState([]);
|
|
||||||
const getSupportTicketsData = async () => {
|
|
||||||
axios
|
|
||||||
.get(`/api/support/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setSupportRequestsData(
|
|
||||||
res.data?.support.filter((ticket) => ticket.status === "Close")
|
|
||||||
);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: "please login to access the resource or refresh the page ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
React.useEffect(() => {
|
|
||||||
setLoading(true);
|
|
||||||
getSupportTicketsData();
|
|
||||||
}, [token]);
|
|
||||||
|
|
||||||
// console.log(showData);
|
|
||||||
|
|
||||||
//********************************* */
|
|
||||||
useEffect(() => {
|
|
||||||
const loadData = () => {
|
|
||||||
const indexOfLastPost = currentPage * itemPerPage;
|
|
||||||
const indexOfFirstPost = indexOfLastPost - itemPerPage;
|
|
||||||
setShowData(SupportRequestsData.slice(indexOfFirstPost, indexOfLastPost));
|
|
||||||
};
|
|
||||||
loadData();
|
|
||||||
}, [currentPage, itemPerPage, SupportRequestsData]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Closed Customer Support Requests
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div
|
|
||||||
className="card-body
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div className="d-flex align-items-center">
|
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-sm-12 col-md-12">
|
|
||||||
<div className="dataTables_length">
|
|
||||||
<label className="w-auto">
|
|
||||||
Show
|
|
||||||
<select
|
|
||||||
style={{ width: "50px" }}
|
|
||||||
name=""
|
|
||||||
onChange={(e) => handleShowEntries(e)}
|
|
||||||
className="select-w custom-select custom-select-sm form-control form-control-sm"
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="ml-2 mt-2">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/support/request`, {
|
|
||||||
replace: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Open Requests
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="error"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
color: "red",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/support/request/closed`, {
|
|
||||||
replace: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Close Requests
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{/* ********* */}
|
|
||||||
<div className="ml-5 mt-2">
|
|
||||||
<TextField
|
|
||||||
type="text"
|
|
||||||
placeholder="Search by Ticket ID"
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
|
||||||
/>
|
|
||||||
<CIcon
|
|
||||||
icon={cilSearch}
|
|
||||||
size="xl"
|
|
||||||
// onClick={() => handleSearch(searchTerm)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/* ********** */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: "1px solid" }}
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
className="thead-info"
|
|
||||||
style={{ background: "rgb(140, 213, 213)" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<th className="text-start">Ticket ID</th>
|
|
||||||
<th className="text-start">Subject</th>
|
|
||||||
<th className="text-start">Created On</th>
|
|
||||||
<th className="text-start">Last Reply</th>
|
|
||||||
<th className="text-start">Status</th>
|
|
||||||
<th
|
|
||||||
className="text-start"
|
|
||||||
style={{ paddingLeft: "15px" }}
|
|
||||||
>
|
|
||||||
Action
|
|
||||||
</th>
|
|
||||||
{/* <th className="text-start">Action</th> */}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
{!loading && showData.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="6">
|
|
||||||
<h5>No Close Tickets Available</h5>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="6">
|
|
||||||
{/* Loading... */}
|
|
||||||
<CircularProgress />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : (
|
|
||||||
showData.map((ticket, i) => {
|
|
||||||
return (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-start">
|
|
||||||
{ticket.ticketId}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">{ticket.subject}</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{ticket.createdOn}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{ticket.lastreply}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">{ticket.status}</td>
|
|
||||||
<td className="text-start">
|
|
||||||
<Link
|
|
||||||
to={`/support/request/closed/${ticket.ticketId}`}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
View
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-20">
|
|
||||||
<div className="col-sm-12 col-md-6 mb-20">
|
|
||||||
<div
|
|
||||||
className="dataTables_info"
|
|
||||||
id="datatable_info"
|
|
||||||
role="status"
|
|
||||||
aria-live="polite"
|
|
||||||
>
|
|
||||||
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
|
|
||||||
{Math.min(
|
|
||||||
currentPage * itemPerPage,
|
|
||||||
SupportRequestsData.length
|
|
||||||
)}{" "}
|
|
||||||
of {SupportRequestsData.length} entries
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-sm-12 col-md-6">
|
|
||||||
<div className="d-flex">
|
|
||||||
<ul className="pagination ms-auto">
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
currentPage === 1
|
|
||||||
? "paginate_button page-item previous disabled"
|
|
||||||
: "paginate_button page-item previous"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev - 1)}
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(currentPage - 1 < 1) && (
|
|
||||||
<li className="paginate_button page-item">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={(e) =>
|
|
||||||
setCurrentPage((prev) => prev - 1)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{currentPage - 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li className="paginate_button page-item active">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
>
|
|
||||||
{currentPage}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
SupportRequestsData.length - 1
|
|
||||||
) && (
|
|
||||||
<li className="paginate_button page-item ">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentPage((prev) => prev + 1);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{currentPage + 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
SupportRequestsData.length - 1
|
|
||||||
)
|
|
||||||
? "paginate_button page-item next"
|
|
||||||
: "paginate_button page-item next disabled"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev + 1)}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SupportRequestClosed;
|
|
@ -1,394 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import ReactQuill from "react-quill";
|
|
||||||
import "react-quill/dist/quill.snow.css";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
const TOOLBAR_OPTIONS = [
|
|
||||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
||||||
[{ font: [] }],
|
|
||||||
[{ list: "ordered" }, { list: "bullet" }],
|
|
||||||
["bold", "italic", "underline", "strike"],
|
|
||||||
[{ color: [] }, { background: [] }],
|
|
||||||
[{ align: [] }],
|
|
||||||
[{ script: "super" }, { script: "sub" }],
|
|
||||||
["undo", "redo"],
|
|
||||||
];
|
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
import { Box, TextField, Checkbox, FormControlLabel } from "@mui/material";
|
|
||||||
|
|
||||||
const EditPanel1 = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [displayPanel, setDisplayPanel] = useState(false);
|
|
||||||
const [content, setContent] = useState("");
|
|
||||||
const [olderContent, setOlderContent] = useState("");
|
|
||||||
const [image, setimage] = useState(null);
|
|
||||||
const [title, setTitle] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [newUpdatedImages, setNewUpdatedImages] = useState(null);
|
|
||||||
const [Img, setImg] = useState(true);
|
|
||||||
const [id, setId] = useState(null);
|
|
||||||
|
|
||||||
const handleContentChange = (content, delta, source, editor) => {
|
|
||||||
setContent(editor.getHTML());
|
|
||||||
};
|
|
||||||
//get Blogdata
|
|
||||||
const getPanel = async () => {
|
|
||||||
try {
|
|
||||||
const res = await axios.get(`/api/panel/panel1/get`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
setTitle(res?.data?.panel1[0]?.title);
|
|
||||||
setimage(res?.data?.panel1[0]?.image);
|
|
||||||
setContent(res?.data?.panel1[0]?.content);
|
|
||||||
setOlderContent(res?.data?.panel1[0]?.content);
|
|
||||||
setDisplayPanel(res?.data?.panel1[0]?.displayPanel);
|
|
||||||
setId(res?.data?.panel1[0]?._id);
|
|
||||||
setImg(false);
|
|
||||||
} catch (err) {
|
|
||||||
swal({
|
|
||||||
title: "Error",
|
|
||||||
text: "Unable to fetch the panel content",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPanel();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files;
|
|
||||||
// Reset error state
|
|
||||||
setError("");
|
|
||||||
|
|
||||||
// Check if more than one image is selected
|
|
||||||
if (files.length > 1 || Img === false || newUpdatedImages !== null) {
|
|
||||||
setError("You can only upload one image.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
const file = files[0]; // Only one file is selected, so we get the first one
|
|
||||||
|
|
||||||
if (allowedTypes.includes(file.type)) {
|
|
||||||
setNewUpdatedImages(file);
|
|
||||||
setimage(file);
|
|
||||||
} else {
|
|
||||||
setError("Please upload only PNG, JPEG, or JPG files.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handelDelete = async (public_id) => {
|
|
||||||
console.log(public_id);
|
|
||||||
const ary = public_id?.split("/");
|
|
||||||
setNewUpdatedImages(null);
|
|
||||||
|
|
||||||
const res = await axios.delete(
|
|
||||||
`/api/v1/blog/deleteImage/jatinMor/Blog/${ary[2]}`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (res) {
|
|
||||||
setimage(null);
|
|
||||||
setImg(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const addContent = async () => {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
formData.append("image", image);
|
|
||||||
|
|
||||||
const response = await axios.post("/api/panel/panel1/add", formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (response.status == 201) {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "Panel 1 added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateContent = () => {
|
|
||||||
if (title === "" || content === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Fill all mandatory fields",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
|
|
||||||
if (newUpdatedImages !== null) {
|
|
||||||
formData.append("image", newUpdatedImages);
|
|
||||||
}
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/panel/panel1/update/${id}`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/form-data",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Updated",
|
|
||||||
text: " Updated successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoading(false);
|
|
||||||
|
|
||||||
const message = err.response?.data?.message
|
|
||||||
? err.response?.data?.message
|
|
||||||
: "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: message,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveClick = async () => {
|
|
||||||
if (olderContent.length === 0) {
|
|
||||||
addContent();
|
|
||||||
} else {
|
|
||||||
updateContent();
|
|
||||||
}
|
|
||||||
// // Reload terms and conditions
|
|
||||||
// await getPrivacyPolicy();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
setDisplayPanel(event.target.checked);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Panel 1
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={displayPanel}
|
|
||||||
onChange={handleChange}
|
|
||||||
inputProps={{ "aria-label": "controlled" }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Display Panel"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSaveClick()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{"Save"}
|
|
||||||
</Button>
|
|
||||||
<Link to="/home">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Panel 1 Title
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="name"
|
|
||||||
placeholder="Enter title"
|
|
||||||
value={title}
|
|
||||||
onChange={(e) => setTitle(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="image" className="form-label">
|
|
||||||
Panel Image
|
|
||||||
</label>
|
|
||||||
<Box>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
multiple
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "100px",
|
|
||||||
height: "100px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
marginLeft: "0.5rem",
|
|
||||||
marginTop: "0.5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
</Box>
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<div>
|
|
||||||
<strong className="fs-6 fst-italic">
|
|
||||||
*You cannot upload more than 1 image
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Box style={{ display: "flex" }}>
|
|
||||||
{image !== null ? (
|
|
||||||
<Box marginRight={"2rem"}>
|
|
||||||
<img
|
|
||||||
src={
|
|
||||||
image?.url ||
|
|
||||||
(newUpdatedImages &&
|
|
||||||
URL.createObjectURL(newUpdatedImages)) ||
|
|
||||||
null
|
|
||||||
}
|
|
||||||
alt="Panel Image"
|
|
||||||
style={{
|
|
||||||
width: 350,
|
|
||||||
height: 270,
|
|
||||||
|
|
||||||
marginBottom: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{console.log("image", image)}
|
|
||||||
|
|
||||||
{ image?.public_id&&<DeleteSharpIcon
|
|
||||||
onClick={() => handelDelete(image?.public_id)}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>}
|
|
||||||
</Box>
|
|
||||||
) : null}
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<label>Panel Content</label>
|
|
||||||
<ReactQuill
|
|
||||||
theme="snow"
|
|
||||||
value={content}
|
|
||||||
onChange={handleContentChange}
|
|
||||||
modules={{ toolbar: TOOLBAR_OPTIONS }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditPanel1;
|
|
@ -1,409 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import ReactQuill from "react-quill";
|
|
||||||
import "react-quill/dist/quill.snow.css";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
const TOOLBAR_OPTIONS = [
|
|
||||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
||||||
[{ font: [] }],
|
|
||||||
[{ list: "ordered" }, { list: "bullet" }],
|
|
||||||
["bold", "italic", "underline", "strike"],
|
|
||||||
[{ color: [] }, { background: [] }],
|
|
||||||
[{ align: [] }],
|
|
||||||
[{ script: "super" }, { script: "sub" }],
|
|
||||||
["undo", "redo"],
|
|
||||||
];
|
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
import {
|
|
||||||
Box,
|
|
||||||
TextField,
|
|
||||||
Checkbox,
|
|
||||||
FormControlLabel
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
const EditPanel2 = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [displayPanel, setDisplayPanel] = useState(false);
|
|
||||||
const [content, setContent] = useState("");
|
|
||||||
const [olderContent, setOlderContent] = useState("");
|
|
||||||
const [image, setimage] = useState("");
|
|
||||||
const [title, setTitle] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [newUpdatedImages, setNewUpdatedImages] = useState(null);
|
|
||||||
const [Img, setImg] = useState(true);
|
|
||||||
const [id, setId] = useState(null);
|
|
||||||
|
|
||||||
const handleContentChange = (content, delta, source, editor) => {
|
|
||||||
setContent(editor.getHTML());
|
|
||||||
};
|
|
||||||
//get panel data
|
|
||||||
const getPanel = async () => {
|
|
||||||
try {
|
|
||||||
const res = await axios.get(`/api/panel/panel2/get`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (res?.status === 200) {
|
|
||||||
setTitle(res?.data?.panel2[0]?.title);
|
|
||||||
setimage(res?.data?.panel2[0]?.image);
|
|
||||||
setContent(res?.data?.panel2[0]?.content);
|
|
||||||
setOlderContent(res?.data?.panel2[0]?.content);
|
|
||||||
setDisplayPanel(res?.data?.panel2[0]?.displayPanel);
|
|
||||||
setId(res?.data?.panel2[0]?._id);
|
|
||||||
setImg(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
swal({
|
|
||||||
title: "Error",
|
|
||||||
text: "Unable to fetch the panel content",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPanel();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files;
|
|
||||||
// Reset error state
|
|
||||||
setError("");
|
|
||||||
|
|
||||||
// Check if more than one image is selected
|
|
||||||
if (files.length > 1 || newUpdatedImages !== null) {
|
|
||||||
setError("You can only upload one image.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
const file = files[0]; // Only one file is selected, so we get the first one
|
|
||||||
|
|
||||||
if (allowedTypes.includes(file.type)) {
|
|
||||||
setNewUpdatedImages(file);
|
|
||||||
setimage(file);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
setError("Please upload only PNG, JPEG, or JPG files.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handelDelete = async (public_id) => {
|
|
||||||
const ary = public_id?.split("/");
|
|
||||||
setNewUpdatedImages(null);
|
|
||||||
|
|
||||||
const res = await axios.delete(
|
|
||||||
`/api/v1/blog/deleteImage/jatinMor/Blog/${ary[2]}`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (res) {
|
|
||||||
setimage(null);
|
|
||||||
setImg(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const addContent = async () => {
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
formData.append("image", image);
|
|
||||||
|
|
||||||
|
|
||||||
const response = await axios.post(
|
|
||||||
"/api/panel/panel2/add",
|
|
||||||
formData,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (response.status == 201) {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "Panel 2 added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateContent = () => {
|
|
||||||
if (title === "" || content === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Fill all mandatory fields",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
|
|
||||||
if (newUpdatedImages !== null) {
|
|
||||||
formData.append("image", newUpdatedImages);
|
|
||||||
}
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/panel/panel2/update/${id}`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/form-data",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Updated",
|
|
||||||
text: " Updated successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoading(false);
|
|
||||||
|
|
||||||
const message = err.response?.data?.message
|
|
||||||
? err.response?.data?.message
|
|
||||||
: "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: message,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveClick = async () => {
|
|
||||||
console.log(olderContent)
|
|
||||||
if (olderContent?.length === 0 || olderContent===undefined) {
|
|
||||||
addContent();
|
|
||||||
} else {
|
|
||||||
updateContent();
|
|
||||||
}
|
|
||||||
// // Reload terms and conditions
|
|
||||||
// await getPrivacyPolicy();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
setDisplayPanel(event.target.checked);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Panel 2
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={displayPanel}
|
|
||||||
onChange={handleChange}
|
|
||||||
inputProps={{ 'aria-label': 'controlled' }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Display Panel"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSaveClick()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{"Save"}
|
|
||||||
</Button>
|
|
||||||
<Link to="/home">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Panel 2 Title
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="name"
|
|
||||||
placeholder="Enter title"
|
|
||||||
value={title}
|
|
||||||
onChange={(e) => setTitle(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="image" className="form-label">
|
|
||||||
Panel Image
|
|
||||||
</label>
|
|
||||||
<Box>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
multiple
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "100px",
|
|
||||||
height: "100px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
marginLeft: "0.5rem",
|
|
||||||
marginTop: "0.5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
</Box>
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<div>
|
|
||||||
<strong className="fs-6 fst-italic">
|
|
||||||
*You cannot upload more than 1 image
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Box style={{ display: "flex" }}>
|
|
||||||
{image && (
|
|
||||||
<Box marginRight={"2rem"}>
|
|
||||||
<img
|
|
||||||
src={newUpdatedImages ? URL.createObjectURL(newUpdatedImages) : image ? image?.url : ""}
|
|
||||||
alt="Panel Image"
|
|
||||||
style={{
|
|
||||||
width: 350,
|
|
||||||
height: 270,
|
|
||||||
|
|
||||||
marginBottom: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{ image?.public_id&& <DeleteSharpIcon
|
|
||||||
onClick={() => handelDelete(image?.public_id)}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<label>Panel Content</label>
|
|
||||||
<ReactQuill
|
|
||||||
theme="snow"
|
|
||||||
value={content}
|
|
||||||
onChange={handleContentChange}
|
|
||||||
modules={{ toolbar: TOOLBAR_OPTIONS }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditPanel2;
|
|
@ -1,407 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import ReactQuill from "react-quill";
|
|
||||||
import "react-quill/dist/quill.snow.css";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
const TOOLBAR_OPTIONS = [
|
|
||||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
||||||
[{ font: [] }],
|
|
||||||
[{ list: "ordered" }, { list: "bullet" }],
|
|
||||||
["bold", "italic", "underline", "strike"],
|
|
||||||
[{ color: [] }, { background: [] }],
|
|
||||||
[{ align: [] }],
|
|
||||||
[{ script: "super" }, { script: "sub" }],
|
|
||||||
["undo", "redo"],
|
|
||||||
];
|
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
import {
|
|
||||||
Box,
|
|
||||||
TextField,
|
|
||||||
Checkbox,
|
|
||||||
FormControlLabel
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
const EditPanel3 = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [displayPanel, setDisplayPanel] = useState(false);
|
|
||||||
const [content, setContent] = useState("");
|
|
||||||
const [olderContent, setOlderContent] = useState("");
|
|
||||||
const [image, setimage] = useState("");
|
|
||||||
const [title, setTitle] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [newUpdatedImages, setNewUpdatedImages] = useState(null);
|
|
||||||
const [Img, setImg] = useState(true);
|
|
||||||
const [id, setId] = useState(null);
|
|
||||||
|
|
||||||
const handleContentChange = (content, delta, source, editor) => {
|
|
||||||
setContent(editor.getHTML());
|
|
||||||
};
|
|
||||||
//get Blogdata
|
|
||||||
const getPanel = async () => {
|
|
||||||
try {
|
|
||||||
const res = await axios.get(`/api/panel/panel3/get`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (res?.status === 200) {
|
|
||||||
setTitle(res?.data?.panel3[0]?.title);
|
|
||||||
setimage(res?.data?.panel3[0]?.image);
|
|
||||||
setContent(res?.data?.panel3[0]?.content);
|
|
||||||
setOlderContent(res?.data?.panel3[0]?.content);
|
|
||||||
setDisplayPanel(res?.data?.panel3[0]?.displayPanel);
|
|
||||||
setId(res?.data?.panel3[0]?._id);
|
|
||||||
setImg(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
swal({
|
|
||||||
title: "Error",
|
|
||||||
text: "Unable to fetch the panel content",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPanel();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files;
|
|
||||||
// Reset error state
|
|
||||||
setError("");
|
|
||||||
|
|
||||||
// Check if more than one image is selected
|
|
||||||
if (files.length > 1 || Img === false || newUpdatedImages !== null) {
|
|
||||||
setError("You can only upload one image.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
const file = files[0]; // Only one file is selected, so we get the first one
|
|
||||||
|
|
||||||
if (allowedTypes.includes(file.type)) {
|
|
||||||
setNewUpdatedImages(file);
|
|
||||||
setimage(file);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
setError("Please upload only PNG, JPEG, or JPG files.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handelDelete = async (public_id) => {
|
|
||||||
const ary = public_id?.split("/");
|
|
||||||
setNewUpdatedImages(null);
|
|
||||||
|
|
||||||
const res = await axios.delete(
|
|
||||||
`/api/v1/blog/deleteImage/jatinMor/Blog/${ary[2]}`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (res) {
|
|
||||||
setimage(null);
|
|
||||||
setImg(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const addContent = async () => {
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
formData.append("image", image);
|
|
||||||
|
|
||||||
|
|
||||||
const response = await axios.post(
|
|
||||||
"/api/panel/panel3/add",
|
|
||||||
formData,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (response.status == 201) {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "Panel 3 added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateContent = () => {
|
|
||||||
if (title === "" || content === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Fill all mandatory fields",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
|
|
||||||
if (newUpdatedImages !== null) {
|
|
||||||
formData.append("image", newUpdatedImages);
|
|
||||||
}
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/panel/panel3/update/${id}`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/form-data",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Updated",
|
|
||||||
text: " Updated successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoading(false);
|
|
||||||
|
|
||||||
const message = err.response?.data?.message
|
|
||||||
? err.response?.data?.message
|
|
||||||
: "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: message,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveClick = async () => {
|
|
||||||
if (olderContent.length === 0) {
|
|
||||||
addContent();
|
|
||||||
} else {
|
|
||||||
updateContent();
|
|
||||||
}
|
|
||||||
// // Reload terms and conditions
|
|
||||||
// await getPrivacyPolicy();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
setDisplayPanel(event.target.checked);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Panel 3
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={displayPanel}
|
|
||||||
onChange={handleChange}
|
|
||||||
inputProps={{ 'aria-label': 'controlled' }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Display Panel"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSaveClick()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{"Save"}
|
|
||||||
</Button>
|
|
||||||
<Link to="/home">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Panel 3 Title
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="name"
|
|
||||||
placeholder="Enter title"
|
|
||||||
value={title}
|
|
||||||
onChange={(e) => setTitle(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="image" className="form-label">
|
|
||||||
Panel Image
|
|
||||||
</label>
|
|
||||||
<Box>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
multiple
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "100px",
|
|
||||||
height: "100px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
marginLeft: "0.5rem",
|
|
||||||
marginTop: "0.5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
</Box>
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<div>
|
|
||||||
<strong className="fs-6 fst-italic">
|
|
||||||
*You cannot upload more than 1 image
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Box style={{ display: "flex" }}>
|
|
||||||
{image && (
|
|
||||||
<Box marginRight={"2rem"}>
|
|
||||||
<img
|
|
||||||
src={newUpdatedImages ? URL.createObjectURL(newUpdatedImages) : image ? image?.url : ""}
|
|
||||||
alt="Panel Image"
|
|
||||||
style={{
|
|
||||||
width: 350,
|
|
||||||
height: 270,
|
|
||||||
|
|
||||||
marginBottom: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{ image?.public_id&&<DeleteSharpIcon
|
|
||||||
onClick={() => handelDelete(image?.public_id)}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<label>Panel Content</label>
|
|
||||||
<ReactQuill
|
|
||||||
theme="snow"
|
|
||||||
value={content}
|
|
||||||
onChange={handleContentChange}
|
|
||||||
modules={{ toolbar: TOOLBAR_OPTIONS }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditPanel3;
|
|
@ -1,402 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import ReactQuill from "react-quill";
|
|
||||||
import "react-quill/dist/quill.snow.css";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
const TOOLBAR_OPTIONS = [
|
|
||||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
|
||||||
[{ font: [] }],
|
|
||||||
[{ list: "ordered" }, { list: "bullet" }],
|
|
||||||
["bold", "italic", "underline", "strike"],
|
|
||||||
[{ color: [] }, { background: [] }],
|
|
||||||
[{ align: [] }],
|
|
||||||
[{ script: "super" }, { script: "sub" }],
|
|
||||||
["undo", "redo"],
|
|
||||||
];
|
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
import { Box, TextField, Checkbox, FormControlLabel } from "@mui/material";
|
|
||||||
|
|
||||||
const Editpanel4 = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [displayPanel, setDisplayPanel] = useState(false);
|
|
||||||
const [content, setContent] = useState("");
|
|
||||||
const [olderContent, setOlderContent] = useState("");
|
|
||||||
const [image, setimage] = useState("");
|
|
||||||
const [title, setTitle] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [newUpdatedImages, setNewUpdatedImages] = useState(null);
|
|
||||||
const [Img, setImg] = useState(true);
|
|
||||||
const [id, setId] = useState(null);
|
|
||||||
|
|
||||||
const handleContentChange = (content, delta, source, editor) => {
|
|
||||||
setContent(editor.getHTML());
|
|
||||||
};
|
|
||||||
//get Blogdata
|
|
||||||
const getPanel = async () => {
|
|
||||||
try {
|
|
||||||
const res = await axios.get(`/api/panel/panel4/get`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (res?.status === 200) {
|
|
||||||
setTitle(res?.data?.panel4[0]?.title);
|
|
||||||
if (
|
|
||||||
res?.data?.panel4[0]?.image !== undefined &&
|
|
||||||
res?.data?.panel4[0]?.image !== null
|
|
||||||
) {
|
|
||||||
setimage(res?.data?.panel4[0]?.image);
|
|
||||||
}
|
|
||||||
setContent(res?.data?.panel4[0]?.content);
|
|
||||||
setOlderContent(res?.data?.panel4[0]?.content);
|
|
||||||
setDisplayPanel(res?.data?.panel4[0]?.displayPanel);
|
|
||||||
setId(res?.data?.panel4[0]?._id);
|
|
||||||
setImg(false);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
swal({
|
|
||||||
title: "Error",
|
|
||||||
text: "Unable to fetch the panel content",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPanel();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files;
|
|
||||||
// Reset error state
|
|
||||||
setError("");
|
|
||||||
|
|
||||||
// Check if more than one image is selected
|
|
||||||
if (files.length > 1 || newUpdatedImages !== null) {
|
|
||||||
setError("You can only upload one image.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
const file = files[0]; // Only one file is selected, so we get the first one
|
|
||||||
|
|
||||||
if (allowedTypes.includes(file.type)) {
|
|
||||||
setNewUpdatedImages(file);
|
|
||||||
setimage(file);
|
|
||||||
} else {
|
|
||||||
setError("Please upload only PNG, JPEG, or JPG files.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handelDelete = async (public_id) => {
|
|
||||||
const ary = public_id?.split("/");
|
|
||||||
setNewUpdatedImages(null);
|
|
||||||
|
|
||||||
const res = await axios.delete(
|
|
||||||
`/api/v1/blog/deleteImage/jatinMor/Blog/${ary[2]}`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (res) {
|
|
||||||
setimage(null);
|
|
||||||
setImg(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const addContent = async () => {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
formData.append("image", image);
|
|
||||||
|
|
||||||
const response = await axios.post("/api/panel/panel4/add", formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (response.status == 201) {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "Panel 4 added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateContent = () => {
|
|
||||||
if (title === "" || content === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Fill all mandatory fields",
|
|
||||||
icon: "error",
|
|
||||||
button: "Close",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("title", title);
|
|
||||||
formData.append("content", content);
|
|
||||||
formData.append("displayPanel", displayPanel);
|
|
||||||
|
|
||||||
if (newUpdatedImages !== null) {
|
|
||||||
formData.append("image", newUpdatedImages);
|
|
||||||
}
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/panel/panel4/update/${id}`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/form-data",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Updated",
|
|
||||||
text: " Updated successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
setLoading(false);
|
|
||||||
|
|
||||||
const message = err.response?.data?.message
|
|
||||||
? err.response?.data?.message
|
|
||||||
: "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: message,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveClick = async () => {
|
|
||||||
if (!olderContent) {
|
|
||||||
addContent();
|
|
||||||
} else {
|
|
||||||
updateContent();
|
|
||||||
}
|
|
||||||
// // Reload terms and conditions
|
|
||||||
// await getPrivacyPolicy();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
setDisplayPanel(event.target.checked);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="container">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Panel 4
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "flex", gap: "1rem" }}>
|
|
||||||
<h4 className="mb-0"></h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={displayPanel}
|
|
||||||
onChange={handleChange}
|
|
||||||
inputProps={{ "aria-label": "controlled" }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Display Panel"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
marginRight: "5px",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSaveClick()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{"Save"}
|
|
||||||
</Button>
|
|
||||||
<Link to="/home">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<div className="mb-3">
|
|
||||||
<label htmlFor="title" className="form-label">
|
|
||||||
Panel 4 Title
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="form-control"
|
|
||||||
id="name"
|
|
||||||
placeholder="Enter title"
|
|
||||||
value={title}
|
|
||||||
onChange={(e) => setTitle(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="image" className="form-label">
|
|
||||||
Panel Image
|
|
||||||
</label>
|
|
||||||
<Box>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
multiple
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "100px",
|
|
||||||
height: "100px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
marginLeft: "0.5rem",
|
|
||||||
marginTop: "0.5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
</Box>
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<div>
|
|
||||||
<strong className="fs-6 fst-italic">
|
|
||||||
*You cannot upload more than 1 image
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Box style={{ display: "flex" }}>
|
|
||||||
{image && (
|
|
||||||
<Box marginRight={"2rem"}>
|
|
||||||
<img
|
|
||||||
src={
|
|
||||||
newUpdatedImages
|
|
||||||
? URL.createObjectURL(newUpdatedImages)
|
|
||||||
: image
|
|
||||||
? image?.url
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
alt="Panel Image"
|
|
||||||
style={{
|
|
||||||
width: 350,
|
|
||||||
height: 270,
|
|
||||||
|
|
||||||
marginBottom: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{image?.public_id && (
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => handelDelete(image?.public_id)}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
|
||||||
<div className="card h-100">
|
|
||||||
<div className="card-body px-5">
|
|
||||||
<label>Panel Content</label>
|
|
||||||
<ReactQuill
|
|
||||||
theme="snow"
|
|
||||||
value={content}
|
|
||||||
onChange={handleContentChange}
|
|
||||||
modules={{ toolbar: TOOLBAR_OPTIONS }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Editpanel4;
|
|
@ -1,165 +0,0 @@
|
|||||||
import {
|
|
||||||
Paper,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import axios from "axios";
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
const [displayPanel1,setDisplayPanel1] = useState("Not Displayed");
|
|
||||||
const [displayPanel2,setDisplayPanel2] = useState("Not Displayed");
|
|
||||||
const [displayPanel3,setDisplayPanel3] = useState("Not Displayed");
|
|
||||||
const [displayPanel4,setDisplayPanel4] = useState("Not Displayed");
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
let token = isAutheticated();
|
|
||||||
|
|
||||||
async function getPanelStatus(){
|
|
||||||
try {
|
|
||||||
setLoading(true)
|
|
||||||
let response1 = await axios.get('/api/panel/panel1/get', {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let response2 = await axios.get('/api/panel/panel2/get', {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let response3 = await axios.get('/api/panel/panel3/get', {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let response4 = await axios.get('/api/panel/panel4/get', {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(response1 && response2 && response3 && response4){
|
|
||||||
if(response1?.data?.panel1[0]?.displayPanel){
|
|
||||||
setDisplayPanel1("Displayed")
|
|
||||||
}
|
|
||||||
if(response2?.data?.panel2[0]?.displayPanel){
|
|
||||||
setDisplayPanel2("Displayed");
|
|
||||||
}
|
|
||||||
if(response3?.data?.panel3[0]?.displayPanel){
|
|
||||||
setDisplayPanel3("Displayed");
|
|
||||||
}
|
|
||||||
if(response4?.data?.panel4[0]?.displayPanel){
|
|
||||||
setDisplayPanel4("Displayed");
|
|
||||||
}
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
useEffect(()=>{
|
|
||||||
getPanelStatus()
|
|
||||||
},[])
|
|
||||||
|
|
||||||
const pages = [
|
|
||||||
{
|
|
||||||
name: "Panel 1",
|
|
||||||
action: "Edit",
|
|
||||||
path: "/home/panel-1",
|
|
||||||
status:displayPanel1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Panel 2",
|
|
||||||
action: "Edit",
|
|
||||||
path: "/home/panel-2",
|
|
||||||
status:displayPanel2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Panel 3",
|
|
||||||
action: "Edit",
|
|
||||||
path: "/home/panel-3",
|
|
||||||
status:displayPanel3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Panel 4",
|
|
||||||
action: "Edit",
|
|
||||||
path: "/home/panel-4",
|
|
||||||
status:displayPanel4
|
|
||||||
},
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="main-home">
|
|
||||||
<Typography variant="h6" fontWeight={"bold"}>
|
|
||||||
Home
|
|
||||||
</Typography>
|
|
||||||
<TableContainer component={Paper}>
|
|
||||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell style={{ fontWeight: "bold" }}>Page</TableCell>
|
|
||||||
<TableCell style={{ fontWeight: "bold" }} align="right">
|
|
||||||
Display Status
|
|
||||||
</TableCell>
|
|
||||||
<TableCell style={{ fontWeight: "bold" }} align="right">
|
|
||||||
Action
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{pages.map((row) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.name}
|
|
||||||
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
|
|
||||||
>
|
|
||||||
<TableCell component="th" scope="row">
|
|
||||||
{row.name}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="right" sx={{pr:4}}>
|
|
||||||
{loading ? "loading" : `${row.status}`}
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
<TableCell align="right">
|
|
||||||
{" "}
|
|
||||||
<Link to={row.path}>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-info btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mt-1
|
|
||||||
mx-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{row.action}
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,706 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Box,
|
|
||||||
IconButton,
|
|
||||||
Modal,
|
|
||||||
Pagination,
|
|
||||||
TextField,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
|
||||||
import { ClipLoader } from "react-spinners";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
|
||||||
import DeleteSharpIcon from "@mui/icons-material/DeleteSharp";
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
position: "absolute",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
width: 400,
|
|
||||||
bgcolor: "background.paper",
|
|
||||||
borderRadius: "0.5rem",
|
|
||||||
boxShadow: 24,
|
|
||||||
width: "500px",
|
|
||||||
};
|
|
||||||
|
|
||||||
const Banners = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [updating, setUpdating] = useState(true); // for loading state
|
|
||||||
// const [isUpdate, setIsUpdate] = useState(false); // for edit state
|
|
||||||
const [saveLoding, setSaveLoading] = useState(true);
|
|
||||||
const [edit, setEdit] = useState(false);
|
|
||||||
const [bannerName, setBannerName] = useState("");
|
|
||||||
const [bannerImage, setBannerImage] = useState("");
|
|
||||||
const [error, setError] = useState("");
|
|
||||||
const [bannerId, setBannerId] = useState("");
|
|
||||||
const [banner, setBanner] = useState([]);
|
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
|
||||||
const [page, setPage] = useState(1);
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [olderBannerName, setOlderBaannerName] = useState("");
|
|
||||||
const [olderImage, setOlderImage] = useState("");
|
|
||||||
|
|
||||||
const handleOpen = () => setOpen(true);
|
|
||||||
const handleClose = () => {
|
|
||||||
setOpen(false);
|
|
||||||
// setUpdating(false);
|
|
||||||
setEdit(false);
|
|
||||||
|
|
||||||
setBannerName("");
|
|
||||||
setBannerId("");
|
|
||||||
setOlderImage("");
|
|
||||||
setBannerImage("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const getBanner = async () => {
|
|
||||||
try {
|
|
||||||
const response = await axios.get("/api/shopImage/getImage", {
|
|
||||||
// headers: {
|
|
||||||
// Authorization: `Bearer ${token}`,
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status === 200) {
|
|
||||||
// console.log(response);
|
|
||||||
setBanner(response?.data?.image);
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: " please login to access the resource ",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getBanner();
|
|
||||||
}, []);
|
|
||||||
// }, [token, banner]);
|
|
||||||
|
|
||||||
const handleEditClick = (_id, bannerImage) => {
|
|
||||||
setOpen(true);
|
|
||||||
console.log("bannerImage", bannerImage);
|
|
||||||
setOlderImage(bannerImage);
|
|
||||||
|
|
||||||
setBannerId(_id);
|
|
||||||
setOlderBaannerName(bannerName);
|
|
||||||
setEdit(true);
|
|
||||||
// setUpdating(false);
|
|
||||||
};
|
|
||||||
// const bannerNamesArray = [];
|
|
||||||
// const setBannerNamesArray = () => {
|
|
||||||
// banner &&
|
|
||||||
// banner.map((banner) => {
|
|
||||||
// bannerNamesArray.push(banner.bannerName.toLowerCase());
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
// setBannerNamesArray();
|
|
||||||
|
|
||||||
const handleUpdate = () => {
|
|
||||||
// const filteredArrayNames = bannerNamesArray.filter(
|
|
||||||
// (item) => item !== olderBannerName.toLowerCase()
|
|
||||||
// );
|
|
||||||
// console.log(filteredArrayNames, "filter");
|
|
||||||
// const bannerExits = filteredArrayNames.includes(bannerName.toLowerCase());
|
|
||||||
// if (bannerExits) {
|
|
||||||
// swal({
|
|
||||||
// title: "Warning",
|
|
||||||
// text: "Banner already exists ",
|
|
||||||
// icon: "error",
|
|
||||||
// button: "Retry",
|
|
||||||
// dangerMode: true,
|
|
||||||
// });
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (!bannerImage && !olderImage) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please fill all the required fields!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setUpdating(false);
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
formData.append("bannerImage", bannerImage);
|
|
||||||
|
|
||||||
formData.append("olderImage", JSON.stringify(olderImage));
|
|
||||||
|
|
||||||
axios
|
|
||||||
.patch(`/api/shopImage/update/${bannerId}`, formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
// setUpdating(true);
|
|
||||||
// setIsUpdate(false);
|
|
||||||
handleClose();
|
|
||||||
setBannerId("");
|
|
||||||
setBannerName("");
|
|
||||||
setBannerImage("");
|
|
||||||
setOlderImage("");
|
|
||||||
setUpdating(true);
|
|
||||||
setEdit(false);
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "The banner was updated successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
// getCategories(); // Refresh the category list after updating
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
// console.log(err);
|
|
||||||
swal({
|
|
||||||
title: "Sorry, please try again",
|
|
||||||
text: err,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
setUpdating(true);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (_id) => {
|
|
||||||
swal({
|
|
||||||
title: "Are you sure?",
|
|
||||||
icon: "error",
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Yes", value: true },
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.delete(`/api/shopImage/delete/${_id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Congratulations!!",
|
|
||||||
text: "The banner was deleted successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
// getCategories(); // Refresh the category list after deleting
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "",
|
|
||||||
text: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSaveBanner = async () => {
|
|
||||||
// const bannerExits = bannerNamesArray.includes(bannerName.toLowerCase());
|
|
||||||
// if (bannerExits) {
|
|
||||||
// swal({
|
|
||||||
// title: "Warning",
|
|
||||||
// text: "Banner Already exits.",
|
|
||||||
// icon: "error",
|
|
||||||
// button: "Retry",
|
|
||||||
// dangerMode: true,
|
|
||||||
// });
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
if (!bannerImage) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please fill all the required fields!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSaveLoading(false);
|
|
||||||
setLoading(true);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("bannerName", bannerName);
|
|
||||||
formData.append("bannerImage", bannerImage);
|
|
||||||
|
|
||||||
axios
|
|
||||||
.post("/api/shopImage/add", formData, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/formdata",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status === 201) {
|
|
||||||
setOpen(false);
|
|
||||||
setLoading(false);
|
|
||||||
setSaveLoading(true);
|
|
||||||
setBannerName("");
|
|
||||||
setBannerImage("");
|
|
||||||
setOlderImage("");
|
|
||||||
swal({
|
|
||||||
title: "Added",
|
|
||||||
text: "New Banner added successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "OK",
|
|
||||||
});
|
|
||||||
// getCategories(); // Refresh the category list after adding
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setSaveLoading(true);
|
|
||||||
swal({
|
|
||||||
title: error,
|
|
||||||
text: "something went wrong",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// const getPageCount = () => {
|
|
||||||
// return Math.max(1, Math.ceil(banner?.length / itemPerPage));
|
|
||||||
// };
|
|
||||||
|
|
||||||
const handleFileChange = (e) => {
|
|
||||||
const files = e.target.files[0];
|
|
||||||
|
|
||||||
// Check file types and append to selectedFiles
|
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/jpg"];
|
|
||||||
if (allowedTypes.includes(files.type)) {
|
|
||||||
setBannerImage(files);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const handeldeleteImage = () => {
|
|
||||||
setBannerImage("");
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Shop Page Image
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="page-title-right">
|
|
||||||
{/* <Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={handleOpen}
|
|
||||||
// onClick={() => {
|
|
||||||
// navigate("/testimonial/new", { replace: true });
|
|
||||||
// }}
|
|
||||||
>
|
|
||||||
Add New Banner
|
|
||||||
</Button> */}
|
|
||||||
<Modal
|
|
||||||
open={open}
|
|
||||||
onClose={handleClose}
|
|
||||||
aria-labelledby="modal-modal-title"
|
|
||||||
aria-describedby="modal-modal-description"
|
|
||||||
>
|
|
||||||
<Box sx={style}>
|
|
||||||
{/* <Box p={2} display={"flex"}>
|
|
||||||
<Typography
|
|
||||||
id="modal-modal-title"
|
|
||||||
variant="body"
|
|
||||||
component="h2"
|
|
||||||
flex={1}
|
|
||||||
>
|
|
||||||
Banner Name
|
|
||||||
</Typography>
|
|
||||||
<IconButton onClick={() => handleClose()}>
|
|
||||||
<CloseIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Box> */}
|
|
||||||
{/* <hr /> */}
|
|
||||||
{/* <TextField
|
|
||||||
placeholder="Banner name"
|
|
||||||
value={bannerName}
|
|
||||||
fullWidth
|
|
||||||
inputProps={{
|
|
||||||
maxLength: 25,
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
onChange={(e) =>
|
|
||||||
setBannerName(
|
|
||||||
e.target.value.charAt(0).toUpperCase() +
|
|
||||||
e.target.value.slice(1)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/> */}
|
|
||||||
{/* {bannerName ? (
|
|
||||||
<>
|
|
||||||
<small className="charLeft mt-2 ml-3 fst-italic">
|
|
||||||
{25 - bannerName.length} characters left
|
|
||||||
</small>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)} */}
|
|
||||||
|
|
||||||
<Box
|
|
||||||
style={{
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "140px",
|
|
||||||
height: "140px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
{bannerImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={URL.createObjectURL(bannerImage)}
|
|
||||||
alt="bannerImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => handeldeleteImage()}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{olderImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={olderImage?.secure_url}
|
|
||||||
alt="bannerImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => setOlderImage("")}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<p className="pt-1 pl-2 text-secondary">
|
|
||||||
Upload jpg, jpeg and png only*
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Box
|
|
||||||
p={2}
|
|
||||||
display={"flex"}
|
|
||||||
justifyContent={"right"}
|
|
||||||
// width={"500px"}
|
|
||||||
>
|
|
||||||
{!edit && (
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
onClick={() => handleSaveBanner()}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<ClipLoader loading={!saveLoding} size={18} />
|
|
||||||
{saveLoding && "Save"}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{edit && (
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
onClick={() => handleUpdate()}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<ClipLoader loading={!updating} size={18} />
|
|
||||||
{updating && "update"}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "black",
|
|
||||||
marginRight: "1rem",
|
|
||||||
background: "grey",
|
|
||||||
}}
|
|
||||||
onClick={() => setOpen(false)}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-sm-12 col-md-12">
|
|
||||||
{/* <div className="dataTables_length">
|
|
||||||
<label className="w-100">
|
|
||||||
Show
|
|
||||||
<select
|
|
||||||
style={{ width: "10%" }}
|
|
||||||
onChange={(e) => setItemPerPage(e.target.value)}
|
|
||||||
className="
|
|
||||||
select-w
|
|
||||||
custom-select custom-select-sm
|
|
||||||
form-control form-control-sm
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: "1px solid" }}
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
className="thead-info"
|
|
||||||
style={{ background: "rgb(140, 213, 213)" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<th> Image</th>
|
|
||||||
|
|
||||||
<th>Action</th>
|
|
||||||
<th>Dimension</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{!loading && banner?.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="6">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={handleOpen}
|
|
||||||
// onClick={() => {
|
|
||||||
// navigate("/testimonial/new", { replace: true });
|
|
||||||
// }}
|
|
||||||
>
|
|
||||||
Add New Image
|
|
||||||
</Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="6">
|
|
||||||
Loading...
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : (
|
|
||||||
banner &&
|
|
||||||
banner.map((item, i) => (
|
|
||||||
<tr key={i}>
|
|
||||||
<td>
|
|
||||||
<img
|
|
||||||
className="me-2"
|
|
||||||
src={item?.image?.secure_url}
|
|
||||||
width="40"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
{/* {item?.image} */}
|
|
||||||
<h5>{} </h5>
|
|
||||||
</td>
|
|
||||||
{/* <td>
|
|
||||||
<h5>{item.bannerName} </h5>
|
|
||||||
</td> */}
|
|
||||||
<td className="text-start">
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className=" btn btn-primary btn-sm waves-effect waves-light btn-table mx-1 mt-1 "
|
|
||||||
onClick={() =>
|
|
||||||
handleEditClick(item._id, item.image)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
{/* <button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-sm btn-primary
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
onClick={() => handleDelete(item._id)}
|
|
||||||
>
|
|
||||||
view
|
|
||||||
</button> */}
|
|
||||||
</td>
|
|
||||||
<td>1200 x 800 pixels</td>
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div style={{ display: "flex", justifyContent: "right" }}>
|
|
||||||
<Pagination
|
|
||||||
style={{ margin: "2rem" }}
|
|
||||||
variant="outlined"
|
|
||||||
size="large"
|
|
||||||
count={getPageCount()}
|
|
||||||
color="primary"
|
|
||||||
onChange={(event, value) => setPage(value)}
|
|
||||||
/>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Banners;
|
|
@ -1,650 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
import React, { useState, useEffect, useRef } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import axios from "axios";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import swal from "sweetalert";
|
|
||||||
const Patient = () => {
|
|
||||||
const token = isAutheticated();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [success, setSuccess] = useState(true);
|
|
||||||
const [patientsData, setPatientsData] = useState([]);
|
|
||||||
|
|
||||||
const nameRef = useRef();
|
|
||||||
// const categoryRef = useRef();
|
|
||||||
const mobileRef = useRef()
|
|
||||||
const VerifyPatientRef = useRef();
|
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
|
||||||
const [itemPerPage, setItemPerPage] = useState(10);
|
|
||||||
const [totalData, setTotalData] = useState(0);
|
|
||||||
|
|
||||||
// const {
|
|
||||||
// edit,
|
|
||||||
// add,
|
|
||||||
// delete: deletepermission,
|
|
||||||
// } = checkPermission("Patient Master");
|
|
||||||
const getPatientsData = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
await axios
|
|
||||||
.get(`/api/patient/getAll/`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
page: currentPage,
|
|
||||||
show: itemPerPage,
|
|
||||||
name: nameRef.current.value,
|
|
||||||
mobileNumber: mobileRef.current.value,
|
|
||||||
isVerified: VerifyPatientRef.current.value,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
// console.log("res.data?.data", res.data);
|
|
||||||
setPatientsData(res.data?.patient);
|
|
||||||
setTotalData(res.data?.total_data);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
const msg = err?.response?.data?.message || "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: err,
|
|
||||||
text: msg,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
// const getCatagories = () => {
|
|
||||||
// axios
|
|
||||||
// .get(`/api/category/getCategories`, {
|
|
||||||
// headers: {
|
|
||||||
// "Access-Control-Allow-Origin": "*",
|
|
||||||
// Authorization: `Bearer ${token}`,
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// .then((res) => {
|
|
||||||
// setCategories(res?.data?.categories);
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// getCatagories();
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPatientsData();
|
|
||||||
}, [success, itemPerPage, currentPage]);
|
|
||||||
|
|
||||||
const handleDelete = (id) => {
|
|
||||||
swal({
|
|
||||||
title: "Are you sure?",
|
|
||||||
icon: "error",
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Yes", value: true },
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.delete(`/api/patient/delete/${id}`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Deleted",
|
|
||||||
text: "Patient Deleted successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
let msg = err?.response?.data?.message
|
|
||||||
? err?.response?.data?.message
|
|
||||||
: "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: msg,
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleVerifydPatient = (id) => {
|
|
||||||
swal({
|
|
||||||
title: "Are you sure?",
|
|
||||||
icon: "warning",
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Yes", value: true },
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.patch(`/api/patient/admin/feature_product/status/${id}`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Changed",
|
|
||||||
text: " Verify Patient status changed successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
let msg = err?.response?.data?.msg
|
|
||||||
? err?.response?.data?.msg
|
|
||||||
: "Something went wrong!";
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: msg,
|
|
||||||
icon: "warning",
|
|
||||||
button: "ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleStatus = (id) => {
|
|
||||||
swal({
|
|
||||||
title: "Are you sure?",
|
|
||||||
icon: "warning",
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Yes", value: true },
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.patch(`/api/patient/admin/status/${id}`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
swal({
|
|
||||||
title: "Changed",
|
|
||||||
text: "Patient status changed successfully!",
|
|
||||||
icon: "success",
|
|
||||||
button: "ok",
|
|
||||||
});
|
|
||||||
setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
Patients
|
|
||||||
</div>
|
|
||||||
{/* <div className="page-title-right">
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/patient/add", { replace: true });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add Patient
|
|
||||||
</Button>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row ml-0 mr-0 mb-10">
|
|
||||||
<div className="col-lg-1">
|
|
||||||
<div className="dataTables_length">
|
|
||||||
<label className="w-100">
|
|
||||||
Show
|
|
||||||
<select
|
|
||||||
onChange={(e) => {
|
|
||||||
setItemPerPage(e.target.value);
|
|
||||||
setCurrentPage(1);
|
|
||||||
}}
|
|
||||||
className="form-control"
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
<option value="10">10</option>
|
|
||||||
<option value="25">25</option>
|
|
||||||
<option value="50">50</option>
|
|
||||||
<option value="100">100</option>
|
|
||||||
</select>
|
|
||||||
entries
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-3">
|
|
||||||
<label>Patient Name:</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="Patient name"
|
|
||||||
className="form-control"
|
|
||||||
ref={nameRef}
|
|
||||||
disabled={loading}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-3">
|
|
||||||
<label>Mobile Number:</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="Mobile Number"
|
|
||||||
className="form-control"
|
|
||||||
ref={mobileRef}
|
|
||||||
disabled={loading}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/* <div className="col-lg-3">
|
|
||||||
<label>Filter by Mobile No.:</label>
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
ref={categoryRef}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
<option value="">All</option>
|
|
||||||
{categories?.map((e, i) => (
|
|
||||||
<option key={i} value={e._id}>
|
|
||||||
{e?.categoryName}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div> */}
|
|
||||||
<div className="col-lg-3">
|
|
||||||
<label>Verify Patient:</label>
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
ref={VerifyPatientRef}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
<option value="">----Select----</option>
|
|
||||||
<option value="true">YES</option>
|
|
||||||
<option value="false">NO</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-2">
|
|
||||||
<button
|
|
||||||
className="btn btn-primary ms-1 mt-4"
|
|
||||||
onClick={() => {
|
|
||||||
getPatientsData();
|
|
||||||
setCurrentPage(1);
|
|
||||||
}}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{loading ? "Searching.." : "Filter"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
|
||||||
<table
|
|
||||||
className="table table-centered table-nowrap"
|
|
||||||
style={{ border: "1px solid" }}
|
|
||||||
>
|
|
||||||
<thead
|
|
||||||
className="thead-light"
|
|
||||||
style={{ background: "#ecdddd" }}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
{/* <th className="text-start">Image</th> */}
|
|
||||||
<th className="text-start">Name</th>
|
|
||||||
{/* <th className="text-start">Category</th> */}
|
|
||||||
<th className="text-start">Mobile No.</th>
|
|
||||||
|
|
||||||
{/* <th className="text-start">Price</th> */}
|
|
||||||
<th className="text-start">Email</th>
|
|
||||||
|
|
||||||
<th className="text-start">Verify</th>
|
|
||||||
<th className="text-start">Device Added</th>
|
|
||||||
|
|
||||||
|
|
||||||
<th className="text-start">Register On</th>
|
|
||||||
<th className="text-start">Action</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
{loading ? (
|
|
||||||
<tr>
|
|
||||||
<td className="text-center" colSpan="6">
|
|
||||||
Loading...
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : patientsData?.length > 0 ? (
|
|
||||||
patientsData?.map((patient, i) => {
|
|
||||||
return (
|
|
||||||
<tr key={i}>
|
|
||||||
{/* <th>
|
|
||||||
{patient?.image &&
|
|
||||||
patient?.image?.length !== 0 ? (
|
|
||||||
<>
|
|
||||||
<img
|
|
||||||
src={patient?.image[0]?.url}
|
|
||||||
width="50"
|
|
||||||
alt="preview"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className=""
|
|
||||||
style={{ fontSize: "13px" }}
|
|
||||||
>
|
|
||||||
<p className="m-0">No</p>
|
|
||||||
<p className="m-0">image</p>
|
|
||||||
<p className="m-0">uploaded!</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</th> */}
|
|
||||||
<td className="text-start">{patient?.name}</td>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<td className="text-start">{patient?.mobileNumber}</td>
|
|
||||||
<td className="text-start">{patient?.email ? patient?.email : <><small className="m-0 text-secondary">No Email Added!</small>
|
|
||||||
</>}</td>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<td className="text-start">
|
|
||||||
<span className={`badge text-white ${patient?.isVerified === true
|
|
||||||
? "text-bg-success"
|
|
||||||
: "text-bg-danger"
|
|
||||||
}`}>
|
|
||||||
{patient?.isVerified ? "YES" : "NO"}
|
|
||||||
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className="text-start">
|
|
||||||
<span className={`badge text-white ${patient?.deviceAdded === true
|
|
||||||
? "text-bg-success"
|
|
||||||
: "text-bg-danger"
|
|
||||||
}`}>
|
|
||||||
{patient?.deviceAdded ? "YES" : "NO"}
|
|
||||||
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
|
|
||||||
|
|
||||||
<td className="text-start">
|
|
||||||
{new Date(patient.createdAt).toLocaleString(
|
|
||||||
"en-IN",
|
|
||||||
{
|
|
||||||
weekday: "short",
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className="text-start">
|
|
||||||
{/* <Link to={`/patients/variants/${patient._id}`}>
|
|
||||||
<button
|
|
||||||
style={{ color: 'white', marginRight: '1rem' }}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Variants
|
|
||||||
</button>
|
|
||||||
</Link> */}
|
|
||||||
<Link
|
|
||||||
to={`/patient/view/${patient._id}`}
|
|
||||||
// to={`/patient/view/${patient._id}`}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-primary btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mx-1
|
|
||||||
mt-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
View
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{/* <Link to={`/patient/edit/${patient._id}`}>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
color: "white",
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-info btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mt-1
|
|
||||||
mx-1
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
</Link> */}
|
|
||||||
|
|
||||||
<Link
|
|
||||||
to={"#"}
|
|
||||||
style={{
|
|
||||||
marginRight: "1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
style={{ color: "white" }}
|
|
||||||
type="button"
|
|
||||||
className="
|
|
||||||
btn btn-danger btn-sm
|
|
||||||
waves-effect waves-light
|
|
||||||
btn-table
|
|
||||||
mt-1
|
|
||||||
mx-1
|
|
||||||
|
|
||||||
"
|
|
||||||
onClick={() => {
|
|
||||||
handleDelete(patient._id);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</Link>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
!loading &&
|
|
||||||
patientsData?.length === 0 && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<td colSpan="6">
|
|
||||||
<h5>No Patient Available...</h5>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="row mt-20">
|
|
||||||
<div className="col-sm-12 col-md-6 mb-20">
|
|
||||||
<div
|
|
||||||
className="dataTables_info"
|
|
||||||
id="datatable_info"
|
|
||||||
role="status"
|
|
||||||
aria-live="polite"
|
|
||||||
>
|
|
||||||
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
|
|
||||||
{Math.min(currentPage * itemPerPage, totalData)} of{" "}
|
|
||||||
{totalData} entries
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="col-sm-12 col-md-6">
|
|
||||||
<div className="d-flex">
|
|
||||||
<ul className="pagination ms-auto">
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
currentPage === 1
|
|
||||||
? "paginate_button page-item previous disabled"
|
|
||||||
: "paginate_button page-item previous"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev - 1)}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(currentPage - 1 < 1) && (
|
|
||||||
<li className="paginate_button page-item">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={(e) =>
|
|
||||||
setCurrentPage((prev) => prev - 1)
|
|
||||||
}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{currentPage - 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li className="paginate_button page-item active">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
>
|
|
||||||
{currentPage}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
totalData - 1
|
|
||||||
) && (
|
|
||||||
<li className="paginate_button page-item ">
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentPage((prev) => prev + 1);
|
|
||||||
}}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{currentPage + 1}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<li
|
|
||||||
className={
|
|
||||||
!(
|
|
||||||
(currentPage + 1) * itemPerPage - itemPerPage >
|
|
||||||
totalData - 1
|
|
||||||
)
|
|
||||||
? "paginate_button page-item next"
|
|
||||||
: "paginate_button page-item next disabled"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="page-link"
|
|
||||||
style={{ cursor: "pointer" }}
|
|
||||||
onClick={() => setCurrentPage((prev) => prev + 1)}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Patient;
|
|
@ -1,263 +0,0 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import axios from "axios";
|
|
||||||
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
|
|
||||||
const ViewPatient = () => {
|
|
||||||
// const id = useParams()?.id;
|
|
||||||
|
|
||||||
const location = useLocation();
|
|
||||||
const { currencyDetails } = location.state || {};
|
|
||||||
|
|
||||||
const { id } = useParams();
|
|
||||||
const token = isAutheticated();
|
|
||||||
|
|
||||||
const [patientData, setPatientData] = useState({});
|
|
||||||
const [SAW, setSAW] = useState([
|
|
||||||
{ volume: "", weight: "" },
|
|
||||||
{ volume: "", weight: "" },
|
|
||||||
{ volume: "", weight: "" },
|
|
||||||
{ volume: "", weight: "" },
|
|
||||||
{ volume: "", weight: "" },
|
|
||||||
]);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const getPatientData = async () => {
|
|
||||||
axios
|
|
||||||
.get(`/api/patient/getOne/${id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(res.data.data);
|
|
||||||
setPatientData(res.data.data);
|
|
||||||
if (res.data.data?.variants) {
|
|
||||||
setSAW((prev) => [...res.data.data?.variants]);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => { });
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
getPatientData();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onCancel = () => {
|
|
||||||
navigate("//patients");
|
|
||||||
};
|
|
||||||
let count = 1;
|
|
||||||
return (
|
|
||||||
<div className=" main-content">
|
|
||||||
<div className=" my-3 page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
{/* <!-- start page title --> */}
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div className="page-title-box d-flex align-items-center justify-content-between">
|
|
||||||
<h4 className="mb-3">Patient Details</h4>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={onCancel}
|
|
||||||
type="button"
|
|
||||||
className="mb-2 ml-2 btn btn-warning btn-cancel waves-effect waves-light mr-3"
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <!-- end page title --> */}
|
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row ml-0 mr-0 mb-10"></div>
|
|
||||||
<div className="table-responsive table-shoot">
|
|
||||||
<table className="table table-centered table-nowrap mb-0">
|
|
||||||
<thead className="thead-light">
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<td>{patientData?.name}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Patient Group</th>
|
|
||||||
<td>{patientData?.category?.categoryName}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Images</th>
|
|
||||||
<td>
|
|
||||||
{patientData?.image &&
|
|
||||||
patientData?.image?.length !== 0
|
|
||||||
? patientData?.image.map((e, i) => (
|
|
||||||
<img
|
|
||||||
className="p-1"
|
|
||||||
src={e.url}
|
|
||||||
width="100"
|
|
||||||
alt="preview"
|
|
||||||
key={i}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
: "No Images Uploaded!"}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>Description</th>
|
|
||||||
<td>{patientData?.description}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Patient Status</th>
|
|
||||||
<td
|
|
||||||
className={`badge m-1 ${patientData?.patient_Status === "Active"
|
|
||||||
? "text-bg-success"
|
|
||||||
: "text-bg-danger"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{patientData?.patient_Status}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Special Instructions</th>
|
|
||||||
<td>
|
|
||||||
<p
|
|
||||||
style={{ whiteSpace: "pre-line" }}
|
|
||||||
className="m-0 p-0"
|
|
||||||
>
|
|
||||||
{patientData?.special_instructions
|
|
||||||
? patientData?.special_instructions
|
|
||||||
: "---"}
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
<table className="table table-primary mt-3">
|
|
||||||
<caption
|
|
||||||
style={{ captionSide: "top" }}
|
|
||||||
className="text-dark fw-bold"
|
|
||||||
>
|
|
||||||
Varients:
|
|
||||||
</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th className="text-center">Variant Name</th>
|
|
||||||
<th className="text-center">Price</th>
|
|
||||||
|
|
||||||
<th className="text-center">VAT</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{SAW.map(
|
|
||||||
(r, i) =>
|
|
||||||
r.variant_Name !== "" && (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-center">
|
|
||||||
{r?.variant_Name}
|
|
||||||
</td>
|
|
||||||
<td className="text-center">
|
|
||||||
{currencyDetails?.CurrencySymbol}
|
|
||||||
{r?.price}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className="text-center">
|
|
||||||
{r?.gst_Id?.name + " " + r?.gst_Id?.tax + "%"}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
{SAW.filter((e) => e.variant_Name !== "").length ===
|
|
||||||
0 && (
|
|
||||||
<tr>
|
|
||||||
<td colSpan={"6"} className="text-center">
|
|
||||||
No data available
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{/* <div className="mb-2">
|
|
||||||
<table className="table table-secondary mt-3">
|
|
||||||
<caption
|
|
||||||
style={{ captionSide: "top" }}
|
|
||||||
className="text-dark fw-bold"
|
|
||||||
>
|
|
||||||
Patient Fabric:
|
|
||||||
</caption>
|
|
||||||
{patientData?.patient_Fabric?.length > 0 ? (
|
|
||||||
<>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th className="text-center">S. No.</th>
|
|
||||||
<th className="text-center"> Name</th>
|
|
||||||
<th className="text-center"> Use For Part</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{patientData?.patient_Fabric?.map((r, i) => (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-center">{++i}</td>
|
|
||||||
<td className="text-center">
|
|
||||||
{r?.fabric_Name}
|
|
||||||
</td>
|
|
||||||
<td className="text-center">{r?.for_Part}</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<h5>No Fabric Allotted for this patient!</h5>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</table>
|
|
||||||
</div> */}
|
|
||||||
{/* <div className="mb-2">
|
|
||||||
<table className="table table-info mt-3">
|
|
||||||
<caption
|
|
||||||
style={{ captionSide: "top" }}
|
|
||||||
className="text-dark fw-bold"
|
|
||||||
>
|
|
||||||
Relevent Patient:
|
|
||||||
</caption>
|
|
||||||
{patientData?.relevent_patient?.length > 0 ? (
|
|
||||||
<>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th className="text-center">S. No.</th>
|
|
||||||
<th className="text-center">Patient Name</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{patientData?.relevent_patient?.map((r, i) => (
|
|
||||||
<tr key={i}>
|
|
||||||
<td className="text-center">{count++}</td>
|
|
||||||
<td className="text-center">{r?.name}</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<h5>No relevent item for this patient !</h5>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</table>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <!-- end table-responsive --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <!-- container-fluid --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ViewPatient;
|
|
@ -1,77 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import Modal from "react-modal";
|
|
||||||
|
|
||||||
const AddressSelectionModal = ({ isOpen, onClose, addresses, onSelect }) => {
|
|
||||||
const modalStyle = {
|
|
||||||
overlay: {
|
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
right: "auto",
|
|
||||||
bottom: "auto",
|
|
||||||
marginRight: "-50%",
|
|
||||||
transform: "translate(-50%, -50%)",
|
|
||||||
maxWidth: "800px",
|
|
||||||
width: "90%",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const tableStyle = {
|
|
||||||
width: "100%",
|
|
||||||
borderCollapse: "collapse",
|
|
||||||
};
|
|
||||||
|
|
||||||
const thTdStyle = {
|
|
||||||
border: "1px solid #ddd",
|
|
||||||
padding: "8px",
|
|
||||||
};
|
|
||||||
|
|
||||||
const thStyle = {
|
|
||||||
...thTdStyle,
|
|
||||||
backgroundColor: "#f2f2f2",
|
|
||||||
};
|
|
||||||
// console.log(addresses);
|
|
||||||
return (
|
|
||||||
<Modal isOpen={isOpen} onRequestClose={onClose} style={modalStyle}>
|
|
||||||
<h2>Select Address</h2>
|
|
||||||
<table style={tableStyle}>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style={thStyle}>First Name</th>
|
|
||||||
<th style={thStyle}>Last Name</th>
|
|
||||||
<th style={thStyle}>Phone Number</th>
|
|
||||||
<th style={thStyle}>Street</th>
|
|
||||||
<th style={thStyle}>City</th>
|
|
||||||
<th style={thStyle}>Postal Code</th>
|
|
||||||
<th style={thStyle}>State</th>
|
|
||||||
{/* Add additional columns as needed */}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{addresses.map((address, index) => (
|
|
||||||
<tr
|
|
||||||
key={index}
|
|
||||||
onClick={() => onSelect(address)}
|
|
||||||
style={{ cursor: "pointer", ...thTdStyle }}
|
|
||||||
>
|
|
||||||
<td>{address.first_Name}</td>
|
|
||||||
<td>{address.last_Name}</td>
|
|
||||||
<td>{address.phone_Number}</td>
|
|
||||||
<td>{address.street}</td>
|
|
||||||
<td>{address.city}</td>
|
|
||||||
<td>{address.postalCode}</td>
|
|
||||||
<td>{address.state}</td>
|
|
||||||
{/* Add additional columns as needed */}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<button onClick={onClose}>Close</button>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AddressSelectionModal;
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -165,7 +165,7 @@ const ProductDetails = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6 ">
|
<div className="col-lg-6 ">
|
||||||
<label htmlFor="product" className="form-label">
|
<label htmlFor="product" className="form-label">
|
||||||
Master VAT *
|
Master GST *
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
name="master_GST"
|
name="master_GST"
|
||||||
|
@ -177,7 +177,7 @@ const ViewProduct = () => {
|
|||||||
<th className="text-center">Variant Name</th>
|
<th className="text-center">Variant Name</th>
|
||||||
<th className="text-center">Price</th>
|
<th className="text-center">Price</th>
|
||||||
|
|
||||||
<th className="text-center">VAT</th>
|
<th className="text-center">GST</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
189
src/views/SalesCoOrdinators/AddSalesCoOrdinator.js
Normal file
189
src/views/SalesCoOrdinators/AddSalesCoOrdinator.js
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
import Modal from "react-bootstrap/Modal";
|
||||||
|
import Button from "react-bootstrap/Button";
|
||||||
|
import Form from "react-bootstrap/Form";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
|
||||||
|
const AddSalesCoOrdinator = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const token = isAutheticated();
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
countryCode: "",
|
||||||
|
mobileNumber: "",
|
||||||
|
otp: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRegister = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
await axios.post("/api/salescoordinator/register", formData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
setShowModal(true); // Show OTP modal after registration
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
let msg =
|
||||||
|
error?.response?.data?.message ||
|
||||||
|
"Failed to register Sales Coordinator. Please try again.";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVerifyOTP = async () => {
|
||||||
|
try {
|
||||||
|
await axios.post("/api/salescoordinator/verify-otp", {
|
||||||
|
otp: formData.otp,
|
||||||
|
fullMobileNumber: `${formData.countryCode}${formData.mobileNumber}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
setShowModal(false); // Close OTP modal after verification
|
||||||
|
swal({
|
||||||
|
title: "Success",
|
||||||
|
text: "OTP verified successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
}).then(() => {
|
||||||
|
navigate("/salescoordinators"); // Navigate to success page or desired route
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
let msg =
|
||||||
|
error?.response?.data?.message ||
|
||||||
|
"OTP verification failed. Please try again.";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="my-3 page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||||
|
<h4 className="mb-3">Add Sales Coordinator</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<form onSubmit={handleRegister}>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Name</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.name}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Email</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.email}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group d-flex">
|
||||||
|
<div className="mr-2" style={{ flex: 1 }}>
|
||||||
|
<label>Country Code</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="countryCode"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.countryCode}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ flex: 3 }}>
|
||||||
|
<label>Mobile Number</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="mobileNumber"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.mobileNumber}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" className="btn btn-primary">
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* OTP Modal */}
|
||||||
|
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title>Enter OTP</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>OTP</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter OTP"
|
||||||
|
value={formData.otp}
|
||||||
|
onChange={(e) =>
|
||||||
|
setFormData({ ...formData, otp: e.target.value })
|
||||||
|
}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button variant="secondary" onClick={() => setShowModal(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="primary" onClick={handleVerifyOTP}>
|
||||||
|
Verify OTP
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddSalesCoOrdinator;
|
395
src/views/SalesCoOrdinators/EditSalesCoOrdinator.js
Normal file
395
src/views/SalesCoOrdinators/EditSalesCoOrdinator.js
Normal file
@ -0,0 +1,395 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
import Modal from "react-bootstrap/Modal";
|
||||||
|
import Button from "react-bootstrap/Button";
|
||||||
|
import Form from "react-bootstrap/Form";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
|
||||||
|
const EditSalesCoOrdinator = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const token = isAutheticated();
|
||||||
|
const { id } = useParams();
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
name: "",
|
||||||
|
email: "",
|
||||||
|
countryCode: "",
|
||||||
|
mobileNumber: "",
|
||||||
|
currentPassword: "",
|
||||||
|
newPassword: "",
|
||||||
|
confirmPassword: "",
|
||||||
|
otp: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const [showVerifyModal, setShowVerifyModal] = useState(false);
|
||||||
|
const [showPasswordModal, setShowPasswordModal] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getSalesCoOrdinatorData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getSalesCoOrdinatorData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`/api/salescoordinator/getOne/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { data } = response.data;
|
||||||
|
|
||||||
|
// Assuming country code always starts with + and is followed by 1-3 digits
|
||||||
|
const fullMobileNumber = data?.mobileNumber || "";
|
||||||
|
const countryCodeMatch = fullMobileNumber.match(/^\+\d{1,2}/);
|
||||||
|
const countryCode = countryCodeMatch ? countryCodeMatch[0] : "";
|
||||||
|
const mobileNumber = fullMobileNumber.replace(countryCode, "");
|
||||||
|
|
||||||
|
setFormData({
|
||||||
|
name: data?.name || "",
|
||||||
|
email: data?.email || "",
|
||||||
|
countryCode: countryCode,
|
||||||
|
mobileNumber: mobileNumber,
|
||||||
|
currentPassword: "",
|
||||||
|
newPassword: "",
|
||||||
|
confirmPassword: "",
|
||||||
|
otp: "",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching sales coordinator data: ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdateBasicInfo = () => {
|
||||||
|
axios
|
||||||
|
.patch(
|
||||||
|
`/api/salescoordinator/profile/update/${id}`,
|
||||||
|
{
|
||||||
|
name: formData.name,
|
||||||
|
email: formData.email,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
swal({
|
||||||
|
title: "Success",
|
||||||
|
text: "Sales coordinator information updated successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
let msg = error?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVerifyMobile = () => {
|
||||||
|
axios
|
||||||
|
.post(
|
||||||
|
`/api/salescoordinator/update-mobile-number/${id}`,
|
||||||
|
{
|
||||||
|
newCountryCode: formData.countryCode,
|
||||||
|
newMobileNumber: formData.mobileNumber,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
setShowVerifyModal(true);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
let msg = error?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVerifyOTP = () => {
|
||||||
|
axios
|
||||||
|
.post(
|
||||||
|
"/api/salescoordinator/verify-updated-mobile-otp",
|
||||||
|
{
|
||||||
|
otp: formData.otp,
|
||||||
|
newMobileNumber: `${formData.countryCode}${formData.mobileNumber}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
setShowVerifyModal(false);
|
||||||
|
// Handle success, if needed
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
let msg = error?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangePassword = () => {
|
||||||
|
axios
|
||||||
|
.put(
|
||||||
|
`/api/salescoordinator/password/update/${id}`,
|
||||||
|
{
|
||||||
|
oldPassword: formData.currentPassword,
|
||||||
|
newPassword: formData.newPassword,
|
||||||
|
confirmPassword: formData.confirmPassword,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
setShowPasswordModal(false);
|
||||||
|
swal({
|
||||||
|
title: "Success",
|
||||||
|
text: "Password updated successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
let msg = error?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
navigate("/salescoordinators");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="my-3 page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||||
|
<h4 className="mb-3">Edit Sales Coordinator</h4>
|
||||||
|
<button
|
||||||
|
onClick={onCancel}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-warning btn-cancel waves-effect waves-light mr-3"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Name</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.name}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>Email</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.email}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 mb-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary mr-2"
|
||||||
|
onClick={handleUpdateBasicInfo}
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="form-group d-flex align-items-center">
|
||||||
|
<div className="mr-2" style={{ flex: 1 }}>
|
||||||
|
<label>Country Code</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="countryCode"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.countryCode}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mr-2" style={{ flex: 3 }}>
|
||||||
|
<label>Mobile Number</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="mobileNumber"
|
||||||
|
className="form-control"
|
||||||
|
value={formData.mobileNumber}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mr-2" style={{ flex: 1 }}>
|
||||||
|
<label> </label>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-success"
|
||||||
|
onClick={handleVerifyMobile}
|
||||||
|
style={{ display: "block" }}
|
||||||
|
>
|
||||||
|
Verify Mobile
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 mb-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-danger"
|
||||||
|
onClick={() => setShowPasswordModal(true)}
|
||||||
|
>
|
||||||
|
Change Password
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* OTP Verification Modal */}
|
||||||
|
<Modal
|
||||||
|
show={showVerifyModal}
|
||||||
|
onHide={() => setShowVerifyModal(false)}
|
||||||
|
>
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title>Verify Mobile</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Enter OTP</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter OTP"
|
||||||
|
name="otp"
|
||||||
|
value={formData.otp}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={() => setShowVerifyModal(false)}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="primary" onClick={handleVerifyOTP}>
|
||||||
|
Verify OTP
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
{/* Change Password Modal */}
|
||||||
|
<Modal
|
||||||
|
show={showPasswordModal}
|
||||||
|
onHide={() => setShowPasswordModal(false)}
|
||||||
|
>
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title>Change Password</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Current Password</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="password"
|
||||||
|
placeholder="Enter current password"
|
||||||
|
name="currentPassword"
|
||||||
|
value={formData.currentPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>New Password</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="password"
|
||||||
|
placeholder="Enter new password"
|
||||||
|
name="newPassword"
|
||||||
|
value={formData.newPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Confirm New Password</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="password"
|
||||||
|
placeholder="Confirm new password"
|
||||||
|
name="confirmPassword"
|
||||||
|
value={formData.confirmPassword}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={() => setShowPasswordModal(false)}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="danger" onClick={handleChangePassword}>
|
||||||
|
Change Password
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditSalesCoOrdinator;
|
428
src/views/SalesCoOrdinators/SalesCoOrdinator.js
Normal file
428
src/views/SalesCoOrdinators/SalesCoOrdinator.js
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
|
||||||
|
const SalesCoOrdinator = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [success, setSuccess] = useState(true);
|
||||||
|
const [salescoordinatorsData, setSalesCoOrdinatorsData] = useState([]);
|
||||||
|
|
||||||
|
const nameRef = useRef();
|
||||||
|
const mobileRef = useRef();
|
||||||
|
const VerifySalesCoOrdinatorRef = useRef();
|
||||||
|
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10);
|
||||||
|
const [totalData, setTotalData] = useState(0);
|
||||||
|
|
||||||
|
const getSalesCoOrdinatorsData = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await axios.get(`/api/salescoordinator/getAll/`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
page: currentPage,
|
||||||
|
show: itemPerPage,
|
||||||
|
name: nameRef.current.value,
|
||||||
|
mobileNumber: mobileRef.current.value,
|
||||||
|
isVerified: VerifySalesCoOrdinatorRef.current.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// console.log(res.data.salesCoOrinators
|
||||||
|
// );
|
||||||
|
setSalesCoOrdinatorsData(res.data?.salesCoOrinators);
|
||||||
|
setTotalData(res.data?.total_data);
|
||||||
|
} catch (err) {
|
||||||
|
const msg = err?.response?.data?.message || "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Error",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getSalesCoOrdinatorsData();
|
||||||
|
}, [success, itemPerPage, currentPage]);
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
swal({
|
||||||
|
title: "Are you sure?",
|
||||||
|
icon: "error",
|
||||||
|
buttons: {
|
||||||
|
Yes: { text: "Yes", value: true },
|
||||||
|
Cancel: { text: "Cancel", value: "cancel" },
|
||||||
|
},
|
||||||
|
}).then((value) => {
|
||||||
|
if (value === true) {
|
||||||
|
axios
|
||||||
|
.delete(`/api/salescoordinator/delete/${id}`, {
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
swal({
|
||||||
|
title: "Deleted",
|
||||||
|
text: "SalesCoOrdinator Deleted successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "ok",
|
||||||
|
});
|
||||||
|
setSuccess((prev) => !prev);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
let msg = err?.response?.data?.message
|
||||||
|
? err?.response?.data?.message
|
||||||
|
: "Something went wrong!";
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: msg,
|
||||||
|
icon: "error",
|
||||||
|
button: "Retry",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div className="page-title-box d-flex align-items-center justify-content-between">
|
||||||
|
<div style={{ fontSize: "22px" }} className="fw-bold">
|
||||||
|
SalesCoOrdinators
|
||||||
|
</div>
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/salescoordinator/add", { replace: true });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add SalesCoOrdinator
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="row ml-0 mr-0 mb-10">
|
||||||
|
<div className="col-lg-1">
|
||||||
|
<div className="dataTables_length">
|
||||||
|
<label className="w-100">
|
||||||
|
Show
|
||||||
|
<select
|
||||||
|
onChange={(e) => {
|
||||||
|
setItemPerPage(e.target.value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
}}
|
||||||
|
className="form-control"
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
</select>
|
||||||
|
entries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>SalesCoOrdinator Name:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="SalesCoOrdinator name"
|
||||||
|
className="form-control"
|
||||||
|
ref={nameRef}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Mobile Number:</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Mobile Number"
|
||||||
|
className="form-control"
|
||||||
|
ref={mobileRef}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<label>Verify SalesCoOrdinator:</label>
|
||||||
|
<select
|
||||||
|
className="form-control"
|
||||||
|
ref={VerifySalesCoOrdinatorRef}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
<option value="">----Select----</option>
|
||||||
|
<option value="true">YES</option>
|
||||||
|
<option value="false">NO</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-2">
|
||||||
|
<button
|
||||||
|
className="btn btn-primary ms-1 mt-4"
|
||||||
|
onClick={() => {
|
||||||
|
getSalesCoOrdinatorsData();
|
||||||
|
setCurrentPage(1);
|
||||||
|
}}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{loading ? "Searching.." : "Filter"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive table-shoot mt-3">
|
||||||
|
<table className="table table-centered table-nowrap">
|
||||||
|
<thead
|
||||||
|
className="thead-light"
|
||||||
|
style={{ background: "#ecdddd" }}
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start">Name</th>
|
||||||
|
<th className="text-start">Mobile No.</th>
|
||||||
|
<th className="text-start">Email</th>
|
||||||
|
<th className="text-start">Verify</th>
|
||||||
|
<th className="text-start">Register On</th>
|
||||||
|
<th className="text-start">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center" colSpan="6">
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : salescoordinatorsData?.length > 0 ? (
|
||||||
|
salescoordinatorsData?.map((salescoordinator, i) => {
|
||||||
|
return (
|
||||||
|
<tr key={i}>
|
||||||
|
<td className="text-start">
|
||||||
|
{salescoordinator?.name}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{salescoordinator?.mobileNumber}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{salescoordinator?.email ? (
|
||||||
|
salescoordinator?.email
|
||||||
|
) : (
|
||||||
|
<small className="m-0 text-secondary">
|
||||||
|
No Email Added!
|
||||||
|
</small>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
<span
|
||||||
|
className={`badge text-white ${
|
||||||
|
salescoordinator?.isVerified === true
|
||||||
|
? "text-bg-success"
|
||||||
|
: "text-bg-danger"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{salescoordinator?.isVerified
|
||||||
|
? "YES"
|
||||||
|
: "NO"}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{new Date(
|
||||||
|
salescoordinator.createdAt
|
||||||
|
).toLocaleString("en-IN", {
|
||||||
|
weekday: "short",
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
hour12: true,
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
|
<td className="text-start">
|
||||||
|
{/* <Link to={`/salescoordinator/view/${salescoordinator._id}`}>
|
||||||
|
<button
|
||||||
|
style={{ color: "white", marginRight: "1rem" }}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm waves-effect waves-light btn-table mx-1 mt-1"
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
</Link> */}
|
||||||
|
|
||||||
|
<Link
|
||||||
|
to={`/salescoordinator/edit/${salescoordinator._id}`}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-info btn-sm waves-effect waves-light btn-table mt-1 mx-1"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<button
|
||||||
|
style={{ color: "white" }}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-danger btn-sm waves-effect waves-light btn-table mt-1 mx-1"
|
||||||
|
onClick={() => {
|
||||||
|
handleDelete(salescoordinator._id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="6">
|
||||||
|
<h5>No SalesCoOrdinator Available...</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row mt-20">
|
||||||
|
<div className="col-sm-12 col-md-6 mb-20">
|
||||||
|
<div
|
||||||
|
className="dataTables_info"
|
||||||
|
id="datatable_info"
|
||||||
|
role="status"
|
||||||
|
aria-live="polite"
|
||||||
|
>
|
||||||
|
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
|
||||||
|
{Math.min(currentPage * itemPerPage, totalData)} of{" "}
|
||||||
|
{totalData} entries
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-sm-12 col-md-6">
|
||||||
|
<div className="d-flex">
|
||||||
|
<ul className="pagination ms-auto">
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
currentPage === 1
|
||||||
|
? "paginate_button page-item previous disabled"
|
||||||
|
: "paginate_button page-item previous"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(currentPage - 1 < 1) && (
|
||||||
|
<li className="paginate_button page-item">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() =>
|
||||||
|
setCurrentPage((prev) => prev - 1)
|
||||||
|
}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{currentPage - 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li className="paginate_button page-item active">
|
||||||
|
<span className="page-link">{currentPage}</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
totalData - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() =>
|
||||||
|
setCurrentPage((prev) => prev + 1)
|
||||||
|
}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
totalData - 1
|
||||||
|
)
|
||||||
|
? "paginate_button page-item next"
|
||||||
|
: "paginate_button page-item next disabled"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SalesCoOrdinator;
|
@ -150,45 +150,45 @@ const Currency = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (_id) => {
|
// const handleDelete = (_id) => {
|
||||||
swal({
|
// swal({
|
||||||
title: "Are you sure?",
|
// title: "Are you sure?",
|
||||||
icon: "error",
|
// icon: "error",
|
||||||
buttons: {
|
// buttons: {
|
||||||
Yes: { text: "Yes", value: true },
|
// Yes: { text: "Yes", value: true },
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
// Cancel: { text: "Cancel", value: "cancel" },
|
||||||
},
|
// },
|
||||||
}).then((value) => {
|
// }).then((value) => {
|
||||||
if (value === true) {
|
// if (value === true) {
|
||||||
axios
|
// axios
|
||||||
.delete(`/api/currency/${_id}`, {
|
// .delete(`/api/currency/${_id}`, {
|
||||||
headers: {
|
// headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
// Authorization: `Bearer ${token}`,
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
.then((res) => {
|
// .then((res) => {
|
||||||
swal({
|
// swal({
|
||||||
title: "Congratulations!!",
|
// title: "Congratulations!!",
|
||||||
text: "The Currency is deleted successfully!",
|
// text: "The Currency is deleted successfully!",
|
||||||
icon: "success",
|
// icon: "success",
|
||||||
button: "OK",
|
// button: "OK",
|
||||||
});
|
// });
|
||||||
setSucess((prev) => !prev);
|
// setSucess((prev) => !prev);
|
||||||
|
|
||||||
// getCategories(); // Refresh the category list after deleting
|
// // getCategories(); // Refresh the category list after deleting
|
||||||
})
|
// })
|
||||||
.catch((err) => {
|
// .catch((err) => {
|
||||||
swal({
|
// swal({
|
||||||
title: "Error",
|
// title: "Error",
|
||||||
text: "Something went wrong!",
|
// text: "Something went wrong!",
|
||||||
icon: "error",
|
// icon: "error",
|
||||||
button: "Retry",
|
// button: "Retry",
|
||||||
dangerMode: true,
|
// dangerMode: true,
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleSaveCurrency = async () => {
|
const handleSaveCurrency = async () => {
|
||||||
// const CurrencyExits = CurrencyNamesArray.includes(
|
// const CurrencyExits = CurrencyNamesArray.includes(
|
||||||
@ -295,7 +295,7 @@ const Currency = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="page-title-right">
|
<div className="page-title-right">
|
||||||
<Button
|
{/* <Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
style={{
|
style={{
|
||||||
@ -309,7 +309,7 @@ const Currency = () => {
|
|||||||
// }}
|
// }}
|
||||||
>
|
>
|
||||||
+ New Currency
|
+ New Currency
|
||||||
</Button>
|
</Button> */}
|
||||||
<Modal
|
<Modal
|
||||||
open={open}
|
open={open}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
@ -368,112 +368,6 @@ const Currency = () => {
|
|||||||
}}
|
}}
|
||||||
onChange={(e) => setCurrencySymbol(e.target.value)}
|
onChange={(e) => setCurrencySymbol(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* <Box
|
|
||||||
style={{
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<label htmlFor="upload-Image">
|
|
||||||
<TextField
|
|
||||||
style={{
|
|
||||||
display: "none",
|
|
||||||
width: "350px",
|
|
||||||
height: "350px",
|
|
||||||
borderRadius: "10%",
|
|
||||||
}}
|
|
||||||
fullWidth
|
|
||||||
id="upload-Image"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg , .png ,.jpeg"
|
|
||||||
label="file"
|
|
||||||
variant="outlined"
|
|
||||||
onChange={(e) => handleFileChange(e)}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
style={{ borderRadius: "10%" }}
|
|
||||||
sx={{
|
|
||||||
margin: "1rem 0rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
width: "140px",
|
|
||||||
height: "140px",
|
|
||||||
border: "2px solid grey",
|
|
||||||
// borderRadius: '50%',
|
|
||||||
|
|
||||||
"&:hover": {
|
|
||||||
background: "rgba(112,112,112,0.5)",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloudUploadIcon
|
|
||||||
style={{
|
|
||||||
color: "grey",
|
|
||||||
margin: "auto",
|
|
||||||
fontSize: "5rem",
|
|
||||||
}}
|
|
||||||
fontSize="large"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</label>
|
|
||||||
{CurrencyImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={URL.createObjectURL(CurrencyImage)}
|
|
||||||
alt="CurrencyImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => handeldeleteImage()}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{olderImage && (
|
|
||||||
<Box>
|
|
||||||
<img
|
|
||||||
src={olderImage?.secure_url}
|
|
||||||
alt="CurrencyImage"
|
|
||||||
style={{
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
borderRadius: "1rem",
|
|
||||||
marginLeft: "1rem",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteSharpIcon
|
|
||||||
onClick={() => setOlderImage("")}
|
|
||||||
fontSize="small"
|
|
||||||
sx={{
|
|
||||||
color: "white",
|
|
||||||
position: "absolute",
|
|
||||||
cursor: "pointer",
|
|
||||||
padding: "0.2rem",
|
|
||||||
background: "black",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
|
||||||
<p className="pt-1 pl-2 text-secondary">
|
|
||||||
Upload jpg, jpeg and png only*
|
|
||||||
</p> */}
|
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
p={2}
|
p={2}
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
@ -654,7 +548,7 @@ const Currency = () => {
|
|||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
<button
|
{/* <button
|
||||||
style={{
|
style={{
|
||||||
color: "white",
|
color: "white",
|
||||||
marginRight: "1rem",
|
marginRight: "1rem",
|
||||||
@ -671,7 +565,7 @@ const Currency = () => {
|
|||||||
onClick={() => handleDelete(item._id)}
|
onClick={() => handleDelete(item._id)}
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button> */}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
|
@ -27,12 +27,17 @@ function Logo() {
|
|||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// console.log(configDetails.data.result[0]?.logo[0]);
|
||||||
configDetails.data.result.map((item) => {
|
const data = configDetails.data.result[0]?.logo[0];
|
||||||
setHeaderlogo(item?.logo[0]?.Headerlogo);
|
setHeaderlogo(data?.Headerlogo);
|
||||||
setFooterlogo(item?.logo[0]?.Footerlogo);
|
setFooterlogo(data?.Footerlogo);
|
||||||
setAdminlogo(item?.logo[0]?.Adminlogo);
|
setAdminlogo(data?.Adminlogo);
|
||||||
});
|
// configDetails.data.result.map((item) => {
|
||||||
|
// console.log(item);
|
||||||
|
// setHeaderlogo(item?.logo[0]?.Headerlogo);
|
||||||
|
// setFooterlogo(item?.logo[0]?.Footerlogo);
|
||||||
|
// setAdminlogo(item?.logo[0]?.Adminlogo);
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
getConfiguration();
|
getConfiguration();
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -1,423 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
|
|
||||||
import swal from "sweetalert";
|
|
||||||
import ClipLoader from "react-spinners/ClipLoader";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import axios from "axios";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { object } from "prop-types";
|
|
||||||
|
|
||||||
function Web_Images() {
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [RegisterImglogo, setRegisterImglogo] = useState("");
|
|
||||||
const [LoginImg, setLoginImg] = useState("");
|
|
||||||
const [ShopImg, setShopImg] = useState("");
|
|
||||||
const [display, setDisplay] = useState(true);
|
|
||||||
const token = isAutheticated();
|
|
||||||
|
|
||||||
// urlcreated images
|
|
||||||
|
|
||||||
const [RegisterImglogoUrl, setRegisterImglogoUrl] = useState("");
|
|
||||||
const [LoginImgUrl, setLoginImgUrl] = useState("");
|
|
||||||
const [ShopImgUrl, setShopImgUrl] = useState("");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// async function getConfiguration() {
|
|
||||||
// const configDetails = await axios.get(`/api/config`, {
|
|
||||||
// headers: {
|
|
||||||
// Authorization: `Bearer ${token}`,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// console.log("configDetails.data.result", configDetails.data.result);
|
|
||||||
// configDetails.data.result.map((item) => {
|
|
||||||
// setRegisterImglogo(item?.logo[0]?.Adminlogo);
|
|
||||||
// setLoginImg(item?.logo[0]?.Footerlogo);
|
|
||||||
// setShopImg(item?.logo[0]?.Adminlogo);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
const getRegisterImage = async () => {
|
|
||||||
const response = await axios.get("/api/registerImage/getImage", {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (response.status === 200) {
|
|
||||||
setRegisterImglogo(response?.data?.image[0]?.image?.secure_url);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getLoginImage = async () => {
|
|
||||||
const response = await axios.get("/api/loginImage/getImage", {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (response.status === 200) {
|
|
||||||
setLoginImg(response?.data?.image[0]?.image?.secure_url);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getShopImage = async () => {
|
|
||||||
const response = await axios.get("/api/shopImage/getImage", {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (response.status === 200) {
|
|
||||||
setShopImg(response?.data?.image[0]?.image?.secure_url);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
getRegisterImage();
|
|
||||||
getLoginImage();
|
|
||||||
getShopImage();
|
|
||||||
}, []);
|
|
||||||
// async function handelChange(e) {
|
|
||||||
// setDisplay(false);
|
|
||||||
// console.log(e.target.name === "Web_Images htmlFor Website RegisterImg(148 x 48 px)");
|
|
||||||
// if (e.target.name === "Web_Images htmlFor Website RegisterImg(148 x 48 px)") {
|
|
||||||
// console.log(e.target.files[0]);
|
|
||||||
// setRegisterImglogo(e.target.files[0]);
|
|
||||||
// } else if (e.target.name === "Web_Images htmlFor Website Footer(148 x 48 px)") {
|
|
||||||
// setLoginImg(e.target.files[0]);
|
|
||||||
// } else if (e.target.name === "Web_Images htmlFor Admin RegisterImg(148 x 48 px)") {
|
|
||||||
// setShopImg(e.target.files[0]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
const [Rloading, setRLoading] = useState(false);
|
|
||||||
async function handeRegister(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (typeof RegisterImglogo !== "object" || RegisterImglogo === null) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please select file",
|
|
||||||
icon: "warning",
|
|
||||||
button: "Ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formdata = new FormData();
|
|
||||||
formdata.append("RegisterImglogo", RegisterImglogo);
|
|
||||||
setRLoading(true);
|
|
||||||
await axios
|
|
||||||
.post(`/api/registerImage/addmodify/`, formdata, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/formdata",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setRLoading(false);
|
|
||||||
swal("Success!", res.data.message);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setRLoading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const [Lloading, setLLoading] = useState(false);
|
|
||||||
|
|
||||||
async function handeLogin(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (typeof LoginImg !== "object" || LoginImg === null) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please select file",
|
|
||||||
icon: "warning",
|
|
||||||
button: "Ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formdata = new FormData();
|
|
||||||
formdata.append("LoginImg", LoginImg);
|
|
||||||
setLLoading(true);
|
|
||||||
|
|
||||||
await axios
|
|
||||||
.post(`/api/loginImage/addmodify/`, formdata, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/formdata",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setLLoading(false);
|
|
||||||
swal("Success!", res.data.message);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setLLoading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [Shoploading, setShoploading] = useState(false);
|
|
||||||
async function handeShopImage(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
if (typeof ShopImg !== "object" || ShopImg === null) {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please select file",
|
|
||||||
icon: "warning",
|
|
||||||
button: "Ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formdata = new FormData();
|
|
||||||
formdata.append("ShopImg", ShopImg);
|
|
||||||
setShoploading(true);
|
|
||||||
await axios
|
|
||||||
.post(`/api/shopImage/addmodify/`, formdata, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
"Content-Type": "multipart/formdata",
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
setShoploading(false);
|
|
||||||
swal("Success!", res.data.message);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setShoploading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// async function handelSubmit() {
|
|
||||||
// setLoading(true);
|
|
||||||
|
|
||||||
// const formdata = new FormData();
|
|
||||||
// formdata.append("RegisterImglogo", RegisterImglogo);
|
|
||||||
// formdata.append("LoginImg", LoginImg);
|
|
||||||
// formdata.append("ShopImg", ShopImg);
|
|
||||||
|
|
||||||
// await axios
|
|
||||||
// .post(`/api/config/logo`, formdata, {
|
|
||||||
// headers: {
|
|
||||||
// Authorization: `Bearer ${token}`,
|
|
||||||
// "Content-Type": "multipart/formdata",
|
|
||||||
// "Access-Control-Allow-Origin": "*",
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// .then((res) => {
|
|
||||||
// setLoading(false);
|
|
||||||
// swal("Success!", res.data.message, res.data.status);
|
|
||||||
// })
|
|
||||||
// .catch((error) => {
|
|
||||||
// setLoading(false);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-12 col-lg-6 col-xl-6">
|
|
||||||
<h1 className="text-left head-small">Website Images</h1>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group">
|
|
||||||
<>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100 mt-3"
|
|
||||||
style={{ fontWeight: "bold" }}
|
|
||||||
>
|
|
||||||
Register Image for Website(800 x 600 pixels){" "}
|
|
||||||
<br />
|
|
||||||
</label>
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
name="Register_Images htmlFor Website RegisterImg(800 x 600 pixels)"
|
|
||||||
onChange={(e) => {
|
|
||||||
setRegisterImglogo(e.target.files[0]);
|
|
||||||
if (
|
|
||||||
e.target.files &&
|
|
||||||
e.target.files[0]
|
|
||||||
) {
|
|
||||||
setRegisterImglogoUrl({
|
|
||||||
image: URL.createObjectURL(
|
|
||||||
e.target.files[0]
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="form-control input-field mb-3 col-md-6 d-inline-block"
|
|
||||||
id="basicpill-phoneno-input"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
className="mx-2 mb-1 btn btn-success"
|
|
||||||
onClick={(e) => handeRegister(e)}
|
|
||||||
>
|
|
||||||
<ClipLoader
|
|
||||||
loading={Rloading}
|
|
||||||
size={18}
|
|
||||||
/>
|
|
||||||
{!Rloading && "New"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{display ? (
|
|
||||||
<img
|
|
||||||
className="ms-1"
|
|
||||||
style={{ width: "100px" }}
|
|
||||||
src={
|
|
||||||
RegisterImglogoUrl.image
|
|
||||||
? RegisterImglogoUrl.image
|
|
||||||
: RegisterImglogo
|
|
||||||
}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100 mt-3"
|
|
||||||
style={{ fontWeight: "bold" }}
|
|
||||||
>
|
|
||||||
{/* Web_Images htmlFor Website Footer(148 x 48 px) */}
|
|
||||||
Login logo for Website(800 x 600 pixels){" "}
|
|
||||||
<br />
|
|
||||||
</label>
|
|
||||||
<br />
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
name="Web_Images htmlFor Website Footer(800 x 600 px)"
|
|
||||||
onChange={(e) => {
|
|
||||||
setLoginImg(e.target.files[0]);
|
|
||||||
|
|
||||||
if (e.target.files && e.target.files[0]) {
|
|
||||||
setLoginImgUrl({
|
|
||||||
image: URL.createObjectURL(
|
|
||||||
e.target.files[0]
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="form-control input-field mt-1 col-md-6 d-inline-block"
|
|
||||||
id="basicpill-phoneno-input"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
className="mx-2 btn mb-1 btn-success"
|
|
||||||
onClick={(e) => handeLogin(e)}
|
|
||||||
>
|
|
||||||
<ClipLoader loading={Lloading} size={18} />
|
|
||||||
{!Lloading && "New"}
|
|
||||||
</button>{" "}
|
|
||||||
{display ? (
|
|
||||||
<img
|
|
||||||
style={{ width: "100px" }}
|
|
||||||
src={
|
|
||||||
LoginImgUrl.image
|
|
||||||
? LoginImgUrl.image
|
|
||||||
: LoginImg
|
|
||||||
}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
<label
|
|
||||||
htmlFor="basicpill-phoneno-input"
|
|
||||||
className="label-100 mt-2 row ms-1"
|
|
||||||
style={{ fontWeight: "bold" }}
|
|
||||||
>
|
|
||||||
{/* Web_Images htmlFor Admin RegisterImg(148 x 48 px) */}
|
|
||||||
Shop Page Image for website(1200 x 800
|
|
||||||
pixels) <br />
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
name="Web_Images htmlFor Admin RegisterImg(1200 x 800 px)"
|
|
||||||
onChange={(e) => {
|
|
||||||
setShopImg(e.target.files[0]);
|
|
||||||
|
|
||||||
if (e.target.files && e.target.files[0]) {
|
|
||||||
setShopImgUrl({
|
|
||||||
image: URL.createObjectURL(
|
|
||||||
e.target.files[0]
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="form-control input-field col-md-6 d-inline-block"
|
|
||||||
id="basicpill-phoneno-input"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
className="mx-2 btn btn-login btn-success mb-1"
|
|
||||||
onClick={(e) => handeShopImage(e)}
|
|
||||||
>
|
|
||||||
<ClipLoader
|
|
||||||
loading={Shoploading}
|
|
||||||
size={18}
|
|
||||||
/>
|
|
||||||
{!Shoploading && "New"}{" "}
|
|
||||||
</button>{" "}
|
|
||||||
{display ? (
|
|
||||||
<img
|
|
||||||
style={{ width: "100px" }}
|
|
||||||
src={
|
|
||||||
ShopImgUrl.image
|
|
||||||
? ShopImgUrl.image
|
|
||||||
: ShopImg
|
|
||||||
}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <div className="row">
|
|
||||||
<div className="col-lg-12">
|
|
||||||
<div className="form-group text-left">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
disabled={
|
|
||||||
ShopImg === "" ||
|
|
||||||
LoginImg === "" ||
|
|
||||||
RegisterImglogo === ""
|
|
||||||
}
|
|
||||||
onClick={handelSubmit}
|
|
||||||
className="btn btn-success btn-login waves-effect waves-light mr-3 pt-2 pb-2 pr-4 pl-4"
|
|
||||||
>
|
|
||||||
<ClipLoader loading={loading} size={18} />
|
|
||||||
{!loading && "Save"}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <!-- end table-responsive --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <!-- container-fluid --> */}
|
|
||||||
</div>
|
|
||||||
{/* <!-- End Page-content --> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Web_Images;
|
|
@ -81,7 +81,7 @@ function Addtax() {
|
|||||||
justify-content-between
|
justify-content-between
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<h4 className="mb-0">Add New VAT Rate</h4>
|
<h4 className="mb-0">Add New GST Rate</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -102,7 +102,7 @@ function Addtax() {
|
|||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Link to="/vat">
|
<Link to="/tax">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="
|
className="
|
||||||
@ -186,7 +186,7 @@ function Addtax() {
|
|||||||
htmlFor="basicpill-phoneno-input"
|
htmlFor="basicpill-phoneno-input"
|
||||||
className="label-100"
|
className="label-100"
|
||||||
>
|
>
|
||||||
VAT Rate (in %)*
|
GST Rate (in %)*
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
value={data.tax}
|
value={data.tax}
|
||||||
|
@ -112,7 +112,7 @@ function Edittax() {
|
|||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Link to="/vat">
|
<Link to="/tax">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="
|
className="
|
||||||
@ -196,7 +196,7 @@ function Edittax() {
|
|||||||
htmlFor="basicpill-phoneno-input"
|
htmlFor="basicpill-phoneno-input"
|
||||||
className="label-100"
|
className="label-100"
|
||||||
>
|
>
|
||||||
VAT Rate (in %)*
|
GST Rate (in %)*
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
value={data.tax}
|
value={data.tax}
|
||||||
|
@ -65,7 +65,7 @@ function Tax() {
|
|||||||
className="fa fa-plus mb-2"
|
className="fa fa-plus mb-2"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>{" "}
|
></i>{" "}
|
||||||
Add New VAT Rate
|
Add New GST Rate
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -79,7 +79,7 @@ function Tax() {
|
|||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>VAT Rate</th>
|
<th>GST Rate</th>
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -1,945 +0,0 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
|
||||||
import axios from "axios";
|
|
||||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
|
||||||
import QRCode from "react-qr-code";
|
|
||||||
import { isAutheticated } from "src/auth";
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
|
||||||
import { addItemsToCart } from "src/redux/Actions/cartAction";
|
|
||||||
import toast from "react-hot-toast";
|
|
||||||
import { cibBlackberry } from "@coreui/icons";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
|
|
||||||
function POSViewOrders() {
|
|
||||||
const { status, id } = useParams();
|
|
||||||
const [success, setSuccess] = useState(true);
|
|
||||||
|
|
||||||
const { cartItems, subTotal, shippingCharge, tax, shipingInfo, total } =
|
|
||||||
useSelector((state) => state.cart);
|
|
||||||
|
|
||||||
const AllStates = useSelector((state) => state);
|
|
||||||
const getValue = useRef();
|
|
||||||
const getFranchiseeID = useRef();
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const printOrderRef = useRef();
|
|
||||||
const token = isAutheticated();
|
|
||||||
const [productData, setProductData] = useState([]);
|
|
||||||
const [allFranchisee, setAllFranchisee] = useState([]);
|
|
||||||
const [allTax, setAllTax] = useState([]);
|
|
||||||
const [orderDetails, setOrderDetails] = useState();
|
|
||||||
|
|
||||||
const [productDetails, setProductDetails] = useState();
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [orderId, setOrderId] = useState(null);
|
|
||||||
const [orderStatus, setOrderStatus] = useState("");
|
|
||||||
// const [data, setData] = useState({
|
|
||||||
// product_Name: '',
|
|
||||||
// address: '',
|
|
||||||
// quantity: '',
|
|
||||||
// contact_Number: '',
|
|
||||||
// total_Price: '',
|
|
||||||
// })
|
|
||||||
useEffect(() => {
|
|
||||||
const getSingleOrder = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
const res = await axios.get(`/api/order/getOne/${id}`, {
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (res.data) {
|
|
||||||
setLoading(false);
|
|
||||||
setOrderId(res.data?.order?.order_id);
|
|
||||||
setOrderDetails(res.data?.order);
|
|
||||||
console.log(res.data);
|
|
||||||
// let options = {
|
|
||||||
// Franchisee: res.data?.order?.shippingInfo?.Franchisee?._id,
|
|
||||||
// name: res.data?.order?.shippingInfo?.name,
|
|
||||||
|
|
||||||
// contact_Number: res.data?.order?.shippingInfo?.contact_Number,
|
|
||||||
// contact_Person_Name: res.data?.order?.shippingInfo?.contact_Person_Name,
|
|
||||||
// address: res.data?.order?.shippingInfo?.address,
|
|
||||||
// city: res.data?.order?.shippingInfo?.city,
|
|
||||||
// price_Lable: res.data?.order?.shippingInfo?.Franchisee?.price_Lable,
|
|
||||||
// state: res.data?.order?.shippingInfo?.state,
|
|
||||||
// banner: res.data?.order?.shippingInfo?.Franchisee?.banner?.url,
|
|
||||||
// // Franchisee_Url: res?.data?.data?.url
|
|
||||||
// }
|
|
||||||
// dispatch({ type: "addShippingInfo", payload: options });
|
|
||||||
// if (res.data?.order?.orderItems) {
|
|
||||||
// res.data?.order?.orderItems.map((i, ind) => {
|
|
||||||
// dispatch({ type: "addToCart", payload: i });
|
|
||||||
// dispatch({ type: "calculatePrice" });
|
|
||||||
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
getSingleOrder();
|
|
||||||
}, [token]);
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
if (e.target.type === "text") {
|
|
||||||
setData((prev) => ({ ...prev, [e.target.id]: e.target.value }));
|
|
||||||
} else {
|
|
||||||
if (e.target.value === "") toast.error("please select status");
|
|
||||||
setOrderStatus(e.target.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const handleQuantityChange = (e) => {
|
|
||||||
setData((prev) => ({
|
|
||||||
...prev,
|
|
||||||
quantity: e.target.value,
|
|
||||||
total_Price: productDetails?.base_Price * e.target.value,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
// ------------------------------------------------------
|
|
||||||
|
|
||||||
const handlechangestatus = () => {
|
|
||||||
if (orderStatus === "dispatched") {
|
|
||||||
swal({
|
|
||||||
title: `Are you sure for ${orderStatus}?`,
|
|
||||||
icon: "warning",
|
|
||||||
content: {
|
|
||||||
element: "div",
|
|
||||||
attributes: {
|
|
||||||
innerHTML:
|
|
||||||
'<input id="input1" placeholder="Enter Courier Name" className="swal2-input" style="margin:3px;height:40px;text-align:center;">' +
|
|
||||||
'<input id="input2" placeholder="Courier Tracking ID" className="swal2-input" style="margin:3px;height:40px;text-align:center;">',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Submit", value: true },
|
|
||||||
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((result) => {
|
|
||||||
if (result === true) {
|
|
||||||
// You have the input values, you can use them in your API call
|
|
||||||
const courierName = document.getElementById("input1").value.trim();
|
|
||||||
const TrackingID = document.getElementById("input2").value.trim();
|
|
||||||
|
|
||||||
// Check if values are entered
|
|
||||||
if (courierName === "" || TrackingID === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please enter values Courier Name And Tracking ID",
|
|
||||||
icon: "warning",
|
|
||||||
button: "Ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
axios
|
|
||||||
.patch(
|
|
||||||
`/api/order/change/status/${id}`,
|
|
||||||
{
|
|
||||||
status: orderStatus,
|
|
||||||
courierName,
|
|
||||||
TrackingID,
|
|
||||||
sendemail: orderDetails?.user?.email,
|
|
||||||
customerName: orderDetails?.user?.name,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
console.log("status");
|
|
||||||
toast.success(
|
|
||||||
`Order status change ${status} to ${orderStatus}`
|
|
||||||
);
|
|
||||||
// setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: err.response.data.message
|
|
||||||
? err.response.data.message
|
|
||||||
: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// swal.close(); // Close the popup if canceled
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
} else if (orderStatus === "cancelled") {
|
|
||||||
swal({
|
|
||||||
title: `Are you sure for ${orderStatus}?`,
|
|
||||||
icon: "warning",
|
|
||||||
content: {
|
|
||||||
element: "div",
|
|
||||||
attributes: {
|
|
||||||
innerHTML:
|
|
||||||
'<p>Reson for cancellation.?</p><input id="input1" placeholder="Enter Reason for Cancellation" className="swal2-input" style="margin:3px;height:40px;text-align:center;">',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Submit", value: true },
|
|
||||||
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((result) => {
|
|
||||||
if (result === true) {
|
|
||||||
// You have the input values, you can use them in your API call
|
|
||||||
const ReasonforCancellation = document
|
|
||||||
.getElementById("input1")
|
|
||||||
.value.trim();
|
|
||||||
|
|
||||||
// Check if values are entered
|
|
||||||
if (ReasonforCancellation === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please enter Reason for Cancellation",
|
|
||||||
icon: "warning",
|
|
||||||
button: "Ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
axios
|
|
||||||
.patch(
|
|
||||||
`/api/order/change/status/${id}`,
|
|
||||||
{
|
|
||||||
status: orderStatus,
|
|
||||||
ReasonforCancellation,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
console.log("status");
|
|
||||||
toast.success(
|
|
||||||
`Order status change ${status} to ${orderStatus}`
|
|
||||||
);
|
|
||||||
// setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: err.response.data.message
|
|
||||||
? err.response.data.message
|
|
||||||
: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// swal.close(); // Close the popup if canceled
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
} else if (orderStatus === "delivered") {
|
|
||||||
swal({
|
|
||||||
title: `Are you sure for ${orderStatus}?`,
|
|
||||||
icon: "warning",
|
|
||||||
content: {
|
|
||||||
element: "div",
|
|
||||||
attributes: {
|
|
||||||
innerHTML:
|
|
||||||
'<input id="input1" type="date" placeholder="Delivered ON" className="swal2-input" style="height:40px;text-align:center;">',
|
|
||||||
// '<input id="input2" placeholder="Courier Tracking ID" className="swal2-input" style="margin:3px;height:40px">',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Submit", value: true },
|
|
||||||
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((result) => {
|
|
||||||
if (result === true) {
|
|
||||||
// You have the input values, you can use them in your API call
|
|
||||||
const DDate = document.getElementById("input1").value.trim();
|
|
||||||
|
|
||||||
// Check if values are entered
|
|
||||||
if (DDate === "") {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: "Please enter Delivered Date",
|
|
||||||
icon: "warning",
|
|
||||||
button: "Ok",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
axios
|
|
||||||
.patch(
|
|
||||||
`/api/order/change/status/${id}`,
|
|
||||||
{
|
|
||||||
status: orderStatus,
|
|
||||||
DDate,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
console.log("status");
|
|
||||||
toast.success(
|
|
||||||
`Order status change ${status} to ${orderStatus}`
|
|
||||||
);
|
|
||||||
// setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: err.response.data.message
|
|
||||||
? err.response.data.message
|
|
||||||
: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// swal.close(); // Close the popup if canceled
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
swal({
|
|
||||||
title: `Are you sure for ${orderStatus}?`,
|
|
||||||
icon: "warning",
|
|
||||||
|
|
||||||
buttons: {
|
|
||||||
Yes: { text: "Yes", value: true },
|
|
||||||
Cancel: { text: "Cancel", value: "cancel" },
|
|
||||||
},
|
|
||||||
}).then((value) => {
|
|
||||||
if (value === true) {
|
|
||||||
axios
|
|
||||||
.patch(
|
|
||||||
`/api/order/change/status/${id}`,
|
|
||||||
{ status: orderStatus },
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
console.log("status");
|
|
||||||
toast.success(`order status change ${status} to ${orderStatus}`);
|
|
||||||
// setSuccess((prev) => !prev);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
swal({
|
|
||||||
title: "Warning",
|
|
||||||
text: err.response.data.message
|
|
||||||
? err.response.data.message
|
|
||||||
: "Something went wrong!",
|
|
||||||
icon: "error",
|
|
||||||
button: "Retry",
|
|
||||||
dangerMode: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function getBack() {
|
|
||||||
navigate(`/orders/${status}`, { replace: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{" "}
|
|
||||||
<div className="main-content">
|
|
||||||
<div className="page-content">
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-12">
|
|
||||||
<div
|
|
||||||
className="
|
|
||||||
page-title-box
|
|
||||||
d-flex
|
|
||||||
align-items-center
|
|
||||||
justify-content-between
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div style={{ fontSize: "22px" }} className="fw-bold">
|
|
||||||
<p> View Order</p>
|
|
||||||
</div>
|
|
||||||
<div className="m-4">
|
|
||||||
{orderDetails?.orderID && (
|
|
||||||
<span>
|
|
||||||
<h6 className="">Order ID : {orderDetails?.orderID}</h6>{" "}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{orderDetails?.courier_name && (
|
|
||||||
<div className="m-4">
|
|
||||||
<span>
|
|
||||||
<h6 className="">
|
|
||||||
Courier Name: {orderDetails?.courier_name}
|
|
||||||
</h6>{" "}
|
|
||||||
<h6 className="">
|
|
||||||
Tracking ID : {orderDetails?.courier_tracking_id}
|
|
||||||
</h6>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{orderDetails?.isDelivered && (
|
|
||||||
<div className="m-4">
|
|
||||||
<span>
|
|
||||||
<h6 className="">Delivered: Yes</h6>{" "}
|
|
||||||
<h6 className="">
|
|
||||||
Delivered Date: {orderDetails?.DeliveredDate}
|
|
||||||
</h6>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="page-title-right">
|
|
||||||
{/* <Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
style={{
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginBottom: '1rem',
|
|
||||||
textTransform: 'capitalize',
|
|
||||||
marginRight: '5px',
|
|
||||||
}}
|
|
||||||
onClick={() => handleSubmit()}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{loading ? 'Loading' : 'Edit Now'}
|
|
||||||
</Button> */}
|
|
||||||
|
|
||||||
<Link
|
|
||||||
to={
|
|
||||||
orderDetails?.paymentMode === "cod"
|
|
||||||
? `/inStoreCashOrders/${status}`
|
|
||||||
: `/InStoreQRCodeOrders/${status}`
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
style={{
|
|
||||||
fontWeight: "bold",
|
|
||||||
marginBottom: "1rem",
|
|
||||||
textTransform: "capitalize",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{loading ? (
|
|
||||||
<div className="d-flex justify-content-center">
|
|
||||||
<div className="spinner-border text-info" role="status">
|
|
||||||
<span className="visually-hidden">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-7 mt-3">
|
|
||||||
{orderDetails?.shipingInfo !== null && (
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
{/* <div className="mt-1">
|
|
||||||
<label className="fw-bold">Select Product:</label>
|
|
||||||
<div className="d-flex">
|
|
||||||
<select
|
|
||||||
className="form-control me-2"
|
|
||||||
// onChange={handleGetSingleProduct}
|
|
||||||
// value={productData?._id}
|
|
||||||
ref={getValue}
|
|
||||||
|
|
||||||
>
|
|
||||||
<option value="" >-----</option>
|
|
||||||
{productData && productData.map((item, index) =>
|
|
||||||
<option key={index} value={item?._id}>{item?.name}</option>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</select>
|
|
||||||
<button className='btn-sm btn-primary' onClick={(e) => handleGetSingleProduct(e)}>Add</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<div className="mt-2">
|
|
||||||
<h6 className="fw-bold">
|
|
||||||
Products : {orderDetails?.orderItems?.length}
|
|
||||||
</h6>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
{orderDetails?.orderItems &&
|
|
||||||
orderDetails?.orderItems.map(
|
|
||||||
(productDetails, i) => (
|
|
||||||
<div className="my-2">
|
|
||||||
<div
|
|
||||||
className="row"
|
|
||||||
style={{ fontSize: "14px" }}
|
|
||||||
>
|
|
||||||
<div className="col-sm-4">
|
|
||||||
<img
|
|
||||||
src={productDetails?.image[0]?.url}
|
|
||||||
alt={productDetails?.name}
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
objectFit: "contain",
|
|
||||||
maxHeight: "150px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-sm-8">
|
|
||||||
<h6 className="m-0 ms-2">
|
|
||||||
{productDetails?.name}
|
|
||||||
</h6>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-sm-6">
|
|
||||||
<div
|
|
||||||
className="d-flex justify-content-center mt-3 me-3 "
|
|
||||||
style={{
|
|
||||||
width: "6rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className="px-2 mt-1"
|
|
||||||
style={{}}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Quantity:{" "}
|
|
||||||
{productDetails?.quantity}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p className="m-0 mt-3 ms-3">
|
|
||||||
<stong> Subtotal:</stong> ₹
|
|
||||||
{productDetails?.product_Subtotal}
|
|
||||||
</p>
|
|
||||||
<p className="m-0 mt-3 ms-3">
|
|
||||||
<stong> Variant:</stong>{" "}
|
|
||||||
{productDetails?.variant_Name}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="col-sm-6">
|
|
||||||
<p className="m-0 mt-3">
|
|
||||||
<stong> Price:</stong> ₹
|
|
||||||
{productDetails?.price}
|
|
||||||
</p>
|
|
||||||
<p className="m-0 mt-3">
|
|
||||||
<stong> GST:</stong> ₹
|
|
||||||
{productDetails?.gst_amount}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
<div className="m-0 contents-center mt-3 mb-2">
|
|
||||||
<small className="mb-4">Shipping Charge: </small> ₹
|
|
||||||
{orderDetails?.shipping_charge}
|
|
||||||
<br />
|
|
||||||
<span className="mt-2"> Total Order Value: </span> ₹
|
|
||||||
{orderDetails?.total_amount}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="card my-1">
|
|
||||||
<div className="card-body">
|
|
||||||
<label className="fw-bold">Status Timeline :</label>
|
|
||||||
<table
|
|
||||||
className="table table-info table-sm m-0"
|
|
||||||
style={{
|
|
||||||
borderRadius: "8px",
|
|
||||||
borderCollapse: "collapse",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr className="text-center">
|
|
||||||
<th scope="row">Order Placed On</th>
|
|
||||||
<td> : </td>
|
|
||||||
<td>
|
|
||||||
{orderDetails?.createdAt
|
|
||||||
? new Date(
|
|
||||||
orderDetails?.createdAt
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})
|
|
||||||
: new Date(
|
|
||||||
productData?.placed_on
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr className="text-center">
|
|
||||||
<th scope="row" className="text-warning">
|
|
||||||
Processing Started
|
|
||||||
</th>
|
|
||||||
<td className="text-warning"> : </td>
|
|
||||||
<td className="text-warning">
|
|
||||||
{orderDetails?.status_timeline?.processing
|
|
||||||
? new Date(
|
|
||||||
orderDetails?.status_timeline?.processing
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})
|
|
||||||
: "-"}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr className="text-center">
|
|
||||||
<th scope="row" className="text-primary">
|
|
||||||
Dispatched On
|
|
||||||
</th>
|
|
||||||
<td className="text-primary"> : </td>
|
|
||||||
<td className="text-primary">
|
|
||||||
{orderDetails?.status_timeline?.dispatched
|
|
||||||
? new Date(
|
|
||||||
orderDetails?.status_timeline?.dispatched
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})
|
|
||||||
: "-"}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr className="text-center">
|
|
||||||
<th scope="row" className="text-success">
|
|
||||||
Delivered On
|
|
||||||
</th>
|
|
||||||
<td className="text-success"> : </td>
|
|
||||||
<td className="text-success">
|
|
||||||
{orderDetails?.status_timeline?.delivered
|
|
||||||
? new Date(
|
|
||||||
orderDetails?.status_timeline?.delivered
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})
|
|
||||||
: "-"}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{orderDetails?.status_timeline?.cancelled && (
|
|
||||||
<tr className="text-center">
|
|
||||||
<th scope="row" className="text-danger">
|
|
||||||
Cancelled On
|
|
||||||
</th>
|
|
||||||
<td className="text-danger"> : </td>
|
|
||||||
<td className="text-danger">
|
|
||||||
{orderDetails?.status_timeline?.cancelled
|
|
||||||
? new Date(
|
|
||||||
orderDetails?.status_timeline?.cancelled
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})
|
|
||||||
: "-"}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{/* <tr className="text-center">
|
|
||||||
<th scope="row">Returned On</th>
|
|
||||||
<td> : </td>
|
|
||||||
<td>
|
|
||||||
{orderDetails?.status_timeline?.returned
|
|
||||||
? new Date(
|
|
||||||
orderDetails?.status_timeline?.returned
|
|
||||||
).toLocaleString("en-IN", {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
})
|
|
||||||
: "-"}
|
|
||||||
</td>
|
|
||||||
</tr> */}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg-5 mt-3">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="mt-1">
|
|
||||||
{orderDetails?.orderStatus !== "cancelled" ? (
|
|
||||||
<h5 className="text-success">
|
|
||||||
Order Status: {orderDetails?.orderStatus}
|
|
||||||
</h5>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<h5 className="text-danger">
|
|
||||||
Order Status: {orderDetails?.orderStatus}
|
|
||||||
</h5>
|
|
||||||
<p className="text-danger">
|
|
||||||
{" "}
|
|
||||||
Order Cancelled Reason:{" "}
|
|
||||||
{orderDetails?.order_Cancelled_Reason}
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{/* order status change */}{" "}
|
|
||||||
<div className="mb-2">
|
|
||||||
{" "}
|
|
||||||
{status !== "cancelled" &&
|
|
||||||
status !== "returned" &&
|
|
||||||
status !== "delivered" && (
|
|
||||||
<div className="mt-1">
|
|
||||||
<label className="fw-bold">
|
|
||||||
Change Status :
|
|
||||||
</label>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-lg-9">
|
|
||||||
<select
|
|
||||||
className="form-control"
|
|
||||||
onChange={handleChange}
|
|
||||||
value={orderStatus}
|
|
||||||
>
|
|
||||||
{orderDetails?.orderStatus === "new" && (
|
|
||||||
<>
|
|
||||||
<option value="">New</option>
|
|
||||||
<option value="processing">
|
|
||||||
Processing
|
|
||||||
</option>
|
|
||||||
<option value="cancelled">
|
|
||||||
Cancelled
|
|
||||||
</option>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{orderDetails?.orderStatus ===
|
|
||||||
"processing" && (
|
|
||||||
<>
|
|
||||||
<option value="">Processing</option>
|
|
||||||
<option value="dispatched">
|
|
||||||
Dispatch
|
|
||||||
</option>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{orderDetails?.orderStatus ===
|
|
||||||
"dispatched" && (
|
|
||||||
<>
|
|
||||||
<option value="">Dispatch</option>
|
|
||||||
<option value="delivered">
|
|
||||||
Delivered
|
|
||||||
</option>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
{orderStatus && (
|
|
||||||
<div className="col-lg-3">
|
|
||||||
<button
|
|
||||||
className="btn btn-primary"
|
|
||||||
onClick={(e) => handlechangestatus(e)}
|
|
||||||
>
|
|
||||||
Update
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{/* */}
|
|
||||||
<label className="fw-bold mt-1">Shipping Info :</label>
|
|
||||||
{/* <div className="d-flex">
|
|
||||||
<select
|
|
||||||
className="form-control me-2"
|
|
||||||
onChange={handleChange}
|
|
||||||
value={orderStatus}
|
|
||||||
ref={getFranchiseeID}
|
|
||||||
disabled={shipingInfo !== null}
|
|
||||||
>
|
|
||||||
<option value="" disabled></option>
|
|
||||||
{allFranchisee && allFranchisee.map((item, index) =>
|
|
||||||
<option key={index} value={item?._id}>{item?.name}</option>
|
|
||||||
)}
|
|
||||||
</select>
|
|
||||||
<button className='btn-sm btn-primary' onClick={(e) => handleGetSingleFrenchisee(e)} >Add</button>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
{orderDetails?.shipingInfo !== null && (
|
|
||||||
<div className="">
|
|
||||||
<div className="row" style={{ fontSize: "14px" }}>
|
|
||||||
{/* <div className="col-sm-4">
|
|
||||||
<img
|
|
||||||
src={
|
|
||||||
orderDetails?.shippingInfo?.Franchisee?.banner
|
|
||||||
?.url
|
|
||||||
}
|
|
||||||
alt={orderDetails?.shippingInfo?.name}
|
|
||||||
// width='100%'
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
objectFit: "contain",
|
|
||||||
maxHeight: "100px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div> */}
|
|
||||||
<div className="col-sm-12">
|
|
||||||
<h6 className="m-0 ms-2">
|
|
||||||
Name: {orderDetails?.shippingInfo?.first_Name}{" "}
|
|
||||||
{orderDetails?.shippingInfo?.last_Name}
|
|
||||||
</h6>
|
|
||||||
|
|
||||||
<p className="m-0 ms-2 mt-1">
|
|
||||||
Contact No. :{" "}
|
|
||||||
{orderDetails?.shippingInfo?.phone_Number}
|
|
||||||
</p>
|
|
||||||
<parent className="m-0 ms-2 mt-3">
|
|
||||||
street. : {orderDetails?.shippingInfo?.street}
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<p className="m-0 ms-2 mt-1">
|
|
||||||
City : {orderDetails?.shippingInfo?.city}
|
|
||||||
</p>
|
|
||||||
<p className="m-0 ms-2 mt-1">
|
|
||||||
State : {orderDetails?.shippingInfo?.state}
|
|
||||||
</p>
|
|
||||||
<p className="m-0 ms-2 mt-1">
|
|
||||||
country : {orderDetails?.shippingInfo?.country}
|
|
||||||
</p>
|
|
||||||
<p className="m-0 ms-2 mt-1">
|
|
||||||
Postal Code. :{" "}
|
|
||||||
{orderDetails?.shippingInfo?.postalCode}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="mt-3">
|
|
||||||
<label>
|
|
||||||
<span className="fw-bold">Payment Status : </span>
|
|
||||||
{orderDetails?.isPaid === false ? (
|
|
||||||
<span className="fw-bold text-danger">
|
|
||||||
Not Paid
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span className="fw-bold text-success">Paid</span>
|
|
||||||
)}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="">
|
|
||||||
<label>
|
|
||||||
<span className="fw-bold">Payment Mode : </span>
|
|
||||||
{orderDetails?.paymentMode === "online" ? (
|
|
||||||
<span className="fw-bold text-success">ONLINE</span>
|
|
||||||
) : (
|
|
||||||
<span className="fw-bold text-primary">
|
|
||||||
CASH ON DELIVERY
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="">
|
|
||||||
<label>
|
|
||||||
<span className="fw-bold"> Paid At: </span>
|
|
||||||
|
|
||||||
{orderDetails?.paidAt
|
|
||||||
? new Date(orderDetails?.paidAt).toLocaleString(
|
|
||||||
"en-IN",
|
|
||||||
{
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "numeric",
|
|
||||||
hour12: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
: "----"}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="">
|
|
||||||
<label>
|
|
||||||
<span className="fw-bold"> Order Created By: </span>
|
|
||||||
{orderDetails?.user?.name}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="mt-1">
|
|
||||||
<label>
|
|
||||||
<span className="fw-bold">
|
|
||||||
Razorpay Payment ID :{" "}
|
|
||||||
</span>
|
|
||||||
{orderDetails?.razorpay_payment_id
|
|
||||||
? orderDetails?.razorpay_payment_id
|
|
||||||
: "----"}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="">
|
|
||||||
<label>
|
|
||||||
<span className="fw-bold">Razorpay Order ID : </span>
|
|
||||||
{orderDetails?.razorpay_order_id
|
|
||||||
? orderDetails?.razorpay_order_id
|
|
||||||
: "----"}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ display: "none" }}>
|
|
||||||
{/* <PrintOrderDetails productData={productData} ref={printOrderRef} /> */}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default POSViewOrders;
|
|
@ -178,7 +178,7 @@ const PrintOrderDetails = React.forwardRef(({ orderData }, ref) => {
|
|||||||
<th>Qnty</th>
|
<th>Qnty</th>
|
||||||
<th>Tax Type</th>
|
<th>Tax Type</th>
|
||||||
<th>Gross Amount</th>
|
<th>Gross Amount</th>
|
||||||
<th>VAT Rate</th>
|
<th>GST Rate</th>
|
||||||
<th>Net Amount</th>
|
<th>Net Amount</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
Loading…
Reference in New Issue
Block a user