From 1a195d2307c4579c23bf2955dc850f902fc129e6 Mon Sep 17 00:00:00 2001 From: i701 Date: Wed, 8 Jan 2025 23:04:30 +0500 Subject: [PATCH] Enhance payment processing and device management features - Updated `package.json` to add a new script for pushing Prisma database changes. - Refactored payment processing functions to include payment method handling for both wallet and transfer options. - Improved `DevicesTable` and `AdminDevicesTable` components to support new payment method display and user association. - Updated Prisma schema to introduce a new `PaymentType` enum and modified the `Payment` model to include a `method` field. - Enhanced UI components to improve user experience in displaying payment and device information. These changes improve the overall functionality and maintainability of the application, particularly in payment processing and device management. --- actions/payment.ts | 37 ++++++++++++------- components/admin/admin-devices-table.tsx | 30 ++++++++++----- components/admin/user-payments-table.tsx | 25 ++++++++----- components/auth/signup-form.tsx | 6 +-- components/devices-table.tsx | 12 ++++-- package.json | 3 +- .../20250108172258_add/migration.sql | 5 +++ .../20250108173116_change/migration.sql | 28 ++++++++++++++ prisma/schema.prisma | 19 ++++++---- 9 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 prisma/migrations/20250108172258_add/migration.sql create mode 100644 prisma/migrations/20250108173116_change/migration.sql diff --git a/actions/payment.ts b/actions/payment.ts index ce00069..5056fc3 100644 --- a/actions/payment.ts +++ b/actions/payment.ts @@ -78,11 +78,15 @@ async function processWalletPayment( data: { paid: true, paidAt: new Date(), + method: "WALLET", devices: { - updateMany: { - where: { paymentId: payment.id }, - data: { isActive: true, expiryDate: expiryDate }, - }, + updateMany: payment.devices.map((device) => ({ + where: { id: device.id }, + data: { + isActive: true, + expiryDate: expiryDate, + }, + })), }, }, }), @@ -136,11 +140,15 @@ async function verifyExternalPayment( data: { paid: true, paidAt: new Date(), + method: "TRANSFER", devices: { - updateMany: { - where: { paymentId: payment.id }, - data: { isActive: true, expiryDate: expiryDate }, - }, + updateMany: payment.devices.map((device) => ({ + where: { id: device.id }, + data: { + isActive: true, + expiryDate: expiryDate, + }, + })), }, }, }); @@ -177,16 +185,19 @@ export async function verifyPayment(data: VerifyPaymentType) { ]); if (data.type === "WALLET") { + console.log("WALLET"); await processWalletPayment(user, payment, Number(data.absAmount)); redirect("/payments"); } + if (data.type === "TRANSFER") { + console.log({ data, payment }); + const verificationResult = await verifyExternalPayment(data, payment); + await updateDevices(payment); - const verificationResult = await verifyExternalPayment(data, payment); - await updateDevices(payment); + revalidatePath("/payment[paymentId]"); - revalidatePath("/payment[paymentId]"); - - return verificationResult; + return verificationResult; + } } catch (error) { console.error("Payment verification failed:", error); throw error; // Re-throw to handle at a higher level diff --git a/components/admin/admin-devices-table.tsx b/components/admin/admin-devices-table.tsx index 0262e29..995c4bc 100644 --- a/components/admin/admin-devices-table.tsx +++ b/components/admin/admin-devices-table.tsx @@ -75,7 +75,10 @@ export async function AdminDevicesTable({ }, ], }, - + include: { + User: true, + payments: true, + }, skip: offset, take: limit, orderBy: { @@ -97,6 +100,7 @@ export async function AdminDevicesTable({ Device Name + User MAC Address isActive blocked @@ -115,14 +119,18 @@ export async function AdminDevicesTable({ > {device.name} - - Active until{" "} - {new Date().toLocaleDateString("en-US", { - month: "short", - day: "2-digit", - year: "numeric", - })} - + {device.isActive && ( + + + Active until{" "} + {new Date().toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + })} + + )} + {device.blocked && (
Comment: @@ -134,6 +142,8 @@ export async function AdminDevicesTable({
+ {device.User?.name} + {device.mac} {device.isActive ? "Active" : "Inactive"} @@ -159,7 +169,7 @@ export async function AdminDevicesTable({ - + {query.length > 0 && (

Showing {devices.length} locations for "{query} diff --git a/components/admin/user-payments-table.tsx b/components/admin/user-payments-table.tsx index 9219835..f590540 100644 --- a/components/admin/user-payments-table.tsx +++ b/components/admin/user-payments-table.tsx @@ -139,14 +139,13 @@ export async function UsersPaymentsTable({ Table of all users. - Name - ID Card - Atoll - Island - House Name - Status - Dob - Phone Number + Devices paid + User + Amount + Duration + Payment Status + Payment Method + Paid At Action @@ -156,7 +155,15 @@ export async function UsersPaymentsTable({ className={`${payment.paid && "title-bg dark:bg-black"}`} key={payment.id} > - {payment.user.name} + +

    + {payment.devices.map((device) => ( +
  1. + {device.name} +
  2. + ))} +
+
{payment.user.id_card} {payment.user?.name} {payment.user?.name} diff --git a/components/auth/signup-form.tsx b/components/auth/signup-form.tsx index 355df34..0a349c0 100644 --- a/components/auth/signup-form.tsx +++ b/components/auth/signup-form.tsx @@ -6,10 +6,10 @@ import Link from "next/link"; import { signup } from "@/actions/auth-actions"; import { cn } from "@/lib/utils"; import type { Island, Prisma } from "@prisma/client"; -import { Loader } from "lucide-react"; +import { Loader2 } from "lucide-react"; import { useSearchParams } from "next/navigation"; -import { useActionState } from "react"; import * as React from "react"; +import { useActionState } from "react"; import { Select, @@ -308,7 +308,7 @@ export default function SignUpForm({ atolls }: { atolls: AtollWithIslands[] }) { diff --git a/components/devices-table.tsx b/components/devices-table.tsx index 423bae4..a8f4434 100644 --- a/components/devices-table.tsx +++ b/components/devices-table.tsx @@ -51,8 +51,10 @@ export async function DevicesTable({ }, ], NOT: { - payment: { - paid: false + payments: { + some: { + paid: false + } } }, isActive: isAdmin ? undefined : parentalControl, @@ -82,8 +84,10 @@ export async function DevicesTable({ }, ], NOT: { - payment: { - paid: false + payments: { + some: { + paid: false + } }, }, isActive: parentalControl, diff --git a/package.json b/package.json index 1955414..ffa2ced 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "build": "bunx prisma migrate deploy && bunx prisma generate && bunx prisma db push && next build", "start": "next start", "lint": "next lint", - "studio": "bunx prisma studio" + "studio": "bunx prisma studio", + "push": "bunx prisma db push" }, "prisma": { "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts" diff --git a/prisma/migrations/20250108172258_add/migration.sql b/prisma/migrations/20250108172258_add/migration.sql new file mode 100644 index 0000000..3bf65d4 --- /dev/null +++ b/prisma/migrations/20250108172258_add/migration.sql @@ -0,0 +1,5 @@ +-- CreateEnum +CREATE TYPE "PaymentType" AS ENUM ('WALLET', 'TRANSFER'); + +-- AlterTable +ALTER TABLE "Payment" ADD COLUMN "method" "PaymentType" NOT NULL DEFAULT 'TRANSFER'; diff --git a/prisma/migrations/20250108173116_change/migration.sql b/prisma/migrations/20250108173116_change/migration.sql new file mode 100644 index 0000000..01ca97d --- /dev/null +++ b/prisma/migrations/20250108173116_change/migration.sql @@ -0,0 +1,28 @@ +/* + Warnings: + + - You are about to drop the column `paymentId` on the `Device` table. All the data in the column will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "Device" DROP CONSTRAINT "Device_paymentId_fkey"; + +-- AlterTable +ALTER TABLE "Device" DROP COLUMN "paymentId"; + +-- CreateTable +CREATE TABLE "_DeviceToPayment" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_DeviceToPayment_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_DeviceToPayment_B_index" ON "_DeviceToPayment"("B"); + +-- AddForeignKey +ALTER TABLE "_DeviceToPayment" ADD CONSTRAINT "_DeviceToPayment_A_fkey" FOREIGN KEY ("A") REFERENCES "Device"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_DeviceToPayment" ADD CONSTRAINT "_DeviceToPayment_B_fkey" FOREIGN KEY ("B") REFERENCES "Payment"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0206b08..facf150 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -115,6 +115,11 @@ enum Blocker { PARENT } +enum PaymentType { + WALLET + TRANSFER +} + model Device { id String @id @default(cuid()) name String @@ -129,20 +134,20 @@ model Device { updatedAt DateTime @updatedAt User User? @relation(fields: [userId], references: [id]) userId String? - payment Payment? @relation(fields: [paymentId], references: [id]) - paymentId String? + payments Payment[] } model Payment { - id String @id @default(cuid()) + id String @id @default(cuid()) numberOfMonths Int amount Float - paid Boolean @default(false) - user User @relation(fields: [userId], references: [id]) + paid Boolean @default(false) + user User @relation(fields: [userId], references: [id]) paidAt DateTime? + method PaymentType @default(TRANSFER) expiresAt DateTime? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt devices Device[] userId String }