148 lines
4.3 KiB
TypeScript

import Link from "next/link";
import { redirect } from "next/navigation";
import { Search } from "lucide-react";
import { prisma } from "@/lib/prisma";
import { getCurrentUser } from "@/lib/session";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
async function getClients(search?: string) {
const where = search
? {
OR: [
{ name: { contains: search } },
{ clientId: { contains: search } },
{ description: { contains: search } },
],
}
: {};
const clients = await prisma.client.findMany({
where,
include: {
user: {
select: {
username: true,
email: true,
},
},
},
orderBy: {
createdAt: "desc",
},
});
return clients;
}
export default async function ClientsPage({
searchParams,
}: {
searchParams: { search?: string };
}) {
const user = await getCurrentUser();
if (!user || user.role !== "ADMIN") {
redirect("/dashboard");
}
const clients = await getClients(searchParams.search);
return (
<div className="mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8">
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</div>
<div className="flex items-center gap-4">
<div className="relative w-64">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
<form>
<Input
placeholder="搜索应用..."
name="search"
defaultValue={searchParams.search}
className="pl-8"
/>
</form>
</div>
</div>
</div>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead>Client ID</TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{clients.map((client) => (
<TableRow key={client.id}>
<TableCell className="font-medium">
<div className="flex items-center gap-2">
{client.logo && (
<img
src={client.logo}
alt={client.name}
className="h-6 w-6 rounded-full"
/>
)}
{client.name}
</div>
</TableCell>
<TableCell>{client.user.username}</TableCell>
<TableCell className="font-mono">{client.clientId}</TableCell>
<TableCell className="max-w-[200px] truncate">
{client.redirectUri}
</TableCell>
<TableCell>
{new Date(client.createdAt).toLocaleString()}
</TableCell>
<TableCell>
<Badge variant={client.enabled ? "default" : "destructive"}>
{client.enabled ? "启用" : "禁用"}
</Badge>
</TableCell>
<TableCell>
<Link href={`/admin/clients/${client.id}`}>
<Button variant="outline" size="sm">
</Button>
</Link>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
</div>
);
}