2024-12-09 22:59:13 +05:00
|
|
|
|
'use client'
|
|
|
|
|
import { verifyPayment } from "@/actions/payment";
|
2024-12-06 14:16:05 +05:00
|
|
|
|
import {
|
|
|
|
|
Table,
|
|
|
|
|
TableBody,
|
|
|
|
|
TableCaption,
|
|
|
|
|
TableCell,
|
|
|
|
|
TableFooter,
|
|
|
|
|
TableRow,
|
2024-12-09 22:59:13 +05:00
|
|
|
|
} from "@/components/ui/table";
|
|
|
|
|
import { formatDate } from "@/lib/utils";
|
|
|
|
|
import type { BillFormula, Prisma, User } from "@prisma/client";
|
2024-12-25 17:21:04 +05:00
|
|
|
|
import { BadgeDollarSign, Clipboard, ClipboardCheck, Loader2, Wallet } from "lucide-react";
|
2024-12-09 22:59:13 +05:00
|
|
|
|
import { useState } from "react";
|
|
|
|
|
import { toast } from "sonner";
|
|
|
|
|
import { Button } from "./ui/button";
|
2024-12-07 14:09:53 +05:00
|
|
|
|
|
|
|
|
|
type PaymentWithDevices = Prisma.PaymentGetPayload<{
|
|
|
|
|
include: {
|
2024-12-09 22:59:13 +05:00
|
|
|
|
devices: true;
|
|
|
|
|
};
|
|
|
|
|
}>;
|
2024-12-07 14:09:53 +05:00
|
|
|
|
|
2024-12-09 22:59:13 +05:00
|
|
|
|
export default function DevicesToPay({
|
|
|
|
|
billFormula,
|
|
|
|
|
payment,
|
|
|
|
|
user
|
|
|
|
|
}: { billFormula?: BillFormula; payment?: PaymentWithDevices, user?: User }) {
|
|
|
|
|
const [verifying, setVerifying] = useState(false)
|
|
|
|
|
|
|
|
|
|
const devices = payment?.devices;
|
2024-12-07 14:09:53 +05:00
|
|
|
|
if (devices?.length === 0) {
|
2024-12-09 22:59:13 +05:00
|
|
|
|
return null;
|
2024-12-06 14:16:05 +05:00
|
|
|
|
}
|
2024-12-09 22:59:13 +05:00
|
|
|
|
const baseAmount = billFormula?.baseAmount ?? 100;
|
|
|
|
|
const discountPercentage = billFormula?.discountPercentage ?? 75;
|
2024-12-06 14:16:05 +05:00
|
|
|
|
// 100+(n−1)×75
|
2024-12-09 22:59:13 +05:00
|
|
|
|
const total = baseAmount + (devices?.length ?? 1 - 1) * discountPercentage;
|
2024-12-25 17:21:04 +05:00
|
|
|
|
const walletBalance = user?.walletBalance ?? 0;
|
|
|
|
|
const isWalletPayVisible = walletBalance > total;
|
2024-12-09 22:59:13 +05:00
|
|
|
|
|
|
|
|
|
|
2024-12-06 14:16:05 +05:00
|
|
|
|
return (
|
2024-12-09 22:59:13 +05:00
|
|
|
|
<div className="w-full">
|
|
|
|
|
<div className="p-2 flex flex-col gap-2">
|
2024-12-13 11:24:13 +05:00
|
|
|
|
<h3 className="title-bg my-1 p-2 font-semibold text-lg">
|
2024-12-09 22:59:13 +05:00
|
|
|
|
{!payment?.paid ? "Devices to pay" : "Devices Paid"}
|
2024-12-07 14:09:53 +05:00
|
|
|
|
</h3>
|
2024-12-06 14:16:05 +05:00
|
|
|
|
<div className="flex flex-col gap-2">
|
2024-12-07 14:09:53 +05:00
|
|
|
|
{devices?.map((device) => (
|
2024-12-09 22:59:13 +05:00
|
|
|
|
<div
|
|
|
|
|
key={device.id}
|
|
|
|
|
className="bg-muted border rounded p-2 flex gap-2 items-center"
|
|
|
|
|
>
|
2024-12-06 14:16:05 +05:00
|
|
|
|
<div className="flex flex-col">
|
|
|
|
|
<div className="text-sm font-medium">{device.name}</div>
|
|
|
|
|
<div className="text-xs text-muted-foreground">
|
|
|
|
|
{device.mac}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-09 22:59:13 +05:00
|
|
|
|
<div className="m-2 flex items-end justify-end p-2 text-sm text-foreground border rounded">
|
2024-12-06 14:16:05 +05:00
|
|
|
|
<Table>
|
2024-12-09 22:59:13 +05:00
|
|
|
|
<TableCaption>
|
|
|
|
|
<div className="max-w-sm mx-auto">
|
|
|
|
|
<p>Please send the following amount to the payment address</p>
|
|
|
|
|
<AccountInfomation
|
|
|
|
|
accName="Baraveli Dev"
|
|
|
|
|
accountNo="90101400028321000"
|
|
|
|
|
/>
|
|
|
|
|
{payment?.paid ? (
|
2024-12-13 11:24:13 +05:00
|
|
|
|
<Button size={"lg"} variant={"secondary"} disabled className="dark:text-green-200 text-green-900 bg-green-500/20 uppercase font-semibold">Payment Verified</Button>
|
2024-12-09 22:59:13 +05:00
|
|
|
|
) : (
|
2024-12-25 17:21:04 +05:00
|
|
|
|
<div className="flex flex-col gap-2">
|
|
|
|
|
{isWalletPayVisible && (
|
|
|
|
|
<Button
|
|
|
|
|
disabled={verifying}
|
|
|
|
|
onClick={async () => {
|
|
|
|
|
setVerifying(true);
|
|
|
|
|
await verifyPayment({
|
|
|
|
|
userId: user?.id ?? "",
|
|
|
|
|
paymentId: payment?.id,
|
|
|
|
|
benefName: user?.name ?? "",
|
|
|
|
|
accountNo: user?.accNo ?? "",
|
|
|
|
|
absAmount: String(total),
|
|
|
|
|
time: formatDate(new Date(payment?.createdAt || "")),
|
|
|
|
|
type: "WALLET",
|
|
|
|
|
});
|
|
|
|
|
setVerifying(false);
|
|
|
|
|
}}
|
|
|
|
|
variant={"secondary"} size={"lg"}>
|
|
|
|
|
{verifying ? "Paying..." : "Pay with wallet"}
|
|
|
|
|
<Wallet />
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
<Button
|
|
|
|
|
disabled={verifying}
|
|
|
|
|
onClick={async () => {
|
|
|
|
|
setVerifying(true);
|
|
|
|
|
const res = await verifyPayment({
|
|
|
|
|
userId: user?.id ?? "",
|
|
|
|
|
paymentId: payment?.id,
|
|
|
|
|
benefName: user?.name ?? "",
|
|
|
|
|
accountNo: user?.accNo ?? "",
|
|
|
|
|
absAmount: String(total),
|
|
|
|
|
type: "TRANSFER",
|
|
|
|
|
time: formatDate(new Date(payment?.createdAt || "")),
|
|
|
|
|
});
|
|
|
|
|
setVerifying(false);
|
|
|
|
|
switch (true) {
|
|
|
|
|
case res?.success === true:
|
|
|
|
|
toast.success(res.message);
|
|
|
|
|
break;
|
|
|
|
|
case res.success === false:
|
|
|
|
|
toast.error(res.message);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
toast.error("Unexpected error occurred.");
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
size={"lg"} className="mb-4">
|
|
|
|
|
{verifying ? "Verifying..." : "Verify Payment"}
|
|
|
|
|
{verifying ? <Loader2 className="animate-spin" /> : <BadgeDollarSign />}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-12-09 22:59:13 +05:00
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</TableCaption>
|
2024-12-21 00:24:29 +05:00
|
|
|
|
<TableBody className="">
|
2024-12-06 14:16:05 +05:00
|
|
|
|
<TableRow>
|
|
|
|
|
<TableCell>Total Devices</TableCell>
|
2024-12-21 00:24:29 +05:00
|
|
|
|
<TableCell className="text-right text-xl">{devices?.length}</TableCell>
|
2024-12-06 14:16:05 +05:00
|
|
|
|
</TableRow>
|
|
|
|
|
</TableBody>
|
|
|
|
|
<TableFooter>
|
2024-12-21 00:24:29 +05:00
|
|
|
|
<TableRow className="">
|
|
|
|
|
<TableCell colSpan={1}>Total Due</TableCell>
|
|
|
|
|
<TableCell className="text-right text-3xl font-bold">{total.toFixed(2)}</TableCell>
|
2024-12-06 14:16:05 +05:00
|
|
|
|
</TableRow>
|
|
|
|
|
</TableFooter>
|
|
|
|
|
</Table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-09 22:59:13 +05:00
|
|
|
|
);
|
|
|
|
|
}
|
2024-12-06 14:16:05 +05:00
|
|
|
|
|
2024-12-09 22:59:13 +05:00
|
|
|
|
function AccountInfomation({
|
|
|
|
|
accountNo,
|
|
|
|
|
accName,
|
|
|
|
|
}: {
|
|
|
|
|
accountNo: string;
|
|
|
|
|
accName: string;
|
|
|
|
|
}) {
|
|
|
|
|
const [accNo, setAccNo] = useState(false)
|
|
|
|
|
return (
|
|
|
|
|
<div className="justify-start items-start border my-4 flex flex-col gap-2 p-2 rounded-md">
|
|
|
|
|
<h6 className="title-bg uppercase p-2 border rounded w-full font-semibold">
|
|
|
|
|
Account Information
|
|
|
|
|
</h6>
|
|
|
|
|
<div className="border justify-start flex flex-col items-start bg-white/10 w-full p-2 rounded">
|
|
|
|
|
<div className="text-sm font-semibold">Account Name</div>
|
|
|
|
|
<span>{accName}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="border flex justify-between items-start gap-2 bg-white/10 w-full p-2 rounded">
|
|
|
|
|
<div className="flex flex-col items-start justify-start">
|
|
|
|
|
<p className="text-sm font-semibold">Account No</p>
|
|
|
|
|
<span>{accountNo}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
setAccNo(true)
|
|
|
|
|
navigator.clipboard.writeText(accountNo)
|
|
|
|
|
}, 2000)
|
|
|
|
|
toast.success("Account number copied!")
|
|
|
|
|
setAccNo((prev) => !prev)
|
|
|
|
|
}}
|
|
|
|
|
variant={"link"}>
|
|
|
|
|
{accNo ? <Clipboard /> : <ClipboardCheck color="green" />}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2024-12-06 14:16:05 +05:00
|
|
|
|
}
|