From 7ff8614127d51a2683c2a532e855e35542b17a2b Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 22 Mar 2026 04:42:46 +0100 Subject: [PATCH] refactor: extract SettingsTabBar as reusable infrastructure component Replace one-off inline tab bar in InstancePanel with a reusable SettingsTabBar that reads from SettingsSectionsContext. Any panel using tab mode can drop it in with zero configuration. Polish: proper underline indicator, consistent gap spacing, negative top margin to sit flush with content area padding. --- .../src/components/modals/SettingsTabBar.tsx | 32 +++++++++++++++++++ .../modals/settingsPanels/InstancePanel.tsx | 17 ++-------- 2 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 packages/web/src/components/modals/SettingsTabBar.tsx diff --git a/packages/web/src/components/modals/SettingsTabBar.tsx b/packages/web/src/components/modals/SettingsTabBar.tsx new file mode 100644 index 00000000..e0fddd80 --- /dev/null +++ b/packages/web/src/components/modals/SettingsTabBar.tsx @@ -0,0 +1,32 @@ +import { useSettingsSectionsContext } from './SettingsSectionsContext'; + +/** + * Reusable tab bar for settings panels in tab mode. + * Reads sections and activeSection from SettingsSectionsContext. + * Drop this into any panel that uses useSettingsSections with onNavigate. + */ +export function SettingsTabBar() { + const ctx = useSettingsSectionsContext(); + if (!ctx || ctx.sections.length === 0) return null; + + return ( +
+ {ctx.sections.map((s) => ( + + ))} +
+ ); +} diff --git a/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx b/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx index f5aa479f..c95ad8bd 100644 --- a/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx +++ b/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react'; import { useSettingsStore } from '../../../stores/settingsStore'; import { useSettingsSections } from '../../../hooks/useSettingsSections'; import type { SettingsSection } from '../SettingsSectionsContext'; +import { SettingsTabBar } from '../SettingsTabBar'; import { GeneralPanel } from '../instanceSettingsPanels/GeneralPanel'; import { StreamingPanel } from '../instanceSettingsPanels/StreamingPanel'; import { StoragePanel } from '../instanceSettingsPanels/StoragePanel'; @@ -34,23 +35,9 @@ export function InstancePanel() { fetchStreamingLimits(); }, [fetchInstanceSettings, fetchStreamingLimits]); - const tabPillClass = (t: SubTab) => - `px-3 py-1.5 text-sm rounded-md transition-colors ${ - subTab === t - ? 'text-txt-primary font-medium border-b-2 border-accent-primary' - : 'text-txt-tertiary hover:text-txt-secondary' - }`; - return (
- {/* Top tab bar */} -
- {SECTIONS.map((s) => ( - - ))} -
+ {subTab === 'general' && } {subTab === 'streaming' && }