Download apps/web/src/components/settings/ApiKeyForm.tsx from Atmint/cpns: direct link, hf CLI and curl.
- Browser
- Download file 5.93 kB
-
https://huggingface.co/spaces/Atmint/cpns/resolve/main/apps/web/src/components/settings/ApiKeyForm.tsx
- Command line
-
hf download hf://spaces/Atmint/cpns/apps/web/src/components/settings/ApiKeyForm.tsx
-
curl -L -o ApiKeyForm.tsx https://huggingface.co/spaces/Atmint/cpns/resolve/main/apps/web/src/components/settings/ApiKeyForm.tsx
5.93 kB
| import { type ApiKeyConfig } from "@/hooks/use-api-key"; | |
| import { Button } from "@pram/ui/components/button"; | |
| import { Input } from "@pram/ui/components/input"; | |
| import { Label } from "@pram/ui/components/label"; | |
| import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@pram/ui/components/card"; | |
| import { | |
| Select, | |
| SelectContent, | |
| SelectGroup, | |
| SelectItem, | |
| SelectTrigger, | |
| SelectValue, | |
| } from "@pram/ui/components/select"; | |
| type FormState = Omit<ApiKeyConfig, "id"> & { apiKey: string }; | |
| interface ProviderOption { | |
| value: string; | |
| label: string; | |
| } | |
| interface ApiKeyFormProps { | |
| isAdding: boolean; | |
| isSaving: boolean; | |
| form: FormState; | |
| canSave: boolean; | |
| providers: ProviderOption[]; | |
| onChange: (field: keyof FormState, value: string | number) => void; | |
| onSave: () => void; | |
| onCancel: () => void; | |
| } | |
| export function ApiKeyForm({ isAdding, isSaving, form, canSave, providers, onChange, onSave, onCancel }: ApiKeyFormProps) { | |
| return ( | |
| <Card className="clay-shadow bg-[var(--pure-white)] border-2 border-[var(--matcha-400)] rounded-[var(--radius-xl)]"> | |
| <CardHeader> | |
| <CardTitle className="font-headline text-[var(--clay-black)]"> | |
| {isAdding ? "Tambah API Key Baru" : "Edit API Key"} | |
| </CardTitle> | |
| <CardDescription className="text-[var(--warm-charcoal)]"> | |
| {isAdding | |
| ? "Tambahkan konfigurasi provider baru." | |
| : "Kosongkan field API Key jika tidak ingin mengubahnya."} | |
| </CardDescription> | |
| </CardHeader> | |
| <CardContent className="space-y-5"> | |
| <div className="space-y-2"> | |
| <Label htmlFor="name" className="text-[var(--clay-black)]">Nama Config</Label> | |
| <Input | |
| id="name" | |
| value={form.name} | |
| onChange={(e) => onChange("name", e.target.value)} | |
| placeholder="Contoh: OpenAI GPT-4o" | |
| className="rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] bg-[var(--pure-white)] text-[var(--clay-black)]" | |
| /> | |
| </div> | |
| <div className="grid grid-cols-2 gap-4"> | |
| <div className="space-y-2"> | |
| <Label htmlFor="provider" className="text-[var(--clay-black)]">Provider</Label> | |
| <Select | |
| items={providers} | |
| value={form.provider} | |
| onValueChange={(v: string | null) => onChange("provider", v ?? "openai")} | |
| > | |
| <SelectTrigger id="provider"> | |
| <SelectValue placeholder="Pilih provider" /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| <SelectGroup> | |
| {providers.map((p) => ( | |
| <SelectItem key={p.value} value={p.value}>{p.label}</SelectItem> | |
| ))} | |
| </SelectGroup> | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="model" className="text-[var(--clay-black)]">Model</Label> | |
| <Input | |
| id="model" | |
| value={form.modelName} | |
| onChange={(e) => onChange("modelName", e.target.value)} | |
| placeholder="gpt-4o-mini" | |
| className="rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] bg-[var(--pure-white)] text-[var(--clay-black)]" | |
| /> | |
| </div> | |
| </div> | |
| <div className="grid grid-cols-2 gap-4"> | |
| <div className="space-y-2"> | |
| <Label htmlFor="baseUrl" className="text-[var(--clay-black)]">Base URL</Label> | |
| <Input | |
| id="baseUrl" | |
| value={form.baseUrl} | |
| onChange={(e) => onChange("baseUrl", e.target.value)} | |
| placeholder="https://api.openai.com/v1" | |
| className="rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] bg-[var(--pure-white)] text-[var(--clay-black)]" | |
| /> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="maxTokens" className="text-[var(--clay-black)]">Max Tokens</Label> | |
| <Input | |
| id="maxTokens" | |
| type="number" | |
| min={1} | |
| max={1_000_000} | |
| value={form.maxTokens} | |
| onChange={(e) => onChange("maxTokens", Number(e.target.value))} | |
| placeholder="16384" | |
| className="rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] bg-[var(--pure-white)] text-[var(--clay-black)]" | |
| /> | |
| </div> | |
| </div> | |
| <div className="space-y-2"> | |
| <Label htmlFor="apiKey" className="text-[var(--clay-black)]"> | |
| API Key | |
| {!isAdding && ( | |
| <span className="text-[var(--warm-silver)] font-normal ml-1"> | |
| (kosongkan jika tidak diubah) | |
| </span> | |
| )} | |
| </Label> | |
| <Input | |
| id="apiKey" | |
| type="password" | |
| value={form.apiKey} | |
| onChange={(e) => onChange("apiKey", e.target.value)} | |
| placeholder={isAdding ? "sk-..." : "•••••••• (kosongkan untuk tidak mengubah)"} | |
| className="rounded-[var(--radius-lg)] border-2 border-[var(--oat-border)] bg-[var(--pure-white)] text-[var(--clay-black)]" | |
| /> | |
| </div> | |
| <div className="flex gap-3"> | |
| <Button | |
| onClick={onSave} | |
| disabled={!canSave || isSaving} | |
| className="bg-[var(--clay-black)] text-[var(--pure-white)] hover:bg-[var(--warm-charcoal)] rounded-[var(--radius-lg)] h-11 clay-shadow clay-hover" | |
| > | |
| {isSaving ? "Menyimpan..." : isAdding ? "Simpan" : "Update"} | |
| </Button> | |
| <Button | |
| variant="outline" | |
| onClick={onCancel} | |
| className="rounded-[var(--radius-lg)] h-11 border-2 border-[var(--oat-border)]" | |
| > | |
| Batal | |
| </Button> | |
| </div> | |
| </CardContent> | |
| </Card> | |
| ); | |
| } | |