181 lines
7.4 KiB
JavaScript
181 lines
7.4 KiB
JavaScript
import { useDispatch } from "react-redux";
|
|
import { useEffect, useState } from "react";
|
|
import axios from "axios";
|
|
import dayjs from "dayjs";
|
|
import {
|
|
FaBuilding,
|
|
FaUser,
|
|
FaPrint
|
|
} from "react-icons/fa";
|
|
import { jsPDF } from "jspdf";
|
|
import html2canvas from "html2canvas";
|
|
|
|
import { PublicQrCodeget } from "../../../Features/ConfigMasterPage/ConfigMasterPage";
|
|
import { decryptToObject, getSession } from "../../../Services/Others";
|
|
import { getBranchDetail } from "../../../Features/BrachLogin/BranchLogin";
|
|
import "./PurchaseLink.scss";
|
|
|
|
const PurchaseLink = () => {
|
|
const dispatch = useDispatch();
|
|
const apiUrlToken = import.meta.env.ENV_API_URL_TOKEN;
|
|
|
|
const [order, setOrder] = useState(null);
|
|
const [branch, setBranch] = useState(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
const url = new URL(window.location.href);
|
|
const codesParam = url.searchParams.get("code");
|
|
|
|
useEffect(() => {
|
|
if (codesParam) initializeData();
|
|
else setLoading(false);
|
|
}, [codesParam]);
|
|
|
|
const initializeData = async () => {
|
|
try {
|
|
if (!getSession("auth")) {
|
|
const { data } = await axios.post(`${apiUrlToken}/jwtTokenGenerator`, {
|
|
username: "1000000001",
|
|
password: "1234",
|
|
});
|
|
sessionStore("auth", data.token);
|
|
sessionStore("LoginType", "Public");
|
|
}
|
|
|
|
const qrData = await dispatch(PublicQrCodeget(codesParam)).unwrap();
|
|
const oldUrl = qrData?.data?.data?.[0]?.OldUrl;
|
|
const decrypted = decryptToObject(oldUrl);
|
|
if (!decrypted) return;
|
|
|
|
setOrder(decrypted);
|
|
if (decrypted?.BranchId) {
|
|
const res = await dispatch(getBranchDetail({ BrId: decrypted.BranchId })).unwrap();
|
|
setBranch(res?.data?.data?.[0]);
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (loading) return <div className="loading-container">Loading...</div>;
|
|
if (!order) return <div className="error-container">Invalid or expired link</div>;
|
|
|
|
// --- PDF Download Function ---
|
|
const handleDownloadPDF = async () => {
|
|
const element = document.getElementById("purchase-pdf");
|
|
const canvas = await html2canvas(element, { scale: 2 });
|
|
const imgData = canvas.toDataURL("image/png");
|
|
const pdf = new jsPDF("p", "mm", "a4");
|
|
|
|
const pdfWidth = pdf.internal.pageSize.getWidth();
|
|
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;
|
|
|
|
pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight);
|
|
pdf.save(`PurchaseOrder_${order?.PurOrderId || "PO"}.pdf`);
|
|
};
|
|
|
|
return (
|
|
<div className="purchase-link" id="purchase-pdf">
|
|
<div className="purchase-link__container">
|
|
{/* Header Section */}
|
|
<div className="purchase-link__header">
|
|
<h1 className="purchase-link__title">Purchase Order</h1>
|
|
{/* <div className="purchase-link__po-info">
|
|
|
|
<div className="date-info">
|
|
<FaCalendarAlt className="icon" />
|
|
<span>{dayjs(order?.PurOrderDate).format("DD MMM YYYY, hh:mm A")}</span>
|
|
</div>
|
|
</div> */}
|
|
</div>
|
|
|
|
{/* Main Content */}
|
|
<div className="purchase-link__content">
|
|
{/* Branch Address */}
|
|
<div className="address-card branch-card">
|
|
<div className="address-card__header">
|
|
<FaBuilding />
|
|
<h3>Branch Details</h3>
|
|
</div>
|
|
<div className="address-card__body">
|
|
<h4>{branch?.BrName || "Krishna Electrical and Electronics"}</h4>
|
|
<div style={{ display: "flex", flexWrap: "wrap",columnGap:"4px" }}>
|
|
|
|
<p>{branch?.Address1}</p>
|
|
<p>{branch?.City}, {branch?.Dist}</p>
|
|
<p>{branch?.State} - {branch?.Zip}</p>
|
|
{branch?.BrGSTIN && <p>GSTIN: {branch.BrGSTIN}</p>}
|
|
{branch?.BrMobile && <p>Phone: {branch.BrMobile}</p>}
|
|
{branch?.BrEmail && <p>Email: {branch.BrEmail}</p>}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Supplier Address */}
|
|
<div className="address-card supplier-card">
|
|
<div className="address-card__header">
|
|
<FaUser />
|
|
<h3>Supplier Details</h3>
|
|
</div>
|
|
<div className="address-card__body">
|
|
<h4>{order.SuppName}</h4>
|
|
|
|
{order?.AddressDetails?.map((addr, idx) => (
|
|
<div key={idx} style={{ display: "flex", flexWrap: "wrap", columnGap:"4px" }}>
|
|
<p>{addr.Address1}</p>
|
|
{addr.Address2 && <p>{addr.Address2}</p>}
|
|
<p>{addr.City}, {addr.Dist}</p>
|
|
<p>{addr.State} - {addr.Zip}</p>
|
|
</div>
|
|
))}
|
|
|
|
{order.SuppMobile && <p>Phone: {order.SuppMobile}</p>}
|
|
{order.SuppEmail && <p>Email: {order.SuppEmail}</p>}
|
|
{order.SuppGSTIN && <p>GSTIN: {order.SuppGSTIN}</p>}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Order Items */}
|
|
<div className="order-items-section">
|
|
<h3>Order Items</h3>
|
|
<table className="order-table">
|
|
<thead>
|
|
<tr>
|
|
<th>S.No</th>
|
|
<th>Product</th>
|
|
<th>Variant</th>
|
|
<th>UOM</th>
|
|
<th>Qty</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{order?.OrderDetails?.map((item, idx) => (
|
|
<tr key={idx}>
|
|
<td>{idx + 1}</td>
|
|
<td>{item.ProdName}</td>
|
|
<td>{item.ProdVariantName || "-"}</td>
|
|
<td>{item.UOM}</td>
|
|
<td>{item.OrderQty}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Download PDF Button */}
|
|
<div className="action-buttons">
|
|
<button className="btn secondary-btn" onClick={handleDownloadPDF}>
|
|
<FaPrint className="btn-icon" />
|
|
Download PDF
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PurchaseLink;
|