feat: update dependencies and improve dashboard functionality
Deploy to VPS / deploy (push) Failing after 1m43s
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:
@@ -26,6 +26,7 @@ export const dashboardApi = {
|
||||
const params = new URLSearchParams();
|
||||
if (limit) params.set("limit", String(limit));
|
||||
if (search) params.set("search", search);
|
||||
// Backend reads req.query.guild_id (snake_case) — see createDashboardRouter in dashboard.routes.ts
|
||||
if (guildId) params.set("guild_id", guildId);
|
||||
const qs = params.toString();
|
||||
return api.get<PaginatedChannels>(
|
||||
|
||||
@@ -8,6 +8,7 @@ export const messagesApi = {
|
||||
channelId?: string,
|
||||
cursor?: string,
|
||||
) => {
|
||||
// Backend messageQuerySchema expects camelCase guildId (see messages.schema.ts)
|
||||
const params = new URLSearchParams({ guildId });
|
||||
if (limit) params.set("limit", String(limit));
|
||||
if (channelId) params.set("channelId", channelId);
|
||||
@@ -31,6 +32,7 @@ export const messagesApi = {
|
||||
api.get<MessageRecord>(`/api/messages/detail/${id}`),
|
||||
|
||||
getImages: (guildId: string, limit?: number) => {
|
||||
// Backend reads req.query.guildId (camelCase) — see handleGetImageMessages in messages.controller.ts
|
||||
const params = new URLSearchParams({ guildId });
|
||||
if (limit) params.set("limit", String(limit));
|
||||
return api.get<{ data: MessageRecord[]; nextCursor: string | null }>(
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { LayoutDashboard, MessageSquare, Radio } from "lucide-react";
|
||||
|
||||
export const tabs = [
|
||||
{ id: "messages", label: "Messages", icon: MessageSquare },
|
||||
{ id: "live", label: "Live", icon: Radio },
|
||||
{ id: "dashboard", label: "Dashboard", icon: LayoutDashboard },
|
||||
] as const;
|
||||
|
||||
export type TabId = (typeof tabs)[number]["id"];
|
||||
@@ -37,13 +37,13 @@ export interface DashboardUser {
|
||||
flagged_count: number;
|
||||
last_message_at?: number | null;
|
||||
trust_score?: number | null;
|
||||
clean_message_streak?: number;
|
||||
clean_message_streak?: number | null;
|
||||
}
|
||||
|
||||
export interface DashboardUserDetail extends DashboardUser {
|
||||
last_analyzed_at?: number | null;
|
||||
clean_message_streak: number;
|
||||
total_infractions: number;
|
||||
clean_message_streak: number | null;
|
||||
total_infractions: number | null;
|
||||
clean_count: number;
|
||||
recent_messages: MessageRecord[];
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
export interface Guild {
|
||||
id: string;
|
||||
name: string;
|
||||
icon?: string | null;
|
||||
icon: string | null;
|
||||
}
|
||||
|
||||
export interface Channel {
|
||||
id: string;
|
||||
name: string;
|
||||
type?: string | null; // "voice" | "text"
|
||||
parent_id?: string | null;
|
||||
type: "voice" | "text";
|
||||
}
|
||||
|
||||
/** Shape of the /api/config response (camelCase keys from backend). */
|
||||
|
||||
@@ -3,7 +3,7 @@ export type MediaMode = "music" | "screen";
|
||||
export interface MediaItem {
|
||||
id?: string | null;
|
||||
source: string;
|
||||
title?: string | null;
|
||||
title: string;
|
||||
mode?: MediaMode | null;
|
||||
durationMs?: number | null;
|
||||
thumbnailUrl?: string | null;
|
||||
@@ -12,6 +12,6 @@ export interface MediaItem {
|
||||
export interface MediaState {
|
||||
playing: boolean;
|
||||
musicVolume: number;
|
||||
current?: MediaItem | null;
|
||||
current: MediaItem | null;
|
||||
queue: MediaItem[];
|
||||
}
|
||||
|
||||
@@ -82,12 +82,14 @@ export interface MessageRecord {
|
||||
channel_id: string;
|
||||
thread_id?: string | null;
|
||||
reference_message_id?: string | null;
|
||||
reference_channel_id?: string | null;
|
||||
reference_guild_id?: string | null;
|
||||
user_id: string;
|
||||
username: string;
|
||||
avatar_url?: string | null;
|
||||
content: string;
|
||||
edited_content?: string | null;
|
||||
type: string; // "text" | "edited" | "deleted"
|
||||
type: "text" | "edited" | "deleted";
|
||||
is_reply?: boolean | null;
|
||||
is_forward?: boolean | null;
|
||||
is_crosspost?: boolean | null;
|
||||
|
||||
@@ -8,10 +8,10 @@ export interface VoiceRecording {
|
||||
channel_name?: string | null;
|
||||
filename: string;
|
||||
size_bytes: number;
|
||||
duration_bytes: number;
|
||||
download_url?: string | null;
|
||||
upload_status: string;
|
||||
upload_error?: string | null;
|
||||
transcription?: string | null;
|
||||
created_at: number;
|
||||
uploaded_at?: number | null;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@ export interface VoiceStatus {
|
||||
}
|
||||
|
||||
export interface ActiveSpeaker {
|
||||
id?: string | null;
|
||||
user_id: string;
|
||||
userId: string;
|
||||
username: string;
|
||||
avatar?: string | null;
|
||||
speaking: boolean;
|
||||
|
||||
@@ -36,7 +36,8 @@ export interface WsEventMap {
|
||||
voice_recording_stopped: unknown;
|
||||
voice_recording_uploaded: VoiceRecording;
|
||||
voice_active_user: ActiveSpeaker;
|
||||
voice_pcm_data: { userId: string; pcm: string };
|
||||
/** NOT delivered as JSON — arrives only via onPcm() binary handler as PcmChunk */
|
||||
voice_pcm_data: never;
|
||||
voice_analyzed: unknown;
|
||||
analysis_queue_status: unknown;
|
||||
reaction_added: unknown;
|
||||
|
||||
Reference in New Issue
Block a user