diff --git a/src/web/App.tsx b/src/web/App.tsx index 280167a..cc3e524 100644 --- a/src/web/App.tsx +++ b/src/web/App.tsx @@ -19,6 +19,7 @@ const License = lazy(() => import("./pages/License").then(module => ({ default: const LoginPage = lazy(() => import("./dashboard/LoginPage")); const SettingsPage = lazy(() => import("./dashboard/SettingsPage")); const UserSettingsPage = lazy(() => import("./dashboard/UserSettingsPage")); +const GuildSelectionPage = lazy(() => import("./dashboard/GuildSelectionPage")); const AuthCallback = lazy(() => import("./pages/AuthCallback")); const queryClient = new QueryClient(); @@ -64,6 +65,7 @@ const DashboardRoutes = () => { } /> } /> } /> + } /> } /> } /> } /> @@ -108,6 +110,7 @@ const MainRoutes = () => { } /> } /> } /> + } /> } /> } /> } /> diff --git a/src/web/components/AuthProvider.tsx b/src/web/components/AuthProvider.tsx index 5267de4..52cd185 100644 --- a/src/web/components/AuthProvider.tsx +++ b/src/web/components/AuthProvider.tsx @@ -68,14 +68,19 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { "X-Discord-Token": localStorage.getItem("discord_token") || "" } }) - .then(res => res.status === 401 ? logout() : res.json()) - .then(data => { - if (data?.user) setUser(data.user); - if (data?.guilds) { - setGuilds(data.guilds); - if (!selectedGuildId && data.guilds.length > 0) { - setSelectedGuildId(data.guilds[0].id); - localStorage.setItem("selectedGuildId", data.guilds[0].id); + + .then(async (res) => { + if (res.status === 401) { + logout(); + throw new Error("Session expired"); + } + if (!res.ok) throw new Error("Failed to fetch user data"); + return res.json(); + }) + .then(data => { + if (data.user) setUser(data.user); + if (data.guilds) { + setGuilds(data.guilds); } } }) diff --git a/src/web/components/Hero.tsx b/src/web/components/Hero.tsx index 20a06be..c5f3dd8 100644 --- a/src/web/components/Hero.tsx +++ b/src/web/components/Hero.tsx @@ -2,7 +2,7 @@ import { memo } from "react"; import { motion } from "framer-motion"; import { Link } from "react-router-dom"; import { Shield, Users, MessageCircle, Sparkles, Zap, Activity, ArrowRight } from "lucide-react"; -import { useStats } from "@/hooks/useStats"; +import { useStats } from "../hooks/useStats"; export const Hero = memo(function Hero() { const { data, isLoading } = useStats(); @@ -61,12 +61,12 @@ export const Hero = memo(function Hero() { {/* Title */} - ManagerX + ManagerX {/* Description */} @@ -74,10 +74,10 @@ export const Hero = memo(function Hero() { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.2 }} - className="text-xl md:text-2xl text-muted-foreground max-w-3xl mb-12 font-medium leading-relaxed" + className="text-xl md:text-2xl text-muted-foreground max-w-2xl mb-14 font-medium leading-relaxed opacity-80" > Die nächste Generation der Discord Server-Verwaltung.
- Sicher, schnell und vollständig anpassbar. + Sicher, blitzschnell und grenzenlos anpassbar. {/* Action Row */} @@ -85,26 +85,26 @@ export const Hero = memo(function Hero() { initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.3 }} - className="flex flex-col sm:flex-row items-center gap-5 mb-20" + className="flex flex-col sm:flex-row items-center gap-6 mb-24" > Bot einladen - + - Features entdecken + Learn More diff --git a/src/web/components/Navbar.tsx b/src/web/components/Navbar.tsx index 9377e45..ca3478a 100644 --- a/src/web/components/Navbar.tsx +++ b/src/web/components/Navbar.tsx @@ -169,7 +169,7 @@ export function Navbar() { diff --git a/src/web/components/OverviewSettings.tsx b/src/web/components/OverviewSettings.tsx index bb8d3ac..5de3b6f 100644 --- a/src/web/components/OverviewSettings.tsx +++ b/src/web/components/OverviewSettings.tsx @@ -4,13 +4,16 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "./ui/ import { Users, MessageSquare, Zap, Activity, TrendingUp, ArrowUpRight, ArrowDownRight } from "lucide-react"; import { motion } from "framer-motion"; import OverviewCharts from "./OverviewCharts"; +import { Badge } from "./ui/badge"; +import { CheckCircle, XCircle } from "lucide-react"; interface OverviewSettingsProps { guildId: string | null; initialStats?: any; + settings?: any; } -export default function OverviewSettings({ guildId, initialStats }: OverviewSettingsProps) { +export default function OverviewSettings({ guildId, initialStats, settings }: OverviewSettingsProps) { const [stats, setStats] = useState(initialStats || null); const [loading, setLoading] = useState(!initialStats); @@ -121,31 +124,79 @@ export default function OverviewSettings({ guildId, initialStats }: OverviewSett /> -
- - - - Nachrichten Volumen - - Aktivität der letzten 7 Tage +
+ {/* Bot Health & Activity Summary */} + + +
+ + Command Center + + Live-Metriken deiner Server-Instanz +
+ + Live updates +
- +
+
+
+ +

Nachrichten Volumen (7 Tage)

+
+
+
+ + + + +
+
- + {/* Module Status Sidebar */} + - - Mitglieder Wachstum - - Wachstumstrend der Woche + Module Status + Aktive Bot-Funktionen - - + + + + + + + +
); } + +const QuickStat = ({ title, value }: { title: string, value: string }) => ( +
+ {title} + {value} +
+); + +const ModuleRow = ({ name, active }: { name: string, active: boolean }) => ( +
+ {name} + {active ? ( +
+ + Active +
+ ) : ( +
+ + Disabled +
+ )} +
+); diff --git a/src/web/dashboard/GuildSelectionPage.tsx b/src/web/dashboard/GuildSelectionPage.tsx new file mode 100644 index 0000000..24577da --- /dev/null +++ b/src/web/dashboard/GuildSelectionPage.tsx @@ -0,0 +1,177 @@ +import React, { useState } from "react"; +import { motion } from "framer-motion"; +import { useAuth } from "../components/AuthProvider"; +import { useNavigate } from "react-router-dom"; +import { + LayoutDashboard, + Search, + Plus, + ChevronRight, + Shield, + Sparkles, + Users, + Settings, + Server +} from "lucide-react"; +import { Button } from "../components/ui/button"; +import { Input } from "../components/ui/input"; +import { Card, CardContent } from "../components/ui/card"; +import { cn } from "../lib/utils"; + +export default function GuildSelectionPage() { + const { guilds, setSelectedGuildId, user } = useAuth(); + const [search, setSearch] = useState(""); + const navigate = useNavigate(); + + const filteredGuilds = guilds.filter(g => + g.name.toLowerCase().includes(search.toLowerCase()) + ); + + const handleSelect = (id: string) => { + setSelectedGuildId(id); + navigate("/dash/settings"); + }; + + return ( +
+ {/* Background Effects */} +
+
+
+ +
+ {/* Header Section */} +
+
+ + + Willkommen zurück, {user?.username} + + +

+ Server Zentrale +

+

+ Wähle einen Server aus, um die ManagerX Suite zu konfigurieren. +

+
+
+ + + + setSearch(e.target.value)} + placeholder="Server suchen..." + className="bg-white/5 border-white/10 h-14 pl-12 rounded-2xl focus:border-primary/50 transition-all text-base" + /> + +
+ + {/* Grid of Servers */} +
+ {filteredGuilds.map((guild, index) => ( + + handleSelect(guild.id)} + className="group relative glass border-white/10 hover:border-primary/40 shadow-2xl rounded-[2.5rem] overflow-hidden cursor-pointer transition-all hover:scale-[1.02] active:scale-[0.98]" + > +
+ +
+
+ {guild.icon ? ( + {guild.name} + ) : ( +
{guild.name.charAt(0)}
+ )} +
+
+ +
+
+ +
+

+ {guild.name} +

+
+
+ + Admin Access +
+ {/* You could add member count here if the API provides it */} +
+
+
+ + + ))} + + {/* Invite Button Card */} + + + +
+ +
+
+

Bot einladen

+

Füge ManagerX einem weiteren Server hinzu.

+
+
+
+
+
+ + {filteredGuilds.length === 0 && search && ( + +
+ +
+

Keine passenden Server gefunden...

+
+ )} +
+ + {/* Sticky Footer */} +
+

ManagerX Engine v2.0.0 Stable

+
+
+ ); +} diff --git a/src/web/dashboard/SettingsPage.tsx b/src/web/dashboard/SettingsPage.tsx index 96e8332..b450711 100644 --- a/src/web/dashboard/SettingsPage.tsx +++ b/src/web/dashboard/SettingsPage.tsx @@ -205,20 +205,33 @@ export default function SettingsPage() {
- System + +
+
+ Core Suite +
- Engagement +
+
+ Engagement +
- Security & Safety +
+
+ Protection +
- Utility +
+
+ Expansion +
@@ -238,7 +251,7 @@ export default function SettingsPage() { transition={{ duration: 0.3, ease: "easeOut" }} > - {guildId ? : } + {guildId ? : } diff --git a/src/web/dashboard/UserSettingsPage.tsx b/src/web/dashboard/UserSettingsPage.tsx index 7c0b2a0..3570929 100644 --- a/src/web/dashboard/UserSettingsPage.tsx +++ b/src/web/dashboard/UserSettingsPage.tsx @@ -232,6 +232,12 @@ export default function UserSettingsPage() {
Total XP

{Math.floor(settings.globalStats.xp).toLocaleString()}

+ {settings.globalStats.rank && ( +
+ + Rank #{settings.globalStats.rank} +
+ )}
diff --git a/src/web/pages/AuthCallback.tsx b/src/web/pages/AuthCallback.tsx index 7ccb0ad..ec145f6 100644 --- a/src/web/pages/AuthCallback.tsx +++ b/src/web/pages/AuthCallback.tsx @@ -40,7 +40,7 @@ export default function AuthCallback() { login(data.access_token, data.user, data.discord_token); toast.success(`Willkommen zurück, ${data.user.username}!`); - navigate("/dash/settings"); // Redirect to dashboard / settings + navigate("/dash/guilds"); // Redirect to server hub } catch (err: any) { console.error("Auth Error:", err); setError(err.message || "Es gab ein Problem beim Anmelden.");