profileShare

rasmusjy / roundtable

Read-only snapshot

No repository description.

main default branch 181 files Expires Sep 13, 2026, 9:06 AM
key-button.tsx 1,376 bytes
1 'use client';
2
3 import { KeyRound } from 'lucide-react';
4 import { useEffect, useState } from 'react';
5 import { ApiKeyDialog } from '@/components/api-key-dialog';
6 import { Button } from '@/components/ui/button';
7 import { cn } from '@/lib/utils';
8
9 export function KeyButton() {
10 const [open, setOpen] = useState(false);
11 const [state, setState] = useState<{ hasKey: boolean; mock: boolean }>({
12 hasKey: false,
13 mock: false,
14 });
15
16 const load = () =>
17 fetch('/api/keys')
18 .then((r) => r.json())
19 .then((s: { hasKey: boolean; mockMode: boolean }) =>
20 setState({ hasKey: s.hasKey, mock: s.mockMode }),
21 )
22 .catch(() => {});
23
24 useEffect(() => {
25 void load();
26 }, []);
27
28 return (
29 <>
30 <Button variant="ghost" size="sm" className="gap-2" onClick={() => setOpen(true)}>
31 <span
32 className={cn(
33 'h-2 w-2 rounded-full',
34 state.mock
35 ? 'bg-amber-500'
36 : state.hasKey
37 ? 'bg-emerald-500'
38 : 'bg-muted-foreground/40',
39 )}
40 />
41 <KeyRound className="h-4 w-4" />
42 <span className="hidden sm:inline">
43 {state.mock ? 'Demo models' : state.hasKey ? 'Models connected' : 'Connect models'}
44 </span>
45 </Button>
46 <ApiKeyDialog open={open} onOpenChange={setOpen} onChanged={load} />
47 </>
48 );
49 }
50