'use client'; import { useState } from 'react'; import { Input } from '../ui/Input'; import Button from '../ui/Button'; import TagDisplay from '../tags/TagDisplay'; import AdvancedFilters from './AdvancedFilters'; import type { Story, Tag, AdvancedFilters as AdvancedFiltersType } from '../../types/api'; interface SidebarLayoutProps { stories: Story[]; tags: Tag[]; totalElements: number; searchQuery: string; selectedTags: string[]; viewMode: 'grid' | 'list'; sortOption: string; sortDirection: 'asc' | 'desc'; advancedFilters?: AdvancedFiltersType; onSearchChange: (e: React.ChangeEvent) => void; onTagToggle: (tagName: string) => void; onViewModeChange: (mode: 'grid' | 'list') => void; onSortChange: (option: string) => void; onSortDirectionToggle: () => void; onAdvancedFiltersChange?: (filters: AdvancedFiltersType) => void; onRandomStory: () => void; onClearFilters: () => void; children: React.ReactNode; } export default function SidebarLayout({ stories, tags, totalElements, searchQuery, selectedTags, viewMode, sortOption, sortDirection, advancedFilters = {}, onSearchChange, onTagToggle, onViewModeChange, onSortChange, onSortDirectionToggle, onAdvancedFiltersChange, onRandomStory, onClearFilters, children }: SidebarLayoutProps) { const [tagSearch, setTagSearch] = useState(''); const [showAdvancedFilters, setShowAdvancedFilters] = useState(false); // Filter tags based on search query const filteredTags = tags.filter(tag => tag.name.toLowerCase().includes(tagSearch.toLowerCase()) ); // Count active advanced filters const activeAdvancedFiltersCount = Object.values(advancedFilters).filter(value => value !== undefined && value !== '' && value !== 'all' && value !== false ).length; return (
{/* Mobile Header - Only shown on mobile */}

Your Library

{totalElements} stories total

{/* Mobile Search */}
{/* Mobile Controls Row */}
{/* View Toggle */}
{/* Sort */} {/* Filter Toggle */}
{/* Mobile Tag Pills - Show selected tags */} {selectedTags.length > 0 && (
{selectedTags.slice(0, 3).map((tagName) => { const tag = tags.find(t => t.name === tagName); return tag ? (
onTagToggle(tag.name)} className="cursor-pointer">
) : null; })} {selectedTags.length > 3 && ( +{selectedTags.length - 3} more )}
)}
{/* Left Sidebar - Hidden on mobile by default */}
{/* Random Story Button */}
{/* Header */}

Your Library

{totalElements} stories total

{/* Search */}
{/* View Toggle */}
{/* Sort Controls */}

Sort By

{/* Tag Filters */}

Filter by Tags

setTagSearch(e.target.value)} className="w-full px-2 py-1 text-xs border rounded theme-card border-gray-300 dark:border-gray-600" />
{filteredTags.map((tag) => ( ))} {filteredTags.length === 0 && tagSearch && (
No tags match "{tagSearch}"
)} {filteredTags.length > 10 && !tagSearch && (
... and {filteredTags.length - 10} more tags
)}
{/* Advanced Filters Toggle */} {onAdvancedFiltersChange && ( )}
{/* Advanced Filters Section */} {showAdvancedFilters && onAdvancedFiltersChange && (
onAdvancedFiltersChange({})} className="space-y-3 max-w-full overflow-hidden" />
)}
{/* Mobile Filter Panel - Shows when filters expanded */} {showAdvancedFilters && (

Filters

{/* Tag Grid */}

Tags

setTagSearch(e.target.value)} className="w-full px-2 py-1 text-sm border rounded theme-card border-gray-300 dark:border-gray-600" />
{filteredTags.slice(0, 19).map((tag) => ( ))}
{/* Advanced Filters */} {onAdvancedFiltersChange && (

Advanced Filters

onAdvancedFiltersChange({})} className="space-y-3" />
)}
)} {/* Main Content */}
{children}
); }