Files
Frontend-Iasis/src/pages/admin/api-keys/ApiKeyTable.tsx

99 lines
2.8 KiB
TypeScript

import { Ban } from 'lucide-react';
import { Badge, Button, DataTable, Tooltip } from '../../../components/ui';
import { SCOPE_LABELS, type ApiKey } from '../../../modules/api-keys';
interface ApiKeyTableProps {
data: ApiKey[];
isLoading: boolean;
onRevoke: (key: ApiKey) => void;
}
function formatDate(value: string | null): string {
if (!value) return '—';
const date = new Date(value);
return date.toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' });
}
export function ApiKeyTable({ data, isLoading, onRevoke }: ApiKeyTableProps) {
return (
<DataTable<ApiKey>
data={data}
isLoading={isLoading}
emptyMessage="Nenhuma API Key emitida."
rowKey="id"
columns={[
{
key: 'name',
header: 'Nome',
render: (k) => (
<span className={k.isActive ? 'text-primary' : 'text-text-muted line-through'}>
{k.name}
</span>
),
},
{
key: 'scopes',
header: 'Escopos',
render: (k) => (
<div className="flex flex-wrap gap-1">
{k.scopes.map((scope) => (
<Badge key={scope} variant="info">
{SCOPE_LABELS[scope] ?? scope}
</Badge>
))}
</div>
),
},
{
key: 'lastFourChars',
header: 'Chave',
render: (k) => (
<code className="font-mono text-small text-text-secondary">
{k.lastFourChars}
</code>
),
},
{
key: 'isActive',
header: 'Status',
render: (k) => (
<Badge variant={k.isActive ? 'success' : 'danger'}>
{k.isActive ? 'Ativa' : 'Revogada'}
</Badge>
),
},
{
key: 'expiresAt',
header: 'Expiração',
render: (k) => <span className="text-text-secondary">{formatDate(k.expiresAt)}</span>,
},
{
key: 'lastUsedAt',
header: 'Último uso',
render: (k) => <span className="text-text-secondary">{formatDate(k.lastUsedAt)}</span>,
},
{
key: 'actions',
header: 'Ações',
render: (k) =>
k.isActive ? (
<Tooltip content="Revogar">
<Button
variant="ghost"
size="icon"
onClick={() => onRevoke(k)}
className="text-danger hover:text-danger/80"
aria-label="Revogar"
>
<Ban size={14} />
</Button>
</Tooltip>
) : (
<span className="text-text-muted text-small"></span>
),
},
]}
/>
);
}