77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
"use client";
|
||
|
||
import { ExternalLink, KeyRound } from "lucide-react";
|
||
import { Badge } from "@/components/ui/badge";
|
||
import { Input } from "@/components/ui/input";
|
||
import { Label } from "@/components/ui/label";
|
||
import { PROVIDER_KEY_LABELS, type ProviderId } from "@/lib/ai/keys";
|
||
|
||
const PROVIDER_ORDER: ProviderId[] = [
|
||
"opencode-go",
|
||
"xai",
|
||
"openai",
|
||
"anthropic",
|
||
"google",
|
||
];
|
||
|
||
interface ApiKeysFormProps {
|
||
values: Partial<Record<ProviderId, string>>;
|
||
configured: Partial<Record<ProviderId, boolean>>;
|
||
onChange: (provider: ProviderId, value: string) => void;
|
||
}
|
||
|
||
export function ApiKeysForm({ values, configured, onChange }: ApiKeysFormProps) {
|
||
return (
|
||
<div className="space-y-4">
|
||
{PROVIDER_ORDER.map((provider) => {
|
||
const meta = PROVIDER_KEY_LABELS[provider];
|
||
const isConfigured = configured[provider];
|
||
|
||
return (
|
||
<div
|
||
key={provider}
|
||
className="rounded-lg border border-border bg-muted p-4"
|
||
>
|
||
<div className="mb-3 flex items-center justify-between gap-3">
|
||
<div className="flex items-center gap-2">
|
||
<KeyRound className="h-4 w-4 text-muted-foreground" />
|
||
<Label className="normal-case text-sm font-semibold text-foreground">
|
||
{meta.label}
|
||
</Label>
|
||
</div>
|
||
<Badge variant={isConfigured ? "success" : "secondary"}>
|
||
{isConfigured ? "已設定" : "未設定"}
|
||
</Badge>
|
||
</div>
|
||
|
||
<p className="mb-3 text-xs leading-relaxed text-muted-foreground">{meta.hint}</p>
|
||
|
||
<Input
|
||
type="password"
|
||
value={values[provider] ?? ""}
|
||
onChange={(e) => onChange(provider, e.target.value)}
|
||
placeholder={isConfigured ? "留空則保留現有 key" : "貼上 API key"}
|
||
autoComplete="off"
|
||
/>
|
||
|
||
{meta.docsUrl && (
|
||
<a
|
||
href={meta.docsUrl}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="mt-2 inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground hover:underline"
|
||
>
|
||
<ExternalLink className="h-3 w-3" />
|
||
取得 {meta.label} API key
|
||
</a>
|
||
)}
|
||
</div>
|
||
);
|
||
})}
|
||
|
||
<p className="text-xs leading-relaxed text-muted-foreground">
|
||
AI Key 綁定你登入巡樓的帳號,所有 Threads 經營帳號共用。只存在本機資料庫;也可在 `.env` 設定環境變數作為備援。
|
||
</p>
|
||
</div>
|
||
);
|
||
} |