feat: update dependencies and improve dashboard functionality
Deploy to VPS / deploy (push) Failing after 1m43s

- Added new dependencies for Next.js and lucide-react in pnpm-workspace.yaml.
- Refactored DashboardPage component to improve readability and error handling.
- Enhanced Header component to display error status with an alert icon.
- Updated MobileTabBar and Sidebar components to use a centralized tabs definition.
- Improved ChannelsView in dashboard-panel to handle channel fetching more cleanly.
- Fixed ActiveSpeaker type to use camelCase for userId.
- Updated MessagesPanel to handle guildId checks more gracefully.
- Adjusted API calls in dashboard and messages to align with backend expectations.
- Refined type definitions across various interfaces for consistency and clarity.
This commit is contained in:
asepharyana
2026-07-26 14:27:36 +07:00
parent 9ecc4a6caa
commit 0a6a9fd982
62 changed files with 2764 additions and 305 deletions
+26 -16
View File
@@ -1,14 +1,14 @@
"use client";
import { Loader2, RefreshCw } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import { voiceApi } from "@/lib/api";
import { useAppConfig } from "@/lib/hooks/use-config";
import type { Guild } from "@/lib/types";
import { useCallback, useEffect, useState } from "react";
import { DashboardPanel } from "@/features/dashboard/dashboard-panel";
import { LivePanel } from "@/features/live/live-panel";
import { MessagesPanel } from "@/features/messages/messages-panel";
import { voiceApi } from "@/lib/api";
import { useAppConfig } from "@/lib/hooks/use-config";
import type { Guild } from "@/lib/types";
export default function DashboardPage() {
const searchParams = useSearchParams();
@@ -45,12 +45,17 @@ export default function DashboardPage() {
if (!cancelled) setGuilds(g);
})
.catch((err) => {
if (!cancelled) setGuildsError(err instanceof Error ? err.message : "Failed to load guilds");
if (!cancelled)
setGuildsError(
err instanceof Error ? err.message : "Failed to load guilds",
);
})
.finally(() => {
if (!cancelled) setGuildsLoading(false);
});
return () => { cancelled = true; };
return () => {
cancelled = true;
};
}, []);
// Resolve guild ID once config and guilds are loaded
@@ -80,9 +85,15 @@ export default function DashboardPage() {
onRetry={() => {
setGuildsLoading(true);
setGuildsError(null);
voiceApi.getGuilds().then(setGuilds).catch(
(err) => setGuildsError(err instanceof Error ? err.message : "Failed to load guilds"),
).finally(() => setGuildsLoading(false));
voiceApi
.getGuilds()
.then(setGuilds)
.catch((err) =>
setGuildsError(
err instanceof Error ? err.message : "Failed to load guilds",
),
)
.finally(() => setGuildsLoading(false));
}}
/>
@@ -90,12 +101,8 @@ export default function DashboardPage() {
{isReady ? (
<>
{tab === "live" && <LivePanel />}
{tab === "dashboard" && (
<DashboardPanel guildId={selectedGuildId} />
)}
{tab === "messages" && (
<MessagesPanel guildId={selectedGuildId} />
)}
{tab === "dashboard" && <DashboardPanel guildId={selectedGuildId} />}
{tab === "messages" && <MessagesPanel guildId={selectedGuildId} />}
</>
) : (
<div className="flex items-center justify-center py-16">
@@ -165,7 +172,10 @@ function GuildBar({
return (
<div className="flex items-center gap-2 rounded-lg border p-3">
<label htmlFor="guild-select" className="text-sm font-medium text-muted-foreground whitespace-nowrap">
<label
htmlFor="guild-select"
className="text-sm font-medium text-muted-foreground whitespace-nowrap"
>
Guild:
</label>
<select
+4 -10
View File
@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import Script from "next/script";
import "./globals.css";
const geistSans = Geist({
@@ -29,16 +30,9 @@ export default function RootLayout({
suppressHydrationWarning
>
<head>
<script
dangerouslySetInnerHTML={{
__html: `
try {
const theme = localStorage.getItem('theme') || 'dark';
document.documentElement.classList.add(theme);
} catch(e) {}
`,
}}
/>
<Script id="theme-script" strategy="beforeInteractive">
{`try{const t=localStorage.getItem('theme')||'dark';document.documentElement.classList.add(t)}catch(e){}`}
</Script>
</head>
<body className="min-h-full flex flex-col">{children}</body>
</html>