import { useState, useEffect } from "react"; import ApiKeyInput from "./ApiKeyInput"; import DockerSettings from "./DockerSettings"; import AwsSettings from "./AwsSettings"; import { useSettings } from "../../hooks/useSettings"; import { useUpdates } from "../../hooks/useUpdates"; import ClaudeInstructionsModal from "../projects/ClaudeInstructionsModal"; import EnvVarsModal from "../projects/EnvVarsModal"; import { detectHostTimezone } from "../../lib/tauri-commands"; import type { EnvVar } from "../../lib/types"; export default function SettingsPanel() { const { appSettings, saveSettings } = useSettings(); const { appVersion, checkForUpdates } = useUpdates(); const [globalInstructions, setGlobalInstructions] = useState(appSettings?.global_claude_instructions ?? ""); const [globalEnvVars, setGlobalEnvVars] = useState(appSettings?.global_custom_env_vars ?? []); const [checkingUpdates, setCheckingUpdates] = useState(false); const [timezone, setTimezone] = useState(appSettings?.timezone ?? ""); const [showInstructionsModal, setShowInstructionsModal] = useState(false); const [showEnvVarsModal, setShowEnvVarsModal] = useState(false); // Sync local state when appSettings change useEffect(() => { setGlobalInstructions(appSettings?.global_claude_instructions ?? ""); setGlobalEnvVars(appSettings?.global_custom_env_vars ?? []); setTimezone(appSettings?.timezone ?? ""); }, [appSettings?.global_claude_instructions, appSettings?.global_custom_env_vars, appSettings?.timezone]); // Auto-detect timezone on first load if not yet set useEffect(() => { if (appSettings && !appSettings.timezone) { detectHostTimezone().then((tz) => { setTimezone(tz); saveSettings({ ...appSettings, timezone: tz }); }).catch(() => {}); } }, [appSettings?.timezone]); const handleCheckNow = async () => { setCheckingUpdates(true); try { await checkForUpdates(); } finally { setCheckingUpdates(false); } }; const handleAutoCheckToggle = async () => { if (!appSettings) return; await saveSettings({ ...appSettings, auto_check_updates: !appSettings.auto_check_updates }); }; return (

Settings

{/* Container Timezone */}

Timezone for containers — affects scheduled task timing (IANA format, e.g. America/New_York)

setTimezone(e.target.value)} onBlur={async () => { if (appSettings) { await saveSettings({ ...appSettings, timezone: timezone || null }); } }} placeholder="UTC" className="w-full px-2 py-1 text-sm bg-[var(--bg-primary)] border border-[var(--border-color)] rounded focus:outline-none focus:border-[var(--accent)]" />
{/* Global Claude Instructions */}

Global instructions applied to all projects (written to ~/.claude/CLAUDE.md in containers)

{globalInstructions ? "Configured" : "Not set"}
{/* Global Environment Variables */}

Applied to all project containers. Per-project variables override global ones with the same key.

{globalEnvVars.length > 0 ? `${globalEnvVars.length} variable${globalEnvVars.length === 1 ? "" : "s"}` : "None"}
{/* Updates section */}
{appVersion && (

Current version: {appVersion}

)}
{showInstructionsModal && ( { setGlobalInstructions(instructions); if (appSettings) { await saveSettings({ ...appSettings, global_claude_instructions: instructions || null }); } }} onClose={() => setShowInstructionsModal(false)} /> )} {showEnvVarsModal && ( { setGlobalEnvVars(vars); if (appSettings) { await saveSettings({ ...appSettings, global_custom_env_vars: vars }); } }} onClose={() => setShowEnvVarsModal(false)} /> )}
); }