feat: enhance mappool integration; include mappool details and average star rating in match views
This commit is contained in:
@@ -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'])
|
||||
});
|
||||
|
||||
|
||||
@@ -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}
|
||||
· <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}
|
||||
· {timeAgo(m.finishedAt ?? m.createdAt)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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}
|
||||
· <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}
|
||||
· {timeAgo(m.finishedAt)}
|
||||
{:else if m.createdAt}
|
||||
|
||||
@@ -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)} · {bm.bpm}bpm · {formatLength(bm.totalLength)}</p>
|
||||
<p class="mt-1 text-center text-xs text-text-secondary">{bm.starRating.toFixed(2)}★ · {bm.bpm}bpm · {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}] · ★{bm.starRating.toFixed(1)} · {bm.bpm}bpm</p>
|
||||
<p class="text-xs text-text-secondary">[{bm.version}] · {bm.starRating.toFixed(2)}★ · {bm.bpm}bpm</p>
|
||||
{:else}
|
||||
<p class="text-xs text-text-secondary">#{slot.beatmapId}</p>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user