add commerce

This commit is contained in:
pawan-dot 2022-05-12 16:40:44 +05:30
parent ebaa25028a
commit 2d1d8a380d
14 changed files with 705 additions and 13 deletions

View File

@ -39,6 +39,7 @@
"@coreui/utils": "^1.3.1",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
"axios": "^0.25.0",
"bootstrap": "^5.1.3",
"chart.js": "^3.6.0",
"classnames": "^2.3.1",
"core-js": "^3.19.1",
@ -51,10 +52,13 @@
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^5.3.0",
"react-spinners": "^0.11.0",
"redux": "4.1.2",
"serve": "^13.0.2",
"simplebar-react": "^2.3.6",
"sweetalert": "^2.1.2",
"sweetalert2": "^11.4.0",
"webpack": "^4.44.2",
"xlsx": "^0.18.0"
},
"devDependencies": {

View File

@ -15,13 +15,15 @@
<meta name="description" content="CoreUI for React - Open Source Bootstrap Admin Template">
<meta name="author" content="Łukasz Holeczek">
<meta name="keyword" content="Bootstrap,Admin,Template,Open,Source,CSS,SCSS,HTML,RWD,Dashboard,React">
<title>Courier</title>
<title>Cafe-Appy2Meet</title>
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
@ -30,7 +32,12 @@
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<!-- <link href="/assets/css/bootstrap.min.css" rel="stylesheet" /> -->
<!-- <link href="/assets/libs/bootstrap-datepicker/css/bootstrap-datepicker.min.css" rel="stylesheet" /> -->
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" /> -->
</head>
<body>
@ -48,6 +55,9 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
<!-- <script src="/assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script> -->
</html>

View File

@ -9,7 +9,7 @@ const loading = (
<div className="sk-spinner sk-spinner-pulse"></div>
</div>
)
// import EditProducts from './views/Commerce/Editproducts'
// Containers
const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout'))
@ -28,6 +28,11 @@ class App extends Component {
<Route exact path="/" name="Login Page" render={(props) => <Login {...props} />} />
<Route exact path="/forgot" name="Forgot Page" render={(props) => <ForgotPassword {...props} />} />
<Route exact path="/newRegister" name="Register Page" render={(props) => <NewRegister {...props} />} />
{/* <Route exact path="/comproducts/edit/:_id" name="commerce-product-edit" render={(props) => <EditProducts {...props} />} /> */}
{/* <Route
exact
path="/register"

View File

@ -301,6 +301,27 @@ const _nav = [
to: '/profile',
},
{
component: CNavGroup,
name: 'Commerce',
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
items: [
{
component: CNavItem,
name: 'Products',
to: '/comproducts',
},
{
component: CNavItem,
name: 'Coupons',
to: '/comcoupon',
},
],
},
// {
// component: CNavGroup,
// name: 'Profile',

View File

@ -8,7 +8,7 @@ const AppFooter = () => {
{/* <a href="https://coreui.io" target="_blank" rel="noopener noreferrer">
CoreUI
</a> */}
<span className="ms-1">&copy; 2021 Courier.</span>
<span className="ms-1">{new Date().getFullYear()} &copy; Appy2Meet.</span>
</div>
{/* <div className="ms-auto">
<span className="me-1">Powered by</span>

View File

@ -31,7 +31,7 @@ const AppSidebar = () => {
>
<CSidebarBrand className="d-none d-md-flex" to="/">
{/* <CIcon className="sidebar-brand-full" icon={logoNegative} height={35} /> */}
<h1>Courier</h1>
<h1>Appy2Meet</h1>
{/* <CIcon className="sidebar-brand-narrow" height={35} /> */}
<CIcon className="sidebar-brand-narrow" icon={sygnet} height={35} />
</CSidebarBrand>

View File

@ -16,6 +16,7 @@ export const AppSidebarNav = ({ items }) => {
{badge.text}
</CBadge>
)}
</>
)
}
@ -24,17 +25,20 @@ export const AppSidebarNav = ({ items }) => {
const { component, name, badge, icon, ...rest } = item
const Component = component
return (
<Component
{...(rest.to &&
!rest.items && {
<>
<Component
{...(rest.to &&
!rest.items && {
component: NavLink,
activeClassName: 'active',
})}
key={index}
{...rest}
>
{navLink(name, icon, badge)}
</Component>
key={index}
{...rest}
>
{navLink(name, icon, badge)}
</Component>
</>
)
}
const navGroup = (item, index) => {

18
src/data.js Normal file
View File

@ -0,0 +1,18 @@
// export const API = "https://mantur-server.herokuapp.com";
// export const API = "https://api.tellytell.com";
// export const API = "http://localhost:5000";
// export const API = "https://popstoreeee.herokuapp.com";
import { useEffect } from 'react';
//export const API = 'https://dating-api-server.herokuapp.com';
// export const API = 'http://localhost:5000';
export const buildType = 'development';
// export const buildType = 'production'
export const useLogger = (...params) => {
useEffect(() => {
console.log(...params);
}, [params]);
};

View File

@ -1,3 +1,9 @@
// import 'bootstrap/dist/css/bootstrap.min.css';
// import "bootstrap/dist/js/bootstrap.js";
// import "bootstrap";
// import "bootstrap/dist/css/bootstrap.css";
// import "bootstrap/dist/js/bootstrap.js";
import 'react-app-polyfill/stable'
import 'core-js'
import React from 'react'
@ -10,6 +16,7 @@ import axios from 'axios'
const setupAxios = () => {
axios.defaults.baseURL = 'https://dating-api-server.herokuapp.com';
//axios.defaults.baseURL = 'http://localhost:5000'
axios.defaults.headers = {
'Cache-Control': 'no-cache,no-store',
'Pragma': 'no-cache',

View File

@ -1,4 +1,6 @@
import React from 'react'
import Products from './views/Commerce/Products'
import EditProducts from './views/Commerce/Editproducts'
const AirwaysBill = React.lazy(() => import('./views/AirwaysBill/AirwaysBill'))
const EditBill = React.lazy(() => import('./views/AirwaysBill/EditBill'))
@ -70,6 +72,12 @@ const routes = [
{ path: '/register', name: 'Change Password', component: Register },
{ path: '/edit', name: 'Change Password', component: EditProfile },
{ path: '/profile', name: 'Change Password', component: Profile },
//product route
{ path: '/comproducts/edit/:id', name: 'Product Edit', component: EditProducts },
{ path: '/comproducts', name: 'Courier Products', component: Products },
,
////
{ path: '/courier', name: 'Courier', component: Courier },
{ path: '/editcourier/:id', name: ' Edit Courier', component: EditCourier },
{ path: '/addcourier', name: 'Courier / Add Courier', component: AddCourier },

View File

View File

@ -0,0 +1,326 @@
import axios from "axios";
import React, { useCallback, useEffect, useState } from "react";
// import { API } from "../../data";
import { isAutheticated } from "../../auth";
import ClipLoader from "react-spinners/ClipLoader";
import swal from 'sweetalert';
// import "bootstrap";
// import "bootstrap/dist/css/bootstrap.css";
// import "bootstrap/dist/js/bootstrap.js";
import { Link, useParams } from "react-router-dom";
import { useHistory } from "react-router-dom";
function EditProducts() {
const { token } = isAutheticated();
let history = useHistory();
const [state, setstate] = useState({
title: "",
description: "",
status: "",
tax: "",
price: "",
taxes: [],
loading: false,
});
const { id } = useParams();
// console.log(id)
const { title, description, status, tax, price, taxes, loading } = state;
const changeState = (newState) =>
setstate((prevState) => ({ ...prevState, ...newState }));
const fetchTax = useCallback(async () => {
let res = await axios.get(`/api/tax/view_tax`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (res.status === 200) changeState({ taxes: res.data });
}, [token]);
const fetchProduct = useCallback(async () => {
const res = await axios.get(`/api/product/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(res.data);
if (res.status === 200) changeState({ ...res.data });
}, [id, token]);
useEffect(() => {
fetchTax();
fetchProduct();
}, [fetchTax, fetchProduct]);
useEffect(() => {
if (!(typeof tax === "object")) return;
changeState({ tax: tax.name });
}, [tax]);
const handleSubmit = async () => {
if (!(title || description || tax || price)) {
alert("Please fill required field ");
return;
}
changeState({ loading: true });
let res = await axios.put(
`/api/product/${id}`,
{
title,
description,
status,
tax: taxes.find((taxObj) => taxObj.name === tax)?._id,
price,
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
if (res.status === 200) window.location.reload();
changeState({ loading: false });
swal("Edit successfully!");
history.goBack()
};
const onCancel = () => {
// window.location = "/comproducts";
history.goBack()
};
const handleChange = (e) => {
const { name, value } = e.target;
changeState({ [name]: value });
};
return (
<div className=" main-content">
<div className="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=" font-weight-bold mb-0">Edit {title} Product</h4>
<div className="page-title-right">
<ol className="breadcrumb m-0">
<li className="breadcrumb-item">
<Link to="/dashboard">Dating App</Link>
</li>
<li className="breadcrumb-item active">Commerce</li>
<li className="breadcrumb-item active">
Edit Product
</li>
</ol>
</div>
</div>
</div>
</div>
{/* <!-- end page title --> */}
{/* <!-- Save options Begins--> */}
<div className="row">
<div className="col-12">
<div className="form-group text-right">
<button
onClick={handleSubmit}
type="button"
className="btn btn-warning mt-3 mb-0 my-1 btn btn-success btn-login waves-effect waves-light mr-1"
>
<ClipLoader loading={loading} size={18} />
{!loading && "Save"}
</button>
<button
onClick={onCancel}
type="button"
className=" mt-3 ml-2 btn btn-success btn-cancel waves-effect waves-light mr-3"
>
Cancel
</button>
</div>
</div>
</div>
{/* <!-- Save options Ends--> */}
{/* <!-- Row 1 Begins --> */}
<div className="row">
{/* <!--Left Column Begins--> */}
<div className="col-lg-8">
<div className="card">
<div className="card-body">
<div className="row">
<div className="col-md-12">
<form>
<div className="row">
<div className="col-lg-12">
<div className="form-group">
<label
for=" basicpill-phoneno-input"
className=" label-100"
>
Title*
</label>
<input
type="text"
name="title"
value={title}
className="mt-0 my-3 form-control input-field"
onChange={handleChange}
placeholder="Title"
/>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-12">
<div className="form-group mb-30 width-100 row">
<label className="my-3 col-md-4 control-label">
Description
</label>
<div className="mt-0 col-md-13">
<textarea
value={description}
onChange={handleChange}
name="description"
className="form-control input-field"
rows="5"
placeholder="Add description"
></textarea>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{/* <!-- Left Column Ends --> */}
{/* <!--Right Column Begins --> */}
<div className=" col-lg-4">
<div className="card">
<div className="card-body">
<div className="row">
<div className="col-md-12">
<form>
{/* <div className="row">
<div className="col-lg-12">
<div className="form-group">
<label
for="basicpill-phoneno-input"
className="label-100"
>
Select Tax*
</label>
<select
name="tax"
value={tax}
onChange={({ target: { value } }) =>
changeState({ tax: value })
}
className="form-control input-field"
>
<option value="">--select--</option>
{taxes.map(({ name, tax }) => (
<option value={name}>
{name}&nbsp;{tax}%
</option>
))}
</select>
</div>
</div>
</div> */}
<div className="row">
<div className="col-lg-12">
<div className="form-group">
<label
for="basicpill-phoneno-input"
className="label-100"
>
Status*
</label>
<select
name="status"
value={status}
onChange={handleChange}
className="form-control input-field"
>
<option value="">--select--</option>
<option value={true}>Active</option>
<option value={false}>Inactive</option>
</select>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{/* <!--Right Column Ends --> */}
</div>
<div className=" mt-4 row">
{/* <!--Left Column Begins--> */}
<div className="col-lg-8">
<div className="card">
<div className="card-body">
<div className="row">
<div className="col-md-12">
<form className="">
<div className="row">
<div className="col-lg-4">
<div className=" form-group">
<label
for=" basicpill-phoneno-input"
className=" label-100"
>
Price*
</label>
<input
type="text"
name="price"
value={price}
onChange={handleChange}
className="form-control input-field"
/>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{/* <!-- Left Column Ends --> */}
</div>
</div>
{/* <!-- container-fluid --> */}
</div>
{/* <!-- End Page-content --> */}
{/* <Footer /> */}
</div>
);
}
export default EditProducts;

View File

@ -0,0 +1,289 @@
import axios from "axios";
import React, { useEffect, useState, useCallback, useMemo } from "react";
import { Link } from "react-router-dom";
// import { API } from "../../data";
import { isAutheticated } from "../../auth";
function Products() {
const [state, setState] = useState({
products: [],
page: 1,
limit: 10,
totalProducts: 0,
pages: 1,
});
window.scrollTo({ behavior: "smooth", top: "0px" });
const { products, page, limit, totalProducts, pages } = state;
const changeState = (newState) =>
setState((prevState) => ({ ...prevState, ...newState }));
const { token } = isAutheticated();
const getProducts = useCallback(async () => {
let res = await axios.get(
`/api/product?page=${page}&limit=${limit}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
changeState({
...res.data,
pages: Math.ceil(res.data.totalProducts / limit),
});
}, [limit, page, token]);
useEffect(() => {
getProducts();
}, [getProducts]);
const getTotalPages = useMemo(() => {
const length = pages > 1 ? pages : totalProducts ? 1 : 0;
return Array.from({ length }, (_, i) => i + 1);
}, [pages, totalProducts]);
// console.log(getTotalPages);
const handleDelete = async (id) => {
let status = window.confirm("Do you want to delete");
if (!status) return;
let res = await axios.delete(`/api/product/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (res.status === 200) window.location.reload();
};
const toggleStatus = async (id) => {
let status = window.confirm("Do you want to delete");
if (!status) {
return;
}
let res = await axios.get(`/api/product/setStatus/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (res.status === 200) window.location.reload();
};
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">Commerce - Products</h4>
<div className="page-title-right">
<ol className="breadcrumb m-0">
<li className="breadcrumb-item">
<Link to="/dashboard">Dating App</Link>
</li>
<li className="breadcrumb-item">Commerce - Products</li>
</ol>
</div>
</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 className="col-sm-12 col-md-6">
<div className="dataTables_length">
<label className="w-100">
Show{" "}
<select
onChange={(e) =>
changeState({ limit: e.target.value, page: 1 })
}
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 className="col-sm-12 col-md-6">
<div className="dropdown d-block">
<a href="/comproducts/add">
<button
type="button"
className="btn btn-primary add-btn waves-effect waves-light float-right"
>
<i className="fa fa-plus" aria-hidden="true"></i>{" "}
Add New Product
</button>
</a>
</div>
</div> */}
</div>
<div className="table-responsive table-shoot">
<table className="table table-centered table-nowrap mb-0">
<thead className="thead-light">
<tr>
<th>Name</th>
<th>Price</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{products.map(
({ title, _id, price, status }) =>
title && (
<tr key={_id}>
<td>{title}</td>
<td>{price}</td>
<td>
<span
className={`badge badge-pill badge-soft-${status ? "success" : "danger"
} font-size-13`}
>
{status ? "Live" : "Suspended"}
</span>
</td>
<td>
<button
type="button"
className={`btn btn-${status ? "danger" : "success"
} btn-sm waves-effect waves-light btn-table`}
onClick={() => toggleStatus(_id)}
>
{status ? "Suspend" : "Activate"}
</button>
<Link to={`/comproducts/edit/${_id}`}>
<button
type="button"
className=" mx-2 btn btn-primary btn-sm waves-effect waves-light btn-table ml-2"
>
Edit
</button>
</Link>
<button
type="button"
onClick={() => handleDelete(_id)}
className=" btn btn-danger btn-sm waves-effect waves-light btn-table ml-2"
id="sa-params"
>
Delete
</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{" "}
{!totalProducts
? totalProducts
: page * limit - (limit - 1)}{" "}
to{" "}
{totalProducts > limit
? limit * page > totalProducts
? totalProducts
: limit * page
: totalProducts}{" "}
of {totalProducts} entries
</div>
</div>
<div className="col-sm-12 col-md-6">
<div className="dataTables_paginate paging_simple_numbers float-right">
<ul className="pagination">
<li
className={`paginate_button page-item previous ${page < 2 ? "disabled" : ""
}`}
>
<button
aria-controls="datatable"
data-dt-idx="0"
tabIndex={page - 1}
onClick={() => changeState({ page: page - 1 })}
className="page-link"
>
Previous
</button>
</li>
{getTotalPages.map((pageNo) => {
return (
<li
className={`paginate_button page-item ${pageNo === page ? "active" : ""
}`}
>
<button
key={`page_no_${pageNo}`}
value={pageNo}
id={pageNo}
aria-controls="datatable"
data-dt-idx="1"
tabIndex="0"
className="page-link "
onClick={() => changeState({ page: pageNo })}
>
{pageNo}
</button>
</li>
);
})}
<li
className={`paginate_button page-item next ${page === getTotalPages.length ? "disabled" : ""
}`}
>
<button
onClick={() => changeState({ page: page + 1 })}
tabIndex={page + 1}
className="page-link"
>
Next
</button>
</li>
</ul>
</div>
</div>
</div> */}
{/* <!-- end table-responsive --> */}
</div>
</div>
</div>
</div>
</div>
{/* <!-- container-fluid --> */}
</div>
</div>
);
}
export default Products;

View File

@ -74,4 +74,4 @@ const Profile = () => {
)
}
export default Profile
export default Profile