{t.name} — Vash Esports

{t.name}

{t.state}
{#if t.description}

{t.description}

{/if}

{formatLabels[t.format] ?? t.format} · {activeRegs.length}/{t.maxSlots} players {#if t.startAt} · starts {new Date(t.startAt).toLocaleDateString()} {/if}

{#if actionError}
{actionError}
{/if} {#if actionSuccess}
{actionSuccess}
{/if} {#if t.state === 'REGISTRATION' && !data.isStaff}
{#if data.userRegistration}
You are registered with {data.userRegistration.team?.name ?? 'your team'}
handleAction()}>
{:else if data.userTeams.length > 0}
handleAction()} class="flex items-center gap-3" > Register as:
{:else}

You need a team to register for this tournament

{/if}
{/if}
{#each tabs() as [value, label]} {/each}
{#if activeTab === 'overview'} {@render overviewTab()} {:else if activeTab === 'bracket'} {@render bracketTab()} {:else if activeTab === 'registrations'} {@render registrationsTab()} {:else if activeTab === 'rounds'} {@render roundsTab()} {:else if activeTab === 'groups'} {@render groupsTab()} {:else if activeTab === 'settings'} {@render settingsTab()} {/if}
{#snippet overviewTab()}

Details

Format
{formatLabels[t.format] ?? t.format}
Players
{activeRegs.length} / {t.maxSlots}
Team Size
{(t.config as any)?.teamSize ?? 1}v{(t.config as any)?.teamSize ?? 1}
Scoring
{(t.config as any)?.scoringType ?? 'score_v2'}
Rounds
{t.rounds.length}
{#if t.startAt}
Start Date
{new Date(t.startAt).toLocaleString()}
{/if}

Staff

{#if t.staff.length === 0}

No staff assigned

{:else}
{#each t.staff as s}
{s.userId.slice(0, 8)}... {s.role}
{/each}
{/if}

Invite Players

Share this link with players to let them register

{#if t.rounds.length > 0}

Rounds

{#each t.rounds as round}
{round.abbreviation ?? round.name} BO{round.bestOf} {#if round.mappool} · {round.mappool.name} {:else} no pool {/if}
{/each}
{/if}
{/snippet} {#snippet bracketTab()} {#if matches.length === 0}

Bracket has not been generated yet

{:else} {#if wbRounds.length > 0} {#if t.format === 'double_elim'}

Winners Bracket

{/if}
{#each wbRounds as { round, matches: roundMatches }}
{round?.name ?? 'Round'}
{#each roundMatches.sort((a: any, b: any) => a.bracketPosition - b.bracketPosition) as m} {@render matchCard(m)} {/each}
{/each}
{/if} {#if lbRounds.length > 0}

Losers Bracket

{#each lbRounds as { round, matches: roundMatches }}
{round?.name ?? 'Round'}
{#each roundMatches.sort((a: any, b: any) => a.bracketPosition - b.bracketPosition) as m} {@render matchCard(m)} {/each}
{/each}
{/if} {#if gfMatches.length > 0}

Grand Finals

{#each gfMatches.sort((a: any, b: any) => (a.round?.roundOrder ?? 0) - (b.round?.roundOrder ?? 0)) as m} {@render matchCard(m)} {/each}
{/if} {/if} {/snippet} {#snippet registrationsTab()}
{#if t.registrations.length === 0}
No registrations yet
{:else} {#each t.registrations as reg} {/each}
Seed Team Status Registered
{reg.seed ?? '-'} {reg.team?.name ?? 'Unknown'} {reg.status} {new Date(reg.registeredAt).toLocaleDateString()}
{/if}
{/snippet} {#snippet roundsTab()}
{#if t.rounds.length === 0 && !showAddRound}

No rounds configured yet

{#if data.isStaff && t.state === 'DRAFT'} {/if}
{:else} {#each t.rounds as round} {#if editingRoundId === round.id && data.isStaff}
handleActionWithMessage('Round updated')} class="rounded-lg border border-accent/20 bg-surface-800 p-4" >
Name
Abbreviation
Best Of
Mappool
Scheduled At
{:else}
{round.name} {#if round.abbreviation} {round.abbreviation} {/if} BO{round.bestOf}
{#if round.mappool} {round.mappool.name} ({round.mappool.slots.length} maps) {:else} no mappool {/if} {#if round.scheduledAt} {new Date(round.scheduledAt).toLocaleString()} {/if} {#if data.isStaff && t.state === 'DRAFT'}
handleActionWithMessage('Round deleted')} >
{/if}
{/if} {/each} {/if} {#if data.isStaff && t.state === 'DRAFT'} {#if showAddRound}
handleActionWithMessage('Round added')} class="rounded-lg border border-accent/20 bg-surface-800 p-4" >

Add Round

Name
Abbreviation
Best Of
Mappool
Scheduled At (optional)
{:else if t.rounds.length > 0} {/if} {/if}
{/snippet} {#snippet groupsTab()}
{#each t.groups as group}

{group.name}

{#each group.entries.sort((a: any, b: any) => b.wins - a.wins || b.mapWins - b.mapLosses - (a.mapWins - a.mapLosses)) as entry} {/each}
Team W L MD
{entry.team?.name ?? 'TBD'} {entry.wins} {entry.losses} {entry.mapWins - entry.mapLosses > 0 ? '+' : ''}{entry.mapWins - entry.mapLosses}
{/each}
{/snippet} {#snippet settingsTab()}

Tournament Actions

Manage the tournament state and lifecycle

{#if t.state === 'DRAFT'}
handleAction()}>
{/if} {#if t.state === 'REGISTRATION'}
handleAction()}>
{/if} {#if t.state === 'SEEDING' || t.state === 'QUALIFIERS'}
handleAction()}>
{/if} {#if t.state !== 'FINISHED' && t.state !== 'CANCELLED'}
handleAction()}>
{/if} {#if t.state === 'FINISHED' || t.state === 'CANCELLED'}

This tournament has ended

{/if}
{#if t.state === 'DRAFT' && t.rounds.length === 0}

You need to add at least one round before opening registration

{/if}

Staff

{#each t.staff as s}
{s.userId.slice(0, 8)}... {s.role}
{#if t.staff.length > 1}
handleActionWithMessage('Staff removed')} >
{/if}
{/each}

Info

ID
{t.id}
Created
{new Date(t.createdAt).toLocaleString()}
{#if t.registrationOpenAt}
Registration Opened
{new Date(t.registrationOpenAt).toLocaleString()}
{/if} {#if t.finishedAt}
Finished
{new Date(t.finishedAt).toLocaleString()}
{/if}
{/snippet} {#snippet matchCard(m: any)}
{m.team1?.name ?? 'TBD'} {#if m.match?.participants} {@const p = m.match.participants.find((p: any) => p.teamId === m.team1Id)} {#if p} {p.score} {/if} {/if}
{m.team2?.name ?? 'TBD'} {#if m.match?.participants} {@const p = m.match.participants.find((p: any) => p.teamId === m.team2Id)} {#if p} {p.score} {/if} {/if}
{#if m.state === 'LIVE'}
LIVE
{:else if m.state === 'BYE'}
BYE
{:else if m.matchId} View Match {/if}
{/snippet}