mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-23 06:42:00 +00:00
- 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.
230 lines
6.2 KiB
TypeScript
230 lines
6.2 KiB
TypeScript
import Pagination from "@/components/pagination";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCaption,
|
|
TableCell,
|
|
TableFooter,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@/components/ui/table";
|
|
import prisma from "@/lib/db";
|
|
import Link from "next/link";
|
|
|
|
export async function UsersPaymentsTable({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<{
|
|
query: string;
|
|
page: number;
|
|
sortBy: string;
|
|
status: string;
|
|
}>;
|
|
}) {
|
|
const query = (await searchParams)?.query || "";
|
|
const page = (await searchParams)?.page;
|
|
const sortBy = (await searchParams)?.sortBy || "asc";
|
|
const totalPayments = await prisma.payment.count({
|
|
where: {
|
|
OR: [
|
|
{
|
|
user: {
|
|
name: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
user: {
|
|
phoneNumber: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
user: {
|
|
address: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
user: {
|
|
id_card: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
],
|
|
},
|
|
});
|
|
|
|
const totalPages = Math.ceil(totalPayments / 10);
|
|
const limit = 10;
|
|
const offset = (Number(page) - 1) * limit || 0;
|
|
|
|
const payments = await prisma.payment.findMany({
|
|
where: {
|
|
OR: [
|
|
{
|
|
user: {
|
|
name: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
user: {
|
|
phoneNumber: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
user: {
|
|
address: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
user: {
|
|
id_card: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
}
|
|
},
|
|
},
|
|
],
|
|
},
|
|
include: {
|
|
user: true,
|
|
devices: true,
|
|
},
|
|
skip: offset,
|
|
take: limit,
|
|
orderBy: {
|
|
id: `${sortBy}` as "asc" | "desc",
|
|
},
|
|
});
|
|
|
|
// const users = await prisma.user.findMany({
|
|
// where: {
|
|
// role: "USER",
|
|
// },
|
|
// include: {
|
|
// atoll: true,
|
|
// island: true,
|
|
// },
|
|
// });
|
|
return (
|
|
<div>
|
|
{payments.length === 0 ? (
|
|
<div className="h-[calc(100svh-400px)] flex flex-col items-center justify-center my-4">
|
|
<h3>No Users yet.</h3>
|
|
</div>
|
|
) : (
|
|
<>
|
|
<Table className="overflow-scroll">
|
|
<TableCaption>Table of all users.</TableCaption>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Devices paid</TableHead>
|
|
<TableHead>User</TableHead>
|
|
<TableHead>Amount</TableHead>
|
|
<TableHead>Duration</TableHead>
|
|
<TableHead>Payment Status</TableHead>
|
|
<TableHead>Payment Method</TableHead>
|
|
<TableHead>Paid At</TableHead>
|
|
<TableHead>Action</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody className="overflow-scroll">
|
|
{payments.map((payment) => (
|
|
<TableRow
|
|
className={`${payment.paid && "title-bg dark:bg-black"}`}
|
|
key={payment.id}
|
|
>
|
|
<TableCell className="font-medium">
|
|
<ol className="list-disc list-inside text-sm">
|
|
{payment.devices.map((device) => (
|
|
<li key={device.id} className="text-sm text-muted-foreground">
|
|
{device.name}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</TableCell>
|
|
<TableCell className="font-medium">{payment.user.id_card}</TableCell>
|
|
<TableCell>{payment.user?.name}</TableCell>
|
|
<TableCell>{payment.user?.name}</TableCell>
|
|
<TableCell>{payment.id}</TableCell>
|
|
|
|
<TableCell>
|
|
{payment.paid ? (
|
|
<Badge
|
|
variant="outline"
|
|
className="bg-lime-100 text-black"
|
|
>
|
|
Verified
|
|
</Badge>
|
|
) : (
|
|
<Badge
|
|
variant="outline"
|
|
className="bg-yellow-100 text-black"
|
|
>
|
|
Unverified
|
|
</Badge>
|
|
)}
|
|
</TableCell>
|
|
<TableCell>
|
|
{new Date(payment.paidAt ?? "").toLocaleDateString("en-US", {
|
|
month: "short",
|
|
day: "2-digit",
|
|
year: "numeric",
|
|
})}
|
|
</TableCell>
|
|
|
|
<TableCell>{payment.id}</TableCell>
|
|
<TableCell>
|
|
<Link href={`/payments/${payment.id}/verify`}>
|
|
<Button>
|
|
Details
|
|
</Button>
|
|
</Link>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
<TableFooter>
|
|
<TableRow>
|
|
<TableCell colSpan={8}>
|
|
{query.length > 0 && (
|
|
<p className="text-sm text-muted-foreground">
|
|
Showing {payments.length} locations for "{query}
|
|
"
|
|
</p>
|
|
)}
|
|
</TableCell>
|
|
<TableCell className="text-muted-foreground">
|
|
{totalPayments} payments
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableFooter>
|
|
</Table>
|
|
<Pagination totalPages={totalPages} currentPage={page} />
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|