diff --git a/actions/payment.ts b/actions/payment.ts index e1f75f9..1ff1204 100644 --- a/actions/payment.ts +++ b/actions/payment.ts @@ -5,7 +5,7 @@ import type { PaymentType } from "@/lib/types"; import { revalidatePath } from "next/cache"; export async function createPayment(data: PaymentType) { - console.log("hi", data); + console.log("data", data); const payment = await prisma.payment.create({ data: { amount: data.amount, @@ -24,3 +24,48 @@ export async function createPayment(data: PaymentType) { revalidatePath("/devices"); return payment; } + +type VerifyPaymentType = { + paymentId?: string; + benefName: string; + accountNo?: string; + absAmount: string; + time: string; +}; + +export async function verifyPayment(data: VerifyPaymentType) { + console.log({ data }); + try { + const payment = await prisma.payment.findUnique({ + where: { + id: data.paymentId, + }, + }); + const response = await fetch( + "https://verifypaymentsapi.baraveli.dev/verify-payment", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }, + ); + const json = await response.json(); + console.log(json); + if (json.success === true) { + await prisma.payment.update({ + where: { + id: payment?.id, + }, + data: { + paid: true, + }, + }); + } + revalidatePath("/payment[paymentId]"); + return json; + } catch (error) { + console.error(error); + } +} diff --git a/app/(dashboard)/payments/[paymentId]/page.tsx b/app/(dashboard)/payments/[paymentId]/page.tsx index 40ce820..075605c 100644 --- a/app/(dashboard)/payments/[paymentId]/page.tsx +++ b/app/(dashboard)/payments/[paymentId]/page.tsx @@ -1,11 +1,22 @@ import DevicesToPay from "@/components/devices-to-pay"; +import { auth } from "@/lib/auth"; import { hasSession } from "@/lib/auth-guard"; import prisma from "@/lib/db"; +import { headers } from "next/headers"; import React from "react"; - export default async function PaymentPage({ params, -}: { params: Promise<{ paymentId: string }> }) { +}: { + params: Promise<{ paymentId: string }>; +}) { + const session = await auth.api.getSession({ + headers: await headers() + }) + const user = await prisma.user.findUnique({ + where: { + id: session?.session.userId + } + }) const paymentId = (await params).paymentId; const payment = await prisma.payment.findUnique({ where: { @@ -28,6 +39,7 @@ export default async function PaymentPage({ className="pb-4 gap-4 flex sm:flex-row flex-col items-start justify-start" > diff --git a/app/favicon.ico b/app/favicon.ico index 86f7217..ff78cbf 100644 Binary files a/app/favicon.ico and b/app/favicon.ico differ diff --git a/app/layout.tsx b/app/layout.tsx index 54221f1..ccefdb5 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -8,37 +8,37 @@ import { Toaster } from "sonner"; import "./globals.css"; import QueryProvider from "@/components/query-provider"; const barlow = Barlow({ - subsets: ["latin"], - weight: ["100", "300", "400", "500", "600", "700", "800", "900"], - variable: "--font-barlow", + subsets: ["latin"], + weight: ["100", "300", "400", "500", "600", "700", "800", "900"], + variable: "--font-barlow", }); export const metadata: Metadata = { - title: "SAR Link Portal", - description: "Sarlink Portal", + title: "SAR Link Portal", + description: "Sarlink Portal", }; export default function RootLayout({ - children, + children, }: Readonly<{ - children: React.ReactNode; + children: React.ReactNode; }>) { - return ( - - - - - - - {children} - - - - - ); + return ( + + + + + + + {children} + + + + + ); } diff --git a/components/device-cart.tsx b/components/device-cart.tsx index 5249bea..4922536 100644 --- a/components/device-cart.tsx +++ b/components/device-cart.tsx @@ -59,7 +59,7 @@ export function DeviceCartDrawer({ } else { setMessage(""); } - setTotal(baseAmount + (devices.length - 1) * discountPercentage); + setTotal(baseAmount + ((devices.length + 1) - 1) * discountPercentage); }, [months, devices.length, baseAmount, discountPercentage]); if (pathname === "/payment") { diff --git a/components/devices-to-pay.tsx b/components/devices-to-pay.tsx index 6d1227b..53dfbe8 100644 --- a/components/devices-to-pay.tsx +++ b/components/devices-to-pay.tsx @@ -1,3 +1,5 @@ +'use client' +import { verifyPayment } from "@/actions/payment"; import { Table, TableBody, @@ -5,35 +7,50 @@ import { TableCell, TableFooter, TableRow, -} from "@/components/ui/table" -import type { BillFormula, Prisma } from "@prisma/client" -import React from 'react' - +} from "@/components/ui/table"; +import { formatDate } from "@/lib/utils"; +import type { BillFormula, Prisma, User } from "@prisma/client"; +import { 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 - } -}> + devices: true; + }; +}>; -export default function DevicesToPay({ billFormula, payment }: { billFormula?: BillFormula, payment?: PaymentWithDevices }) { - const devices = payment?.devices +export default function DevicesToPay({ + billFormula, + payment, + user +}: { billFormula?: BillFormula; payment?: PaymentWithDevices, user?: User }) { + const [verifying, setVerifying] = useState(false) + + const devices = payment?.devices; if (devices?.length === 0) { - return null + return null; } - const baseAmount = billFormula?.baseAmount ?? 100 - const discountPercentage = billFormula?.discountPercentage ?? 75 + const baseAmount = billFormula?.baseAmount ?? 100; + const discountPercentage = billFormula?.discountPercentage ?? 75; // 100+(n−1)×75 - const total = baseAmount + (devices?.length ?? 1 - 1) * discountPercentage + const total = baseAmount + (devices?.length ?? 1 - 1) * discountPercentage; + + + return ( -
-
-

- {!payment?.paid ? 'Devices to pay' : 'Devices Paid'} +
+
+

+ {!payment?.paid ? "Devices to pay" : "Devices Paid"}

{devices?.map((device) => ( -
+
{device.name}
@@ -44,9 +61,49 @@ export default function DevicesToPay({ billFormula, payment }: { billFormula?: B ))}
-
+
- Please send the following amount to the payment address + +
+

Please send the following amount to the payment address

+ + {payment?.paid ? ( + + ) : ( + + )} + +
+
Total Devices @@ -62,6 +119,44 @@ export default function DevicesToPay({ billFormula, payment }: { billFormula?: B
- - ) + ); +} + +function AccountInfomation({ + accountNo, + accName, +}: { + accountNo: string; + accName: string; +}) { + const [accNo, setAccNo] = useState(false) + return ( +
+
+ Account Information +
+
+
Account Name
+ {accName} +
+
+
+

Account No

+ {accountNo} +
+ +
+
+ ); } diff --git a/lib/utils.ts b/lib/utils.ts index ac680b3..e0d51a2 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -4,3 +4,15 @@ import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } + +export const formatDate = (date: Date): string => { + const pad = (num: number): string => num.toString().padStart(2, "0"); + + const year = date.getFullYear(); + const month = pad(date.getMonth() + 1); // Months are zero-based + const day = pad(date.getDate()); + const hours = pad(date.getHours()); + const minutes = pad(date.getMinutes() + 5); + + return `${year}-${month}-${day} ${hours}:${minutes}`; +}; diff --git a/prisma/migrations/20241209164451_add/migration.sql b/prisma/migrations/20241209164451_add/migration.sql new file mode 100644 index 0000000..299138a --- /dev/null +++ b/prisma/migrations/20241209164451_add/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "user" ADD COLUMN "accNo" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6b731de..91199ad 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -20,6 +20,7 @@ model User { emailVerified Boolean @default(false) firstPaymentDone Boolean @default(false) verified Boolean @default(false) + accNo String? // island String? address String? id_card String? @unique