mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-23 07:02:00 +00:00
- Updated `package.json` to include a new script for launching Prisma Studio. - Modified `signup` function in `auth-actions.ts` to include account number in user data. - Refactored `createPayment` function in `payment.ts` to improve error handling and return structured responses. - Updated UI components in the dashboard to improve layout and responsiveness, including changes to `UserDevices` and `UserPayments` pages. - Introduced new `AdminDevicesTable` and `UsersPaymentsTable` components for better admin functionalities. - Enhanced `DeviceCartDrawer` to provide user feedback during payment processing. - Added account number input to the signup form and updated validation schema accordingly. - Updated Prisma schema to include a new `ninja_user_id` field for user management. These changes improve the overall functionality, maintainability, and user experience of the application, particularly in user management and payment processing.
223 lines
5.9 KiB
TypeScript
223 lines
5.9 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>Name</TableHead>
|
|
<TableHead>ID Card</TableHead>
|
|
<TableHead>Atoll</TableHead>
|
|
<TableHead>Island</TableHead>
|
|
<TableHead>House Name</TableHead>
|
|
<TableHead>Status</TableHead>
|
|
<TableHead>Dob</TableHead>
|
|
<TableHead>Phone Number</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">{payment.user.name}</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>
|
|
);
|
|
}
|