'use client'; import { useState, useRef, useEffect, MouseEvent } from 'react'; // Configuration const BASE_URL = "https://openwheels.racing/files/music/"; // Types interface Track { title: string; artist: string; fileName: string; theme?: string; } type IconProps = { className?: string }; // Icons function PlayIcon({ className = "w-6 h-6" }: IconProps) { return ( ); } function PauseIcon({ className = "w-6 h-6" }: IconProps) { return ( ); } function SkipNextIcon({ className = "w-6 h-6" }: IconProps) { return ( ); } function SkipPrevIcon({ className = "w-6 h-6" }: IconProps) { return ( ); } function VideoIcon({ className = "w-5 h-5" }: IconProps) { return ( ); } function MusicIcon({ className = "w-5 h-5" }: IconProps) { return ( ); } function RefreshIcon({ className = "w-5 h-5" }: IconProps) { return ( ); } export default function MusicPage() { const [tracks, setTracks] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [currentTrackIndex, setCurrentTrackIndex] = useState(0); const [isPlaying, setIsPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(0); const [duration, setDuration] = useState(0); const [selectedTheme, setSelectedTheme] = useState('all'); const mediaRef = useRef(null); // Fetch available tracks from the server const fetchTracks = async () => { setLoading(true); setError(null); try { const response = await fetch('/api/music/tracks'); if (!response.ok) { throw new Error('Failed to fetch tracks'); } const data = await response.json(); setTracks(data.tracks || []); } catch (err: unknown) { console.error('Error fetching tracks:', err); setError(err instanceof Error ? err.message : 'Unknown error'); setTracks([]); } finally { setLoading(false); } }; useEffect(() => { fetchTracks(); }, []); // Group tracks by theme const tracksByTheme = tracks.reduce>((acc, track) => { const theme = track?.theme || 'general'; if (!acc[theme]) { acc[theme] = []; } acc[theme].push(track); return acc; }, {}); const themes = Object.keys(tracksByTheme).sort(); // Get filtered tracks based on selected theme const filteredTracks = selectedTheme === 'all' ? tracks : tracksByTheme[selectedTheme] || []; const currentTrack = filteredTracks[currentTrackIndex]; const isVideo = currentTrack?.fileName.toLowerCase().endsWith('.mp4'); useEffect(() => { if (mediaRef.current && currentTrack) { mediaRef.current.load(); if (isPlaying) { mediaRef.current.play().catch(err => { console.error('Playback error:', err); setIsPlaying(false); }); } } }, [currentTrackIndex, currentTrack]); // Removed isPlaying from deps to prevent loop const togglePlayPause = () => { if (mediaRef.current) { if (isPlaying) { mediaRef.current.pause(); } else { mediaRef.current.play().catch(err => { console.error('Playback error:', err); }); } setIsPlaying(!isPlaying); } }; const nextTrack = () => { if (filteredTracks.length > 0) { setCurrentTrackIndex((prev) => (prev + 1) % filteredTracks.length); setIsPlaying(true); } }; const prevTrack = () => { if (filteredTracks.length > 0) { setCurrentTrackIndex((prev) => (prev - 1 + filteredTracks.length) % filteredTracks.length); setIsPlaying(true); } }; const handleTimeUpdate = () => { if (mediaRef.current) { setCurrentTime(mediaRef.current.currentTime); setDuration(mediaRef.current.duration || 0); } }; const handleSeek = (e: MouseEvent) => { const rect = e.currentTarget.getBoundingClientRect(); const x = e.clientX - rect.left; const percentage = x / rect.width; if (mediaRef.current) { mediaRef.current.currentTime = percentage * duration; } }; const formatTime = (time: number) => { if (isNaN(time)) return "0:00"; const minutes = Math.floor(time / 60); const seconds = Math.floor(time % 60); return `${minutes}:${seconds.toString().padStart(2, '0')}`; }; const handleThemeChange = (theme: string) => { setSelectedTheme(theme); setCurrentTrackIndex(0); setIsPlaying(false); }; if (loading) { return (
MUSIC STREAM

AUDIO SYSTEM

High-fidelity streaming for the racing community

LOADING TRACKS...

); } if (!currentTrack) { return (
MUSIC STREAM

AUDIO SYSTEM

High-fidelity streaming for the racing community

NO TRACKS AVAILABLE

{error &&

Error: {error}

}
); } return (
{/* Animated Background */}
MUSIC STREAM

AUDIO SYSTEM

High-fidelity streaming for the racing community

{/* Theme Filter */}
FILTER: {themes.map(theme => ( ))}
{/* Main Player Container */}
{/* Left Column - Now Playing */}
{/* Video/Audio Display */}
{isVideo ? ( ) : (
{/* Audio Visualizer */}
{/* Pulsing circles */} {[...Array(3)].map((_, i) => (
))} {/* Center icon */}
{/* Audio element (hidden) */}
)}
{/* Track Info & Controls */}
{/* Track Info */}

{currentTrack.title}

{currentTrack.artist}

{isVideo ? : } {isVideo ? 'VIDEO' : 'AUDIO'}
{currentTrack.theme?.toUpperCase() || 'GENERAL'}
{/* Progress Bar */}
{formatTime(currentTime)} {formatTime(duration)}
{/* Controls */}
{/* Right Column - Playlist */}

PLAYLIST {selectedTheme !== 'all' && ` - ${selectedTheme.toUpperCase()}`}

{filteredTracks.length === 0 ? (
No tracks in this category
) : ( filteredTracks.map((track, index) => ( )) )}
{/* Info Box */}

SYSTEM INFO

FORMAT

MP4 / AUDIO

QUALITY

HIGH FIDELITY

TRACKS

{tracks.length} AVAILABLE

STREAMING

PROGRESSIVE LOAD

{/* Animations */}
); }