Create dashboard for Discord bot

Implement a dashboard interface to manage the Discord bot with a dark theme and a soothing purple primary color. The dashboard will facilitate interaction with the bot's functionalities across the user's Discord server(s).
[skip gpt_engineer]
This commit is contained in:
gpt-engineer-app[bot]
2025-01-04 14:59:53 +00:00
parent 711f699178
commit c051347693
5 changed files with 167 additions and 80 deletions

View File

@@ -0,0 +1,45 @@
import { Home, Server, Settings, Activity, HelpCircle } from "lucide-react";
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar";
const menuItems = [
{ title: "Overview", icon: Home, url: "/" },
{ title: "Servers", icon: Server, url: "/servers" },
{ title: "Activity", icon: Activity, url: "/activity" },
{ title: "Settings", icon: Settings, url: "/settings" },
{ title: "Help", icon: HelpCircle, url: "/help" },
];
export function DashboardSidebar() {
return (
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Dashboard</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{menuItems.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<a href={item.url} className="flex items-center gap-3">
<item.icon className="w-5 h-5" />
<span>{item.title}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
);
}

View File

@@ -0,0 +1,27 @@
import { Server } from "lucide-react";
import { Card } from "@/components/ui/card";
interface ServerCardProps {
name: string;
memberCount: number;
botStatus: "online" | "offline";
}
export const ServerCard = ({ name, memberCount, botStatus }: ServerCardProps) => {
return (
<Card className="glass-card hover-scale">
<div className="p-6 flex items-start gap-4">
<div className="p-3 rounded-full bg-primary/10">
<Server className="w-6 h-6 text-primary" />
</div>
<div className="flex-1">
<h3 className="font-semibold text-lg">{name}</h3>
<p className="text-muted-foreground">{memberCount} members</p>
</div>
<div className={`px-3 py-1 rounded-full text-sm ${botStatus === 'online' ? 'bg-green-500/20 text-green-400' : 'bg-destructive/20 text-destructive'}`}>
{botStatus}
</div>
</div>
</Card>
);
};

View File

@@ -0,0 +1,17 @@
interface StatCardProps {
title: string;
value: string | number;
icon: React.ReactNode;
}
export const StatCard = ({ title, value, icon }: StatCardProps) => {
return (
<div className="stat-card">
<div className="flex items-center justify-between">
<p className="text-muted-foreground">{title}</p>
<div className="text-primary">{icon}</div>
</div>
<p className="text-2xl font-semibold">{value}</p>
</div>
);
};

View File

@@ -4,89 +4,35 @@
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--background: 222 26% 13%;
--foreground: 210 40% 98%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--card: 222 26% 15%;
--card-foreground: 210 40% 98%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--popover: 222 26% 13%;
--popover-foreground: 210 40% 98%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--primary: 255 52% 75%;
--primary-foreground: 222 26% 13%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--secondary: 222 26% 15%;
--secondary-foreground: 210 40% 98%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--muted: 222 26% 20%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--accent: 255 52% 75%;
--accent-foreground: 222 26% 13%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--border: 222 26% 20%;
--input: 222 26% 20%;
--ring: 255 52% 75%;
--radius: 0.5rem;
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
--radius: 0.75rem;
}
}
@@ -94,8 +40,19 @@
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
.glass-card {
@apply bg-card/30 backdrop-blur-sm border border-white/10;
}
.stat-card {
@apply glass-card p-6 rounded-lg flex flex-col gap-2;
}
.hover-scale {
@apply transition-transform duration-200 hover:scale-[1.02];
}

View File

@@ -1,14 +1,55 @@
// Update this page (the content is just a fallback if you fail to update the page)
import { Activity, MessageCircle, Server, Users } from "lucide-react";
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { DashboardSidebar } from "@/components/dashboard/DashboardSidebar";
import { ServerCard } from "@/components/dashboard/ServerCard";
import { StatCard } from "@/components/dashboard/StatCard";
const Index = () => {
// Mock data - replace with actual data when integrating with Discord
const stats = [
{ title: "Total Servers", value: "12", icon: <Server className="w-5 h-5" /> },
{ title: "Active Users", value: "1,234", icon: <Users className="w-5 h-5" /> },
{ title: "Commands Used", value: "8,392", icon: <MessageCircle className="w-5 h-5" /> },
{ title: "Uptime", value: "99.9%", icon: <Activity className="w-5 h-5" /> },
];
const servers = [
{ name: "Gaming Community", memberCount: 1234, botStatus: "online" as const },
{ name: "Developer Hub", memberCount: 567, botStatus: "online" as const },
{ name: "Music Lovers", memberCount: 890, botStatus: "offline" as const },
];
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">Welcome to Your Blank App</h1>
<p className="text-xl text-gray-600">Start building your amazing project here!</p>
<SidebarProvider>
<div className="min-h-screen flex w-full">
<DashboardSidebar />
<main className="flex-1 p-8">
<div className="max-w-7xl mx-auto">
<div className="flex items-center justify-between mb-8">
<div>
<h1 className="text-3xl font-bold">Dashboard</h1>
<p className="text-muted-foreground">Manage your Discord bot</p>
</div>
<SidebarTrigger />
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
{stats.map((stat) => (
<StatCard key={stat.title} {...stat} />
))}
</div>
<h2 className="text-xl font-semibold mb-4">Connected Servers</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{servers.map((server) => (
<ServerCard key={server.name} {...server} />
))}
</div>
</div>
</main>
</div>
</div>
</SidebarProvider>
);
};
export default Index;
export default Index;