| import { Copy, KeyRound } from 'lucide-react'; |
| import { useState } from 'react'; |
| import { toast } from 'sonner'; |
|
|
| import { ConfigError } from '@/components/admin/admin-form-parts'; |
| import { Button } from '@/components/ui/button'; |
| import { |
| Card, |
| CardContent, |
| CardDescription, |
| CardHeader, |
| CardTitle, |
| } from '@/components/ui/card'; |
| import { Input } from '@/components/ui/input'; |
| import { Label } from '@/components/ui/label'; |
| import { Spinner } from '@/components/ui/spinner'; |
| import { generateApiKey } from '@/lib/rag-client'; |
| import type { GeneratedApiKey } from '@/types/admin'; |
|
|
| export function AdminApiKeyCard() { |
| const [generatedApiKey, setGeneratedApiKey] = |
| useState<GeneratedApiKey | null>(null); |
| const [isLoading, setIsLoading] = useState(false); |
| const [error, setError] = useState<string | undefined>(); |
|
|
| async function handleGenerateApiKey(): Promise<void> { |
| setIsLoading(true); |
| setError(undefined); |
|
|
| try { |
| const result = await generateApiKey(); |
| setGeneratedApiKey(result); |
| } catch (e) { |
| setError( |
| e instanceof Error ? e.message : 'Gagal membuat API key.', |
| ); |
| } finally { |
| setIsLoading(false); |
| } |
| } |
|
|
| function handleCopyApiKey(): void { |
| if (!generatedApiKey?.api_key) { |
| return; |
| } |
|
|
| void navigator.clipboard.writeText(generatedApiKey.api_key); |
| toast.success('API key disalin.'); |
| } |
|
|
| return ( |
| <Card className="border-(--lecturer-border) bg-(--lecturer-surface)"> |
| <CardHeader> |
| <CardTitle className="flex items-center gap-2"> |
| <KeyRound className="size-5 text-(--lecturer-primary)" /> |
| API Key Iframe |
| </CardTitle> |
| <CardDescription> |
| API key hanya ditampilkan sekali setelah dibuat. |
| </CardDescription> |
| </CardHeader> |
| <CardContent className="grid gap-4"> |
| <Button |
| disabled={isLoading} |
| onClick={() => { |
| void handleGenerateApiKey(); |
| }} |
| type="button" |
| > |
| {isLoading ? ( |
| <Spinner className="size-4" /> |
| ) : ( |
| <KeyRound className="size-4" /> |
| )} |
| Generate API Key |
| </Button> |
| |
| <ConfigError message={error} /> |
| |
| {generatedApiKey ? ( |
| <div className="grid gap-3 rounded-xl border border-(--lecturer-border) bg-(--lecturer-surface) p-4"> |
| <Label>API Key Baru</Label> |
| <div className="flex gap-2"> |
| <Input readOnly value={generatedApiKey.api_key} /> |
| <Button |
| onClick={handleCopyApiKey} |
| type="button" |
| variant="outline" |
| > |
| <Copy className="size-4" /> |
| </Button> |
| </div> |
| <p className="text-sm text-muted-foreground"> |
| Expired: {generatedApiKey.expires_at ?? '-'} |
| </p> |
| </div> |
| ) : null} |
| </CardContent> |
| </Card> |
| ); |
| } |
|
|