import { useMutation, useQuery } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { Key, Plus, RefreshCw, Trash2 } from "lucide-react"; import { Link } from "react-router-dom"; import { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "../../components/ui/card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../../components/ui/table"; import { deleteApiKey, fetchApiKeys } from "../../lib/adminApi"; import { t } from "../../lib/i18n"; function ApiKeyListPage() { const query = useQuery({ queryKey: ["api-keys", { limit: 50, offset: 0 }], queryFn: () => fetchApiKeys(50, 0), }); const deleteMutation = useMutation({ mutationFn: (id: string) => deleteApiKey(id), onSuccess: () => { query.refetch(); }, }); const errorMsg = (query.error as AxiosError<{ error?: string }>)?.response ?.data?.error; const fallbackError = !errorMsg && query.isError ? t( "msg.admin.api_keys.list.fetch_error", "API 키 목록 조회에 실패했습니다.", ) : null; const items = query.data?.items ?? []; const handleDelete = (id: string, name: string) => { if ( !window.confirm( t( "msg.admin.api_keys.list.delete_confirm", 'API 키 "{{name}}"를 삭제할까요?', { name }, ), ) ) { return; } deleteMutation.mutate(id); }; return (

{t("ui.admin.api_keys.list.title", "API 키 관리 (M2M)")}

{t( "msg.admin.api_keys.list.subtitle", "서버 간 통신(Machine-to-Machine)을 위한 API 키를 발급하고 관리합니다.", )}

{t("ui.admin.apikeys.registry.title", "API Key Registry")} {t( "msg.admin.apikeys.registry.count", "총 {{count}}개의 활성 키가 등록되어 있습니다.", { count: query.data?.items?.length ?? 0 }, )}
{(errorMsg || fallbackError) && (
{errorMsg ?? fallbackError}
)}
{t("ui.admin.api_keys.list.table.name", "NAME")} {t("ui.admin.api_keys.list.table.client_id", "CLIENT ID")} {t("ui.admin.api_keys.list.table.scopes", "SCOPES")} {t("ui.admin.api_keys.list.table.last_used", "LAST USED")} {t("ui.admin.api_keys.list.table.actions", "ACTIONS")} {query.isLoading && ( {t("msg.common.loading", "로딩 중...")} )} {!query.isLoading && items.length === 0 && ( {t( "msg.admin.api_keys.list.empty", "등록된 API 키가 없습니다.", )} )} {items.map((key) => (
{key.name}
{key.client_id}
{key.scopes.map((scope) => ( {scope} ))}
{key.lastUsedAt ? new Date(key.lastUsedAt).toLocaleString("ko-KR") : t("ui.common.never", "Never")}
))}
); } export default ApiKeyListPage;