feat: Add event collection and event page structure
All checks were successful
SteamWarCI Build successful
All checks were successful
SteamWarCI Build successful
- Introduced a new events collection in config.ts with schema validation. - Created a new event markdown file for the WarGear event. - Updated German translations to include new event-related strings. - Modified PageLayout to support a wide layout option. - Enhanced announcements page to improve tag filtering and post rendering. - Implemented dynamic event pages with detailed event information and fight plans. - Added an index page for events to list all upcoming events.
This commit is contained in:
70
src/components/event/GroupDisplay.svelte
Normal file
70
src/components/event/GroupDisplay.svelte
Normal file
@@ -0,0 +1,70 @@
|
||||
<script lang="ts">
|
||||
import type { EventFight, ExtendedEvent, ResponseGroups } from "@type/event.ts";
|
||||
import type { GroupViewConfig } from "./types";
|
||||
import EventCard from "./EventCard.svelte";
|
||||
import EventCardOutline from "./EventCardOutline.svelte";
|
||||
import EventTeamChip from "./EventTeamChip.svelte";
|
||||
import EventFightChip from "./EventFightChip.svelte";
|
||||
|
||||
const {
|
||||
event,
|
||||
config,
|
||||
}: {
|
||||
event: ExtendedEvent;
|
||||
config: GroupViewConfig;
|
||||
} = $props();
|
||||
|
||||
// Groups fights into rounds: a round starts at the first fight's start;
|
||||
// all fights starting within 10 minutes (600_000 ms) of that are in the same round.
|
||||
function detectRounds(fights: EventFight[]): EventFight[][] {
|
||||
if (!fights || fights.length === 0) return [];
|
||||
|
||||
const TEN_MIN_MS = 10 * 60 * 1000;
|
||||
const sorted = [...fights].sort((a, b) => a.start - b.start);
|
||||
|
||||
const rounds: EventFight[][] = [];
|
||||
let currentRound: EventFight[] = [];
|
||||
let roundStart = sorted[0].start;
|
||||
|
||||
for (const fight of sorted) {
|
||||
if (fight.start - roundStart <= TEN_MIN_MS) {
|
||||
currentRound.push(fight);
|
||||
} else {
|
||||
if (currentRound.length) rounds.push(currentRound);
|
||||
currentRound = [fight];
|
||||
roundStart = fight.start;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentRound.length) rounds.push(currentRound);
|
||||
return rounds;
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each config.groups as groupId}
|
||||
{@const group = event.groups.find((g) => g.id === groupId)!!}
|
||||
{@const fights = event.fights.filter((f) => f.group?.id === groupId)}
|
||||
{@const rounds = detectRounds(fights)}
|
||||
<div class="flex">
|
||||
<div>
|
||||
<EventCard title={group.name}>
|
||||
<EventCardOutline>
|
||||
{#each Object.entries(group.points ?? {}).toSorted((v1, v2) => v2[1] - v1[1]) as points}
|
||||
{@const [teamId, point] = points}
|
||||
{@const team = event.teams.find((t) => t.id.toString() === teamId)!!}
|
||||
<EventTeamChip {team} score={point.toString()} />
|
||||
{/each}
|
||||
</EventCardOutline>
|
||||
</EventCard>
|
||||
</div>
|
||||
{#each rounds as round, index}
|
||||
<div>
|
||||
<EventCard title="Runde {index + 1}">
|
||||
{#each round as fight}
|
||||
<EventFightChip {fight} {group} />
|
||||
{/each}
|
||||
</EventCard>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
Reference in New Issue
Block a user