import { type EnvironmentId, UsageLimitSourceId } from "@t3tools/contracts"; import { useState } from "react"; import { useUpdateEnvironmentSettings } from "../../hooks/useSettings"; import { Button } from "../ui/button"; import { Dialog, DialogDescription, DialogFooter, DialogHeader, DialogPanel, DialogPopup, DialogTitle, } from "../ui/dialog"; import { Input } from "../ui/input"; import { Label } from "../ui/label"; /** * Stable per hub and readable in settings.json. Dots and dashes in the host * are kept so `foo-bar.com` and `foo.bar.com` do not collide; anything else * (a port's colon, a path) is folded to a dash. */ function sourceIdFromUrl(url: string): UsageLimitSourceId { let host = url; try { host = new URL(url).host; } catch { // Keep the raw text; the server reports the bad URL on its row. } const slug = host .toLowerCase() .replace(/[^a-z0-9.-]+/g, "-") .replace(/^-+|-+$/g, ""); return UsageLimitSourceId.make(`cliproxy-${slug || "hub"}`); } /** * Adds a CLIProxyAPI hub from provider settings on one environment. The * management key is sent once and kept in that server's secret store; * settings only ever carry a redaction marker for it afterwards. */ export function AddUsageLimitSourceDialog({ open, onOpenChange, environmentId, environmentLabel, }: { readonly open: boolean; readonly onOpenChange: (open: boolean) => void; readonly environmentId: EnvironmentId; readonly environmentLabel: string; }) { const updateSettings = useUpdateEnvironmentSettings(environmentId); const [label, setLabel] = useState(""); const [url, setUrl] = useState(""); const [managementKey, setManagementKey] = useState(""); const trimmedUrl = url.trim(); const canSave = trimmedUrl.length > 0 && managementKey.trim().length > 0; const reset = () => { setLabel(""); setUrl(""); setManagementKey(""); }; const save = () => { if (!canSave) return; const id = sourceIdFromUrl(trimmedUrl); // The patch names only this entry; the server merges it into its map. updateSettings({ usageLimitSources: { [id]: { kind: "cliproxy", ...(label.trim() ? { label: label.trim() } : {}), url: trimmedUrl, managementKey: managementKey.trim(), enabled: true, }, }, }); reset(); onOpenChange(false); }; return ( { if (!next) reset(); onOpenChange(next); }} > Add a CLIProxyAPI hub Show the quota of every account the hub pools, next to the providers on{" "} {environmentLabel}. The key stays on that server.
{ event.preventDefault(); save(); }} >
setUrl(event.target.value)} autoFocus />
setManagementKey(event.target.value)} />
setLabel(event.target.value)} />
); }