From aa246cd7ea42d11ad84a0bb42e59efef70fccba9 Mon Sep 17 00:00:00 2001 From: Pepe44DEV Date: Fri, 3 Jul 2026 23:15:35 +0200 Subject: [PATCH] add badges, weekly plans, polls, suggestions, mod-case system, branding, partner system, alt-account detection, gallery, growth tracking Two feature batches plus a deploy fix: Moderation & engagement: persistent ModCase history (retrofits ban/kick/ mute/timeout/tempban to record cases), /warn, /watch watchlist with automatic alerts on deletions/tickets/automod hits, /case file lookup, achievement badges (/badges, /profile) with message/streak/ticket/ birthday/event/booster triggers, /weekplan RSVP boards, /poll with anonymous mode and scheduled auto-close, /suggest with vote/comment/ decide flow. Branding & growth: /branding (per-guild embed color/logo/footer/bot name/theme, applied across logging/ticket/register/embed-builder embeds and the dashboard sidebar/accent color at runtime), two new /setup server-type presets (Roleplay, Creator), /rules generate (template-based rule sets), /partner apply/list/config with invite validation and showcase posting, alt-account suspicion scoring on join (account age, avatar, name pattern, join bursts, ban-list similarity), /gallery submit with voting and weekly-winner scheduler, invite-attributed join/leave tracking with a new Wachstum dashboard page, and an expanded Admin dashboard (guild list, feature-usage counters). Also fixes production: the Docker container never ran `prisma migrate deploy`, so schema changes never reached the live database. The compose command now applies pending migrations on every start. Co-Authored-By: Claude Sonnet 5 --- docker-compose.yml | 2 +- frontend/src/App.tsx | 23 +- frontend/src/components/layout/Sidebar.tsx | 21 +- frontend/src/context/AppContext.tsx | 44 +- frontend/src/pages/Admin.tsx | 69 +- frontend/src/pages/Branding.tsx | 100 + frontend/src/pages/Growth.tsx | 76 + frontend/src/pages/Watchlist.tsx | 36 + frontend/src/types/index.ts | 24 + node_modules/.prisma/client/edge.js | 165 +- node_modules/.prisma/client/index-browser.js | 159 +- node_modules/.prisma/client/index.d.ts | 17714 +++++++++++++++- node_modules/.prisma/client/index.js | 165 +- node_modules/.prisma/client/wasm.js | 159 +- src/commands/admin/ban.ts | 2 + src/commands/admin/case.ts | 76 + src/commands/admin/kick.ts | 2 + src/commands/admin/mute.ts | 2 + src/commands/admin/tempban.ts | 2 + src/commands/admin/timeout.ts | 2 + src/commands/admin/warn.ts | 27 + src/commands/admin/watch.ts | 61 + src/commands/utility/announcement.ts | 17 + src/commands/utility/badges.ts | 63 + src/commands/utility/branding.ts | 71 + src/commands/utility/gallery.ts | 56 + src/commands/utility/partner.ts | 63 + src/commands/utility/poll.ts | 32 + src/commands/utility/profile.ts | 41 + src/commands/utility/rules.ts | 47 + src/commands/utility/suggest.ts | 17 + src/commands/utility/weekplan.ts | 23 + src/config/context.ts | 36 +- src/config/state.ts | 41 +- .../migration.sql | 178 + .../migration.sql | 72 + src/database/schema.prisma | 187 + src/events/guildCreate.ts | 1 + src/events/guildMemberAdd.ts | 9 + src/events/guildMemberRemove.ts | 1 + src/events/guildMemberUpdate.ts | 3 + src/events/interactionCreate.ts | 35 +- src/events/messageCreate.ts | 1 + src/events/messageDelete.ts | 3 + src/events/ready.ts | 4 + src/index.ts | 3 + src/services/altAccountService.ts | 70 + src/services/automodService.ts | 2 + src/services/badgeService.ts | 70 + src/services/birthdayService.ts | 7 + src/services/brandingService.ts | 21 + src/services/commandHandler.ts | 5 +- src/services/embedBuilderService.ts | 26 +- src/services/eventService.ts | 7 + src/services/galleryService.ts | 125 + src/services/growthService.ts | 96 + src/services/loggingService.ts | 56 + src/services/modCaseService.ts | 26 + src/services/moduleService.ts | 6 +- src/services/partnerService.ts | 149 + src/services/pollService.ts | 156 + src/services/registerService.ts | 6 +- src/services/rulesService.ts | 41 + src/services/setupService.ts | 28 +- src/services/suggestionService.ts | 126 + src/services/ticketService.ts | 6 +- src/services/watchlistService.ts | 48 + src/services/weeklyPlanService.ts | 123 + src/web/routes/api.ts | 42 +- 69 files changed, 21111 insertions(+), 66 deletions(-) create mode 100644 frontend/src/pages/Branding.tsx create mode 100644 frontend/src/pages/Growth.tsx create mode 100644 frontend/src/pages/Watchlist.tsx create mode 100644 src/commands/admin/case.ts create mode 100644 src/commands/admin/warn.ts create mode 100644 src/commands/admin/watch.ts create mode 100644 src/commands/utility/announcement.ts create mode 100644 src/commands/utility/badges.ts create mode 100644 src/commands/utility/branding.ts create mode 100644 src/commands/utility/gallery.ts create mode 100644 src/commands/utility/partner.ts create mode 100644 src/commands/utility/poll.ts create mode 100644 src/commands/utility/profile.ts create mode 100644 src/commands/utility/rules.ts create mode 100644 src/commands/utility/suggest.ts create mode 100644 src/commands/utility/weekplan.ts create mode 100644 src/database/migrations/20260703140000_add_moderation_badges_events_polls/migration.sql create mode 100644 src/database/migrations/20260704090000_add_branding_partner_gallery_growth/migration.sql create mode 100644 src/services/altAccountService.ts create mode 100644 src/services/badgeService.ts create mode 100644 src/services/brandingService.ts create mode 100644 src/services/galleryService.ts create mode 100644 src/services/growthService.ts create mode 100644 src/services/modCaseService.ts create mode 100644 src/services/partnerService.ts create mode 100644 src/services/pollService.ts create mode 100644 src/services/rulesService.ts create mode 100644 src/services/suggestionService.ts create mode 100644 src/services/watchlistService.ts create mode 100644 src/services/weeklyPlanService.ts diff --git a/docker-compose.yml b/docker-compose.yml index 45218cd..e9f5cd0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: working_dir: /usr/src/app env_file: - .env - command: sh -c "npm run dev" + command: sh -c "npx prisma migrate deploy --schema=src/database/schema.prisma && npm run dev" ports: - "3000:3000" depends_on: diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d5573bf..6adccad 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react'; import { useApp } from './context/AppContext'; import { AppLayout } from './components/layout/AppLayout'; import { GuildSelect } from './pages/GuildSelect'; @@ -17,10 +18,27 @@ import { SettingsPage } from './pages/Settings'; import { ModulesPage } from './pages/Modules'; import { Events } from './pages/Events'; import { Tasks } from './pages/Tasks'; +import { Watchlist } from './pages/Watchlist'; import { Admin } from './pages/Admin'; +import { Branding } from './pages/Branding'; +import { Growth } from './pages/Growth'; + +const THEME_COLORS: Record = { + orange: '#f97316', + blue: '#3b82f6', + green: '#22c55e', + purple: '#a855f7', + red: '#ef4444' +}; function AppContent() { - const { guilds, currentGuildId, section } = useApp(); + const { guilds, currentGuildId, section, settings } = useApp(); + + useEffect(() => { + const branding = settings.brandingConfig || {}; + const color = branding.embedColor || (branding.theme ? THEME_COLORS[branding.theme] : undefined); + if (color) document.documentElement.style.setProperty('--accent', color); + }, [settings.brandingConfig]); if (!guilds.length) { return ; @@ -47,6 +65,9 @@ function AppContent() { case 'modules': return ; case 'events': return ; case 'tasks': return ; + case 'watchlist': return ; + case 'branding': return ; + case 'growth': return ; case 'admin': return ; default: return ; } diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index 0e33464..42a375b 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -5,8 +5,8 @@ import { } from '@heroui/react'; import { LogOut, PanelLeftClose, PanelLeft, Activity, AudioLines, CalendarDays, - ClipboardList, Home, LogIn, ListChecks, Music, Puzzle, RadioTower, Settings, - Shield, Sparkles, Tag, Ticket, Wrench + ClipboardList, Eye, Home, LogIn, ListChecks, Music, Palette, Puzzle, RadioTower, Settings, + Shield, Sparkles, Tag, Ticket, TrendingUp, Wrench } from 'lucide-react'; import { useApp } from '../../context/AppContext'; import { AppAvatar } from '../shared/AppAvatar'; @@ -40,6 +40,7 @@ const navGroups = [ { key: 'automod', label: 'Automod', icon: }, { key: 'reactionroles', label: 'Reaction Roles', icon: }, { key: 'tasks', label: 'Team-Aufgaben', icon: }, + { key: 'watchlist', label: 'Watchlist', icon: }, ] }, { @@ -49,29 +50,39 @@ const navGroups = [ { key: 'music', label: 'Musik', icon: }, { key: 'statuspage', label: 'Statuspage', icon: }, { key: 'serverstats', label: 'Server Stats', icon: }, + { key: 'growth', label: 'Wachstum', icon: }, ] }, { label: 'System', items: [ { key: 'modules', label: 'Module', icon: }, + { key: 'branding', label: 'Branding', icon: }, { key: 'settings', label: 'Einstellungen', icon: }, ] } ]; export function Sidebar() { - const { user, guilds, currentGuildId, section, setCurrentGuildId, setSection, handleLogout } = useApp(); + const { user, guilds, currentGuildId, section, setCurrentGuildId, setSection, handleLogout, settings } = useApp(); const [collapsed, setCollapsed] = useState(false); + const branding = settings.brandingConfig || {}; + const botName = branding.botName || 'Papo'; return (