Tag Enhancement + bugfixes

This commit is contained in:
Stefan Hardegger
2025-08-17 17:16:40 +02:00
parent 6b83783381
commit 1a99d9830d
34 changed files with 2996 additions and 97 deletions

View File

@@ -3,11 +3,13 @@
import { useState } from 'react';
import { Input } from '../ui/Input';
import Button from '../ui/Button';
import TagDisplay from '../tags/TagDisplay';
import { Story, Tag } from '../../types/api';
interface SidebarLayoutProps {
stories: Story[];
tags: Tag[];
totalElements: number;
searchQuery: string;
selectedTags: string[];
viewMode: 'grid' | 'list';
@@ -26,6 +28,7 @@ interface SidebarLayoutProps {
export default function SidebarLayout({
stories,
tags,
totalElements,
searchQuery,
selectedTags,
viewMode,
@@ -40,6 +43,13 @@ export default function SidebarLayout({
onClearFilters,
children
}: SidebarLayoutProps) {
const [tagSearch, setTagSearch] = useState('');
// Filter tags based on search query
const filteredTags = tags.filter(tag =>
tag.name.toLowerCase().includes(tagSearch.toLowerCase())
);
return (
<div className="flex min-h-screen">
{/* Left Sidebar */}
@@ -58,7 +68,7 @@ export default function SidebarLayout({
{/* Header */}
<div className="mb-6">
<h1 className="text-2xl font-bold theme-header">Your Library</h1>
<p className="theme-text mt-1">{stories.length} stories total</p>
<p className="theme-text mt-1">{totalElements} stories total</p>
</div>
{/* Search */}
@@ -125,6 +135,8 @@ export default function SidebarLayout({
<input
type="text"
placeholder="Search tags..."
value={tagSearch}
onChange={(e) => setTagSearch(e.target.value)}
className="w-full px-2 py-1 text-xs border rounded theme-card border-gray-300 dark:border-gray-600"
/>
</div>
@@ -136,9 +148,9 @@ export default function SidebarLayout({
checked={selectedTags.length === 0}
onChange={() => onClearFilters()}
/>
<span className="text-xs">All Stories ({stories.length})</span>
<span className="text-xs">All Stories ({totalElements})</span>
</label>
{tags.map((tag) => (
{filteredTags.map((tag) => (
<label
key={tag.id}
className="flex items-center gap-2 py-1 cursor-pointer"
@@ -148,14 +160,27 @@ export default function SidebarLayout({
checked={selectedTags.includes(tag.name)}
onChange={() => onTagToggle(tag.name)}
/>
<span className="text-xs">
{tag.name} ({tag.storyCount})
</span>
<div className="flex items-center gap-2 flex-1 min-w-0">
<TagDisplay
tag={tag}
size="sm"
clickable={false}
className="flex-shrink-0"
/>
<span className="text-xs text-gray-600 dark:text-gray-400 flex-shrink-0">
({tag.storyCount})
</span>
</div>
</label>
))}
{tags.length > 10 && (
{filteredTags.length === 0 && tagSearch && (
<div className="text-center text-xs text-gray-500 py-2">
... and {tags.length - 10} more tags
No tags match "{tagSearch}"
</div>
)}
{filteredTags.length > 10 && !tagSearch && (
<div className="text-center text-xs text-gray-500 py-2">
... and {filteredTags.length - 10} more tags
</div>
)}
</div>