From 9e3c411e800aa8b9563897f6de1c225019499864 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:10:56 +0200 Subject: [PATCH] feat: badge count on Federation tab for pending approval requests --- .../modals/SettingsSectionsContext.tsx | 1 + .../src/components/modals/SettingsTabBar.tsx | 5 ++++ .../modals/settingsPanels/InstancePanel.tsx | 23 ++++++++++--------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/web/src/components/modals/SettingsSectionsContext.tsx b/packages/web/src/components/modals/SettingsSectionsContext.tsx index 576c7a39..41f27481 100644 --- a/packages/web/src/components/modals/SettingsSectionsContext.tsx +++ b/packages/web/src/components/modals/SettingsSectionsContext.tsx @@ -3,6 +3,7 @@ import React, { createContext, useContext, useState, useCallback, useRef, useMem export interface SettingsSection { id: string; label: string; + badgeCount?: number; } interface SettingsSectionsContextValue { diff --git a/packages/web/src/components/modals/SettingsTabBar.tsx b/packages/web/src/components/modals/SettingsTabBar.tsx index e0fddd80..055aa24f 100644 --- a/packages/web/src/components/modals/SettingsTabBar.tsx +++ b/packages/web/src/components/modals/SettingsTabBar.tsx @@ -22,6 +22,11 @@ export function SettingsTabBar() { }`} > {s.label} + {s.badgeCount !== undefined && s.badgeCount > 0 && ( + + {s.badgeCount} + + )} {ctx.activeSection === s.id && ( )} diff --git a/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx b/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx index b74d19be..16e5ffc2 100644 --- a/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx +++ b/packages/web/src/components/modals/settingsPanels/InstancePanel.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useMemo } from 'react'; import { useSettingsStore } from '../../../stores/settingsStore'; import { useSettingsSections } from '../../../hooks/useSettingsSections'; import type { SettingsSection } from '../SettingsSectionsContext'; @@ -11,26 +11,27 @@ import { UsersPanel } from '../instanceSettingsPanels/UsersPanel'; type SubTab = 'general' | 'federation' | 'streaming' | 'storage' | 'users'; -const SECTIONS: SettingsSection[] = [ - { id: 'general', label: 'General' }, - { id: 'federation', label: 'Federation' }, - { id: 'streaming', label: 'Streaming' }, - { id: 'storage', label: 'Storage' }, - { id: 'users', label: 'Users' }, -]; - export function InstancePanel() { const fetchInstanceSettings = useSettingsStore((s) => s.fetchInstanceSettings); const fetchStreamingLimits = useSettingsStore((s) => s.fetchStreamingLimits); const [subTab, setSubTab] = useState('general'); + const [approvalCount, setApprovalCount] = useState(0); + + const sections = useMemo(() => [ + { id: 'general', label: 'General' }, + { id: 'federation', label: 'Federation', badgeCount: approvalCount }, + { id: 'streaming', label: 'Streaming' }, + { id: 'storage', label: 'Storage' }, + { id: 'users', label: 'Users' }, + ], [approvalCount]); const handleNavigate = useCallback((id: string) => { setSubTab(id as SubTab); }, []); // Register sections for sidebar sub-links (tab mode — no scroll-spy) - useSettingsSections(SECTIONS, { onNavigate: handleNavigate, activeTab: subTab }); + useSettingsSections(sections, { onNavigate: handleNavigate, activeTab: subTab }); useEffect(() => { fetchInstanceSettings(); @@ -42,7 +43,7 @@ export function InstancePanel() { {subTab === 'general' && } - {subTab === 'federation' && } + {subTab === 'federation' && } {subTab === 'streaming' && } {subTab === 'storage' && } {subTab === 'users' && }