sarlink-portal/components/devices-to-pay.tsx
i701 a3f0759731
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 55s
Refactor user verification and data handling
- Updated `package.json` to add a new script for Prisma database setup.
- Replaced `usePerson` hook with `getNationalPerson` function in `lib/person.ts` for improved national data fetching.
- Refactored imports in `auth-actions.ts`, `user-actions.ts`, and `verify/page.tsx` to use the new `getNationalPerson` function.
- Enhanced device notification logic in `check-devices/route.ts` to correctly handle payment data.
- Improved error handling in `devices-to-pay.tsx` for better user feedback.

These changes streamline user verification processes and enhance data integrity across the application.
2025-01-10 21:58:13 +05:00

190 lines
6.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { verifyPayment } from "@/actions/payment";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableFooter,
TableRow,
} from "@/components/ui/table";
import { formatDate } from "@/lib/utils";
import type { Prisma, User } from "@prisma/client";
import { BadgeDollarSign, Clipboard, ClipboardCheck, Loader2, Wallet } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { Button } from "./ui/button";
type PaymentWithDevices = Prisma.PaymentGetPayload<{
include: {
devices: true;
};
}>;
export default function DevicesToPay({
payment,
user
}: { payment?: PaymentWithDevices, user?: User }) {
const [verifying, setVerifying] = useState(false)
const devices = payment?.devices;
if (devices?.length === 0) {
return null;
}
// 100+(n1)×75
const walletBalance = user?.walletBalance ?? 0;
const isWalletPayVisible = walletBalance > (payment?.amount ?? 0);
return (
<div className="w-full">
<div className="p-2 flex flex-col gap-2">
<h3 className="title-bg my-1 p-2 border border-dashed rounded-md font-semibold text-lg">
{!payment?.paid ? "Devices to pay" : "Devices Paid"}
</h3>
<div className="flex flex-col gap-2">
{devices?.map((device) => (
<div
key={device.id}
className="bg-muted border rounded p-2 flex gap-2 items-center"
>
<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>
<div className="m-2 flex items-end justify-end p-2 text-sm text-foreground border rounded">
<Table>
<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 ? (
<Button size={"lg"} variant={"secondary"} disabled className="dark:text-green-200 text-green-900 bg-green-500/20 uppercase font-semibold">Payment Verified</Button>
) : (
<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(payment?.amount),
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(payment?.amount),
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>
)}
</div>
</TableCaption>
<TableBody className="">
<TableRow>
<TableCell>Total Devices</TableCell>
<TableCell className="text-right text-xl">{devices?.length}</TableCell>
</TableRow>
<TableRow>
<TableCell>Duration</TableCell>
<TableCell className="text-right text-xl">{payment?.numberOfMonths} Months</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow className="">
<TableCell colSpan={1}>Total Due</TableCell>
<TableCell className="text-right text-3xl font-bold">{payment?.amount.toFixed(2)}</TableCell>
</TableRow>
</TableFooter>
</Table>
</div>
</div>
);
}
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>
);
}