From af846749631c37617257fcf7eac867519967d5f3 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Tue, 17 Mar 2026 15:41:19 +0100 Subject: [PATCH] feat(mobile): add MobileSettingsScreen with drill-down navigation --- .../layout/MobileSettingsScreen.tsx | 114 ++++++++++++++++++ .../web/src/components/layout/MobileShell.tsx | 2 +- 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 packages/web/src/components/layout/MobileSettingsScreen.tsx diff --git a/packages/web/src/components/layout/MobileSettingsScreen.tsx b/packages/web/src/components/layout/MobileSettingsScreen.tsx new file mode 100644 index 00000000..d58e91b1 --- /dev/null +++ b/packages/web/src/components/layout/MobileSettingsScreen.tsx @@ -0,0 +1,114 @@ +import React from 'react'; +import { useUIStore } from '../../stores/uiStore'; +import { useAuthStore } from '../../stores/authStore'; +import { AccountPanel } from '../modals/settingsPanels/AccountPanel'; +import { VoicePanel } from '../modals/settingsPanels/VoicePanel'; +import { ConnectionsPanel } from '../modals/settingsPanels/ConnectionsPanel'; +import { PrivacyPanel } from '../modals/settingsPanels/PrivacyPanel'; +import { InstancePanel } from '../modals/settingsPanels/InstancePanel'; + +interface MobileSettingsScreenProps { + initialPanel?: string; +} + +const panelConfig: Record = { + account: { title: 'Account', component: }, + voice: { title: 'Voice & Audio', component: }, + privacy: { title: 'Privacy', component: }, + connections: { title: 'Connections', component: }, + instance: { title: 'Instance', component: }, +}; + +const sectionIcons: Record = { + account: ( + + + + ), + voice: ( + + + + ), + privacy: ( + + + + ), + connections: ( + + + + ), + instance: ( + + + + ), +}; + +export function MobileSettingsScreen({ initialPanel }: MobileSettingsScreenProps) { + const popMobileScreen = useUIStore((s) => s.popMobileScreen); + const pushMobileScreen = useUIStore((s) => s.pushMobileScreen); + const isAdmin = useAuthStore((s) => s.user?.is_admin); + + // If initialPanel is set, render that panel directly + if (initialPanel) { + const panel = panelConfig[initialPanel]; + if (!panel) return null; + if (initialPanel === 'instance' && !isAdmin) return null; + + return ( +
+
+ +

{panel.title}

+
+
+ {panel.component} +
+
+ ); + } + + // Settings section list + const sections = [ + { id: 'account', label: 'Account' }, + { id: 'voice', label: 'Voice & Audio' }, + { id: 'privacy', label: 'Privacy' }, + { id: 'connections', label: 'Connections' }, + ...(isAdmin ? [{ id: 'instance', label: 'Instance' }] : []), + ]; + + return ( +
+
+ +

Settings

+
+
+ {sections.map((section) => ( + + ))} +
+
+ ); +} diff --git a/packages/web/src/components/layout/MobileShell.tsx b/packages/web/src/components/layout/MobileShell.tsx index ed4b573c..3a8b0f28 100644 --- a/packages/web/src/components/layout/MobileShell.tsx +++ b/packages/web/src/components/layout/MobileShell.tsx @@ -19,7 +19,7 @@ import { MobileSpacesScreen } from './MobileSpacesScreen'; import { MobileDmsScreen } from './MobileDmsScreen'; import { MobileYouScreen } from './MobileYouScreen'; import { MobileChatScreen } from './MobileChatScreen'; -const MobileSettingsScreen = ({ initialPanel: _p }: { initialPanel?: string }) => ; +import { MobileSettingsScreen } from './MobileSettingsScreen'; const MobileVoiceMiniBar = () => null; const MobileVoiceFullScreen = () => ;