1'use client';
2
3import { useState } from 'react';
4
5import { Badge } from '@/components/ui/badge';
6import { Button } from '@/components/ui/button';
7import { Table } from '@/components/ui/table';
8
9const apiKeys = [
10 { id: 'key_prod', name: 'Production', secret: 'sk_live_••••4f2a', lastUsed: '2m ago' },
11 { id: 'key_ci', name: 'CI pipeline', secret: 'sk_live_••••9b71', lastUsed: '3h ago' },
12 { id: 'key_dev', name: 'Local dev', secret: 'sk_test_••••1c05', lastUsed: 'Mar 12' },
13];
14
15export function WithActions() {
16 const [revoked, setRevoked] = useState<string[]>([]);
17
18 return (
19 <Table>
20 <Table.Caption>API keys for the storefront-api project.</Table.Caption>
21 <Table.Header>
22 <Table.Row>
23 <Table.Head>Name</Table.Head>
24 <Table.Head>Key</Table.Head>
25 <Table.Head>Status</Table.Head>
26 <Table.Head className="text-right">Actions</Table.Head>
27 </Table.Row>
28 </Table.Header>
29 <Table.Body>
30 {apiKeys.map((apiKey) => {
31 const isRevoked = revoked.includes(apiKey.id);
32
33 return (
34 <Table.Row key={apiKey.id}>
35 <Table.Cell className="font-medium">{apiKey.name}</Table.Cell>
36 <Table.Cell className="font-mono">{apiKey.secret}</Table.Cell>
37 <Table.Cell>
38 {isRevoked ? (
39 <Badge variant="secondary">Revoked</Badge>
40 ) : (
41 <span className="flex items-center gap-2">
42 <Badge variant="success">Active</Badge>
43 <span className="text-muted-foreground">Used {apiKey.lastUsed}</span>
44 </span>
45 )}
46 </Table.Cell>
47 <Table.Cell className="text-right">
48 <div className="flex justify-end gap-2">
49 <Button variant="ghost" className="h-8 px-2 text-xs" disabled={isRevoked}>
50 Copy
51 </Button>
52 <Button
53 variant="ghost"
54 className="text-destructive-text h-8 px-2 text-xs"
55 disabled={isRevoked}
56 onClick={() => setRevoked((keys) => [...keys, apiKey.id])}
57 >
58 Revoke
59 </Button>
60 </div>
61 </Table.Cell>
62 </Table.Row>
63 );
64 })}
65 </Table.Body>
66 </Table>
67 );
68}