import React, { useEffect, useMemo, useState } from 'react'; import Room from './Room.jsx'; import { ToastProvider, useToasts } from './Toasts.jsx'; import { log } from './logger.js'; import { prettyError } from './utils.js'; function Lobby({ onEnter }) { const { push } = useToasts(); const [name, setName] = useState(''); const [rooms, setRooms] = useState([]); const [loading, setLoading] = useState(false); const [creating, setCreating] = useState(false); const [newRoomName, setNewRoomName] = useState(''); const [newRoomId, setNewRoomId] = useState(''); const fetchRooms = async () => { try { setLoading(true); const res = await fetch('/api/rooms'); const json = await res.json(); setRooms(json.rooms || []); setLoading(false); } catch (e) { setLoading(false); log.error(e); push(`Failed to fetch rooms: ${prettyError(e)}`, 'bad', 4000); } }; useEffect(() => { fetchRooms(); const t = setInterval(fetchRooms, 5000); return () => clearInterval(t); }, []); const canEnter = useMemo(() => name.trim().length >= 2, [name]); return (
Your name
setName(e.target.value)} placeholder="DJ Neo" />
Your name appears in the party member list.
Create a new party
setNewRoomName(e.target.value)} />
setNewRoomId(e.target.value.replace(/\s+/g, '-'))} />
Active parties
{rooms.length === 0 ? (
No active parties yet. Create one above.
) : (
{rooms.map(r => (
{r.name}
ID: {r.id} · Members: {r.members} · {r.isPlaying ? 'Playing' : 'Paused'}
))}
)}
); } function Shell({ children }) { return (
Neon Party
{children}
); } export default function App() { const [session, setSession] = useState(null); if (session) { return ( ); } return ( ); }