feat: replace watermarks with corner tags, improve parlay layout and admin polish

- MatchDetailView: replace StatusWatermark with top-right solid status tags, remove match-hero background image
- ParlayPanel: replace StatusWatermark with corner tags, improve toggle button style and layout spacing, fix overflow clipping
- Admin: wallet ledger dialog, agent manager, and player page refinements

🤖 Generated with [Qoder][https://qoder.com]
This commit is contained in:
2026-06-10 16:24:01 +08:00
parent ef6b15f119
commit a8ee28fcce
7 changed files with 159 additions and 58 deletions

View File

@@ -20,11 +20,7 @@ import { usePullToRefresh } from '../composables/usePullToRefresh';
import vsImg from '../assets/images/vs.png';
import GoldSpinner from '../components/GoldSpinner.vue';
import BetSuccessOverlay from '../components/BetSuccessOverlay.vue';
import StatusWatermark from '../components/StatusWatermark.vue';
import { matchPhaseLabel, matchPhaseVariant, type MatchPhase } from '../utils/matchPhase';
import cardBg from '../assets/images/card-bg.png';
const heroCardBg = `url(${cardBg})`;
import { matchPhaseLabel, type MatchPhase } from '../utils/matchPhase';
const route = useRoute();
const router = useRouter();
@@ -372,12 +368,8 @@ function hasSlipPickForMarket(marketType: string) {
</div>
<template v-else-if="match">
<section class="match-hero" :class="{ 'match-hero--phase': matchPhase !== 'open' }">
<StatusWatermark
v-if="matchPhase !== 'open'"
:label="phaseLabel"
:variant="matchPhaseVariant(matchPhase)"
size="lg"
/>
<span v-if="matchPhase === 'settled'" class="status-tag status-tag--settled">{{ phaseLabel }}</span>
<span v-else-if="matchPhase === 'closed_pending'" class="status-tag status-tag--pending">{{ phaseLabel }}</span>
<div class="hero-teams">
<!-- home -->
<div class="hero-team">
@@ -482,12 +474,8 @@ function hasSlipPickForMarket(marketType: string) {
/>
<template v-if="isExpanded(marketType) && marketsByType.get(marketType)">
<div class="market-panel-wrap" :class="{ locked: !bettingOpen }">
<StatusWatermark
v-if="!bettingOpen"
:label="phaseLabel"
:variant="matchPhaseVariant(matchPhase)"
size="md"
/>
<span v-if="!bettingOpen && matchPhase === 'settled'" class="market-status-tag market-status-tag--settled">{{ phaseLabel }}</span>
<span v-else-if="!bettingOpen" class="market-status-tag market-status-tag--pending">{{ phaseLabel }}</span>
<CorrectScorePanel
v-if="isCorrectScoreMarket(marketType)"
:market-type="marketType"
@@ -603,20 +591,68 @@ function hasSlipPickForMarket(marketType: string) {
overflow: hidden;
}
.match-hero::before {
content: '';
position: absolute;
inset: 0;
background: v-bind(heroCardBg) center / 100% 100% no-repeat;
opacity: 0.22;
z-index: 0;
pointer-events: none;
}
.match-hero--phase {
opacity: 0.98;
}
/* ── hero status tag (top-right corner) ── */
.status-tag {
position: absolute;
top: 0;
right: 0;
z-index: 5;
font-size: 11px;
font-weight: 800;
padding: 4px 14px;
border-radius: 0 6px 0 10px;
line-height: 1.3;
white-space: nowrap;
letter-spacing: 0.02em;
}
.status-tag--settled {
background: linear-gradient(180deg, #2a2a3a 0%, #1a1a28 100%);
color: #8a9ab8;
border-bottom: 1px solid rgba(120, 140, 180, 0.3);
border-left: 1px solid rgba(120, 140, 180, 0.3);
}
.status-tag--pending {
background: linear-gradient(180deg, #3a3a2a 0%, #28251a 100%);
color: #c8a84e;
border-bottom: 1px solid rgba(200, 168, 78, 0.3);
border-left: 1px solid rgba(200, 168, 78, 0.3);
}
/* ── market panel smaller status tag ── */
.market-status-tag {
position: absolute;
top: 0;
right: 0;
z-index: 5;
font-size: 10px;
font-weight: 800;
padding: 3px 10px;
border-radius: 0 4px 0 8px;
line-height: 1.3;
white-space: nowrap;
letter-spacing: 0.02em;
}
.market-status-tag--settled {
background: linear-gradient(180deg, #2a2a3a 0%, #1a1a28 100%);
color: #8a9ab8;
border-bottom: 1px solid rgba(120, 140, 180, 0.3);
border-left: 1px solid rgba(120, 140, 180, 0.3);
}
.market-status-tag--pending {
background: linear-gradient(180deg, #3a3a2a 0%, #28251a 100%);
color: #c8a84e;
border-bottom: 1px solid rgba(200, 168, 78, 0.3);
border-left: 1px solid rgba(200, 168, 78, 0.3);
}
.market-panel-wrap {
position: relative;
overflow: hidden;