mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-22 09:02:01 +00:00
Some checks failed
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 1m24s
- Updated `auth-actions.ts` to improve user verification notification formatting and date handling. - Modified `layout.tsx` to support dark mode styling for better user experience. - Refactored `signup/page.tsx` to enhance layout and responsiveness. - Introduced a new API route in `route.ts` for sending user verification notifications. - Improved user feedback in `user-payments-table.tsx` by updating the no payment message. - Made minor adjustments in `application-layout.tsx` for consistent padding. - Enhanced `signup-form.tsx` to display error messages for invalid user validation. These changes improve the user verification process, enhance UI consistency, and provide better feedback to users.
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 user payments 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>
|
|
);
|
|
}
|