CAPS04-FE-REFACTOR / resources /js /components /admin /admin-api-key-card.tsx
wepee's picture
change: consume api in resources
cc20f66
Raw
History Blame Contribute Delete
3.55 kB
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>
);
}