import { useEffect, useState } from 'react' import { AppLayout } from '@/components/AppLayout' import { SoundCard } from '@/components/sounds/SoundCard' import { soundsService, type Sound } from '@/lib/api/services/sounds' import { Skeleton } from '@/components/ui/skeleton' import { AlertCircle } from 'lucide-react' import { toast } from 'sonner' import { useTheme } from '@/hooks/use-theme' import { soundEvents, SOUND_EVENTS } from '@/lib/events' interface SoundPlayedEventData { sound_id: number sound_name: string user_id: number | null user_name: string | null play_count: number } const lightModeColors = [ 'bg-red-600/30 hover:bg-red-600/40 text-red-900 border-red-600/20', 'bg-blue-700/30 hover:bg-blue-700/40 text-blue-900 border-blue-700/20', 'bg-yellow-400/30 hover:bg-yellow-400/40 text-yellow-800 border-yellow-400/20', 'bg-purple-700/30 hover:bg-purple-700/40 text-purple-900 border-purple-700/20', 'bg-green-600/30 hover:bg-green-600/40 text-green-900 border-green-600/20', 'bg-pink-500/30 hover:bg-pink-500/40 text-pink-900 border-pink-500/20', 'bg-cyan-500/30 hover:bg-cyan-500/40 text-cyan-900 border-cyan-500/20', 'bg-amber-500/30 hover:bg-amber-500/40 text-amber-900 border-amber-500/20', 'bg-indigo-800/30 hover:bg-indigo-800/40 text-indigo-900 border-indigo-800/20', 'bg-lime-500/30 hover:bg-lime-500/40 text-lime-900 border-lime-500/20', 'bg-fuchsia-600/30 hover:bg-fuchsia-600/40 text-fuchsia-900 border-fuchsia-600/20', 'bg-orange-600/30 hover:bg-orange-600/40 text-orange-900 border-orange-600/20', ] const darkModeColors = [ 'bg-red-700/40 hover:bg-red-700/50 text-red-100 border border-red-500/50', 'bg-blue-800/40 hover:bg-blue-800/50 text-blue-100 border border-blue-600/50', 'bg-yellow-600/40 hover:bg-yellow-600/50 text-yellow-100 border border-yellow-400/50', 'bg-purple-800/40 hover:bg-purple-800/50 text-purple-100 border border-purple-600/50', 'bg-green-700/40 hover:bg-green-700/50 text-green-100 border border-green-500/50', 'bg-pink-700/40 hover:bg-pink-700/50 text-pink-100 border border-pink-500/50', 'bg-cyan-700/40 hover:bg-cyan-700/50 text-cyan-100 border border-cyan-500/50', 'bg-amber-700/40 hover:bg-amber-700/50 text-amber-100 border border-amber-500/50', 'bg-indigo-900/40 hover:bg-indigo-900/50 text-indigo-100 border border-indigo-700/50', 'bg-lime-700/40 hover:bg-lime-700/50 text-lime-100 border border-lime-500/50', 'bg-fuchsia-800/40 hover:bg-fuchsia-800/50 text-fuchsia-100 border border-fuchsia-600/50', 'bg-orange-700/40 hover:bg-orange-700/50 text-orange-100 border border-orange-500/50', ] export function SoundsPage() { const [sounds, setSounds] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [currentColors, setCurrentColors] = useState(lightModeColors) const handlePlaySound = async (sound: Sound) => { try { await soundsService.playSound(sound.id) toast.success(`Playing: ${sound.name || sound.filename}`) } catch (error) { toast.error(`Failed to play sound: ${error instanceof Error ? error.message : 'Unknown error'}`) } } const { theme } = useTheme() useEffect(() => { if (theme === 'dark') { setCurrentColors(darkModeColors) } else { setCurrentColors(lightModeColors) } }, [theme]) const getSoundColor = (soundIdx: number) => { const index = soundIdx % currentColors.length return currentColors[index] } useEffect(() => { const fetchSounds = async () => { try { setLoading(true) setError(null) const sdbSounds = await soundsService.getSDBSounds() setSounds(sdbSounds) } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to fetch sounds' setError(errorMessage) toast.error(errorMessage) } finally { setLoading(false) } } fetchSounds() }, []) // Listen for sound_played events and update play_count useEffect(() => { const handleSoundPlayed = (eventData: SoundPlayedEventData) => { setSounds(prevSounds => prevSounds.map(sound => sound.id === eventData.sound_id ? { ...sound, play_count: eventData.play_count } : sound ) ) } soundEvents.on(SOUND_EVENTS.SOUND_PLAYED, handleSoundPlayed) return () => { soundEvents.off(SOUND_EVENTS.SOUND_PLAYED, handleSoundPlayed) } }, []) const renderContent = () => { if (loading) { return (
{Array.from({ length: 10 }).map((_, i) => (
))}
) } if (error) { return (

Failed to load sounds

{error}

) } if (sounds.length === 0) { return (
🎵

No sounds found

No SDB type sounds are available in your library.

) } return (
{sounds.map((sound, idx) => ( ))}
) } return (

Sounds

Browse and play your soundboard library

{!loading && !error && (
{sounds.length} sound{sounds.length !== 1 ? 's' : ''}
)}
{renderContent()}
) }