Sidebar.tsx•4.89 kB
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>
  );
}