'use client'; import { useState } from 'react'; import { Header, SearchBar, ServiceCard, BookmarkCard, CategorySection, Icon } from '@/components'; import { usePortal } from '@/lib/PortalContext'; import { categoryLabels, categoryOrder, bookmarkCategoryLabels, bookmarkCategoryOrder, ServiceCategory, BookmarkCategory } from '@/lib/services'; type TabId = 'services' | 'bookmarks' | 'ai' | 'whyrating' | 'settings'; const tabs: { id: TabId; label: string; icon: string }[] = [ { id: 'whyrating', label: 'WhyRating', icon: 'star' }, { id: 'services', label: 'Services', icon: 'server' }, { id: 'ai', label: 'AI', icon: 'bot' }, { id: 'bookmarks', label: 'Bookmarks', icon: 'external-link' }, { id: 'settings', label: 'Settings', icon: 'settings' }, ]; const aiTools = [ { name: 'Claude', url: 'https://claude.ai', icon: 'bot', description: 'Anthropic AI assistant' }, { name: 'ChatGPT', url: 'https://chat.openai.com', icon: 'message-square', description: 'OpenAI chat assistant' }, { name: 'Perplexity', url: 'https://perplexity.ai', icon: 'search', description: 'AI-powered search' }, { name: 'Phind', url: 'https://phind.com', icon: 'code', description: 'AI for developers' }, { name: 'Cursor', url: 'https://cursor.com', icon: 'terminal', description: 'AI-first code editor' }, { name: 'v0', url: 'https://v0.dev', icon: 'layout', description: 'Vercel AI UI generator' }, { name: 'Replicate', url: 'https://replicate.com', icon: 'cpu', description: 'ML model hosting' }, { name: 'Hugging Face', url: 'https://huggingface.co', icon: 'smile', description: 'ML models & datasets' }, { name: 'Together AI', url: 'https://together.ai', icon: 'users', description: 'Open model inference' }, ]; const whyratingLinks = [ { name: 'WhyRating Hub', url: 'http://whyrating.nuc.lan', icon: 'star', description: 'WhyRating project hub and quick links' }, { name: 'Brand Site', url: 'http://brand.nuc.lan', icon: 'palette', description: 'WhyRating brand guidelines and assets' }, { name: 'Templates Site', url: 'http://templates.nuc.lan', icon: 'layout', description: 'WhyRating email and document templates' }, { name: 'Outline Docs', url: 'http://192.168.1.3:3080', icon: 'file-text', description: 'Project documentation and notes' }, ]; export default function Home() { const [activeTab, setActiveTab] = useState('whyrating'); const { filteredServices, filteredBookmarks, healthStatus, searchQuery, darkMode, setDarkMode, services } = usePortal(); // Group services by category const servicesByCategory = categoryOrder.reduce((acc, category) => { const categoryServices = filteredServices.filter(s => s.category === category); if (categoryServices.length > 0) { acc[category] = categoryServices; } return acc; }, {} as Record); // Group bookmarks by category const bookmarksByCategory = bookmarkCategoryOrder.reduce((acc, category) => { const categoryBookmarks = filteredBookmarks.filter(b => b.category === category); if (categoryBookmarks.length > 0) { acc[category] = categoryBookmarks; } return acc; }, {} as Record); const hasServices = Object.keys(servicesByCategory).length > 0; const hasBookmarks = Object.keys(bookmarksByCategory).length > 0; const noResults = searchQuery && !hasServices && !hasBookmarks; // Count running services const runningCount = services.filter(s => healthStatus[s.name] === 'running').length; const totalServices = services.length; const renderTabContent = () => { switch (activeTab) { case 'services': return ( <> {/* Search */}
{/* Status summary */}
{runningCount} of {totalServices} services running
{/* No results message */} {noResults && (

No services found for "{searchQuery}"

)} {/* Services */} {hasServices && (
{Object.entries(servicesByCategory).map(([category, services]) => ( {services.map(service => ( ))} ))}
)} ); case 'bookmarks': return ( <> {/* Search */}
{/* No results message */} {searchQuery && !hasBookmarks && (

No bookmarks found for "{searchQuery}"

)} {/* Bookmarks */} {hasBookmarks && (
{Object.entries(bookmarksByCategory).map(([category, bookmarks]) => ( {bookmarks.map(bookmark => ( ))} ))}
)} ); case 'ai': return (

AI Tools & Platforms

Quick access to AI assistants and platforms

{aiTools.map(tool => (

{tool.name}

{tool.description}

))}
); case 'whyrating': return (

WhyRating.com

Project resources and documentation

{whyratingLinks.map(link => (

{link.name}

{link.description}

))}
); case 'settings': return (

Appearance

{/* Dark Mode Toggle */}

Dark Mode

Use dark theme for the portal

About

Version 1.0.0
Server IP 192.168.1.3
Services {totalServices}
Bookmarks {filteredBookmarks.length}
); default: return null; } }; return (
setActiveTab(tab as TabId)} tabs={tabs} />
{renderTabContent()}
{/* Footer */}
); }