import React, { useState } from 'react'; import { Category, Feed, FilterState, Stats } from '../types'; import { Inbox, Star, Layers, Folder, FolderOpen, Rss, ChevronRight, ChevronDown, } from 'lucide-react'; interface SidebarProps { filter: FilterState; onFilterChange: (newFilter: Partial) => void; categories: Category[]; feeds: Feed[]; stats: Stats | null; } export const Sidebar: React.FC = ({ filter, onFilterChange, categories, feeds, stats, }) => { const [collapsedCats, setCollapsedCats] = useState>({}); const toggleCategoryCollapse = (catId: string, e: React.MouseEvent) => { e.stopPropagation(); setCollapsedCats((prev) => ({ ...prev, [catId]: !prev[catId] })); }; // Group feeds by category const categorizedFeeds: Record = {}; const uncategorizedFeeds: Feed[] = []; feeds.forEach((f) => { if (f.category_id) { if (!categorizedFeeds[f.category_id]) { categorizedFeeds[f.category_id] = []; } categorizedFeeds[f.category_id].push(f); } else { uncategorizedFeeds.push(f); } }); return (
{/* Core Navigation Items */}
onFilterChange({ view: 'inbox', feedId: undefined, categoryId: undefined, }) } >
Inbox
{stats && stats.total_unread > 0 && ( {stats.total_unread} )}
onFilterChange({ view: 'starred', feedId: undefined, categoryId: undefined, }) } >
Starred
{stats && stats.total_starred > 0 && ( {stats.total_starred} )}
onFilterChange({ view: 'all', feedId: undefined, categoryId: undefined, }) } >
All Articles
{/* Categories Section */} {categories.length > 0 && (
Categories
{categories.map((cat) => { const catFeeds = categorizedFeeds[cat.id] || []; const isCollapsed = collapsedCats[cat.id]; const isCatActive = filter.categoryId === cat.id && !filter.feedId; const catUnread = catFeeds.reduce((sum, f) => sum + f.unread_count, 0); return (
onFilterChange({ categoryId: cat.id, feedId: undefined, }) } >
{isCollapsed ? : } {cat.title}
{catUnread > 0 && {catUnread}}
{/* Category feeds */} {!isCollapsed && catFeeds.map((feed) => { const isFeedActive = filter.feedId === feed.id; return (
onFilterChange({ feedId: feed.id, categoryId: undefined, }) } >
{feed.title}
{feed.unread_count > 0 && ( {feed.unread_count} )}
); })}
); })}
)} {/* Uncategorized Feeds */} {uncategorizedFeeds.length > 0 && (
Feeds
{uncategorizedFeeds.map((feed) => { const isFeedActive = filter.feedId === feed.id; return (
onFilterChange({ feedId: feed.id, categoryId: undefined, }) } >
{feed.title}
{feed.unread_count > 0 && ( {feed.unread_count} )}
); })}
)}
); };