import { useEffect, useState } from 'react';
import Link from 'next/link';
import { Feed } from '@/lib/db';
interface SidebarProps {
selectedCategory?: string;
selectedFeed?: string;
}
export default function Sidebar({ selectedCategory, selectedFeed }: SidebarProps) {
const [categories, setCategories] = useState<string[]>([]);
const [feeds, setFeeds] = useState<Feed[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Fetch categories and feeds
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
// Fetch categories
const categoriesResponse = await fetch('/api/categories');
if (!categoriesResponse.ok) {
throw new Error('Failed to fetch categories');
}
const categoriesData = await categoriesResponse.json();
setCategories(categoriesData);
// Fetch feeds
const feedsResponse = await fetch('/api/feeds');
if (!feedsResponse.ok) {
throw new Error('Failed to fetch feeds');
}
const feedsData = await feedsResponse.json();
setFeeds(feedsData);
setLoading(false);
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
setLoading(false);
}
};
fetchData();
}, []);
// Group feeds by category
const feedsByCategory: Record<string, Feed[]> = {};
const uncategorizedFeeds: Feed[] = [];
feeds.forEach(feed => {
if (feed.category) {
if (!feedsByCategory[feed.category]) {
feedsByCategory[feed.category] = [];
}
feedsByCategory[feed.category].push(feed);
} else {
uncategorizedFeeds.push(feed);
}
});
if (loading) {
return (
<div className="w-64 bg-gray-100 p-4 h-screen">
<h2 className="text-xl font-bold mb-4">RSS Feeds</h2>
<div className="animate-pulse">
<div className="h-4 bg-gray-300 rounded mb-2"></div>
<div className="h-4 bg-gray-300 rounded mb-2"></div>
<div className="h-4 bg-gray-300 rounded mb-2"></div>
</div>
</div>
);
}
if (error) {
return (
<div className="w-64 bg-gray-100 p-4 h-screen">
<h2 className="text-xl font-bold mb-4">RSS Feeds</h2>
<div className="text-red-500">Error: {error}</div>
</div>
);
}
return (
<div className="w-64 bg-gray-100 p-4 h-screen flex flex-col">
<h2 className="text-xl font-bold mb-4">RSS Feeds</h2>
<div className="mb-4">
<Link
href="/"
className={`block p-2 rounded ${!selectedCategory && !selectedFeed ? 'bg-blue-500 text-white' : 'hover:bg-gray-200'}`}
>
All Recent Items
</Link>
</div>
<div className="mb-4">
<h3 className="font-semibold mb-2">Categories</h3>
<ul>
{categories.map(category => (
<li key={category}>
<Link
href={`/category/${encodeURIComponent(category)}`}
className={`block p-2 rounded ${selectedCategory === category ? 'bg-blue-500 text-white' : 'hover:bg-gray-200'}`}
>
{category}
</Link>
</li>
))}
</ul>
</div>
<div className="flex-1 overflow-y-auto">
<h3 className="font-semibold mb-2">All Feeds</h3>
{Object.entries(feedsByCategory).map(([category, categoryFeeds]) => (
<div key={category} className="mb-4">
<h4 className="text-sm font-medium text-gray-600 mb-1">{category}</h4>
<ul className="pl-2">
{categoryFeeds.map(feed => (
<li key={feed.id}>
<Link
href={`/feed/${encodeURIComponent(feed.id)}`}
className={`block p-2 rounded ${selectedFeed === feed.id ? 'bg-blue-500 text-white' : 'hover:bg-gray-200'}`}
>
{feed.name}
</Link>
</li>
))}
</ul>
</div>
))}
{uncategorizedFeeds.length > 0 && (
<div className="mb-4">
<h4 className="text-sm font-medium text-gray-600 mb-1">Uncategorized</h4>
<ul className="pl-2">
{uncategorizedFeeds.map(feed => (
<li key={feed.id}>
<Link
href={`/feed/${encodeURIComponent(feed.id)}`}
className={`block p-2 rounded ${selectedFeed === feed.id ? 'bg-blue-500 text-white' : 'hover:bg-gray-200'}`}
>
{feed.name}
</Link>
</li>
))}
</ul>
</div>
)}
</div>
</div>
);
}