feat: split admin dashboard, improve match ops, and player closed-match UX

Admin: add match/player overview sub-nav; refine settlement flow and league
match management UI; improve action button enabled/disabled styles; enhance
logo upload and outright odds sync.

API: expose matchPhase/bettingOpen for closed matches; league publish guards;
settlement preview with auto score save; outright team auto-sync.

Player: watermark for closed/settled states; keep match and bet details visible;
remove default login credentials.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-10 13:00:14 +08:00
parent 6124313369
commit 03f54ca689
43 changed files with 2787 additions and 519 deletions

View File

@@ -11,6 +11,7 @@ const props = defineProps<{
}[];
isSelected: (id: string) => boolean;
compact?: boolean;
locked?: boolean;
}>();
const emit = defineEmits<{ pick: [id: string] }>();
@@ -22,18 +23,24 @@ function label(sel: (typeof props.selections)[number]) {
}
return sel.selectionName;
}
function onPick(id: string) {
if (props.locked) return;
emit('pick', id);
}
</script>
<template>
<div class="wrap" :class="{ compact }">
<div class="wrap" :class="{ compact, locked }">
<div class="panel">
<button
v-for="sel in selections"
:key="sel.id"
type="button"
class="odds-btn"
:class="{ selected: isSelected(sel.id) }"
@click="emit('pick', sel.id)"
:class="{ selected: isSelected(sel.id), 'odds-btn--locked': locked }"
:disabled="locked"
@click="onPick(sel.id)"
>
<span class="label">{{ label(sel) }}</span>
<span class="odds">{{ sel.odds }}</span>
@@ -48,6 +55,10 @@ function label(sel: (typeof props.selections)[number]) {
background: #0c0c0c;
}
.wrap.locked {
opacity: 0.78;
}
.panel {
display: grid;
grid-template-columns: repeat(3, 1fr);
@@ -73,6 +84,17 @@ function label(sel: (typeof props.selections)[number]) {
background: rgba(212, 175, 55, 0.1);
}
.odds-btn--locked {
background: #111;
border-color: #333;
cursor: not-allowed;
}
.odds-btn--locked .label,
.odds-btn--locked .odds {
color: #666;
}
.label {
font-size: 9px;
color: var(--text-muted);