feat: refactor InstancePanel from tabs to sectioned single page
This commit is contained in:
@@ -1,54 +1,59 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useSettingsStore } from '../../../stores/settingsStore';
|
||||
import { useSettingsSections } from '../../../hooks/useSettingsSections';
|
||||
import { GeneralPanel } from '../instanceSettingsPanels/GeneralPanel';
|
||||
import { StreamingPanel } from '../instanceSettingsPanels/StreamingPanel';
|
||||
import { StoragePanel } from '../instanceSettingsPanels/StoragePanel';
|
||||
import { UsersPanel } from '../instanceSettingsPanels/UsersPanel';
|
||||
|
||||
type SubTab = 'general' | 'streaming' | 'storage' | 'users';
|
||||
const SECTIONS = [
|
||||
{ id: 'general', label: 'General' },
|
||||
{ id: 'streaming', label: 'Streaming' },
|
||||
{ id: 'storage', label: 'Storage' },
|
||||
{ id: 'users', label: 'Users' },
|
||||
] as const;
|
||||
|
||||
export function InstancePanel() {
|
||||
const fetchInstanceSettings = useSettingsStore((s) => s.fetchInstanceSettings);
|
||||
const fetchStreamingLimits = useSettingsStore((s) => s.fetchStreamingLimits);
|
||||
|
||||
const [subTab, setSubTab] = useState<SubTab>('general');
|
||||
const { sectionRef } = useSettingsSections([...SECTIONS]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchInstanceSettings();
|
||||
fetchStreamingLimits();
|
||||
}, [fetchInstanceSettings, fetchStreamingLimits]);
|
||||
|
||||
const pillClass = (t: SubTab) =>
|
||||
`px-3 py-1 text-sm rounded-full transition-colors ${
|
||||
subTab === t
|
||||
? 'bg-interactive-selected text-txt-primary'
|
||||
: 'text-txt-tertiary hover:text-txt-secondary hover:bg-interactive-hover'
|
||||
}`;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold text-txt-primary mb-6">Instance</h2>
|
||||
{/* Sub-tab switcher */}
|
||||
<div className="flex gap-1 p-1 bg-white/[0.02] rounded-full w-fit">
|
||||
<button onClick={() => setSubTab('general')} className={pillClass('general')}>
|
||||
General
|
||||
</button>
|
||||
<button onClick={() => setSubTab('streaming')} className={pillClass('streaming')}>
|
||||
Streaming
|
||||
</button>
|
||||
<button onClick={() => setSubTab('storage')} className={pillClass('storage')}>
|
||||
Storage
|
||||
</button>
|
||||
<button onClick={() => setSubTab('users')} className={pillClass('users')}>
|
||||
Users
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-0">
|
||||
{/* General */}
|
||||
<h3 ref={sectionRef('general')} className="text-base font-semibold text-txt-primary mb-4">
|
||||
General
|
||||
</h3>
|
||||
<GeneralPanel />
|
||||
|
||||
{/* Content */}
|
||||
{subTab === 'general' && <GeneralPanel />}
|
||||
{subTab === 'streaming' && <StreamingPanel />}
|
||||
{subTab === 'storage' && <StoragePanel />}
|
||||
{subTab === 'users' && <UsersPanel />}
|
||||
<div className="border-t border-white/[0.04] my-6" />
|
||||
|
||||
{/* Streaming */}
|
||||
<h3 ref={sectionRef('streaming')} className="text-base font-semibold text-txt-primary mb-4">
|
||||
Streaming
|
||||
</h3>
|
||||
<StreamingPanel />
|
||||
|
||||
<div className="border-t border-white/[0.04] my-6" />
|
||||
|
||||
{/* Storage */}
|
||||
<h3 ref={sectionRef('storage')} className="text-base font-semibold text-txt-primary mb-4">
|
||||
Storage
|
||||
</h3>
|
||||
<StoragePanel />
|
||||
|
||||
<div className="border-t border-white/[0.04] my-6" />
|
||||
|
||||
{/* Users */}
|
||||
<h3 ref={sectionRef('users')} className="text-base font-semibold text-txt-primary mb-4">
|
||||
Users
|
||||
</h3>
|
||||
<UsersPanel />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user