import { useState } from "react" import { AnimatePresence, motion } from "framer-motion" import { EnvelopeSimple, Hash, Buildings, Megaphone, Fire, MagnifyingGlass, Funnel } from "@phosphor-icons/react" import type { AgentRecord, MessageChannel } from "@shared/types" import { AgentAvatar } from "./MessageItem" import type { ChannelDescriptor, TaskDiscussionDescriptor } from "./ChannelHeader" import { useT } from "../../i18n" const channelConfig: Record = { direct: { label: "Direct Messages", icon: EnvelopeSimple }, department: { label: "Department", icon: Buildings }, company: { label: "Company-wide", icon: Megaphone }, project: { label: "Project", icon: Hash }, incident: { label: "Incident", icon: Fire }, } function ChannelItem({ descriptor, active, unreadCount, hasUrgent, agents, onClick, }: { descriptor: ChannelDescriptor active: boolean unreadCount: number hasUrgent: boolean agents: AgentRecord[] onClick: () => void }) { const config = channelConfig[descriptor.channel] const Icon = config.icon const agent = descriptor.agentId ? agents.find((a) => a.id === descriptor.agentId) : undefined return ( ) } interface ChannelSidebarProps { channelGroups: Array<{ type: MessageChannel; label: string; items: ChannelDescriptor[] }> taskDiscussionChannels: TaskDiscussionDescriptor[] selectedChannelKey: string | null onSelectChannel: (key: string) => void unreadByChannel: Map agents: AgentRecord[] totalChannels: number onHideSidebar: () => void } export function ChannelSidebar({ channelGroups, taskDiscussionChannels, selectedChannelKey, onSelectChannel, unreadByChannel, agents, totalChannels, onHideSidebar: _onHideSidebar, }: ChannelSidebarProps) { const t = useT() return (
{channelGroups.map((group) => (
{group.label}
{group.items.map((ch) => { const stats = unreadByChannel.get(ch.key) return ( onSelectChannel(ch.key)} /> ) })}
))} {taskDiscussionChannels.length > 0 ? (
{t("comm.taskDiscussions")}
{taskDiscussionChannels.map((discussion) => ( ))}
) : null} {totalChannels === 0 ? (
{t("comm.noActiveDepartments")}
) : null}
{totalChannels} channels {agents.length} agents
) } export interface FilterState { search: string channelType: MessageChannel | "all" priority: string unreadOnly: boolean } export function FilterBar({ filters, onChangeFilters, scopeToggle, onSearchKeyDown, }: { filters: FilterState onChangeFilters: (next: FilterState) => void scopeToggle?: React.ReactNode onSearchKeyDown?: (e: React.KeyboardEvent) => void }) { const t = useT() const [expanded, setExpanded] = useState(false) return (
onChangeFilters({ ...filters, search: e.target.value })} onKeyDown={onSearchKeyDown} placeholder={t("comm.searchMessages")} className="w-full rounded-lg border border-border bg-card py-1.5 pl-8 pr-3 text-[11px] text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1" style={{ focusRingColor: "var(--primary)" } as React.CSSProperties} />
{scopeToggle}
{expanded ? ( {(filters.channelType !== "all" || filters.priority !== "all" || filters.unreadOnly) ? ( ) : null} ) : null}
) }