Add gameday TeamSnap loading state
This commit is contained in:
@@ -60,6 +60,8 @@ export function GamedayPage() {
|
||||
const [playerFilterMenuOpen, setPlayerFilterMenuOpen] = useState(false);
|
||||
const playerFilterMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
const teamId = walkup.selectedTeamId;
|
||||
const resolvedSelectedGameId =
|
||||
selectedGameId || searchParams.get("gameId") || (walkup.nextGame ? String(walkup.nextGame.id) : "");
|
||||
const {
|
||||
activeKey: playingClipKey,
|
||||
activeDetails: nowPlaying,
|
||||
@@ -111,25 +113,25 @@ export function GamedayPage() {
|
||||
}, [playerFilterMenuOpen]);
|
||||
|
||||
const assignmentsQuery = useQuery({
|
||||
queryKey: ["assignments", selectedGameId],
|
||||
queryFn: () => api.listAssignments(selectedGameId),
|
||||
enabled: Boolean(selectedGameId),
|
||||
queryKey: ["assignments", resolvedSelectedGameId],
|
||||
queryFn: () => api.listAssignments(resolvedSelectedGameId),
|
||||
enabled: Boolean(resolvedSelectedGameId),
|
||||
retry: 0,
|
||||
});
|
||||
|
||||
const preparedGame = selectedGameId ? loadPreparedGame(selectedGameId) : null;
|
||||
const preparedGame = resolvedSelectedGameId ? loadPreparedGame(resolvedSelectedGameId) : null;
|
||||
const assignmentList = assignmentsQuery.data ?? preparedGame?.assignments ?? [];
|
||||
|
||||
const eventLineupQuery = useQuery({
|
||||
queryKey: ["teamsnap", "eventLineup", teamId, selectedGameId],
|
||||
queryFn: () => teamsnapClient.loadEventLineupData(teamId, selectedGameId),
|
||||
enabled: Boolean(teamId && selectedGameId),
|
||||
queryKey: ["teamsnap", "eventLineup", teamId, resolvedSelectedGameId],
|
||||
queryFn: () => teamsnapClient.loadEventLineupData(teamId, resolvedSelectedGameId),
|
||||
enabled: Boolean(teamId && resolvedSelectedGameId),
|
||||
});
|
||||
|
||||
const availabilityQuery = useQuery({
|
||||
queryKey: ["teamsnap", "availabilities", teamId, selectedGameId],
|
||||
queryFn: () => teamsnapClient.loadAvailabilities(teamId, selectedGameId),
|
||||
enabled: Boolean(teamId && selectedGameId),
|
||||
queryKey: ["teamsnap", "availabilities", teamId, resolvedSelectedGameId],
|
||||
queryFn: () => teamsnapClient.loadAvailabilities(teamId, resolvedSelectedGameId),
|
||||
enabled: Boolean(teamId && resolvedSelectedGameId),
|
||||
});
|
||||
|
||||
const orderedMembers = useMemo(
|
||||
@@ -147,7 +149,12 @@ export function GamedayPage() {
|
||||
? orderedMembers
|
||||
: orderedMembers.filter((member) => (playerFilter === "players" ? isPlayerMember(member) : !isPlayerMember(member)));
|
||||
|
||||
const selectedGame = walkup.games.find((game) => String(game.id) === selectedGameId) ?? null;
|
||||
const selectedGame = walkup.games.find((game) => String(game.id) === resolvedSelectedGameId) ?? null;
|
||||
const isLoadingTeamSnapData =
|
||||
walkup.teamsQuery.isLoading ||
|
||||
walkup.membersQuery.isLoading ||
|
||||
walkup.eventsQuery.isLoading ||
|
||||
(Boolean(teamId && resolvedSelectedGameId) && (eventLineupQuery.isLoading || availabilityQuery.isLoading));
|
||||
|
||||
function selectGame(gameId: string) {
|
||||
setSelectedGameId(gameId);
|
||||
@@ -168,6 +175,21 @@ export function GamedayPage() {
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoadingTeamSnapData) {
|
||||
return (
|
||||
<section className="page-grid gameday-page">
|
||||
<div className="panel gameday-loading-panel" role="status" aria-live="polite">
|
||||
<div className="gameday-loading-spinner spinner-border text-primary" aria-hidden="true" />
|
||||
<div className="gameday-loading-copy">
|
||||
<span className="gameday-loading-label">Waiting for TeamSnap</span>
|
||||
<strong>Loading gameday data</strong>
|
||||
<span className="muted">Teams, games, roster data, and lineup details are being fetched.</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="page-grid gameday-page">
|
||||
{isPlaybackPlaying && nowPlaying ? (
|
||||
|
||||
@@ -279,6 +279,35 @@ select {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.gameday-loading-panel {
|
||||
min-height: min(42vh, 24rem);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
gap: 1rem;
|
||||
text-align: center;
|
||||
padding: 2rem 1.5rem;
|
||||
}
|
||||
|
||||
.gameday-loading-spinner {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
border-width: 0.28rem;
|
||||
}
|
||||
|
||||
.gameday-loading-copy {
|
||||
display: grid;
|
||||
gap: 0.35rem;
|
||||
max-width: 24rem;
|
||||
}
|
||||
|
||||
.gameday-loading-label {
|
||||
color: var(--accent);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
|
||||
Reference in New Issue
Block a user