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

@@ -193,11 +193,6 @@ defineExpose({ reload: load });
<template>
<div class="league-matches-panel">
<div class="panel-toolbar">
<el-button type="primary" size="small" @click="emit('add-match')">
{{ t('match.create_fixture_btn') }}
</el-button>
</div>
<el-table v-loading="loading" :data="matches" stripe row-key="id" class="nested-match-table">
<el-table-column prop="id" label="ID" width="64" />
<el-table-column :label="t('match.col.matchup')" min-width="180">
@@ -229,7 +224,15 @@ defineExpose({ reload: load });
<span v-else class="bet-stat-zero">0</span>
</template>
</el-table-column>
<el-table-column :label="t('common.actions')" width="460" align="center">
<el-table-column width="460" align="center">
<template #header>
<div class="actions-col-header">
<span class="actions-col-header__label">{{ t('common.actions') }}</span>
<el-button type="primary" size="small" @click.stop="emit('add-match')">
{{ t('match.create_fixture_btn') }}
</el-button>
</div>
</template>
<template #default="{ row }">
<div class="action-btns">
<div class="action-group">
@@ -299,8 +302,41 @@ defineExpose({ reload: load });
padding: 10px 12px 12px;
background: #0a0a0a;
}
.panel-toolbar {
margin-bottom: 8px;
.actions-col-header {
display: inline-flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 8px;
padding: 0 4px;
box-sizing: border-box;
white-space: nowrap;
}
.actions-col-header__label {
font-size: 12px;
font-weight: 600;
color: #aaa;
line-height: 1;
}
.actions-col-header :deep(.el-button) {
margin: 0 !important;
padding: 6px 10px !important;
height: 28px !important;
min-height: 28px !important;
font-size: 12px !important;
font-weight: 600;
border-radius: 6px;
white-space: nowrap;
}
.nested-match-table :deep(.el-table__header .el-table__cell) {
padding: 6px 0;
}
.nested-match-table :deep(.el-table__header .cell) {
overflow: visible;
}
.empty-hint {
font-size: 12px;
@@ -338,5 +374,15 @@ defineExpose({ reload: load });
min-width: 52px;
padding: 4px 10px !important;
font-size: 12px !important;
border-radius: 6px;
}
.action-btns :deep(.el-button:not(.is-disabled):not(:disabled)) {
cursor: pointer;
}
.action-btns :deep(.el-button.is-disabled),
.action-btns :deep(.el-button:disabled) {
cursor: not-allowed;
}
</style>