import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; import { listTokens, createToken, revokeToken, deleteToken, updateToken, fetchUsers, createUser, deleteUser, updateUser, TokenDto, UserDto } from "@/lib/api"; import { Card, CardHeader, CardTitle, CardDescription, CardContent, Button, Badge, FormField, FormInput, FormSelect, FormRow } from "@/app/components/ui"; import { TokenUserSelect } from "@/app/components/TokenUserSelect"; import { UsernameEdit } from "@/app/components/UsernameEdit"; import { getServerTranslations } from "@/lib/i18n/server"; export const dynamic = "force-dynamic"; export default async function TokensPage({ searchParams }: { searchParams: Promise<{ created?: string }>; }) { const { t } = await getServerTranslations(); const params = await searchParams; const tokens = await listTokens().catch(() => [] as TokenDto[]); const users = await fetchUsers().catch(() => [] as UserDto[]); async function createTokenAction(formData: FormData) { "use server"; const name = formData.get("name") as string; const scope = formData.get("scope") as string; const userId = (formData.get("user_id") as string) || undefined; if (name) { const result = await createToken(name, scope, userId); revalidatePath("/tokens"); redirect(`/tokens?created=${encodeURIComponent(result.token)}`); } } async function revokeTokenAction(formData: FormData) { "use server"; const id = formData.get("id") as string; await revokeToken(id); revalidatePath("/tokens"); } async function deleteTokenAction(formData: FormData) { "use server"; const id = formData.get("id") as string; await deleteToken(id); revalidatePath("/tokens"); } async function createUserAction(formData: FormData) { "use server"; const username = formData.get("username") as string; if (username) { await createUser(username); revalidatePath("/tokens"); } } async function deleteUserAction(formData: FormData) { "use server"; const id = formData.get("id") as string; await deleteUser(id); revalidatePath("/tokens"); } async function renameUserAction(formData: FormData) { "use server"; const id = formData.get("id") as string; const username = formData.get("username") as string; if (username?.trim()) { await updateUser(id, username.trim()); revalidatePath("/tokens"); } } async function reassignTokenAction(formData: FormData) { "use server"; const id = formData.get("id") as string; const userId = (formData.get("user_id") as string) || null; await updateToken(id, userId); revalidatePath("/tokens"); } return ( <>

{t("tokens.title")}

{/* ── Lecteurs ─────────────────────────────────────────── */}

{t("users.title")}

{t("users.createNew")} {t("users.createDescription")}
{/* Ligne admin synthétique */} {/* Ligne tokens read non assignés */} {(() => { const unassigned = tokens.filter(tok => tok.scope === "read" && !tok.user_id && !tok.revoked_at); if (unassigned.length === 0) return null; return ( ); })()} {users.map((user) => ( ))}
{t("users.name")} {t("users.tokenCount")} {t("status.read")} {t("status.reading")} {t("users.createdAt")} {t("users.actions")}
{process.env.ADMIN_USERNAME ?? "admin"} {t("tokens.scopeAdmin")} {tokens.filter(tok => tok.scope === "admin" && !tok.revoked_at).length}
{t("tokens.noUser")} {unassigned.length}
{user.token_count} {user.books_read > 0 ? {user.books_read} : } {user.books_reading > 0 ? {user.books_reading} : } {new Date(user.created_at).toLocaleDateString()}
{/* ── Tokens API ───────────────────────────────────────── */}

{t("tokens.apiTokens")}

{params.created ? ( {t("tokens.created")} {t("tokens.createdDescription")}
{params.created}
) : null} {t("tokens.createNew")} {t("tokens.createDescription")}
{users.map((user) => ( ))}
{tokens.map((token) => ( ))}
{t("tokens.name")} {t("tokens.user")} {t("tokens.scope")} {t("tokens.prefix")} {t("tokens.status")} {t("tokens.actions")}
{token.name} {token.scope} {token.prefix} {token.revoked_at ? ( {t("tokens.revoked")} ) : ( {t("tokens.active")} )} {!token.revoked_at ? (
) : (
)}
); }