Initial commit
This commit is contained in:
commit
afed023152
8152 files changed
+2086461
No files matched your search
@@ -0,0 +1,161 @@
|
||||
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 & 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 & 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>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user