Files
llm-browser/frontend/src/components/examples/SettingsPanel.tsx
T
2026-10-19 16:04:17 +02:00

162 lines
6.5 KiB
TypeScript

import { useState } from 'react'
import { useTimeout } from '../../utils/useTimeout'
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '../ui/Card'
import { Switch } from '../ui/Switch'
import { Badge } from '../ui/Badge'
import { Alert, AlertTitle, AlertDescription } from '../ui/Alert'
import { Tooltip } from '../ui/Tooltip'
import { Kbd } from '../ui/Kbd'
import { Icon } from '../Icon'
export function SettingsPanel() {
const [apiKeyVisible, setApiKeyVisible] = useState(false)
const [copied, setCopied] = useState(false)
const [saved, setSaved] = useState(false)
// Toggles
const [canaryEnabled, setCanaryEnabled] = useState(true)
const [telemetryEnabled, setTelemetryEnabled] = useState(true)
const [autoRollback, setAutoRollback] = useState(false)
const apiKey = 'nsk_live_98a72ef01bc34d89a2'
const { schedule } = useTimeout()
const copyKey = () => {
navigator.clipboard?.writeText(apiKey)
setCopied(true)
schedule(() => setCopied(false), 2000)
}
const handleSave = () => {
setSaved(true)
schedule(() => setSaved(false), 2500)
}
return (
<div className="stack-lg">
<Card>
<CardHeader>
<div className="flex-between">
<CardTitle>Environment &amp; Access Keys</CardTitle>
<Badge variant="primary">Production</Badge>
</div>
<CardDescription>
Manage authentication credentials and runtime ingress access.
</CardDescription>
</CardHeader>
<CardContent>
<div className="stack-md">
<div>
<label style={{ display: 'block', fontSize: 'var(--text-xs)', fontWeight: 600, marginBottom: 'var(--space-2)' }}>
Production Secret API Key
</label>
<div className="row-xs" style={{ alignItems: 'center' }}>
<div
style={{
flex: 1,
background: 'var(--secondary)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)',
padding: 'var(--space-2) var(--space-3)',
fontFamily: 'var(--font-mono)',
fontSize: 'var(--text-xs)',
color: 'var(--foreground)',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<span>
{apiKeyVisible ? apiKey : '••••••••••••••••••••••••••••••••'}
</span>
<button
className="icon-button"
style={{ padding: 4 }}
onClick={() => setApiKeyVisible(!apiKeyVisible)}
aria-label={apiKeyVisible ? 'Hide API key' : 'Show API key'}
>
<Icon name={apiKeyVisible ? 'eye' : 'eye'} size={14} />
</button>
</div>
<Tooltip content="Copy key to clipboard">
<button className="button secondary" onClick={copyKey}>
<Icon name={copied ? 'check' : 'copy'} size={14} />
{copied ? 'Copied' : 'Copy'}
</button>
</Tooltip>
</div>
</div>
<Alert variant="info">
<AlertTitle>Zero-Trust Rotation Enabled</AlertTitle>
<AlertDescription>
Keys are automatically renewed every 90 days. Next scheduled rotation in 14 days.
</AlertDescription>
</Alert>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Deployment &amp; Runtime Safeguards</CardTitle>
<CardDescription>
Fine-tune canary threshold tolerances and telemetry logging.
</CardDescription>
</CardHeader>
<CardContent>
<div className="stack-md">
<div className="flex-between">
<div>
<div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, color: 'var(--foreground)' }}>
Automated Canary Progression
</div>
<div style={{ fontSize: 'var(--text-xs)', color: 'var(--muted-foreground)', marginTop: 2 }}>
Gradually increase traffic from 5% to 100% based on error budget.
</div>
</div>
<Switch checked={canaryEnabled} onCheckedChange={setCanaryEnabled} />
</div>
<div className="flex-between" style={{ paddingTop: 'var(--space-3)', borderTop: '1px solid var(--border)' }}>
<div>
<div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, color: 'var(--foreground)' }}>
Detailed OpenTelemetry Tracing
</div>
<div style={{ fontSize: 'var(--text-xs)', color: 'var(--muted-foreground)', marginTop: 2 }}>
Emit span metrics for all inbound HTTP and gRPC remote procedure calls.
</div>
</div>
<Switch checked={telemetryEnabled} onCheckedChange={setTelemetryEnabled} />
</div>
<div className="flex-between" style={{ paddingTop: 'var(--space-3)', borderTop: '1px solid var(--border)' }}>
<div>
<div style={{ fontSize: 'var(--text-sm)', fontWeight: 600, color: 'var(--foreground)' }}>
Immediate Circuit-Breaker Rollback
</div>
<div style={{ fontSize: 'var(--text-xs)', color: 'var(--muted-foreground)', marginTop: 2 }}>
Instantly revert to prior green build if P99 latency breaches 100ms.
</div>
</div>
<Switch checked={autoRollback} onCheckedChange={setAutoRollback} />
</div>
</div>
</CardContent>
<CardFooter>
<span style={{ fontSize: 'var(--text-3xs)', color: 'var(--muted-foreground)' }}>
Shortcut: <Kbd>Ctrl</Kbd> + <Kbd>S</Kbd> to persist
</span>
<div className="row-xs" style={{ marginLeft: 'auto' }}>
<button className="button ghost">Discard</button>
<button className="button primary" onClick={handleSave}>
<Icon name={saved ? 'check' : 'sparkles'} size={14} />
{saved ? 'Saved Successfully' : 'Save Changes'}
</button>
</div>
</CardFooter>
</Card>
</div>
)
}