"use client"; import { Hash } from "lucide-react"; import { useEffect, useState } from "react"; import { useAmbient } from "@/components/ambient/ambient-context"; import { ChannelCultureGlossary } from "@/components/ChannelCultureGlossary"; import { GlassPanel } from "@/components/primitives"; import { EmptyState, ErrorState, PageTransition, SectionHeader, SkeletonPanel, } from "@/components/shared"; import { useChannelCultures, useChannels } from "@/hooks"; import { useStaggerReveal } from "@/hooks/use-gsap-animation"; import { formatNumber } from "@/lib/format"; import type { DashboardChannel } from "@/lib/types"; type ViewMode = "roster" | "culture"; export function ChannelsView({ initialCultures, }: { initialCultures?: import("@/lib/types").ChannelCultureRow[]; }) { const [viewMode, setViewMode] = useState("roster"); const { data: channels, isLoading, error } = useChannels(); const ambient = useAmbient(); const containerRef = useStaggerReveal( ".channel-roster-card", { stagger: 0.03, y: 8, dependencies: [channels?.length], }, ); useEffect(() => { ambient.set("signal", 0.25, "channels"); }, [ambient]); if (error && !channels) return ; return (
{/* Tactical HUD Header Bar */}

Channel Roster · Signal Map

NODES: {channels?.length ?? 0}
{viewMode === "culture" ? ( ) : ( <> {isLoading && !channels ? ( ) : !channels || channels.length === 0 ? ( } title="No channels discovered" description="Channels appear here once the Discord gateway captures messages." /> ) : ( {channels.length} channels } />
{channels.map((ch) => ( ))}
Channel Messages Clean Flagged Risk Last Activity
)} )}
); } function ChannelRow({ channel }: { channel: DashboardChannel }) { const total = channel.total_messages || 1; const flaggedPct = channel.flagged_count ? (channel.flagged_count / total) * 100 : 0; const riskTone = flaggedPct > 10 ? "vermilion" : flaggedPct > 3 ? "amber" : "signal"; return (
{channel.channel_name ?? channel.channel_id.slice(0, 20)}
{channel.guild_id && (
guild: {channel.guild_id.slice(0, 12)}…
)}
{formatNumber(channel.total_messages)} {formatNumber(channel.total_messages - channel.flagged_count)} 0 ? "text-vermilion" : "text-ink-muted" }`} > {formatNumber(channel.flagged_count)}
{flaggedPct.toFixed(1)}%
{channel.last_message_at ? ( {new Date(channel.last_message_at).toLocaleDateString()} ) : ( — )} ); } function ChannelsCultureView({ initialCultures, }: { initialCultures?: import("@/lib/types").ChannelCultureRow[]; }) { const { data: cultures } = useChannelCultures(100, initialCultures); return cultures ? ( ) : ( ); }