diff --git a/services/frontend/src/widgets/DashboardLayout.tsx b/services/frontend/src/widgets/DashboardLayout.tsx
index 158dd2f..9457641 100644
--- a/services/frontend/src/widgets/DashboardLayout.tsx
+++ b/services/frontend/src/widgets/DashboardLayout.tsx
@@ -3,7 +3,6 @@ import type { ReactNode } from "react";
import type { DashboardTab } from "../entities/ui/types";
import type { MessageRecord, VoiceStatus } from "../shared/api/client";
import { fadeSlideUp } from "../shared/hooks/useFramerStagger";
-import { useMascotSummary } from "../shared/hooks/useMascotSummary";
import type { WsStatus } from "../shared/ws/socket";
import { Header } from "./Header";
import { ParticleBackground } from "./particles/ParticleBackground";
@@ -30,11 +29,6 @@ export function DashboardLayout({
guildId,
channelId,
}: DashboardLayoutProps) {
- // Generate mascot summary from recent messages
- const mascotSummary = useMascotSummary({
- messages: recentMessages,
- enabled: activeTab === "messages" && recentMessages.length > 0,
- });
return (
{/* Sakura particle layer */}
@@ -44,7 +38,6 @@ export function DashboardLayout({
void;
collapsed?: boolean;
- mascotChatMessage?: string;
recentMessages?: MessageRecord[];
guildId?: string;
channelId?: string;
@@ -28,14 +27,15 @@ export function Sidebar({
activeTab,
onTabChange,
collapsed = true,
- mascotChatMessage = "",
recentMessages = [],
guildId,
channelId,
}: SidebarProps) {
const mascotChat = useMascotChat({
messageCount: recentMessages.length,
- activeParticipants: new Set(recentMessages.map((message) => message.user_id)).size,
+ activeParticipants: new Set(
+ recentMessages.map((message) => message.user_id),
+ ).size,
lastActivity: recentMessages.length > 0 ? "Active" : "Idle",
topicsDiscussed: ["Messages", "Moderation", "Analytics"],
guildId,
@@ -43,108 +43,113 @@ export function Sidebar({
});
return (
<>
-
- {/* App icon only — no branding text */}
-
-
-
- {/* Mascot image — only when expanded */}
- {!collapsed && (
-
- )}
-
-
- {/* Navigation items */}
-
- {navItems.map((item) => {
- const Icon = item.icon;
- const isActive = activeTab === item.id;
- return (
- onTabChange(item.id)}
- title={collapsed ? item.label : undefined}
- className={cn(
- "group relative flex items-center rounded-xl p-2.5 text-sm font-medium transition-all duration-200 ease-out",
- collapsed ? "justify-center" : "gap-3",
- isActive
- ? "bg-primary-soft text-primary ring-2 ring-primary/20"
- : "text-muted-foreground hover:bg-primary-soft/40 hover:text-primary/80",
- )}
- onMouseEnter={(e) => {
- e.currentTarget.style.transform = "translateX(2px) scale(1.1)";
- }}
- onMouseLeave={(e) => {
- e.currentTarget.style.transform = "translateX(0) scale(1)";
- }}
- >
-
- {!collapsed && {item.label} }
-
- );
- })}
-
-
- {/* Spacer pushes mascot to bottom */}
-
-
- {/* Mascot PNG with anchored chatbot */}
-
- {!mascotChat.isOpen && (
-
-
-
- Discord Watcher
-
-
- {mascotChatMessage ||
- "Halo! Saya mascot mu. Klik aku kalau mau tanya soal obrolan atau moderasi ✨"}
-
- {/* Outer: border layer — 1px larger, extends left & down to show border on diagonal/bottom edges */}
-
- {/* Inner: fill layer — original position & size, matches bubble bg */}
-
-
-
- )}
-
mascotChat.setIsOpen(!mascotChat.isOpen)}
- className="relative z-50 rounded-2xl p-1 transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-primary/40"
- title="Chat dengan mascot"
+ {/* App icon only — no branding text */}
+
-
-
-
-
- mascotChat.setIsOpen(false)}
- onSendMessage={mascotChat.handleSendMessage}
- mascotName="Discord Watcher"
- className="fixed bottom-20 left-[80px] z-[9999]"
- />
+
+
+ {/* Mascot image — only when expanded */}
+ {!collapsed && (
+
+ )}
+
+
+ {/* Navigation items */}
+
+ {navItems.map((item) => {
+ const Icon = item.icon;
+ const isActive = activeTab === item.id;
+ return (
+ onTabChange(item.id)}
+ title={collapsed ? item.label : undefined}
+ className={cn(
+ "group relative flex items-center rounded-xl p-2.5 text-sm font-medium transition-all duration-200 ease-out",
+ collapsed ? "justify-center" : "gap-3",
+ isActive
+ ? "bg-primary-soft text-primary ring-2 ring-primary/20"
+ : "text-muted-foreground hover:bg-primary-soft/40 hover:text-primary/80",
+ )}
+ onMouseEnter={(e) => {
+ e.currentTarget.style.transform =
+ "translateX(2px) scale(1.1)";
+ }}
+ onMouseLeave={(e) => {
+ e.currentTarget.style.transform = "translateX(0) scale(1)";
+ }}
+ >
+
+ {!collapsed && {item.label} }
+
+ );
+ })}
+
+
+ {/* Spacer pushes mascot to bottom */}
+
+
+ {/* Mascot PNG with anchored chatbot */}
+
+ {!mascotChat.isOpen && (
+
+
+
+ Discord Watcher
+
+
+ Halo! Saya mascot mu. Klik aku kalau mau tanya soal obrolan
+ atau moderasi ✨
+
+ {/* Outer: border layer — 1px larger, extends left & down to show border on diagonal/bottom edges */}
+
+ {/* Inner: fill layer — original position & size, matches bubble bg */}
+
+
+
+ )}
+
mascotChat.setIsOpen(!mascotChat.isOpen)}
+ className="relative z-50 rounded-2xl p-1 transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-primary/40"
+ title="Chat dengan mascot"
+ >
+
+
+
+
+ mascotChat.setIsOpen(false)}
+ onSendMessage={mascotChat.handleSendMessage}
+ mascotName="Discord Watcher"
+ className="fixed bottom-[170px] left-[80px] z-[9999]"
+ />
>
);
}