// This account's event participation (EVENTS.md §J, Phase 14a). // // **The screen's one real design decision is what an unranked row says.** A run // whose participants were collected but whose results have not been published // has a score and no rank, and that is a real state rather than an error — it is // the same state the admin run console has shown since Phase 10. Rendering "—" // with nothing explaining it would read as a bug; the row says "not published", // which is a fact about the event rather than about the reader. // // The list is keyset-paged on the participation row's own id, not offset-paged: // it gains a row every time the reader attends something. import { useCallback, useState } from 'react' import { Link } from 'react-router-dom' import { Loading, ErrorState, EmptyState } from '../../components/PageState.jsx' import { useAsync } from '../../lib/useAsync.js' import { api } from '../../api/client.js' import { eventDateTime } from '../../lib/eventCalendar.js' const PAGE = 25 export default function PlayerEvents() { const [pages, setPages] = useState([]) const [more, setMore] = useState(false) const [loadingMore, setLoadingMore] = useState(false) const load = useCallback(async () => { const result = await api.player.eventHistory({ limit: PAGE }) setPages([result.entries || []]) setMore((result.entries || []).length === PAGE) return result }, []) const { loading, error } = useAsync(load) const entries = pages.flat() const loadMore = async () => { const last = entries[entries.length - 1] if (!last) return setLoadingMore(true) try { const result = await api.player.eventHistory({ limit: PAGE, before: last.id }) setPages((p) => [...p, result.entries || []]) setMore((result.entries || []).length === PAGE) } finally { setLoadingMore(false) } } if (error) return if (loading) return if (entries.length === 0) { return You have not taken part in an event yet. } return (
{entries.map((e) => (
{e.title}
{eventDateTime(e.scheduledFor, e.timezone)} {e.seriesName && ` · ${e.seriesName}`}
{e.rank != null ? `Rank ${e.rank}` : Results not published}
Score {e.score}
))} {more && ( )}
) }