重构
This commit is contained in:
@@ -7,6 +7,10 @@ import api from '../../api';
|
||||
import MatchArchiveDialog from '../../components/MatchArchiveDialog.vue';
|
||||
import { ensureLeagueExpanded } from '../../utils/matchesListState';
|
||||
import { formatAmount } from '../../utils/format-amount';
|
||||
import {
|
||||
formatPlatformMatchDateTime,
|
||||
platformPickerDateTimeToIso,
|
||||
} from '@thebet365/shared';
|
||||
const props = defineProps<{
|
||||
leagueId: string;
|
||||
filterStatus: string;
|
||||
@@ -180,7 +184,7 @@ function matchId(row: unknown) {
|
||||
return String(rowOf(row).id ?? '');
|
||||
}
|
||||
function matchTime(row: unknown) {
|
||||
return new Date(String(rowOf(row).startTime)).toLocaleString();
|
||||
return formatPlatformMatchDateTime(String(rowOf(row).startTime), locale.value);
|
||||
}
|
||||
function betCount(row: unknown) {
|
||||
return Number(rowOf(row).betCount ?? 0);
|
||||
@@ -260,6 +264,13 @@ async function promptReopenKickoff(): Promise<string | null> {
|
||||
},
|
||||
t('match.reopen_kickoff_hint'),
|
||||
),
|
||||
h(
|
||||
'p',
|
||||
{
|
||||
style: 'margin: 0 0 12px; font-size: 12px; color: var(--el-text-color-secondary)',
|
||||
},
|
||||
t('match.timezone.platform_hint'),
|
||||
),
|
||||
h(ElDatePicker, {
|
||||
modelValue: kickoff.value,
|
||||
'onUpdate:modelValue': (v: string) => {
|
||||
@@ -275,7 +286,8 @@ async function promptReopenKickoff(): Promise<string | null> {
|
||||
cancelButtonText: t('common.cancel'),
|
||||
beforeClose: (action, _instance, done) => {
|
||||
if (action === 'confirm') {
|
||||
if (!kickoff.value || new Date(kickoff.value) <= new Date()) {
|
||||
const iso = kickoff.value ? platformPickerDateTimeToIso(kickoff.value) : '';
|
||||
if (!iso || Number.isNaN(new Date(iso).getTime()) || new Date(iso) <= new Date()) {
|
||||
ElMessage.warning(t('match.reopen_kickoff_invalid'));
|
||||
return;
|
||||
}
|
||||
@@ -283,7 +295,7 @@ async function promptReopenKickoff(): Promise<string | null> {
|
||||
done();
|
||||
},
|
||||
});
|
||||
return kickoff.value || null;
|
||||
return kickoff.value ? platformPickerDateTimeToIso(kickoff.value) : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
@@ -316,6 +328,11 @@ defineExpose({ reload: load });
|
||||
|
||||
<template>
|
||||
<div class="league-matches-panel">
|
||||
<div class="nested-panel-toolbar">
|
||||
<el-button type="primary" size="small" @click.stop="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">
|
||||
@@ -328,7 +345,7 @@ defineExpose({ reload: load });
|
||||
<el-tag :type="matchStatusType(row)" size="small">{{ matchStatusLabel(row) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('match.col.kickoff')" min-width="150">
|
||||
<el-table-column :label="t('match.col.kickoff')" min-width="190">
|
||||
<template #default="{ row }">{{ matchTime(row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('match.col.bet_count')" width="72" align="center">
|
||||
@@ -347,18 +364,15 @@ defineExpose({ reload: load });
|
||||
<span v-else class="bet-stat-zero">0</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="460" align="center">
|
||||
<el-table-column width="256" 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">
|
||||
<div class="action-row action-row--primary">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@@ -371,13 +385,12 @@ defineExpose({ reload: load });
|
||||
size="small"
|
||||
type="primary"
|
||||
plain
|
||||
class="action-btn--markets"
|
||||
:disabled="!canManage(row)"
|
||||
@click="openMarkets(matchId(row))"
|
||||
>
|
||||
{{ t('match.btn.markets') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="action-group">
|
||||
<el-button
|
||||
v-if="canPublishRow(row)"
|
||||
size="small"
|
||||
@@ -394,6 +407,8 @@ defineExpose({ reload: load });
|
||||
>
|
||||
{{ t('match.btn.unpublish') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="action-row action-row--workflow">
|
||||
<el-button
|
||||
size="small"
|
||||
type="warning"
|
||||
@@ -419,15 +434,15 @@ defineExpose({ reload: load });
|
||||
>
|
||||
{{ settleButtonLabel(row) }}
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
plain
|
||||
@click="confirmDelete(row)"
|
||||
>
|
||||
{{ t('common.delete') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
plain
|
||||
@click="confirmDelete(row)"
|
||||
>
|
||||
{{ t('common.delete') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -456,8 +471,17 @@ defineExpose({ reload: load });
|
||||
|
||||
<style scoped>
|
||||
.league-matches-panel {
|
||||
width: min(100%, calc(100vw - 272px));
|
||||
max-width: calc(100vw - 272px);
|
||||
padding: 10px 12px 12px;
|
||||
background: #0a0a0a;
|
||||
overflow: hidden;
|
||||
background: #fbfaf7;
|
||||
}
|
||||
.nested-panel-toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.nested-pager {
|
||||
display: flex;
|
||||
@@ -477,8 +501,8 @@ defineExpose({ reload: load });
|
||||
|
||||
.actions-col-header__label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #aaa;
|
||||
font-weight: 700;
|
||||
color: var(--text-muted);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -502,43 +526,70 @@ defineExpose({ reload: load });
|
||||
}
|
||||
.empty-hint {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--text-muted);
|
||||
margin: 8px 0 0;
|
||||
}
|
||||
.matchup-link {
|
||||
color: var(--green-text);
|
||||
color: var(--primary-link);
|
||||
}
|
||||
.bet-stat-active {
|
||||
color: var(--green-text);
|
||||
color: var(--success-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.bet-stat-zero {
|
||||
color: #555;
|
||||
color: #aaa49a;
|
||||
}
|
||||
.action-btns {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
display: grid;
|
||||
grid-template-rows: repeat(2, 26px);
|
||||
align-items: center;
|
||||
gap: 6px 8px;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
.action-group {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
.action-row {
|
||||
display: inline-grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: max-content;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
min-width: 0;
|
||||
padding: 2px 4px;
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
background: #ffffff;
|
||||
border: 1px solid var(--border-soft);
|
||||
}
|
||||
.action-row--primary {
|
||||
background: #fbfaf7;
|
||||
}
|
||||
.action-row--workflow {
|
||||
background: #ffffff;
|
||||
}
|
||||
.action-btns :deep(.el-button) {
|
||||
margin: 0 !important;
|
||||
min-width: 52px;
|
||||
padding: 4px 10px !important;
|
||||
min-width: 48px;
|
||||
height: 22px !important;
|
||||
min-height: 22px !important;
|
||||
padding: 0 9px !important;
|
||||
font-size: 12px !important;
|
||||
line-height: 1 !important;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.action-btns :deep(.action-btn--markets:not(.is-disabled):not(:disabled)) {
|
||||
background: var(--info-bg) !important;
|
||||
border-color: var(--info-border) !important;
|
||||
color: var(--info-text) !important;
|
||||
}
|
||||
|
||||
.action-btns :deep(.action-btn--markets:not(.is-disabled):not(:disabled):hover),
|
||||
.action-btns :deep(.action-btn--markets:not(.is-disabled):not(:disabled):focus) {
|
||||
background: #d5ecfb !important;
|
||||
border-color: #9fd0ed !important;
|
||||
color: #155b86 !important;
|
||||
}
|
||||
|
||||
.action-btns :deep(.el-button:not(.is-disabled):not(:disabled)) {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -547,4 +598,21 @@ defineExpose({ reload: load });
|
||||
.action-btns :deep(.el-button:disabled) {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.league-matches-panel {
|
||||
width: calc(100vw - 32px);
|
||||
max-width: calc(100vw - 32px);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.nested-panel-toolbar,
|
||||
.nested-pager {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.action-btns {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user