import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import type { Theme } from '../../types/theme'; import { getThemes } from '../../themes'; import { LayoutPreview } from './LayoutPreview'; export const ThemeBrowser: React.FC = () => { const navigate = useNavigate(); const [themes, setThemes] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [expandedTheme, setExpandedTheme] = useState(null); const [showLayoutPreviews, setShowLayoutPreviews] = useState>({}); useEffect(() => { const loadThemes = async () => { try { setLoading(true); const discoveredThemes = await getThemes(); setThemes(discoveredThemes); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load themes'); } finally { setLoading(false); } }; loadThemes(); }, []); const handleThemeClick = (theme: Theme) => { navigate(`/themes/${theme.id}`); }; const handleThemeExpand = (themeId: string) => { setExpandedTheme(expandedTheme === themeId ? null : themeId); }; const handleLayoutPreviewsToggle = (themeId: string) => { setShowLayoutPreviews(prev => ({ ...prev, [themeId]: !prev[themeId] })); }; if (loading) { return (
Loading themes...
); } if (error) { return (

Error loading themes

{error}

); } if (themes.length === 0) { return (

No themes found

No themes were discovered. Check your themes directory.

); } return (

Available Themes

{themes.length} theme{themes.length !== 1 ? 's' : ''}
{themes.map((theme) => (
handleThemeClick(theme)} >

{theme.name}

{theme.description}

{theme.author && ( by {theme.author} )} {theme.version && ( v{theme.version} )}
{theme.variables && Object.keys(theme.variables).length > 0 && (
{Object.entries(theme.variables) .filter(([_, value]) => value.startsWith('#') || value.includes('rgb') || value.includes('hsl')) .slice(0, 6) // Show max 6 color swatches to avoid overcrowding .map(([key, value]) => (
))}
)} {expandedTheme === theme.id && (

Layouts ({theme.layouts.length})

{showLayoutPreviews[theme.id] ? (
{theme.layouts.map((layout) => ( ))}
) : (
{theme.layouts.map((layout) => (
{layout.name} {layout.slots.length} slot{layout.slots.length !== 1 ? 's' : ''}
))}
)}
{theme.variables && (

CSS Variables

{Object.entries(theme.variables).map(([key, value]) => (
--{key} {value}
))}
)}
Path: {theme.basePath}
CSS File: {theme.cssFile}
{theme.masterSlideTemplate && (
Master Slide: Yes
)}
)}
))}
); };