mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-02-22 16:22: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.
192 lines
4.7 KiB
TypeScript
192 lines
4.7 KiB
TypeScript
import {
|
|
Table,
|
|
TableBody,
|
|
TableCaption,
|
|
TableCell,
|
|
TableFooter,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@/components/ui/table";
|
|
import { auth } from "@/lib/auth";
|
|
import prisma from "@/lib/db";
|
|
import { headers } from "next/headers";
|
|
import ClickableRow from "./clickable-row";
|
|
import DeviceCard from "./device-card";
|
|
import Pagination from "./pagination";
|
|
|
|
export async function DevicesTable({
|
|
searchParams,
|
|
parentalControl,
|
|
}: {
|
|
searchParams: Promise<{
|
|
query: string;
|
|
page: number;
|
|
sortBy: string;
|
|
}>;
|
|
parentalControl?: boolean;
|
|
}) {
|
|
const session = await auth.api.getSession({
|
|
headers: await headers()
|
|
})
|
|
const isAdmin = session?.user.role === "ADMIN"
|
|
const query = (await searchParams)?.query || "";
|
|
const page = (await searchParams)?.page;
|
|
const sortBy = (await searchParams)?.sortBy || "asc";
|
|
const totalDevices = await prisma.device.count({
|
|
where: {
|
|
userId: isAdmin ? undefined : session?.session.userId,
|
|
OR: [
|
|
{
|
|
name: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
},
|
|
},
|
|
{
|
|
mac: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
},
|
|
},
|
|
],
|
|
NOT: {
|
|
payments: {
|
|
some: {
|
|
paid: false
|
|
}
|
|
}
|
|
},
|
|
isActive: isAdmin ? undefined : parentalControl,
|
|
blocked: isAdmin ? undefined : parentalControl !== undefined ? undefined : false,
|
|
},
|
|
});
|
|
|
|
const totalPages = Math.ceil(totalDevices / 10);
|
|
const limit = 10;
|
|
const offset = (Number(page) - 1) * limit || 0;
|
|
|
|
const devices = await prisma.device.findMany({
|
|
where: {
|
|
userId: session?.session.userId,
|
|
OR: [
|
|
{
|
|
name: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
},
|
|
},
|
|
{
|
|
mac: {
|
|
contains: query || "",
|
|
mode: "insensitive",
|
|
},
|
|
},
|
|
],
|
|
NOT: {
|
|
payments: {
|
|
some: {
|
|
paid: false
|
|
}
|
|
},
|
|
},
|
|
isActive: parentalControl,
|
|
blocked: parentalControl !== undefined ? undefined : false,
|
|
},
|
|
|
|
skip: offset,
|
|
take: limit,
|
|
orderBy: {
|
|
name: `${sortBy}` as "asc" | "desc",
|
|
},
|
|
});
|
|
|
|
return (
|
|
<div>
|
|
{devices.length === 0 ? (
|
|
<div className="h-[calc(100svh-400px)] flex flex-col items-center justify-center my-4">
|
|
<h3>No devices yet.</h3>
|
|
</div>
|
|
) : (
|
|
<>
|
|
<div className="hidden sm:block">
|
|
<Table className="overflow-scroll">
|
|
<TableCaption>Table of all devices.</TableCaption>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Device Name</TableHead>
|
|
<TableHead>MAC Address</TableHead>
|
|
<TableHead>#</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody className="overflow-scroll">
|
|
{devices.map((device) => (
|
|
// <TableRow key={device.id}>
|
|
// <TableCell>
|
|
// <div className="flex flex-col items-start">
|
|
// <Link
|
|
// className="font-medium hover:underline"
|
|
// href={`/devices/${device.id}`}
|
|
// >
|
|
// {device.name}
|
|
// </Link>
|
|
// <span className="text-muted-foreground">
|
|
// Active until{" "}
|
|
// {new Date().toLocaleDateString("en-US", {
|
|
// month: "short",
|
|
// day: "2-digit",
|
|
// year: "numeric",
|
|
// })}
|
|
// </span>
|
|
// {parentalControl && (
|
|
// <div className="p-2 rounded border my-2">
|
|
// <span>Comment: </span>
|
|
// <p className="text-neutral-500">
|
|
// blocked because he was watching youtube
|
|
// </p>
|
|
// </div>
|
|
// )}
|
|
|
|
// </div>
|
|
// </TableCell>
|
|
// <TableCell className="font-medium">{device.mac}</TableCell>
|
|
// <TableCell>
|
|
// {!parentalControl ? (
|
|
// <AddDevicesToCartButton device={device} />
|
|
// ) : (
|
|
// <BlockDeviceButton device={device} />
|
|
// )}
|
|
// </TableCell>
|
|
// </TableRow>
|
|
<ClickableRow admin={isAdmin} key={device.id} device={device} parentalControl={parentalControl} />
|
|
))}
|
|
</TableBody>
|
|
<TableFooter>
|
|
<TableRow>
|
|
<TableCell colSpan={2}>
|
|
{query.length > 0 && (
|
|
<p className="text-sm text-muted-foreground">
|
|
Showing {devices.length} locations for "{query}
|
|
"
|
|
</p>
|
|
)}
|
|
</TableCell>
|
|
<TableCell className="text-muted-foreground">
|
|
{totalDevices} devices
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableFooter>
|
|
</Table>
|
|
<Pagination totalPages={totalPages} currentPage={page} />
|
|
</div>
|
|
<div className="sm:hidden my-4">
|
|
{devices.map((device) => (
|
|
<DeviceCard parentalControl={parentalControl} key={device.id} device={device} />
|
|
))}
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|