feat: enhance mappool integration; include mappool details and average star rating in match views

This commit is contained in:
2026-03-01 19:39:13 +01:00
parent f399f1d546
commit f14cce8769
7 changed files with 28 additions and 8 deletions

View File

@@ -18,13 +18,13 @@ export const load: PageServerLoad = async ({ locals }) => {
// ── LOGGED IN → dashboard data ──
const recentMatches = await db.query.match.findMany({
with: { participants: { with: { team: true } } },
with: { participants: { with: { team: true } }, mappool: { with: { slots: true } } },
orderBy: desc(match.createdAt),
limit: 5
});
const liveMatches = await db.query.match.findMany({
with: { participants: { with: { team: true } } },
with: { participants: { with: { team: true } }, mappool: { with: { slots: true } } },
where: inArray(match.state, ['LOBBY', 'ROLLING', 'PICKING', 'PLAYING'])
});

View File

@@ -76,6 +76,13 @@
return () => clearInterval(id);
});
function avgSR(mappool: any): string | null {
const slots = mappool?.slots;
if (!slots?.length) return null;
const avg = slots.reduce((s: number, sl: any) => s + (sl.starRating ?? 0), 0) / slots.length;
return avg.toFixed(2);
}
function timeAgo(date: string | Date) {
const d = new Date(date);
const diff = Date.now() - d.getTime();
@@ -335,6 +342,9 @@
</div>
<p class="mt-0.5 text-xs text-text-secondary">
{m.name ? `${m.name} · ` : ''}BO{config.bestOf}
{#if m.mappool}
&middot; <a href='/mappools/{m.mappool.id}' onclick={(e) => e.stopPropagation()} class='hover:text-accent hover:underline'>{m.mappool.name}</a>{#if avgSR(m.mappool)} <span>{avgSR(m.mappool)}★</span>{/if}
{/if}
&middot; {timeAgo(m.finishedAt ?? m.createdAt)}
</p>
</div>

View File

@@ -63,7 +63,7 @@
<h2 class="text-sm font-600">{pool.name}</h2>
<p class="mt-1 text-xs text-text-secondary">
{pool.slots.length} map{pool.slots.length !== 1 ? 's' : ''}
{#if avgSr}· ★ {avgSr}{/if}
{#if avgSr}· {avgSr}★{/if}
· Created {new Date(pool.createdAt).toLocaleDateString()}
</p>
</div>

View File

@@ -242,7 +242,7 @@
</a>
<div class="mt-0.5 flex items-center gap-3 text-xs text-text-secondary">
<span>[{slot.beatmap.version}]</span>
<span>★ {slot.beatmap.starRating.toFixed(2)}</span>
<span>{slot.beatmap.starRating.toFixed(2)}★</span>
<span>{slot.beatmap.bpm} BPM</span>
<span>{formatLength(slot.beatmap.totalLength)}</span>
</div>

View File

@@ -11,7 +11,7 @@ export const load: PageServerLoad = async ({ locals }) => {
requireAuth(locals);
const matches = await db.query.match.findMany({
with: { participants: { with: { team: true } } },
with: { participants: { with: { team: true } }, mappool: { with: { slots: true } } },
orderBy: desc(match.createdAt),
limit: 50
});

View File

@@ -39,6 +39,13 @@
return { p1, p2 };
}
function avgSR(mappool: any): string | null {
const slots = mappool?.slots;
if (!slots?.length) return null;
const avg = slots.reduce((s: number, sl: any) => s + (sl.starRating ?? 0), 0) / slots.length;
return avg.toFixed(2);
}
function timeAgo(date: string | Date) {
const d = new Date(date);
const diff = Date.now() - d.getTime();
@@ -281,6 +288,9 @@
</div>
<p class="mt-0.5 text-xs text-text-secondary">
{m.name ? `${m.name} · ` : ''}BO{config.bestOf}
{#if m.mappool}
&middot; <a href='/mappools/{m.mappool.id}' onclick={(e) => e.stopPropagation()} class='hover:text-accent hover:underline'>{m.mappool.name}</a>{#if avgSR(m.mappool)} <span>{avgSR(m.mappool)}★</span>{/if}
{/if}
{#if m.finishedAt}
&middot; {timeAgo(m.finishedAt)}
{:else if m.createdAt}

View File

@@ -304,7 +304,7 @@
</div>
{#if bm}
<p class="mt-2 text-center text-sm">{bm.artist} - {bm.title} <span class="text-text-secondary">[{bm.version}]</span></p>
<p class="mt-1 text-center text-xs text-text-secondary">★{bm.starRating.toFixed(1)} &middot; {bm.bpm}bpm &middot; {formatLength(bm.totalLength)}</p>
<p class="mt-1 text-center text-xs text-text-secondary">{bm.starRating.toFixed(2)}★ &middot; {bm.bpm}bpm &middot; {formatLength(bm.totalLength)}</p>
{/if}
<!-- Per-player lobby status -->
@@ -370,7 +370,7 @@
{/if}
</h2>
{#if mappoolAvgSR()}
<span class="text-xs text-text-secondary">avg ★{mappoolAvgSR()}</span>
<span class="text-xs text-text-secondary">avg {mappoolAvgSR()}★</span>
{/if}
{#if pickingPhase}
<span class="rounded bg-blue-500/20 px-2 py-0.5 text-[10px] font-600 text-blue-400">
@@ -452,7 +452,7 @@
<div class="min-w-0 flex-1">
{#if bm}
<p class="truncate text-xs font-500">{bm.artist} - {bm.title}</p>
<p class="text-xs text-text-secondary">[{bm.version}] &middot; ★{bm.starRating.toFixed(1)} &middot; {bm.bpm}bpm</p>
<p class="text-xs text-text-secondary">[{bm.version}] &middot; {bm.starRating.toFixed(2)}★ &middot; {bm.bpm}bpm</p>
{:else}
<p class="text-xs text-text-secondary">#{slot.beatmapId}</p>
{/if}