import { useState, useRef, useCallback } from 'react' import { X, Eye, EyeSlash, GithubLogo, SignOut } from '@phosphor-icons/react' import { GitHubDeviceFlow } from './GitHubDeviceFlow' import type { Settings } from '../types' interface SettingsPanelProps { open: boolean settings: Settings onSave: (settings: Settings) => void onClose: () => void } interface KeyFieldProps { label: string placeholder: string value: string onChange: (value: string) => void onClear: () => void } function KeyField({ label, placeholder, value, onChange, onClear }: KeyFieldProps) { const [revealed, setRevealed] = useState(false) const inputRef = useRef(null) return (
onChange(e.target.value)} placeholder={placeholder} className="w-full border border-border bg-transparent text-foreground rounded" style={{ fontSize: 13, padding: '8px 60px 8px 10px', outline: 'none', fontFamily: 'inherit' }} autoComplete="off" data-testid={`settings-key-${label.toLowerCase().replace(/\s+/g, '-')}`} />
{value && ( <> )}
) } // --- GitHub OAuth Section --- interface GitHubSectionProps { githubUsername: string | null githubToken: string | null onConnected: (token: string, username: string) => void onDisconnect: () => void } function GitHubSection({ githubUsername, githubToken, onConnected, onDisconnect }: GitHubSectionProps) { const isConnected = !!githubToken && !!githubUsername if (isConnected) { return } return } function GitHubConnectedRow({ username, onDisconnect }: { username: string; onDisconnect: () => void }) { return (
{username} Connected
) } // --- Settings Panel --- export function SettingsPanel({ open, settings, onSave, onClose }: SettingsPanelProps) { if (!open) return null return } function SettingsPanelInner({ settings, onSave, onClose }: Omit) { const [anthropicKey, setAnthropicKey] = useState(settings.anthropic_key ?? '') const [openaiKey, setOpenaiKey] = useState(settings.openai_key ?? '') const [googleKey, setGoogleKey] = useState(settings.google_key ?? '') const [githubToken, setGithubToken] = useState(settings.github_token) const [githubUsername, setGithubUsername] = useState(settings.github_username) const [pullInterval, setPullInterval] = useState(settings.auto_pull_interval_minutes ?? 5) const buildSettings = useCallback((ghOverride?: { token: string | null; username: string | null }): Settings => ({ anthropic_key: anthropicKey.trim() || null, openai_key: openaiKey.trim() || null, google_key: googleKey.trim() || null, github_token: ghOverride ? ghOverride.token : (githubToken ?? null), github_username: ghOverride ? ghOverride.username : (githubUsername ?? null), auto_pull_interval_minutes: pullInterval, }), [anthropicKey, openaiKey, googleKey, githubToken, githubUsername, pullInterval]) const handleSave = () => { onSave(buildSettings()) onClose() } const handleGitHubConnected = useCallback((token: string, username: string) => { setGithubToken(token) setGithubUsername(username) onSave(buildSettings({ token, username })) }, [onSave, buildSettings]) const handleGitHubDisconnect = useCallback(() => { setGithubToken(null) setGithubUsername(null) onSave(buildSettings({ token: null, username: null })) }, [onSave, buildSettings]) const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Escape') { e.stopPropagation() onClose() } if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { e.preventDefault() handleSave() } } return (
{ if (e.target === e.currentTarget) onClose() }} onKeyDown={handleKeyDown} data-testid="settings-panel" >
) } function SettingsHeader({ onClose }: { onClose: () => void }) { return (
Settings
) } interface SettingsBodyProps { anthropicKey: string; setAnthropicKey: (v: string) => void openaiKey: string; setOpenaiKey: (v: string) => void googleKey: string; setGoogleKey: (v: string) => void githubToken: string | null; githubUsername: string | null onGitHubConnected: (token: string, username: string) => void onGitHubDisconnect: () => void pullInterval: number; setPullInterval: (v: number) => void } function SettingsBody(props: SettingsBodyProps) { return (
AI Provider Keys
API keys are stored locally on your device. Never sent to our servers.
props.setAnthropicKey('')} /> props.setOpenaiKey('')} /> props.setGoogleKey('')} />
GitHub
Connect your GitHub account to clone and sync vaults.
Sync
Automatically pull vault changes from Git in the background.
) } function SettingsFooter({ onClose, onSave }: { onClose: () => void; onSave: () => void }) { return (
{'\u2318'}, to open settings
) }