Skip to content

Commit 142b164

Browse files
committed
refactor(settings): split SettingsView into modular sections
1 parent c0e92b3 commit 142b164

14 files changed

Lines changed: 3200 additions & 2843 deletions

memory/decisions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,10 @@ Type: decision
253253
Event: App and daemon both needed the same latest-state-safe token persistence behavior after Orbit poll/sign-out.
254254
Action: Added `update_remote_backend_token_core` in `shared/settings_core.rs` and switched both Orbit adapters to use it instead of cloning stale settings snapshots.
255255
Rule: Persist Orbit token changes only via shared settings-core mutation helpers to avoid app/daemon divergence and stale overwrite races.
256+
257+
## 2026-02-07 20:11
258+
Context: SettingsView component decomposition
259+
Type: decision
260+
Event: Split `SettingsView` into section-focused components plus a dedicated sidebar nav while keeping orchestration/state in the container.
261+
Action: Added `SettingsNav`, extracted section components under `src/features/settings/components/sections/*`, introduced shared settings types in `settingsTypes.ts`, and rewired `SettingsView.tsx` to modal shell + section routing.
262+
Rule: For large settings surfaces, keep `SettingsView` as layout/orchestration and move section UI into dedicated components with typed props.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import LayoutGrid from "lucide-react/dist/esm/icons/layout-grid";
2+
import SlidersHorizontal from "lucide-react/dist/esm/icons/sliders-horizontal";
3+
import Mic from "lucide-react/dist/esm/icons/mic";
4+
import Keyboard from "lucide-react/dist/esm/icons/keyboard";
5+
import GitBranch from "lucide-react/dist/esm/icons/git-branch";
6+
import TerminalSquare from "lucide-react/dist/esm/icons/terminal-square";
7+
import FileText from "lucide-react/dist/esm/icons/file-text";
8+
import FlaskConical from "lucide-react/dist/esm/icons/flask-conical";
9+
import ExternalLink from "lucide-react/dist/esm/icons/external-link";
10+
import Layers from "lucide-react/dist/esm/icons/layers";
11+
import type { CodexSection } from "./settingsTypes";
12+
13+
type SettingsNavProps = {
14+
activeSection: CodexSection;
15+
onSelectSection: (section: CodexSection) => void;
16+
};
17+
18+
export function SettingsNav({ activeSection, onSelectSection }: SettingsNavProps) {
19+
return (
20+
<aside className="settings-sidebar">
21+
<button
22+
type="button"
23+
className={`settings-nav ${activeSection === "projects" ? "active" : ""}`}
24+
onClick={() => onSelectSection("projects")}
25+
>
26+
<LayoutGrid aria-hidden />
27+
Projects
28+
</button>
29+
<button
30+
type="button"
31+
className={`settings-nav ${activeSection === "environments" ? "active" : ""}`}
32+
onClick={() => onSelectSection("environments")}
33+
>
34+
<Layers aria-hidden />
35+
Environments
36+
</button>
37+
<button
38+
type="button"
39+
className={`settings-nav ${activeSection === "display" ? "active" : ""}`}
40+
onClick={() => onSelectSection("display")}
41+
>
42+
<SlidersHorizontal aria-hidden />
43+
Display &amp; Sound
44+
</button>
45+
<button
46+
type="button"
47+
className={`settings-nav ${activeSection === "composer" ? "active" : ""}`}
48+
onClick={() => onSelectSection("composer")}
49+
>
50+
<FileText aria-hidden />
51+
Composer
52+
</button>
53+
<button
54+
type="button"
55+
className={`settings-nav ${activeSection === "dictation" ? "active" : ""}`}
56+
onClick={() => onSelectSection("dictation")}
57+
>
58+
<Mic aria-hidden />
59+
Dictation
60+
</button>
61+
<button
62+
type="button"
63+
className={`settings-nav ${activeSection === "shortcuts" ? "active" : ""}`}
64+
onClick={() => onSelectSection("shortcuts")}
65+
>
66+
<Keyboard aria-hidden />
67+
Shortcuts
68+
</button>
69+
<button
70+
type="button"
71+
className={`settings-nav ${activeSection === "open-apps" ? "active" : ""}`}
72+
onClick={() => onSelectSection("open-apps")}
73+
>
74+
<ExternalLink aria-hidden />
75+
Open in
76+
</button>
77+
<button
78+
type="button"
79+
className={`settings-nav ${activeSection === "git" ? "active" : ""}`}
80+
onClick={() => onSelectSection("git")}
81+
>
82+
<GitBranch aria-hidden />
83+
Git
84+
</button>
85+
<button
86+
type="button"
87+
className={`settings-nav ${activeSection === "codex" ? "active" : ""}`}
88+
onClick={() => onSelectSection("codex")}
89+
>
90+
<TerminalSquare aria-hidden />
91+
Codex
92+
</button>
93+
<button
94+
type="button"
95+
className={`settings-nav ${activeSection === "features" ? "active" : ""}`}
96+
onClick={() => onSelectSection("features")}
97+
>
98+
<FlaskConical aria-hidden />
99+
Features
100+
</button>
101+
</aside>
102+
);
103+
}

0 commit comments

Comments
 (0)