From 54376fdad78acb08748c96399a8988be7e911597 Mon Sep 17 00:00:00 2001 From: Pepe44DEV Date: Fri, 3 Jul 2026 23:48:44 +0200 Subject: [PATCH] unify module-active toggle styling and regroup sidebar navigation Extracts the accent-card toggle from Automod into a shared ModuleActiveToggle component and applies it to every module's "aktiv" switch (Statuspage, Dynamic Voice, Server Stats, Birthday, Welcome) so they all match instead of the plain switch some pages had. Also regroups the sidebar: Reaction Roles moves to Community (it's member self-service, not moderation), and a new "Statistiken" group splits Statuspage/Server Stats/Wachstum out of the catch-all "Funktionen" section. Co-Authored-By: Claude Sonnet 5 --- frontend/src/components/layout/Sidebar.tsx | 7 +++++- .../components/shared/ModuleActiveToggle.tsx | 25 +++++++++++++++++++ frontend/src/pages/Automod.tsx | 22 ++++++---------- frontend/src/pages/Birthday.tsx | 8 +++--- frontend/src/pages/DynamicVoice.tsx | 8 +++--- frontend/src/pages/ServerStats.tsx | 8 +++--- frontend/src/pages/Statuspage.tsx | 8 +++--- frontend/src/pages/Welcome.tsx | 8 +++--- 8 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 frontend/src/components/shared/ModuleActiveToggle.tsx diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index 42a375b..6222975 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -24,6 +24,7 @@ const navGroups = [ { key: 'welcome', label: 'Willkommen', icon: }, { key: 'birthday', label: 'Birthday', icon: }, { key: 'events', label: 'Events', icon: }, + { key: 'reactionroles', label: 'Reaction Roles', icon: }, ] }, { @@ -38,7 +39,6 @@ const navGroups = [ label: 'Moderation', items: [ { key: 'automod', label: 'Automod', icon: }, - { key: 'reactionroles', label: 'Reaction Roles', icon: }, { key: 'tasks', label: 'Team-Aufgaben', icon: }, { key: 'watchlist', label: 'Watchlist', icon: }, ] @@ -48,6 +48,11 @@ const navGroups = [ items: [ { key: 'dynamicvoice', label: 'Dynamic Voice', icon: }, { key: 'music', label: 'Musik', icon: }, + ] + }, + { + label: 'Statistiken', + items: [ { key: 'statuspage', label: 'Statuspage', icon: }, { key: 'serverstats', label: 'Server Stats', icon: }, { key: 'growth', label: 'Wachstum', icon: }, diff --git a/frontend/src/components/shared/ModuleActiveToggle.tsx b/frontend/src/components/shared/ModuleActiveToggle.tsx new file mode 100644 index 0000000..5efd088 --- /dev/null +++ b/frontend/src/components/shared/ModuleActiveToggle.tsx @@ -0,0 +1,25 @@ +import type { ReactNode } from 'react'; +import { AppSwitch } from './AppSwitch'; + +type Props = { + icon: ReactNode; + title: string; + description: string; + isSelected: boolean; + onChange: (value: boolean) => void; +}; + +export function ModuleActiveToggle({ icon, title, description, isSelected, onChange }: Props) { + return ( +
+
+ {icon} +
+
+
{title}
+
{description}
+
+ +
+ ); +} diff --git a/frontend/src/pages/Automod.tsx b/frontend/src/pages/Automod.tsx index dcab63a..a41bb9c 100644 --- a/frontend/src/pages/Automod.tsx +++ b/frontend/src/pages/Automod.tsx @@ -6,6 +6,7 @@ import { SectionCard } from '../components/shared/SectionCard'; import { ChannelSelect, type ChannelOption } from '../components/shared/ChannelSelect'; import { RoleSelect, type RoleOption } from '../components/shared/RoleSelect'; import { AppSwitch } from '../components/shared/AppSwitch'; +import { ModuleActiveToggle } from '../components/shared/ModuleActiveToggle'; import { useGuildResources } from '../hooks/useGuildResources'; const FILTERS = [ @@ -206,20 +207,13 @@ export function Automod() {

Automod

-
-
- -
-
-
Automod aktiv
-
Schaltet alle Filter unten gesammelt ein oder aus.
-
- setSettings((s) => ({ ...s, automodEnabled: v }))} - /> -
+ } + title="Automod aktiv" + description="Schaltet alle Filter unten gesammelt ein oder aus." + isSelected={settings.automodEnabled !== false} + onChange={(v) => setSettings((s) => ({ ...s, automodEnabled: v }))} + />
{FILTERS.map((f) => { diff --git a/frontend/src/pages/Birthday.tsx b/frontend/src/pages/Birthday.tsx index f7f2ae7..05358ef 100644 --- a/frontend/src/pages/Birthday.tsx +++ b/frontend/src/pages/Birthday.tsx @@ -3,7 +3,7 @@ import { CalendarDays, Save, Cake, Clock } from 'lucide-react'; import { useApp } from '../context/AppContext'; import { SectionCard } from '../components/shared/SectionCard'; import { ChannelSelect } from '../components/shared/ChannelSelect'; -import { AppSwitch } from '../components/shared/AppSwitch'; +import { ModuleActiveToggle } from '../components/shared/ModuleActiveToggle'; import { useGuildResources } from '../hooks/useGuildResources'; export function Birthday() { @@ -18,10 +18,12 @@ export function Birthday() {

Konfiguration

- } + title="Birthday aktiv" + description="Speichert Geburtstage und sendet automatisch Glückwünsche." isSelected={birthday.config?.enabled !== false} onChange={(v) => setBirthday((s) => ({ ...s, config: { ...s.config, enabled: v } }))} - label={
Birthday aktiv
} /> diff --git a/frontend/src/pages/DynamicVoice.tsx b/frontend/src/pages/DynamicVoice.tsx index 161fc2b..be51656 100644 --- a/frontend/src/pages/DynamicVoice.tsx +++ b/frontend/src/pages/DynamicVoice.tsx @@ -3,7 +3,7 @@ import { AudioLines, Save, Mic, Users } from 'lucide-react'; import { useApp } from '../context/AppContext'; import { SectionCard } from '../components/shared/SectionCard'; import { ChannelSelect } from '../components/shared/ChannelSelect'; -import { AppSwitch } from '../components/shared/AppSwitch'; +import { ModuleActiveToggle } from '../components/shared/ModuleActiveToggle'; import { useGuildResources } from '../hooks/useGuildResources'; export function DynamicVoice() { @@ -18,10 +18,12 @@ export function DynamicVoice() {

Konfiguration

- } + title="Dynamic Voice aktiv" + description="Erstellt private Voice-Channels aus der konfigurierten Lobby." isSelected={settings.dynamicVoiceEnabled !== false} onChange={(v) => setSettings((s) => ({ ...s, dynamicVoiceEnabled: v }))} - label={
Dynamic Voice aktiv
} /> diff --git a/frontend/src/pages/ServerStats.tsx b/frontend/src/pages/ServerStats.tsx index b2ea9de..98dd6c9 100644 --- a/frontend/src/pages/ServerStats.tsx +++ b/frontend/src/pages/ServerStats.tsx @@ -2,7 +2,7 @@ import { Card, CardContent, CardHeader, Input, Button, Chip, Separator, TextFiel import { Activity, Save, Trash2, Plus, BarChart3 } from 'lucide-react'; import { useApp } from '../context/AppContext'; import { SectionCard } from '../components/shared/SectionCard'; -import { AppSwitch } from '../components/shared/AppSwitch'; +import { ModuleActiveToggle } from '../components/shared/ModuleActiveToggle'; export function ServerStats() { const { statsDraft, setStatsDraft, saveServerStats, statsItemDraft, setStatsItemDraft, addStatsItem, deleteStatsItem } = useApp(); @@ -17,10 +17,12 @@ export function ServerStats() {

Konfiguration

- } + title="Server Stats aktiv" + description="Zeigt Mitglieder-/Channel-Zahlen als Voice-Statistiken an." isSelected={statsDraft?.enabled === true} onChange={(v) => setStatsDraft((s) => ({ ...(s || {}), enabled: v }))} - label={
Server Stats aktiv
} /> diff --git a/frontend/src/pages/Statuspage.tsx b/frontend/src/pages/Statuspage.tsx index 72fecdd..6fb490b 100644 --- a/frontend/src/pages/Statuspage.tsx +++ b/frontend/src/pages/Statuspage.tsx @@ -4,7 +4,7 @@ import { useApp } from '../context/AppContext'; import { SectionCard } from '../components/shared/SectionCard'; import type { StatusService } from '../types'; import { ChannelSelect } from '../components/shared/ChannelSelect'; -import { AppSwitch } from '../components/shared/AppSwitch'; +import { ModuleActiveToggle } from '../components/shared/ModuleActiveToggle'; import { useGuildResources } from '../hooks/useGuildResources'; export function Statuspage() { @@ -21,10 +21,12 @@ export function Statuspage() {

Konfiguration

- } + title="Statuspage aktiv" + description="Postet und aktualisiert die Statusseite mit deinen Services." isSelected={statusDraft?.enabled !== false} onChange={(v) => setStatusDraft((s) => ({ ...(s || {}), enabled: v }))} - label={
Statuspage aktiv
} /> diff --git a/frontend/src/pages/Welcome.tsx b/frontend/src/pages/Welcome.tsx index 0ec2e80..494a21a 100644 --- a/frontend/src/pages/Welcome.tsx +++ b/frontend/src/pages/Welcome.tsx @@ -4,7 +4,7 @@ import { useApp } from '../context/AppContext'; import { SectionCard } from '../components/shared/SectionCard'; import { DiscordPreview } from '../components/shared/DiscordPreview'; import { ChannelSelect } from '../components/shared/ChannelSelect'; -import { AppSwitch } from '../components/shared/AppSwitch'; +import { ModuleActiveToggle } from '../components/shared/ModuleActiveToggle'; import { useGuildResources } from '../hooks/useGuildResources'; export function Welcome() { @@ -22,10 +22,12 @@ export function Welcome() {
- } + title="Welcome aktiv" + description="Sendet ein Begrüßungs-Embed, wenn neue Mitglieder beitreten." isSelected={settings.welcomeConfig?.enabled !== false} onChange={(v) => setSettings((s) => ({ ...s, welcomeConfig: { ...(s.welcomeConfig || {}), enabled: v } }))} - label={
Welcome aktiv
} />