'use client' import { Button } from '@thedaviddias/design-system/button' import { ErrorBoundaryCustom } from '@thedaviddias/design-system/error-boundary' import { ToggleGroup, ToggleGroupItem } from '@thedaviddias/design-system/toggle-group' import { Clock, Grid, List, SortAsc } from 'lucide-react' import { useEffect, useState } from 'react' import { EmptyState } from '@/components/empty-state' import { LLMGrid } from '@/components/llm/llm-grid' import { useWebsiteFilters } from '@/hooks/use-website-filters' import { categories } from '@/lib/categories' import type { WebsiteMetadata } from '@/lib/content-loader' import { getRoute } from '@/lib/routes' interface ClientProjectsListProps { initialWebsites: WebsiteMetadata[] } /** * Type guard to validate WebsiteMetadata objects * * @param website - Object to validate * @returns True if object is a valid WebsiteMetadata */ function isValidWebsite(website: any): website is WebsiteMetadata { const isValid = website && typeof website.slug === 'string' && typeof website.name === 'string' && typeof website.description === 'string' && typeof website.website === 'string' && typeof website.llmsUrl === 'string' && typeof website.category === 'string' && typeof website.publishedAt === 'string' return isValid } /** * Client-side component for displaying and filtering a list of websites * * @param props - Component props * @param props.initialWebsites - Initial list of websites to display * * @returns React component with filtering, sorting, and view mode controls * * @example * ```tsx * * ``` */ export function ClientProjectsList({ initialWebsites }: ClientProjectsListProps) { const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid') const [websites, setWebsites] = useState(initialWebsites) const { categoryFilter, sortBy, setCategoryFilter, setSortBy } = useWebsiteFilters() // Get current category name for heading const currentCategoryName = categoryFilter === 'all' ? 'All LLMs Websites' : `${categories.find(cat => cat.slug === categoryFilter)?.name || 'Unknown'} Websites` // Update filtered and sorted websites when filters or initial websites change useEffect(() => { let filteredWebsites = [...initialWebsites] // Filter by category if selected if (categoryFilter !== 'all') { filteredWebsites = filteredWebsites.filter(website => website.category === categoryFilter) } // Sort by selected criteria if (sortBy === 'latest') { filteredWebsites.sort( (a, b) => new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime() ) } else if (sortBy === 'name') { filteredWebsites.sort((a, b) => a.name.localeCompare(b.name)) } // Validate websites after all filtering and sorting const validWebsites = filteredWebsites.filter(isValidWebsite) setWebsites(validWebsites) }, [initialWebsites, categoryFilter, sortBy]) return (

{currentCategoryName}

{categories.map(category => ( ))}
Sort by: value && setSortBy(value)} className="bg-background border rounded-md" > Latest Name
{websites.length === 0 ? ( ) : viewMode === 'grid' ? (

Websites list

) : (

Websites list

)}
) }