Affiliate&Coupon Section added
This commit is contained in:
parent
248e0f05e0
commit
de3300af02
@ -47,6 +47,7 @@
|
|||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
"country-state-city": "^3.2.1",
|
"country-state-city": "^3.2.1",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"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",
|
||||||
|
21
src/_nav.js
21
src/_nav.js
@ -208,6 +208,27 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
//Affiliate start
|
||||||
|
{
|
||||||
|
component: CNavGroup,
|
||||||
|
name: "Affiliate & Coupons",
|
||||||
|
icon: <CIcon icon={cilCart} customClassName="nav-icon" />,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Coupons",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/affiliate/coupons",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: CNavItem,
|
||||||
|
name: "Affiliates",
|
||||||
|
icon: <CIcon icon={cilNotes} customClassName="nav-icon" />,
|
||||||
|
to: "/affiliate/affiliates",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
//Affiliate end
|
||||||
];
|
];
|
||||||
|
|
||||||
export default _nav;
|
export default _nav;
|
||||||
|
@ -100,8 +100,16 @@ 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";
|
import ShopImage from "./views/Images/ShopImage";
|
||||||
|
//Affiliate
|
||||||
|
import Coupons from "./views/Affiliate/Coupons";
|
||||||
|
import Affiliates from "./views/Affiliate/Affiliates";
|
||||||
|
import CreateCoupon from "./views/Affiliate/CreateCoupon";
|
||||||
|
import CreateAffiliate from "./views/Affiliate/CreateAffiliate";
|
||||||
|
import EditAffiliate from "./views/Affiliate/EditAffiliate";
|
||||||
|
import EditCoupon from "./views/Affiliate/EditCoupon";
|
||||||
|
import PayAffiliate from "./views/Affiliate/PayAffiliate";
|
||||||
|
import AffiliateHistory from "./views/Affiliate/AffiliateHistory";
|
||||||
|
import CouponHistory from "./views/Affiliate/CouponHistory";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{ path: "/", exact: true, name: "Home" },
|
{ path: "/", exact: true, name: "Home" },
|
||||||
@ -391,11 +399,46 @@ const routes = [
|
|||||||
path: "/seo/request/new",
|
path: "/seo/request/new",
|
||||||
name: "seo Request",
|
name: "seo Request",
|
||||||
element: AddSeoRequest,
|
element: AddSeoRequest,
|
||||||
}
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
//Affiliate Dashboard
|
||||||
|
{ path: "/affiliate/coupons", name: "Coupon", element: Coupons },
|
||||||
|
{ path: "/affiliate/affiliates", name: "Affiliate", element: Affiliates },
|
||||||
|
{
|
||||||
|
path: "/affiliate/coupons/create",
|
||||||
|
name: "Create Coupon",
|
||||||
|
element: CreateCoupon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/affiliate/affiliates/create",
|
||||||
|
name: "Create Affiliate",
|
||||||
|
element: CreateAffiliate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/affiliate/affiliates/edit/:id",
|
||||||
|
name: "Edit Affiliate",
|
||||||
|
element: EditAffiliate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/affiliate/affiliates/pay/:id",
|
||||||
|
name: "Pay Affiliate",
|
||||||
|
element: PayAffiliate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/affiliate/affiliates/history/:id",
|
||||||
|
name: "Pay Affiliate",
|
||||||
|
element: AffiliateHistory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/affiliate/coupons/edit/:id",
|
||||||
|
name: "Edit Coupon",
|
||||||
|
element: EditCoupon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/affiliate/coupons/history/:id",
|
||||||
|
name: "Edit Coupon",
|
||||||
|
element: CouponHistory,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
225
src/views/Affiliate/AffiliateHistory.jsx
Normal file
225
src/views/Affiliate/AffiliateHistory.jsx
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { Button, Pagination } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
|
||||||
|
const AffiliateHistory = () => {
|
||||||
|
const id = useParams().id;
|
||||||
|
const token = isAutheticated();
|
||||||
|
//Navigation
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [apiData, setApiData] = useState([]);
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
//Date format change function
|
||||||
|
const dateFormat = (inputDate) => {
|
||||||
|
const months = [
|
||||||
|
"Jan",
|
||||||
|
"Feb",
|
||||||
|
"Mar",
|
||||||
|
"Apr",
|
||||||
|
"May",
|
||||||
|
"Jun",
|
||||||
|
"Jul",
|
||||||
|
"Aug",
|
||||||
|
"Sep",
|
||||||
|
"Oct",
|
||||||
|
"Nov",
|
||||||
|
"Dec",
|
||||||
|
];
|
||||||
|
const parts = inputDate.split("-");
|
||||||
|
const rearrangedDate = `${parts[2]}-${months[parseInt(parts[1]) - 1]}-${
|
||||||
|
parts[0]
|
||||||
|
}`;
|
||||||
|
// console.log(rearrangedDate); // Output: 11-Mar-2024
|
||||||
|
return rearrangedDate;
|
||||||
|
};
|
||||||
|
//Extract time from mongodb
|
||||||
|
const extractTime = (dateTimeString) => {
|
||||||
|
const date = new Date(dateTimeString);
|
||||||
|
const hours = date.getUTCHours().toString().padStart(2, "0");
|
||||||
|
const minutes = date.getUTCMinutes().toString().padStart(2, "0");
|
||||||
|
const seconds = date.getUTCSeconds().toString().padStart(2, "0");
|
||||||
|
const time = `${hours}:${minutes}:${seconds}`;
|
||||||
|
// console.log(time);
|
||||||
|
return time;
|
||||||
|
};
|
||||||
|
//Func to get all Affiliate data
|
||||||
|
const fetchHistoryData = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/v1/affiliate/history/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
// console.log(response.data.message.affiliate_pay_history);
|
||||||
|
setApiData(response.data.message.affiliate_pay_history);
|
||||||
|
setName(response.data.message.name);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Call api onLoad of page
|
||||||
|
useEffect(() => {
|
||||||
|
fetchHistoryData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//pagination related
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10); //pagination
|
||||||
|
const [page, setPage] = useState(1); //pagination
|
||||||
|
|
||||||
|
const getPageCount = () => {
|
||||||
|
return Math.max(1, Math.ceil(apiData.length / itemPerPage));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="my-3 page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
{/* Coupon header start */}
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ fontSize: "22px", fontWeight: "bold" }}
|
||||||
|
className="fw-bold"
|
||||||
|
>
|
||||||
|
<p>Payment History :{name}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Link to="/affiliate/affiliates">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Coupon header End */}
|
||||||
|
{/* Coupon main body Start*/}
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Table Start */}
|
||||||
|
<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>Transection ID</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && apiData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td>
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center">Loading...</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
apiData &&
|
||||||
|
apiData
|
||||||
|
.slice(
|
||||||
|
(`${page}` - 1) * itemPerPage,
|
||||||
|
`${page}` * itemPerPage
|
||||||
|
)
|
||||||
|
.map((item, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>{item.transecId}</td>
|
||||||
|
<td>₹{item.amount}</td>
|
||||||
|
<td>{dateFormat(item.date)}</td>
|
||||||
|
<td>{item.time}</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/* Table End */}
|
||||||
|
{/* Pagination div Start*/}
|
||||||
|
<div style={{ display: "flex", justifyContent: "right" }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ margin: "2rem" }}
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
count={getPageCount()}
|
||||||
|
color="primary"
|
||||||
|
onChange={(event, value) => setPage(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* Pagination div End*/}
|
||||||
|
{/* Coupon main body End */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AffiliateHistory;
|
391
src/views/Affiliate/Affiliates.jsx
Normal file
391
src/views/Affiliate/Affiliates.jsx
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import { Button, Pagination } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
|
||||||
|
const Affiliates = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
//Navigation
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [apiData, setApiData] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
const handelSuspend = (id, active) => {
|
||||||
|
axios
|
||||||
|
.patch(
|
||||||
|
"api/v1/affiliate/suspend",
|
||||||
|
{
|
||||||
|
id: id,
|
||||||
|
is_affiliate_active: !active,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
// Fetch data again after updating kind of updating page
|
||||||
|
fetchAffiliateData();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Func to get all Affiliate data
|
||||||
|
const fetchAffiliateData = () => {
|
||||||
|
axios
|
||||||
|
.get("/api/v1/affiliate/getall", {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
// console.log(response.data.message);
|
||||||
|
setLoading(false);
|
||||||
|
setApiData(response.data.message);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Call api onLoad of page
|
||||||
|
useEffect(() => {
|
||||||
|
fetchAffiliateData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//pagination related
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10); //pagination
|
||||||
|
const [page, setPage] = useState(1); //pagination
|
||||||
|
|
||||||
|
//Create navigation
|
||||||
|
const navigCreate = () => {
|
||||||
|
navigate("/affiliate/affiliates/create");
|
||||||
|
};
|
||||||
|
const style = {
|
||||||
|
position: "absolute",
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
width: 400,
|
||||||
|
bgcolor: "background.paper",
|
||||||
|
borderRadius: "0.5rem",
|
||||||
|
boxShadow: 24,
|
||||||
|
width: "500px",
|
||||||
|
padding: "1rem",
|
||||||
|
};
|
||||||
|
const InputSpace = {
|
||||||
|
marginBottom: "1rem",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPageCount = () => {
|
||||||
|
return Math.max(1, Math.ceil(apiData.length / itemPerPage));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="my-3 page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
{/* Coupon header start */}
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ fontSize: "22px", fontWeight: "bold" }}
|
||||||
|
className="fw-bold"
|
||||||
|
>
|
||||||
|
Affiliates
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
onClick={navigCreate}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add New Affiliate
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Coupon header End */}
|
||||||
|
{/* Coupon main body Start*/}
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Table Start */}
|
||||||
|
<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> Affiliate</th>
|
||||||
|
<th> Coupon Code</th>
|
||||||
|
<th>Coupon Claimed</th>
|
||||||
|
<th>Total Amount Earned</th>
|
||||||
|
<th>Amount to be Paid</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{" "}
|
||||||
|
{!loading && apiData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td>
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center">Loading...</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
apiData &&
|
||||||
|
apiData
|
||||||
|
.slice(
|
||||||
|
(`${page}` - 1) * itemPerPage,
|
||||||
|
`${page}` * itemPerPage
|
||||||
|
)
|
||||||
|
.map((item, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>{item.name}</td>
|
||||||
|
{item.coupon_code ? (
|
||||||
|
<td>{item.coupon_code}</td>
|
||||||
|
) : (
|
||||||
|
<td>NONE</td>
|
||||||
|
)}
|
||||||
|
{item.coupon_claimed ? (
|
||||||
|
<td>{item.coupon_claimed}</td>
|
||||||
|
) : (
|
||||||
|
<td>0</td>
|
||||||
|
)}
|
||||||
|
{item.total_earning ? (
|
||||||
|
<td>₹{item.total_earning}</td>
|
||||||
|
) : (
|
||||||
|
<td>₹0</td>
|
||||||
|
)}
|
||||||
|
{item.total_earning ? (
|
||||||
|
<td>₹{item.total_earning - item.paid_amount}</td>
|
||||||
|
) : (
|
||||||
|
<td>₹0</td>
|
||||||
|
)}
|
||||||
|
{item.is_affiliate_active ? (
|
||||||
|
<td>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
backgroundColor: "green",
|
||||||
|
color: "white",
|
||||||
|
display: "inline-block",
|
||||||
|
padding: "2px",
|
||||||
|
width: "65px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
active
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
) : (
|
||||||
|
<td>
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
backgroundColor: "red",
|
||||||
|
color: "white",
|
||||||
|
display: "inline-block",
|
||||||
|
padding: "2px",
|
||||||
|
width: "65px",
|
||||||
|
textAlign: "center",
|
||||||
|
borderRadius: "8px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
unactive
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
<td>
|
||||||
|
<Link to={`/affiliate/affiliates/edit/${item._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
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: `${
|
||||||
|
item.is_affiliate_active ? "red" : "green"
|
||||||
|
}`,
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
handelSuspend(item._id, item.is_affiliate_active)
|
||||||
|
}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{item.is_affiliate_active ? "Suspend" : "Activate"}
|
||||||
|
</button>
|
||||||
|
{item.total_earning - item.paid_amount != 0 ? (
|
||||||
|
<Link to={`/affiliate/affiliates/pay/${item._id}`}>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: "green",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Pay
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
disabled
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: "green",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Pay
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<Link
|
||||||
|
to={`/affiliate/affiliates/history/${item._id}`}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: "grey",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
History
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/* Table End */}
|
||||||
|
{/* Pagination div Start*/}
|
||||||
|
<div style={{ display: "flex", justifyContent: "right" }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ margin: "2rem" }}
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
count={getPageCount()}
|
||||||
|
color="primary"
|
||||||
|
onChange={(event, value) => setPage(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* Pagination div End*/}
|
||||||
|
{/* Coupon main body End */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Affiliates;
|
236
src/views/Affiliate/CouponHistory.jsx
Normal file
236
src/views/Affiliate/CouponHistory.jsx
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { Button, Pagination } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
const CouponHistory = () => {
|
||||||
|
const id = useParams().id;
|
||||||
|
const token = isAutheticated();
|
||||||
|
//Navigation
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [apiData, setApiData] = useState([]);
|
||||||
|
const [couponName, setCouponName] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(true); //only for testing
|
||||||
|
//Date format change function
|
||||||
|
const dateFormat = (inputDate) => {
|
||||||
|
// Split the date string by spaces to get individual components
|
||||||
|
const dateComponents = inputDate.split(" ");
|
||||||
|
|
||||||
|
// Extract day, month, and year from the components
|
||||||
|
const day = dateComponents[2];
|
||||||
|
const monthName = dateComponents[1];
|
||||||
|
const year = dateComponents[3];
|
||||||
|
|
||||||
|
// Map month names to their respective indexes
|
||||||
|
const monthsMap = {
|
||||||
|
Jan: "01",
|
||||||
|
Feb: "02",
|
||||||
|
Mar: "03",
|
||||||
|
Apr: "04",
|
||||||
|
May: "05",
|
||||||
|
Jun: "06",
|
||||||
|
Jul: "07",
|
||||||
|
Aug: "08",
|
||||||
|
Sep: "09",
|
||||||
|
Oct: "10",
|
||||||
|
Nov: "11",
|
||||||
|
Dec: "12",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the numerical representation of the month
|
||||||
|
const month = monthsMap[monthName];
|
||||||
|
|
||||||
|
// Create the rearranged date string
|
||||||
|
const rearrangedDate = `${day} ${month} ${year}`;
|
||||||
|
|
||||||
|
return rearrangedDate;
|
||||||
|
};
|
||||||
|
//Extract time from mongodb
|
||||||
|
const extractTime = (dateTimeString) => {
|
||||||
|
const date = new Date(dateTimeString);
|
||||||
|
const hours = date.getUTCHours().toString().padStart(2, "0");
|
||||||
|
const minutes = date.getUTCMinutes().toString().padStart(2, "0");
|
||||||
|
const seconds = date.getUTCSeconds().toString().padStart(2, "0");
|
||||||
|
const time = `${hours}:${minutes}:${seconds}`;
|
||||||
|
return time;
|
||||||
|
};
|
||||||
|
//Func to get all Affiliate data
|
||||||
|
const fetchHistoryData = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/v1/coupon/history/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
// console.log(response.data.message.coupon_used_history);
|
||||||
|
setLoading(false);
|
||||||
|
setApiData(response.data.message.coupon_used_history);
|
||||||
|
setCouponName(response.data.message.coupon_used_history[0].couponCode);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Call api onLoad of page
|
||||||
|
useEffect(() => {
|
||||||
|
fetchHistoryData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//pagination related
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10); //pagination
|
||||||
|
const [page, setPage] = useState(1); //pagination
|
||||||
|
// console.log(apiData);
|
||||||
|
|
||||||
|
const getPageCount = () => {
|
||||||
|
return Math.max(1, Math.ceil(apiData.length / itemPerPage));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="my-3 page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
{/* Coupon header start */}
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-12">
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ fontSize: "22px", fontWeight: "bold" }}
|
||||||
|
className="fw-bold"
|
||||||
|
>
|
||||||
|
Coupon History {couponName}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Link to="/affiliate/affiliates">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Coupon header End */}
|
||||||
|
{/* Coupon main body Start*/}
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Table Start */}
|
||||||
|
<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>Order Id</th>
|
||||||
|
<th>User Id</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{!loading && apiData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td>
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center">Loading...</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
apiData &&
|
||||||
|
apiData
|
||||||
|
?.slice(
|
||||||
|
(`${page}` - 1) * itemPerPage,
|
||||||
|
`${page}` * itemPerPage
|
||||||
|
)
|
||||||
|
?.map((item, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>{item.orderId}</td>
|
||||||
|
<td>{item.userId}</td>
|
||||||
|
<td>{dateFormat(item.date)}</td>
|
||||||
|
<td>{moment(item.date).format("HH:mm:ss")}</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/* Table End */}
|
||||||
|
{/* Pagination div Start*/}
|
||||||
|
<div style={{ display: "flex", justifyContent: "right" }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ margin: "2rem" }}
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
count={getPageCount()}
|
||||||
|
color="primary"
|
||||||
|
onChange={(event, value) => setPage(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* Pagination div End*/}
|
||||||
|
{/* Coupon main body End */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CouponHistory;
|
331
src/views/Affiliate/Coupons.jsx
Normal file
331
src/views/Affiliate/Coupons.jsx
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Button, Pagination } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
const Coupons = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
//Navigation
|
||||||
|
const navigate = useNavigate();
|
||||||
|
//pagination related
|
||||||
|
const [loading, setLoading] = useState(true); //only for testing
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10); //pagination
|
||||||
|
const [page, setPage] = useState(1); //pagination
|
||||||
|
const [apiData, setApiData] = useState([]);
|
||||||
|
//Handel Suspend
|
||||||
|
const handelSuspend = (id, active) => {
|
||||||
|
axios
|
||||||
|
.patch(
|
||||||
|
"api/v1/coupon/suspend",
|
||||||
|
{
|
||||||
|
id: id,
|
||||||
|
is_coupon_active: !active,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
// Fetch data again after updating
|
||||||
|
getAllCoupon();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Get all Coupons from the api
|
||||||
|
const getAllCoupon = () => {
|
||||||
|
axios
|
||||||
|
.get("/api/v1/coupon/getall", {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
setLoading(false);
|
||||||
|
setApiData(response.data.message);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Calling api Onload of page
|
||||||
|
useEffect(() => {
|
||||||
|
getAllCoupon();
|
||||||
|
}, []);
|
||||||
|
//Create navigation
|
||||||
|
const navigCreate = () => {
|
||||||
|
navigate("/affiliate/coupons/create");
|
||||||
|
};
|
||||||
|
const style = {
|
||||||
|
position: "absolute",
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
width: 400,
|
||||||
|
bgcolor: "background.paper",
|
||||||
|
borderRadius: "0.5rem",
|
||||||
|
boxShadow: 24,
|
||||||
|
width: "500px",
|
||||||
|
padding: "1rem",
|
||||||
|
};
|
||||||
|
const InputSpace = {
|
||||||
|
marginBottom: "1rem",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPageCount = () => {
|
||||||
|
return Math.max(1, Math.ceil(apiData?.length / itemPerPage));
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="main-content">
|
||||||
|
<div className="my-3 page-content">
|
||||||
|
<div className="container-fluid">
|
||||||
|
{/* Coupon header start */}
|
||||||
|
<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">
|
||||||
|
Coupons
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="page-title-right">
|
||||||
|
<Button
|
||||||
|
onClick={navigCreate}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add New Coupon
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Coupon header End */}
|
||||||
|
{/* Coupon main body Start*/}
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Table Start */}
|
||||||
|
<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> Coupon Code</th>
|
||||||
|
<th> Affiliate</th>
|
||||||
|
<th>Discount</th>
|
||||||
|
<th>Affilite Discount</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{" "}
|
||||||
|
{!loading && apiData.length === 0 && (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td>
|
||||||
|
<h5>No Data Available</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td className="text-center">Loading...</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
apiData &&
|
||||||
|
apiData
|
||||||
|
.slice(
|
||||||
|
(`${page}` - 1) * itemPerPage,
|
||||||
|
`${page}` * itemPerPage
|
||||||
|
)
|
||||||
|
.map((item, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>
|
||||||
|
<p style={{ fontWeight: "bold" }}>
|
||||||
|
{item.coupon_code}
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>{item.name}</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>₹{item.discount_amount}</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>₹{item.affiliate_discount_amount}</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{item.is_coupon_active ? (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
backgroundColor: "green",
|
||||||
|
color: "white",
|
||||||
|
display: "inline-block",
|
||||||
|
padding: "2px",
|
||||||
|
width: "65px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
active
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<p
|
||||||
|
style={{
|
||||||
|
backgroundColor: "red",
|
||||||
|
color: "white",
|
||||||
|
display: "inline-block",
|
||||||
|
padding: "2px",
|
||||||
|
width: "65px",
|
||||||
|
textAlign: "center",
|
||||||
|
borderRadius: "8px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
unactive
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Link to={`/affiliate/coupons/edit/${item._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
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: `${
|
||||||
|
item.is_coupon_active ? "red" : "green"
|
||||||
|
}`,
|
||||||
|
}}
|
||||||
|
onClick={() =>
|
||||||
|
handelSuspend(item._id, item.is_coupon_active)
|
||||||
|
}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{item.is_coupon_active ? "Suspend" : "Activate"}
|
||||||
|
</button>
|
||||||
|
<Link to={`/affiliate/coupons/history/${item._id}`}>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
background: "grey",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="
|
||||||
|
btn btn-sm
|
||||||
|
waves-effect waves-light
|
||||||
|
btn-table
|
||||||
|
mx-1
|
||||||
|
mt-1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
History
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{/* Table End */}
|
||||||
|
{/* Pagination div Start*/}
|
||||||
|
<div style={{ display: "flex", justifyContent: "right" }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ margin: "2rem" }}
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
count={getPageCount()}
|
||||||
|
color="primary"
|
||||||
|
onChange={(event, value) => setPage(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/* Pagination div End*/}
|
||||||
|
{/* Coupon main body End */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Coupons;
|
433
src/views/Affiliate/CreateAffiliate.jsx
Normal file
433
src/views/Affiliate/CreateAffiliate.jsx
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import swal from "sweetalert";
|
||||||
|
import { Country, State, City } from "country-state-city";
|
||||||
|
import axios from "axios";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
|
||||||
|
const CreateAffiliate = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
//My states
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [mobile, setMobile] = useState();
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [country, setCountry] = useState("");
|
||||||
|
const [state, setState] = useState("");
|
||||||
|
const [city, setCity] = useState("");
|
||||||
|
const [address, setAddress] = useState("");
|
||||||
|
const [pincode, setPincode] = useState();
|
||||||
|
const [nameAsBank, setNameAsBank] = useState("");
|
||||||
|
const [accountNo, setAccountNo] = useState();
|
||||||
|
const [ifsc, setIfsc] = useState("");
|
||||||
|
const [bankName, setBankName] = useState("");
|
||||||
|
const [branchName, setBranchName] = useState("");
|
||||||
|
//Handeling Country State City
|
||||||
|
const [stateListData, setStateListData] = useState();
|
||||||
|
const [cityListData, setCityListData] = useState();
|
||||||
|
|
||||||
|
//Handel City State Country
|
||||||
|
const countrieList = Country.getAllCountries();
|
||||||
|
// const stateList = State.getStatesOfCountry();
|
||||||
|
// const cityList = City.getCitiesOfState("IN", "CT");
|
||||||
|
// console.log("Cityyyyyyyyyyy", cityList);
|
||||||
|
useEffect(() => {
|
||||||
|
const countryCode = countrieList.find((item) => item.name === country);
|
||||||
|
if (countryCode) {
|
||||||
|
const states = State.getStatesOfCountry(countryCode.isoCode);
|
||||||
|
setStateListData(states);
|
||||||
|
}
|
||||||
|
}, [country, countrieList]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (state) {
|
||||||
|
const stateCode = stateListData.find((item) => item.name === state);
|
||||||
|
// console.log(stateCode);
|
||||||
|
if (stateCode) {
|
||||||
|
const cities = City.getCitiesOfState(
|
||||||
|
stateCode.countryCode,
|
||||||
|
stateCode.isoCode
|
||||||
|
);
|
||||||
|
// console.log(cities);
|
||||||
|
setCityListData(cities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [state, stateListData]);
|
||||||
|
//Handel Mobile Number
|
||||||
|
const handelNumber = (e) => {
|
||||||
|
if (!(e.target.value.length > 10)) {
|
||||||
|
setMobile(e.target.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCountry = async (e) => {
|
||||||
|
await setCountry(e.target.value);
|
||||||
|
if (stateListData || cityListData) {
|
||||||
|
setCity("");
|
||||||
|
setState("");
|
||||||
|
setCityListData([]);
|
||||||
|
setCountry(e.target.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (
|
||||||
|
name === "" ||
|
||||||
|
mobile === 0 ||
|
||||||
|
email == "" ||
|
||||||
|
country === "" ||
|
||||||
|
address === "" ||
|
||||||
|
pincode === 0 ||
|
||||||
|
nameAsBank === "" ||
|
||||||
|
accountNo === 0 ||
|
||||||
|
ifsc === "" ||
|
||||||
|
bankName === "" ||
|
||||||
|
branchName === ""
|
||||||
|
) {
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: "Fill all mandatory fields",
|
||||||
|
icon: "error",
|
||||||
|
button: "Close",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
const formDataObject = {
|
||||||
|
name: name,
|
||||||
|
mobile: mobile,
|
||||||
|
email: email,
|
||||||
|
country: country,
|
||||||
|
state: state,
|
||||||
|
city: city,
|
||||||
|
address: address,
|
||||||
|
pincode: pincode,
|
||||||
|
nameAsBank: nameAsBank,
|
||||||
|
accountNo: accountNo,
|
||||||
|
ifsc: ifsc,
|
||||||
|
bankName: bankName,
|
||||||
|
branchName: branchName,
|
||||||
|
};
|
||||||
|
|
||||||
|
axios
|
||||||
|
.post("/api/v1/affiliate/create", formDataObject, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
// Handle the data returned by the server
|
||||||
|
setLoading(false);
|
||||||
|
setName("");
|
||||||
|
setMobile("");
|
||||||
|
setEmail("");
|
||||||
|
setCountry("");
|
||||||
|
setState("");
|
||||||
|
setCity("");
|
||||||
|
setAddress("");
|
||||||
|
setPincode("");
|
||||||
|
setNameAsBank("");
|
||||||
|
setAccountNo("");
|
||||||
|
setIfsc("");
|
||||||
|
setBankName("");
|
||||||
|
setBranchName("");
|
||||||
|
swal({
|
||||||
|
title: "Congratulations!!",
|
||||||
|
text: "The Coupon was Created successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
// Handle errors
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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">
|
||||||
|
Add Affiliate
|
||||||
|
</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="/affiliate/affiliates">
|
||||||
|
<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">
|
||||||
|
Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="name"
|
||||||
|
value={name}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
/>
|
||||||
|
{name ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - name.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}{" "}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Mobile
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="mobile"
|
||||||
|
value={mobile}
|
||||||
|
onChange={handelNumber}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Email
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
className="form-control"
|
||||||
|
id="email"
|
||||||
|
value={email}
|
||||||
|
maxLength="100"
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="categorySelect">Select a Country</label>
|
||||||
|
<select
|
||||||
|
id="country"
|
||||||
|
className="form-control"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
value={country}
|
||||||
|
onChange={handleCountry}
|
||||||
|
>
|
||||||
|
<option value={"None"}>None</option>
|
||||||
|
{countrieList.map((country) => (
|
||||||
|
<option key={country.isoCode} value={country.name}>
|
||||||
|
{country.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="categorySelect">Select a State</label>
|
||||||
|
<select
|
||||||
|
id="state"
|
||||||
|
className="form-control"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
value={state}
|
||||||
|
onChange={(e) => setState(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value={""}>None</option>
|
||||||
|
{stateListData?.map((states) => (
|
||||||
|
<option key={states.isoCode}>{states.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="categorySelect">Select a City</label>
|
||||||
|
<select
|
||||||
|
id="city"
|
||||||
|
className="form-control"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
value={city}
|
||||||
|
onChange={(e) => setCity(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value={""}>None</option>
|
||||||
|
{cityListData?.map((city) => (
|
||||||
|
<option value={city.isoCode}>{city.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Address
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="address"
|
||||||
|
value={address}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => setAddress(e.target.value)}
|
||||||
|
/>
|
||||||
|
{name ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - name.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}{" "}
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Pincode
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="pincode"
|
||||||
|
value={pincode}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => setPincode(e.target.value)}
|
||||||
|
/>
|
||||||
|
{name ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - name.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}{" "}
|
||||||
|
</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">
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Name as per Bank records
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="nameasbank"
|
||||||
|
value={nameAsBank}
|
||||||
|
onChange={(e) => setNameAsBank(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Account Number
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="accountno"
|
||||||
|
value={accountNo}
|
||||||
|
onChange={(e) => setAccountNo(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
IFSC Code
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="ifsc"
|
||||||
|
value={ifsc}
|
||||||
|
onChange={(e) => setIfsc(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Bank Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="bankname"
|
||||||
|
value={bankName}
|
||||||
|
onChange={(e) => setBankName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Branch Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="branchname"
|
||||||
|
value={branchName}
|
||||||
|
onChange={(e) => setBranchName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateAffiliate;
|
355
src/views/Affiliate/CreateCoupon.jsx
Normal file
355
src/views/Affiliate/CreateCoupon.jsx
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import toast, { Toaster } from "react-hot-toast";
|
||||||
|
import { Button, Box, TextField, Typography } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
const CreateCoupon = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [loading, setLoading] = useState(false); //only for testing
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10); //pagination
|
||||||
|
const [page, setPage] = useState(1); //pagination
|
||||||
|
//Form States
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [coupon, setCoupon] = useState("");
|
||||||
|
const [discount, setDiscount] = useState("");
|
||||||
|
const [affiliateDiscountAmt, setAffiliateDiscountAmt] = useState("");
|
||||||
|
const [valid, setValid] = useState("");
|
||||||
|
const [affiliate, setAffiliate] = useState("");
|
||||||
|
//Form error states
|
||||||
|
const [couponError, setCouponError] = useState(false);
|
||||||
|
const [discountError, setDiscountError] = useState(false);
|
||||||
|
const [validError, setValidError] = useState(false);
|
||||||
|
const [affiliateError, setAffiliateError] = useState(false);
|
||||||
|
const [affiliateDiscountAmtError, setAffiliateDiscountAmtError] =
|
||||||
|
useState(false);
|
||||||
|
const [apiData, setApiData] = useState([]);
|
||||||
|
//Discount limit
|
||||||
|
const handelDiscount = (event) => {
|
||||||
|
let value = event.target.value;
|
||||||
|
if (parseInt(value) >= 9999) {
|
||||||
|
setDiscount(9999);
|
||||||
|
setDiscountError(true);
|
||||||
|
} else if (parseInt(value) < 0) {
|
||||||
|
setDiscount(0);
|
||||||
|
} else {
|
||||||
|
setDiscountError(false);
|
||||||
|
setDiscount(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handelAffilateDiscount = (event) => {
|
||||||
|
let value = event.target.value;
|
||||||
|
if (parseInt(value) >= 9999) {
|
||||||
|
setAffiliateDiscountAmt(9999);
|
||||||
|
setAffiliateDiscountAmtError(true);
|
||||||
|
} else if (parseInt(value) < 0) {
|
||||||
|
setDiscount(0);
|
||||||
|
} else {
|
||||||
|
setAffiliateDiscountAmtError(false);
|
||||||
|
setAffiliateDiscountAmt(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//Handel Form Submition
|
||||||
|
const handelCreate = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!(coupon.length === 8)) {
|
||||||
|
setCouponError(true);
|
||||||
|
toast.error("Code should be of 8 charecter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (valid === "") {
|
||||||
|
setValidError(true);
|
||||||
|
toast.error("Valid till is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (affiliate === "") {
|
||||||
|
setAffiliateError(true);
|
||||||
|
toast.error("Affiliate is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (discount == "") {
|
||||||
|
setDiscountError(true);
|
||||||
|
toast.error("Discount amount is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (affiliateDiscountAmt == "") {
|
||||||
|
setAffiliateDiscountAmtError(true);
|
||||||
|
toast.error("Affiliate Discount Amount is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Sending api Obj--------------------
|
||||||
|
let formDataObject = {
|
||||||
|
coupon_code: coupon,
|
||||||
|
discount_amount: discount,
|
||||||
|
affiliate_discount_amount: affiliateDiscountAmt,
|
||||||
|
valid_till: valid,
|
||||||
|
is_coupon_active: true,
|
||||||
|
id: affiliate,
|
||||||
|
};
|
||||||
|
|
||||||
|
axios
|
||||||
|
.patch("/api/v1/coupon/create", formDataObject, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
//reset Inputs
|
||||||
|
setDiscount("");
|
||||||
|
setCoupon("");
|
||||||
|
setValid("");
|
||||||
|
setAffiliate("");
|
||||||
|
fetchAffiliate();
|
||||||
|
setCouponError(false);
|
||||||
|
setDiscountError(false);
|
||||||
|
setValidError(false);
|
||||||
|
setAffiliateError(false);
|
||||||
|
setAffiliateDiscountAmtError(false);
|
||||||
|
swal({
|
||||||
|
title: "Congratulations!!",
|
||||||
|
text: "The Coupon was Created successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// Handle errors
|
||||||
|
const message = error.response?.data?.message
|
||||||
|
? error.response?.data?.message
|
||||||
|
: "Something went wrong!";
|
||||||
|
toast.error(message);
|
||||||
|
console.error("There was a problem with your fetch operation:", error);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// Reset the affiliate and affiliateError state
|
||||||
|
setAffiliateError(false);
|
||||||
|
// Show success message
|
||||||
|
// console.log(coupon, discount, valid, affiliate);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const InputSpace = {
|
||||||
|
marginBottom: "1rem",
|
||||||
|
width: "20rem ",
|
||||||
|
height: "45px",
|
||||||
|
};
|
||||||
|
//Back to Coupons
|
||||||
|
const handelBack = () => {
|
||||||
|
navigate("/affiliate/coupons");
|
||||||
|
};
|
||||||
|
//Calling api to get Affiliates
|
||||||
|
const fetchAffiliate = () => {
|
||||||
|
axios
|
||||||
|
.get("/api/v1/coupon/getaffiliate", {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
setApiData(response.data.message);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Calling api
|
||||||
|
useEffect(() => {
|
||||||
|
fetchAffiliate();
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<div
|
||||||
|
className=" page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
flex-direction-row"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h3>Coupons</h3>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex">
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
className="mx-2"
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
onClick={handelCreate}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
onClick={handelBack}
|
||||||
|
variant="contained"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
backgroundColor: "red",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: "2rem",
|
||||||
|
borderRadius: "0.5rem",
|
||||||
|
backgroundColor: "white",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "80%",
|
||||||
|
margin: "auto",
|
||||||
|
}}
|
||||||
|
className="border"
|
||||||
|
>
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Box>
|
||||||
|
<Typography className="mb-1">
|
||||||
|
Coupon Code (Must be 8 digit)
|
||||||
|
</Typography>
|
||||||
|
<TextField
|
||||||
|
className="mb-3"
|
||||||
|
required={true}
|
||||||
|
sx={InputSpace}
|
||||||
|
value={coupon}
|
||||||
|
InputProps={{
|
||||||
|
inputProps: {
|
||||||
|
maxLength: 8,
|
||||||
|
minLength: 8,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCoupon(e.target.value);
|
||||||
|
}}
|
||||||
|
error={couponError}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
/>
|
||||||
|
{couponError ? (
|
||||||
|
<small style={{ color: "red" }}>8 characters required</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Typography className="mb-1">Discount Amount</Typography>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginRight: "5px",
|
||||||
|
}}
|
||||||
|
className="d-flex justify-content-center"
|
||||||
|
>
|
||||||
|
<span style={{ fontSize: "1.7rem" }}>₹</span>
|
||||||
|
</div>
|
||||||
|
<TextField
|
||||||
|
className="mb-3"
|
||||||
|
required={true}
|
||||||
|
error={discountError}
|
||||||
|
type="number"
|
||||||
|
value={discount}
|
||||||
|
sx={InputSpace}
|
||||||
|
onChange={handelDiscount}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Typography className="mb-1">
|
||||||
|
Affiliate Discount Amount
|
||||||
|
</Typography>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginRight: "5px",
|
||||||
|
}}
|
||||||
|
className="d-flex justify-content-center"
|
||||||
|
>
|
||||||
|
<span style={{ fontSize: "1.7rem" }}>₹</span>
|
||||||
|
</div>
|
||||||
|
<TextField
|
||||||
|
className="mb-3"
|
||||||
|
required={true}
|
||||||
|
error={discountError}
|
||||||
|
type="number"
|
||||||
|
value={affiliateDiscountAmt}
|
||||||
|
sx={InputSpace}
|
||||||
|
onChange={handelAffilateDiscount}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{affiliateDiscountAmtError ? (
|
||||||
|
<small style={{ color: "red" }}>Max Amount Rs.9999</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Typography className="mb-1">Coupon Valid Till: </Typography>
|
||||||
|
<input
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "50px",
|
||||||
|
outline: validError ? "1px solid red" : "",
|
||||||
|
}}
|
||||||
|
className="mb-2"
|
||||||
|
value={valid}
|
||||||
|
sx={InputSpace}
|
||||||
|
onChange={(e) => {
|
||||||
|
setValid(e.target.value);
|
||||||
|
}}
|
||||||
|
type="date"
|
||||||
|
/>
|
||||||
|
{validError ? (
|
||||||
|
<small style={{ color: "red" }}>
|
||||||
|
Validity Date is Required
|
||||||
|
</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<Typography className="mb-1">Select Affiliate</Typography>
|
||||||
|
<select
|
||||||
|
onChange={(e) => {
|
||||||
|
setAffiliate(e.target.value);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "50px",
|
||||||
|
outline: validError ? "1px solid red" : "",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="">None</option>
|
||||||
|
{apiData?.length > 0 &&
|
||||||
|
apiData.map((data) => {
|
||||||
|
return (
|
||||||
|
<option value={data._id} key={data._id}>
|
||||||
|
{data.name}-{data.mobile}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
{affiliateError ? (
|
||||||
|
<small style={{ color: "red" }}>Affiliation is Required</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
</Box>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateCoupon;
|
458
src/views/Affiliate/EditAffiliate.jsx
Normal file
458
src/views/Affiliate/EditAffiliate.jsx
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
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 { Country, State, City } from "country-state-city";
|
||||||
|
import axios from "axios";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
|
||||||
|
const EditAffiliate = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const id = useParams().id;
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
//My states
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [mobile, setMobile] = useState();
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [country, setCountry] = useState("");
|
||||||
|
const [state, setState] = useState("");
|
||||||
|
const [city, setCity] = useState("");
|
||||||
|
const [address, setAddress] = useState("");
|
||||||
|
const [pincode, setPincode] = useState();
|
||||||
|
const [nameAsBank, setNameAsBank] = useState("");
|
||||||
|
const [accountNo, setAccountNo] = useState();
|
||||||
|
const [ifsc, setIfsc] = useState("");
|
||||||
|
const [bankName, setBankName] = useState("");
|
||||||
|
const [branchName, setBranchName] = useState("");
|
||||||
|
//Handel Mobile Number
|
||||||
|
const handelNumber = (e) => {
|
||||||
|
if (!(e.target.value.length > 10)) {
|
||||||
|
setMobile(e.target.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//Handeling Country State City
|
||||||
|
const [stateListData, setStateListData] = useState();
|
||||||
|
const [cityListData, setCityListData] = useState();
|
||||||
|
const handleCountry = async (e) => {
|
||||||
|
await setCountry(e.target.value);
|
||||||
|
if (stateListData || cityListData) {
|
||||||
|
setCity("");
|
||||||
|
setState("");
|
||||||
|
setCityListData([]);
|
||||||
|
setCountry(e.target.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//Handel City State Country
|
||||||
|
const countrieList = Country.getAllCountries();
|
||||||
|
// const stateList = State.getStatesOfCountry();
|
||||||
|
// const cityList = City.getCitiesOfState("IN", "CT");
|
||||||
|
// console.log("Cityyyyyyyyyyy", cityList);
|
||||||
|
useEffect(() => {
|
||||||
|
const countryCode = countrieList.find((item) => item.name === country);
|
||||||
|
if (countryCode) {
|
||||||
|
const states = State.getStatesOfCountry(countryCode.isoCode);
|
||||||
|
setStateListData(states);
|
||||||
|
}
|
||||||
|
}, [country, countrieList]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (state) {
|
||||||
|
const stateCode = stateListData?.find((item) => item.name === state);
|
||||||
|
// console.log(stateCode);
|
||||||
|
if (stateCode) {
|
||||||
|
const cities = City.getCitiesOfState(
|
||||||
|
stateCode.countryCode,
|
||||||
|
stateCode.isoCode
|
||||||
|
);
|
||||||
|
// console.log(cities);
|
||||||
|
setCityListData(cities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [state, stateListData]);
|
||||||
|
//Calling to Fill form
|
||||||
|
useEffect(() => {
|
||||||
|
axios
|
||||||
|
.get(`/api/v1/affiliate/getone/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
// console.log(res.data.message);
|
||||||
|
setName(res.data.message.name);
|
||||||
|
setMobile(res.data.message.mobile);
|
||||||
|
setEmail(res.data.message.email);
|
||||||
|
setCountry(res.data.message.country);
|
||||||
|
setState(res.data.message.state);
|
||||||
|
setCity(res.data.message.city);
|
||||||
|
setAddress(res.data.message.address);
|
||||||
|
setPincode(res.data.message.pincode);
|
||||||
|
setNameAsBank(res.data.message.nameAsBank);
|
||||||
|
setAccountNo(res.data.message.accountNo);
|
||||||
|
setIfsc(res.data.message.ifsc);
|
||||||
|
setBankName(res.data.message.bankName);
|
||||||
|
setBranchName(res.data.message.branchName);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//On form submit
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (
|
||||||
|
name === "" ||
|
||||||
|
mobile === 0 ||
|
||||||
|
email == "" ||
|
||||||
|
country === "" ||
|
||||||
|
address === "" ||
|
||||||
|
pincode === 0 ||
|
||||||
|
nameAsBank === "" ||
|
||||||
|
accountNo === 0 ||
|
||||||
|
ifsc === "" ||
|
||||||
|
bankName === "" ||
|
||||||
|
branchName === ""
|
||||||
|
) {
|
||||||
|
swal({
|
||||||
|
title: "Warning",
|
||||||
|
text: "Fill all mandatory fields",
|
||||||
|
icon: "error",
|
||||||
|
button: "Close",
|
||||||
|
dangerMode: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
const formDataObject = {
|
||||||
|
name: name,
|
||||||
|
mobile: mobile,
|
||||||
|
email: email,
|
||||||
|
country: country,
|
||||||
|
state: state,
|
||||||
|
city: city,
|
||||||
|
address: address,
|
||||||
|
pincode: pincode,
|
||||||
|
nameAsBank: nameAsBank,
|
||||||
|
accountNo: accountNo,
|
||||||
|
ifsc: ifsc,
|
||||||
|
bankName: bankName,
|
||||||
|
branchName: branchName,
|
||||||
|
};
|
||||||
|
axios
|
||||||
|
.patch(`/api/v1/affiliate/edit/${id}`, formDataObject, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
// Handle the data returned by the server
|
||||||
|
setLoading(false);
|
||||||
|
//Resetting Inputs
|
||||||
|
setName("");
|
||||||
|
setMobile("");
|
||||||
|
setEmail("");
|
||||||
|
setCountry("");
|
||||||
|
setState("");
|
||||||
|
setCity("");
|
||||||
|
setAddress("");
|
||||||
|
setPincode("");
|
||||||
|
setNameAsBank("");
|
||||||
|
setAccountNo("");
|
||||||
|
setIfsc("");
|
||||||
|
setBankName("");
|
||||||
|
setBranchName("");
|
||||||
|
swal({
|
||||||
|
title: "Congratulations!!",
|
||||||
|
text: "The Coupon was Created successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
navigate("/affiliate/affiliates");
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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">
|
||||||
|
Edit Affiliate
|
||||||
|
</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="/affiliate/affiliates">
|
||||||
|
<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">
|
||||||
|
Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="name"
|
||||||
|
value={name}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
/>
|
||||||
|
{name ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - name.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}{" "}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Mobile
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="mobile"
|
||||||
|
value={mobile}
|
||||||
|
maxLength="100"
|
||||||
|
onChange={handelNumber}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Email
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
className="form-control"
|
||||||
|
id="email"
|
||||||
|
value={email}
|
||||||
|
maxLength="100"
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="categorySelect">Select a Country</label>
|
||||||
|
<select
|
||||||
|
id="country"
|
||||||
|
className="form-control"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
value={country}
|
||||||
|
onChange={handleCountry}
|
||||||
|
>
|
||||||
|
<option value={"None"}>None</option>
|
||||||
|
{countrieList.map((country) => (
|
||||||
|
<option key={country.isoCode} value={country.name}>
|
||||||
|
{country.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="categorySelect">Select a State</label>
|
||||||
|
<select
|
||||||
|
id="state"
|
||||||
|
className="form-control"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
value={state}
|
||||||
|
onChange={(e) => setState(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value={""}>None</option>
|
||||||
|
{stateListData?.map((states, i) => (
|
||||||
|
<option key={states.isoCode}>{states.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="categorySelect">Select a City</label>
|
||||||
|
<select
|
||||||
|
id="city"
|
||||||
|
className="form-control"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
value={city}
|
||||||
|
onChange={(e) => setCity(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value={""}>None</option>
|
||||||
|
{cityListData?.map((city, i) => (
|
||||||
|
<option key={i} value={city.isoCode}>
|
||||||
|
{city.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Address
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="address"
|
||||||
|
value={address}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => setAddress(e.target.value)}
|
||||||
|
/>
|
||||||
|
{name ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - name.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}{" "}
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Pincode
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="pincode"
|
||||||
|
value={pincode}
|
||||||
|
maxLength={25}
|
||||||
|
onChange={(e) => setPincode(e.target.value)}
|
||||||
|
/>
|
||||||
|
{name ? (
|
||||||
|
<>
|
||||||
|
<small className="charLeft mt-4 fst-italic">
|
||||||
|
{25 - name.length} characters left
|
||||||
|
</small>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}{" "}
|
||||||
|
</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">
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Name as per Bank records
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="nameasbank"
|
||||||
|
value={nameAsBank}
|
||||||
|
onChange={(e) => setNameAsBank(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Account Number
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control"
|
||||||
|
id="accountno"
|
||||||
|
value={accountNo}
|
||||||
|
onChange={(e) => setAccountNo(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
IFSC Code
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="ifsc"
|
||||||
|
value={ifsc}
|
||||||
|
onChange={(e) => setIfsc(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Bank Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="bankname"
|
||||||
|
value={bankName}
|
||||||
|
onChange={(e) => setBankName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3 me-3">
|
||||||
|
<label htmlFor="title" className="form-label">
|
||||||
|
Branch Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="branchname"
|
||||||
|
value={branchName}
|
||||||
|
onChange={(e) => setBranchName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditAffiliate;
|
373
src/views/Affiliate/EditCoupon.jsx
Normal file
373
src/views/Affiliate/EditCoupon.jsx
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import toast, { Toaster } from "react-hot-toast";
|
||||||
|
import { Button, Box, TextField, Typography } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
const EditCoupon = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const id = useParams().id;
|
||||||
|
const navigate = useNavigate();
|
||||||
|
//Style for inputs
|
||||||
|
const InputSpace = {
|
||||||
|
marginBottom: "1rem",
|
||||||
|
width: "20rem ",
|
||||||
|
height: "45px",
|
||||||
|
};
|
||||||
|
//Pagination Related
|
||||||
|
const [loading, setLoading] = useState(false); //only for testing
|
||||||
|
const [itemPerPage, setItemPerPage] = useState(10); //pagination
|
||||||
|
const [page, setPage] = useState(1); //pagination
|
||||||
|
//Form related
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [coupon, setCoupon] = useState("");
|
||||||
|
const [discount, setDiscount] = useState();
|
||||||
|
const [affiliateDiscountAmt, setAffiliateDiscountAmt] = useState();
|
||||||
|
const [valid, setValid] = useState("");
|
||||||
|
const [affiliate, setAffiliate] = useState("");
|
||||||
|
//Form error states
|
||||||
|
const [couponError, setCouponError] = useState(false);
|
||||||
|
const [discountError, setDiscountError] = useState(false);
|
||||||
|
const [validError, setValidError] = useState(false);
|
||||||
|
const [affiliateError, setAffiliateError] = useState(false);
|
||||||
|
const [affiliateDiscountAmtError, setAffiliateDiscountAmtError] =
|
||||||
|
useState(false);
|
||||||
|
//Start of Page
|
||||||
|
const [apiData, setApiData] = useState([]);
|
||||||
|
//Discount limit
|
||||||
|
const handelDiscount = (event) => {
|
||||||
|
let value = event.target.value;
|
||||||
|
if (parseInt(value) >= 9999) {
|
||||||
|
setDiscount(9999);
|
||||||
|
setDiscountError(true);
|
||||||
|
} else if (parseInt(value) < 0) {
|
||||||
|
setDiscount(0);
|
||||||
|
} else {
|
||||||
|
setDiscountError(false);
|
||||||
|
setDiscount(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//Affiliate Earning Handler
|
||||||
|
const handelAffilateDiscount = (event) => {
|
||||||
|
let value = event.target.value;
|
||||||
|
if (parseInt(value) >= 9999) {
|
||||||
|
setAffiliateDiscountAmt(9999);
|
||||||
|
setAffiliateDiscountAmtError(true);
|
||||||
|
} else if (parseInt(value) < 0) {
|
||||||
|
setDiscount(0);
|
||||||
|
} else {
|
||||||
|
setAffiliateDiscountAmtError(false);
|
||||||
|
setAffiliateDiscountAmt(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//Handel Form Submition
|
||||||
|
const handelCreate = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!(coupon.length === 8)) {
|
||||||
|
setCouponError(true);
|
||||||
|
toast.error("Code should be of 8 charecter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (valid === "") {
|
||||||
|
setValidError(true);
|
||||||
|
toast.error("Valid till is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (affiliate === "") {
|
||||||
|
setAffiliateError(true);
|
||||||
|
toast.error("Affiliate is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (discount === 0) {
|
||||||
|
setDiscountError(true);
|
||||||
|
toast.error("Discount amount is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Testing Validation for Affiliate Amount
|
||||||
|
if (!affiliateDiscountAmt) {
|
||||||
|
setAffiliateDiscountAmtError(true);
|
||||||
|
toast.error("Affiliate Discount Amount is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (affiliateDiscountAmt === 0 || affiliateDiscountAmt === "") {
|
||||||
|
setAffiliateDiscountAmtError(true);
|
||||||
|
toast.error("Affiliate Discount Amount is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Sending api --------------------
|
||||||
|
let formDataObject = {
|
||||||
|
coupon_code: coupon,
|
||||||
|
discount_amount: discount,
|
||||||
|
affiliate_discount_amount: affiliateDiscountAmt,
|
||||||
|
valid_till: valid,
|
||||||
|
is_coupon_active: true,
|
||||||
|
id: affiliate,
|
||||||
|
};
|
||||||
|
//PATCH REQUEST
|
||||||
|
axios
|
||||||
|
.patch(`/api/v1/coupon/edit/${id}`, formDataObject, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
//Reset Inputs
|
||||||
|
// console.log("Response:", data);
|
||||||
|
setDiscount("");
|
||||||
|
setCoupon("");
|
||||||
|
setValid("");
|
||||||
|
setAffiliate("");
|
||||||
|
setAffiliateDiscountAmt("");
|
||||||
|
// fetchCoupon();
|
||||||
|
setCouponError(false);
|
||||||
|
setDiscountError(false);
|
||||||
|
setValidError(false);
|
||||||
|
setAffiliateError(false);
|
||||||
|
setAffiliateDiscountAmtError(false);
|
||||||
|
swal({
|
||||||
|
title: "Congratulations!!",
|
||||||
|
text: "The Coupon was Edited successfully!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
navigate("/affiliate/coupons");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// Handle errors
|
||||||
|
const message = error.response?.data?.message
|
||||||
|
? error.response?.data?.message
|
||||||
|
: "Something went wrong!";
|
||||||
|
|
||||||
|
toast.error(message);
|
||||||
|
console.error("There was a problem with your fetch operation:", error);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setAffiliateError(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Back to Coupons
|
||||||
|
const handelBack = () => {
|
||||||
|
navigate("/affiliate/coupons");
|
||||||
|
};
|
||||||
|
|
||||||
|
//Fetch coupon data
|
||||||
|
const fetchCoupon = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/v1/coupon/getone/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setCoupon(res.data.message.coupon_code);
|
||||||
|
setDiscount(res.data.message.discount_amount);
|
||||||
|
setAffiliateDiscountAmt(res.data.message.affiliate_discount_amount);
|
||||||
|
setValid(res.data.message.valid_till);
|
||||||
|
setApiData({
|
||||||
|
name: res.data.message.name,
|
||||||
|
mobile: res.data.message.mobile,
|
||||||
|
});
|
||||||
|
setAffiliate(id);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Calling to fill form and Affiliate
|
||||||
|
useEffect(() => {
|
||||||
|
fetchCoupon();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<div
|
||||||
|
className=" page-title-box
|
||||||
|
d-flex
|
||||||
|
align-items-center
|
||||||
|
justify-content-between
|
||||||
|
flex-direction-row"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h3>Edit Coupons</h3>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex">
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
className="mx-2"
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
onClick={handelCreate}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
onClick={handelBack}
|
||||||
|
variant="contained"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
backgroundColor: "red",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: "2rem",
|
||||||
|
borderRadius: "0.5rem",
|
||||||
|
backgroundColor: "white",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "80%",
|
||||||
|
margin: "auto",
|
||||||
|
}}
|
||||||
|
className="border"
|
||||||
|
>
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Box>
|
||||||
|
<Typography className="mb-1">Coupon Code</Typography>
|
||||||
|
<TextField
|
||||||
|
className="mb-3"
|
||||||
|
required={true}
|
||||||
|
sx={InputSpace}
|
||||||
|
value={coupon}
|
||||||
|
InputProps={{
|
||||||
|
inputProps: {
|
||||||
|
maxLength: 8,
|
||||||
|
minLength: 8,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCoupon(e.target.value);
|
||||||
|
}}
|
||||||
|
error={couponError}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
/>
|
||||||
|
{couponError ? (
|
||||||
|
<small style={{ color: "red" }}>8 characters required</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Typography className="mb-1">Discount Amount</Typography>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginRight: "5px",
|
||||||
|
}}
|
||||||
|
className="d-flex justify-content-center"
|
||||||
|
>
|
||||||
|
<span style={{ fontSize: "1.7rem" }}>₹</span>
|
||||||
|
</div>
|
||||||
|
<TextField
|
||||||
|
className="mb-3"
|
||||||
|
required={true}
|
||||||
|
error={discountError}
|
||||||
|
type="number"
|
||||||
|
value={discount}
|
||||||
|
sx={InputSpace}
|
||||||
|
onChange={handelDiscount}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Typography className="mb-1">
|
||||||
|
Affiliate Discount Amount
|
||||||
|
</Typography>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginRight: "5px",
|
||||||
|
}}
|
||||||
|
className="d-flex justify-content-center"
|
||||||
|
>
|
||||||
|
<span style={{ fontSize: "1.7rem" }}>₹</span>
|
||||||
|
</div>
|
||||||
|
<TextField
|
||||||
|
className="mb-3"
|
||||||
|
required={true}
|
||||||
|
error={discountError}
|
||||||
|
type="number"
|
||||||
|
value={affiliateDiscountAmt}
|
||||||
|
sx={InputSpace}
|
||||||
|
onChange={handelAffilateDiscount}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{affiliateDiscountAmtError ? (
|
||||||
|
<small style={{ color: "red" }}>Max Amount Rs.9999</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Typography className="mb-1">Coupon Valid Till: </Typography>
|
||||||
|
<input
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "50px",
|
||||||
|
outline: validError ? "1px solid red" : "",
|
||||||
|
}}
|
||||||
|
className="mb-2"
|
||||||
|
value={valid}
|
||||||
|
sx={InputSpace}
|
||||||
|
onChange={(e) => {
|
||||||
|
setValid(e.target.value);
|
||||||
|
}}
|
||||||
|
type="date"
|
||||||
|
/>
|
||||||
|
{validError ? (
|
||||||
|
<small style={{ color: "red" }}>
|
||||||
|
Validity Date is Required
|
||||||
|
</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<Typography className="mb-1">Select Affiliate</Typography>
|
||||||
|
<select
|
||||||
|
onChange={(e) => {
|
||||||
|
setAffiliate(e.target.value);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "50px",
|
||||||
|
outline: validError ? "1px solid red" : "",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value={id}
|
||||||
|
>{`${apiData.name} - ${apiData.mobile}`}</option>
|
||||||
|
</select>
|
||||||
|
{affiliateError ? (
|
||||||
|
<small style={{ color: "red" }}>Affiliation is Required</small>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
</Box>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditCoupon;
|
309
src/views/Affiliate/PayAffiliate.jsx
Normal file
309
src/views/Affiliate/PayAffiliate.jsx
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
|
import axios from "axios";
|
||||||
|
import toast, { Toaster } from "react-hot-toast";
|
||||||
|
import { Button, Box, TextField, Typography } from "@mui/material";
|
||||||
|
import { isAutheticated } from "src/auth";
|
||||||
|
const PayAffiliate = () => {
|
||||||
|
const token = isAutheticated();
|
||||||
|
const id = useParams().id;
|
||||||
|
const navigate = useNavigate();
|
||||||
|
//Style for inputs
|
||||||
|
const InputSpace = {
|
||||||
|
marginBottom: "1rem",
|
||||||
|
width: "20rem ",
|
||||||
|
height: "45px",
|
||||||
|
};
|
||||||
|
//Set Affiliate Data
|
||||||
|
const [affiliate, setAffiliate] = useState("");
|
||||||
|
const [affiliateID, setAffiliateID] = useState("");
|
||||||
|
const [noOfCoupons, setNoOfCoupons] = useState("");
|
||||||
|
const [amountToPay, setAmountToPay] = useState("");
|
||||||
|
const [coupon, setCoupon] = useState("");
|
||||||
|
const [nameAsBank, setNameAsBank] = useState("");
|
||||||
|
const [accountNo, setAccountNo] = useState("");
|
||||||
|
const [ifsc, setIfsc] = useState("");
|
||||||
|
const [bankName, setBankName] = useState("");
|
||||||
|
const [branchName, setBranchName] = useState("");
|
||||||
|
const [affiliateDiscountAmt, setAffiliateDiscountAmt] = useState();
|
||||||
|
//Form related
|
||||||
|
const [amount, setAmount] = useState();
|
||||||
|
const [transecId, setTransecId] = useState("");
|
||||||
|
const [date, setDate] = useState("");
|
||||||
|
const [time, setTime] = useState("");
|
||||||
|
//Handel Pay
|
||||||
|
const handlePay = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log(amount, transecId, date);
|
||||||
|
const formDataObject = {
|
||||||
|
noOfCoupons,
|
||||||
|
amountToPay,
|
||||||
|
amount,
|
||||||
|
transecId,
|
||||||
|
date,
|
||||||
|
time,
|
||||||
|
};
|
||||||
|
axios
|
||||||
|
.post(`/api/v1/affiliate/pay/${id}`, formDataObject, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
swal({
|
||||||
|
title: "Congratulations!!",
|
||||||
|
text: "Successfully Payed!",
|
||||||
|
icon: "success",
|
||||||
|
button: "OK",
|
||||||
|
});
|
||||||
|
navigate("/affiliate/affiliates");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// Handle errors
|
||||||
|
const message = error.response?.data?.message
|
||||||
|
? error.response?.data?.message
|
||||||
|
: "Something went wrong!";
|
||||||
|
toast.error(message);
|
||||||
|
console.error("Error in Payment:", error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Fetch coupon data
|
||||||
|
const fetchPayData = () => {
|
||||||
|
axios
|
||||||
|
.get(`/api/v1/affiliate/getpay/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
// console.log(res.data.message);
|
||||||
|
setAffiliate(res.data.message.name);
|
||||||
|
setNoOfCoupons(
|
||||||
|
res.data.message?.coupon_claimed - res.data.message?.no_of_paid_coupon
|
||||||
|
);
|
||||||
|
setAmountToPay(
|
||||||
|
res.data.message.total_earning - res.data.message.paid_amount
|
||||||
|
);
|
||||||
|
setAmount(
|
||||||
|
res.data.message.total_earning - res.data.message.paid_amount
|
||||||
|
);
|
||||||
|
setCoupon(res.data.message.coupon_code);
|
||||||
|
setAffiliateDiscountAmt(res.data.message.affiliate_discount_amount);
|
||||||
|
setAffiliateID(id);
|
||||||
|
setNameAsBank(res.data.message.nameAsBank);
|
||||||
|
setAccountNo(res.data.message.accountNo);
|
||||||
|
setIfsc(res.data.message.ifsc);
|
||||||
|
setBankName(res.data.message.bankName);
|
||||||
|
setBranchName(res.data.message.branchName);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message =
|
||||||
|
error?.response?.data?.message || "Something went wrong!";
|
||||||
|
console.log(message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//Calling to fill form and Affiliate
|
||||||
|
useEffect(() => {
|
||||||
|
fetchPayData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="d-flex justify-content-end">
|
||||||
|
<Link to="/affiliate/affiliates">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
style={{
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: "1rem",
|
||||||
|
textTransform: "capitalize",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
className="card"
|
||||||
|
>
|
||||||
|
<div className="card-body p-2">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: "2rem",
|
||||||
|
borderRadius: "0.5rem",
|
||||||
|
backgroundColor: "white",
|
||||||
|
// marginBottom: "1rem",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
className="border"
|
||||||
|
>
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>Affiliate Name: </span>
|
||||||
|
{affiliate}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>Coupon Code: </span>
|
||||||
|
{coupon}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>
|
||||||
|
Per coupon price:{" "}
|
||||||
|
</span>
|
||||||
|
₹{affiliateDiscountAmt}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>
|
||||||
|
No of coupon paying for:{" "}
|
||||||
|
</span>
|
||||||
|
{noOfCoupons} Units
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>
|
||||||
|
Amount to be paid:{" "}
|
||||||
|
</span>
|
||||||
|
₹{amountToPay}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-6 col-md-6 col-sm-12 my-1">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
className="card"
|
||||||
|
>
|
||||||
|
<div className="card-body p-2">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: "2rem",
|
||||||
|
borderRadius: "0.5rem",
|
||||||
|
backgroundColor: "white",
|
||||||
|
// marginBottom: "1rem",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
className="border"
|
||||||
|
>
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>
|
||||||
|
Name as per Bank records:{" "}
|
||||||
|
</span>
|
||||||
|
{nameAsBank}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>Account Number: </span>
|
||||||
|
{accountNo}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>IFSC Code: </span>
|
||||||
|
{ifsc}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>Bank Name: </span>
|
||||||
|
{bankName}
|
||||||
|
</Typography>
|
||||||
|
<Typography className="mb-3">
|
||||||
|
<span style={{ fontWeight: "bold" }}>Branch Name: </span>
|
||||||
|
{branchName}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-12 col-md-12 col-sm-12 my-1">
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body p-5">
|
||||||
|
<form onSubmit={handlePay}>
|
||||||
|
<div className="d-lg-flex justify-content-center align-items-center">
|
||||||
|
<label htmlFor="title" className="form-label mr-2">
|
||||||
|
Transection ID
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
onChange={(e) => setTransecId(e.target.value)}
|
||||||
|
required="true"
|
||||||
|
type="text"
|
||||||
|
className="form-control mb-3 col-lg-4 col-md-12 col-sm-12 mr-5"
|
||||||
|
id="ifsc"
|
||||||
|
/>
|
||||||
|
<label htmlFor="title" className="form-label mr-2">
|
||||||
|
Date
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
required="true"
|
||||||
|
type="date"
|
||||||
|
onChange={(e) => setDate(e.target.value)}
|
||||||
|
className="form-control mb-3 col-lg-3 col-md-12 col-sm-12"
|
||||||
|
id="ifsc"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="d-lg-flex align-items-center justify-content-center">
|
||||||
|
<label htmlFor="title" className="form-label mr-2">
|
||||||
|
Time
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
required="true"
|
||||||
|
type="time"
|
||||||
|
onChange={(e) => setTime(e.target.value)}
|
||||||
|
className="form-control mb-3 col-lg-3 col-md-12 col-sm-12 mr-5"
|
||||||
|
id="ifsc"
|
||||||
|
/>
|
||||||
|
{/* <label htmlFor="title" className="form-label mr-2">
|
||||||
|
Amount
|
||||||
|
</label> */}
|
||||||
|
<span className="mb-3" style={{ marginRight: "0.5rem" }}>
|
||||||
|
Amount Rs.
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
required="true"
|
||||||
|
type="number"
|
||||||
|
className="form-control mb-3 col-lg-3 col-md-12 col-sm-12 mr-4 mb-4"
|
||||||
|
value={amount}
|
||||||
|
onChange={(e) => setAmount(e.target.value)}
|
||||||
|
id="amount"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
sx={{ marginTop: "-20px" }}
|
||||||
|
type="submit"
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
>
|
||||||
|
Pay
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PayAffiliate;
|
Loading…
Reference in New Issue
Block a user