// frontend/src/pages/Dashboard.jsx
import { Calendar, ChevronDown, ChevronUp, History, Plus, SlidersHorizontal, Users, MapPin, Clock } from 'lucide-react';
import { useEffect, useState } from 'react';
import { useNavigate, useOutletContext } from 'react-router-dom';
import TournamentForm from '../components/Forms/TournamentForm';
import Modal from '../components/UI/Modal';
import api, { WS_URL } from '../services/api';
// --- RESTORED DASHCARD DESIGN ---
const DashCard = ({ t, isAdmin, onSelect, onEdit }) => (
onSelect(t.id)}
className="block bg-white dark:bg-zinc-900 p-6 rounded-xl shadow-sm border border-zinc-200 dark:border-zinc-800 relative group hover:shadow-md hover:scale-[1.02] transition-all duration-200 will-change-transform transform-gpu cursor-pointer"
>
{t.name}
{/* Parse date safely */}
{t.timestamp ? new Date(t.timestamp).toLocaleDateString() : 'TBD'}
{t.timestamp ? new Date(t.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : ''}
{t.type}
{t.team_count} Teams
{t.court_count} Courts
{isAdmin && (
)}
);
export default function Dashboard() {
const { setNavTitle, setNavSubtitle, isAdmin, showSettings, setShowSettings } = useOutletContext();
const [tournaments, setTournaments] = useState([]);
const [editTarget, setEditTarget] = useState(null);
const [showPast, setShowPast] = useState(false);
const [showAllFuture, setShowAllFuture] = useState(false);
const navigate = useNavigate();
const loadDashboard = async () => {
try {
const res = await api.get('/tournaments');
const list = Array.isArray(res) ? res : (res.items || []);
setTournaments(list);
} catch (e) { console.error(e); }
};
useEffect(() => {
setNavTitle('Dashboard');
setNavSubtitle('');
loadDashboard();
let ws;
const connect = () => {
try {
ws = new WebSocket(WS_URL);
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'dashboard_update') loadDashboard();
};
} catch (err) { }
};
connect();
return () => { if (ws) ws.close(); };
}, []);
const handleEdit = (t) => {
setEditTarget(t);
setShowSettings(true);
};
const handleSuccess = () => {
setShowSettings(false);
setEditTarget(null);
loadDashboard();
};
const handleDelete = async (id) => {
if (window.confirm("Purge this tournament and all its history?")) {
await api.delete(`/tournaments/${id}`);
handleSuccess();
}
};
// Grouping Logic
const now = new Date();
const groups = { live: [], future: [], past: [] };
tournaments.forEach(t => {
const tDate = new Date(t.timestamp);
const isToday = tDate.toDateString() === now.toDateString();
if (tDate > now && !isToday) groups.future.push(t);
else if (isToday) groups.live.push(t);
else groups.past.push(t);
});
groups.future.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
groups.live.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
groups.past.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
const futureShow = showAllFuture ? groups.future : groups.future.slice(0, 4);
return (
{/* Create Button */}
{isAdmin && (
)}
{groups.live.length > 0 && (
Live Events
{groups.live.map(t => navigate(`/tournaments/${id}`)} onEdit={handleEdit} />)}
)}
Upcoming
{groups.future.length > 0 ? (
<>
{futureShow.map(t => navigate(`/tournaments/${id}`)} onEdit={handleEdit} />)}
{groups.future.length > 4 && (
)}
>
) : No Upcoming Events
}
{groups.past.length > 0 && (
{showPast && (
{groups.past.map(t => navigate(`/tournaments/${id}`)} onEdit={handleEdit} />)}
)}
)}
{ setShowSettings(false); setEditTarget(null); }} title={editTarget ? 'Modify Event' : 'Initialize Event'}>
);
}