238 lines
10 KiB
TypeScript
238 lines
10 KiB
TypeScript
'use client';
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
import axios from 'axios';
|
|
import Link from 'next/link';
|
|
import IconDownload from '@/components/icon/icon-download';
|
|
import IconEdit from '@/components/icon/icon-edit';
|
|
import IconPlus from '@/components/icon/icon-plus';
|
|
import IconPrinter from '@/components/icon/icon-printer';
|
|
import IconSend from '@/components/icon/icon-send';
|
|
import { formatCreatedAtWithEnd } from '@/utils/commonFunction.utils';
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
const ComponentsAppsInvoicePreview = () => {
|
|
const [payment, setPayment] = useState<any>(null);
|
|
const router = useRouter();
|
|
|
|
// 🧩 Print invoice
|
|
const exportTable = () => {
|
|
window.print();
|
|
};
|
|
|
|
// 🧩 Fetch payment data
|
|
useEffect(() => {
|
|
const sessionId = localStorage.getItem('payment_session');
|
|
if (!sessionId) {
|
|
router.push('/pricing');
|
|
return;
|
|
}
|
|
|
|
const fetchPayment = async () => {
|
|
try {
|
|
const res: any = await axios.get(
|
|
'https://ebay.backend.data4autos.com/api/payment/details',
|
|
{ params: { session_id: sessionId } }
|
|
);
|
|
setPayment(res.data.payment);
|
|
} catch (error) {
|
|
console.error('Error fetching payment details:', error);
|
|
}
|
|
};
|
|
|
|
fetchPayment();
|
|
}, [router]);
|
|
|
|
// 🧩 Invoice line items (example if your backend doesn't send itemized data)
|
|
const items = [
|
|
{
|
|
id: 1,
|
|
title: payment?.plan || 'Subscription Plan',
|
|
quantity: 1,
|
|
price: payment?.amount || '0',
|
|
amount: payment?.amount || '0',
|
|
},
|
|
];
|
|
|
|
const columns = [
|
|
{ key: 'id', label: 'S.NO' },
|
|
{ key: 'title', label: 'PLAN' },
|
|
{ key: 'quantity', label: 'QTY' },
|
|
{ key: 'price', label: 'PRICE', class: 'ltr:text-right rtl:text-left' },
|
|
{ key: 'amount', label: 'AMOUNT', class: 'ltr:text-right rtl:text-left' },
|
|
];
|
|
|
|
return (
|
|
<div className="p-6">
|
|
|
|
|
|
{/* ========= INVOICE CARD ========= */}
|
|
<div className="panel bg-white shadow-md rounded-xl p-6">
|
|
{/* Header */}
|
|
<div className="flex flex-wrap justify-between gap-4 px-4">
|
|
<div className="text-2xl font-semibold uppercase">Invoice</div>
|
|
<div className="shrink-0">
|
|
<img src="/assets/images/logo_dark.png" alt="logo" className="w-64" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="px-4 text-right text-gray-500">
|
|
<div className="mt-6 space-y-1">
|
|
<div>Data4Autos</div>
|
|
<div>sales@data4autos.com</div>
|
|
<div>
|
|
+1-647-679-7651</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr className="my-6 border-gray-200" />
|
|
|
|
{/* ========= INVOICE DETAILS ========= */}
|
|
<div className="flex flex-col justify-between gap-6 lg:flex-row">
|
|
<div className="flex-1">
|
|
<div className="space-y-1 text-gray-500">
|
|
<div>Issue For:</div>
|
|
<div className="font-semibold text-black">{payment?.email || '—'}</div>
|
|
<div>Customer ID: {payment?.userid || '—'}</div>
|
|
<div>Plan: {payment?.plan || '—'}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-col justify-between gap-6 sm:flex-row lg:w-2/3">
|
|
<div className="sm:w-1/2 lg:w-2/5">
|
|
<div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">Invoice :</span>
|
|
<span>#{payment?.id || '—'}</span>
|
|
</div>
|
|
<div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">Issue Date :</span>
|
|
<span>
|
|
{payment?.createdAt
|
|
? new Date(payment.createdAt).toLocaleDateString('en-GB', {
|
|
day: '2-digit',
|
|
month: 'short',
|
|
year: 'numeric',
|
|
})
|
|
: '—'}
|
|
</span>
|
|
</div>
|
|
<div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">Valid Till :</span>
|
|
<span>{formatCreatedAtWithEnd(payment?.createdAt)?.split(' - ')[1]}</span>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<span className="text-gray-500">Status :</span>
|
|
<span
|
|
className={`font-medium ${payment?.status === 'succeeded' ? 'text-green-600' : 'text-yellow-700'
|
|
}`}
|
|
>
|
|
{payment?.status === 'succeeded' ? 'Paid' : payment?.status || '—'}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="sm:w-1/2 lg:w-2/5">
|
|
<div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">Bank Name:</span>
|
|
<span>Bank of Canada</span>
|
|
</div>
|
|
<div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">Account No:</span>
|
|
<span>1234567890</span>
|
|
</div>
|
|
{/* <div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">SWIFT Code:</span>
|
|
<span>S58K796</span>
|
|
</div> */}
|
|
<div className="mb-2 flex justify-between">
|
|
<span className="text-gray-500">Country:</span>
|
|
<span>Canada</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* ========= ITEMS TABLE ========= */}
|
|
<div className="table-responsive mt-6">
|
|
<table className="table-striped w-full border-collapse">
|
|
<thead>
|
|
<tr className="bg-gray-100 text-gray-700">
|
|
{columns.map((column) => (
|
|
<th key={column.key} className={`p-3 text-left ${column.class || ''}`}>
|
|
{column.label}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{items.map((item) => (
|
|
<tr key={item.id} className="border-t">
|
|
<td className="p-3">{item.id}</td>
|
|
<td className="p-3">{item.title}</td>
|
|
<td className="p-3">{item.quantity}</td>
|
|
<td className="p-3 text-right">${item.price}</td>
|
|
<td className="p-3 text-right">${item.amount}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{/* ========= TOTAL ========= */}
|
|
<div className="mt-6 grid grid-cols-1 sm:grid-cols-2 px-4">
|
|
<div></div>
|
|
<div className="space-y-2 text-right">
|
|
<div className="flex justify-between">
|
|
<span>Subtotal</span>
|
|
<span>${payment?.amount || '0'}</span>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<span>Tax</span>
|
|
<span>$0</span>
|
|
</div>
|
|
<div className="flex justify-between font-semibold text-lg">
|
|
<span>Grand Total</span>
|
|
<span>${payment?.amount || '0'}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* ========= ACTION BUTTONS ========= */}
|
|
<div className="mt-6 flex flex-wrap items-center justify-center gap-4 lg:justify-end">
|
|
{/* <button type="button" className="btn btn-info gap-2">
|
|
<IconSend />
|
|
Send Invoice
|
|
</button> */}
|
|
<button
|
|
type="button"
|
|
className="btn btn-primary bg-[#00d1ff] border-[#00d1ff] gap-2 hover:bg-[#00b8e6] transition"
|
|
onClick={exportTable}
|
|
>
|
|
|
|
|
|
<IconPrinter />
|
|
Print
|
|
</button>
|
|
|
|
{/* <button type="button" className="btn btn-success gap-2">
|
|
<IconDownload />
|
|
Download
|
|
</button>
|
|
|
|
<Link href="/apps/invoice/add" className="btn btn-secondary gap-2">
|
|
<IconPlus />
|
|
Create
|
|
</Link>
|
|
|
|
<Link href="/apps/invoice/edit" className="btn btn-warning gap-2">
|
|
<IconEdit />
|
|
Edit
|
|
</Link> */}
|
|
</div>
|
|
</div >
|
|
);
|
|
};
|
|
|
|
export default ComponentsAppsInvoicePreview;
|