/** * @file components/sidebar/CategorySection.tsx * @description Sub-component for rendering a category group and its list of channels with persistent collapse state and animations. */ "use client"; import { ChevronDown, Plus, Settings } from "lucide-react"; import { motion, AnimatePresence } from "framer-motion"; import { ChannelItem } from "./ChannelItem"; import type { Channel } from "@/db/schema"; import { useLocalStorage } from "@/lib/hooks/useLocalStorage"; interface CategorySectionProps { id: string; title: string; channels: Channel[]; currentChannelId: string; serverId: string; onCloseNav: () => void; onCreateChannel: () => void; onEditChannel: (channel: Channel) => void; onEditCategory?: () => void; } /** Renders a collapsible category section with persistent collapse state and smooth animation. */ export function CategorySection({ id, title, channels, currentChannelId, serverId, onCloseNav, onCreateChannel, onEditChannel, onEditCategory, }: CategorySectionProps) { const [isCollapsed, setIsCollapsed] = useLocalStorage( `category_collapsed_${id}`, false, ); const toggleCollapsed = () => { setIsCollapsed((prev) => !prev); }; const handleChannelClick = () => { if (!window.matchMedia("(min-width: 768px)").matches) { onCloseNav(); } }; const handleOpenChannelSettings = (e: React.MouseEvent, channel: Channel) => { e.preventDefault(); e.stopPropagation(); onEditChannel(channel); }; const handleOpenCategorySettings = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); onEditCategory?.(); }; return (
{onEditCategory && ( )}
{!isCollapsed && ( {channels.map((channel) => ( ))} )}
); }