feat(nav): Settings as a page module (Design B)

Move Settings out of the right-side overlay into a left-nav page (page='settings'),
so it opens where you're already looking — no cross-screen mouse travel. The Settings
rail item now sets the page (with active highlight) instead of opening a dialog; the
panel is refactored to an in-flow .glass card (keeps the frosted look over the ambient
backdrop), with the page title shown in the header. Removed the overlay + Esc/backdrop
close path.
This commit is contained in:
npeter83 2026-06-16 01:05:05 +02:00
parent b82016c818
commit c5330e02f5
5 changed files with 71 additions and 102 deletions

View file

@ -57,7 +57,13 @@ function loadInitialPage(): Page {
const params = new URLSearchParams(window.location.search);
if (params.has("page")) return readPage();
const stored = localStorage.getItem(PAGE_KEY);
if (stored === "channels" || stored === "stats" || stored === "playlists") return stored;
if (
stored === "channels" ||
stored === "stats" ||
stored === "playlists" ||
stored === "settings"
)
return stored;
return "feed";
}
@ -83,7 +89,6 @@ export default function App() {
const [view, setView] = useState<"grid" | "list">("grid");
const [sidebarLayout, setSidebarLayoutState] = useState<SidebarLayout>(loadLayout);
const [page, setPageState] = useState<Page>(loadInitialPage);
const [settingsOpen, setSettingsOpen] = useState(false);
const [wizardOpen, setWizardOpen] = useState(false);
const [channelFilter, setChannelFilter] = useState<ChannelStatusFilter>("all");
const [aboutOpen, setAboutOpen] = useState(false);
@ -198,7 +203,6 @@ export default function App() {
me={meQuery.data!}
page={page}
setPage={setPage}
onOpenSettings={() => setSettingsOpen(true)}
onOpenAbout={() => setAboutOpen(true)}
/>
<div className="flex-1 min-w-0 flex flex-col">
@ -239,6 +243,15 @@ export default function App() {
<Stats />
) : page === "playlists" ? (
<Playlists canWrite={meQuery.data!.can_write} />
) : page === "settings" ? (
<SettingsPanel
me={meQuery.data!}
theme={theme}
setTheme={setTheme}
view={view}
setView={changeView}
onOpenWizard={() => setWizardOpen(true)}
/>
) : (
<Feed
filters={filters}
@ -251,20 +264,6 @@ export default function App() {
</main>
</div>
</div>
{settingsOpen && (
<SettingsPanel
me={meQuery.data!}
theme={theme}
setTheme={setTheme}
view={view}
setView={changeView}
onClose={() => setSettingsOpen(false)}
onOpenWizard={() => {
setSettingsOpen(false);
setWizardOpen(true);
}}
/>
)}
{wizardOpen && meQuery.data && (
<OnboardingWizard me={meQuery.data} onClose={() => setWizardOpen(false)} />
)}