7c97980b3a
Брендовые success и warning нечитаемы текстом: success даёт 4.25:1 на белой карточке и 3.83:1 на ивори, warning — 2.25 и 2.03 при норме WCAG 2.1 AA 4.5:1. Сами цвета не тронуты — остаются для заливок, иконок и рамок. Рядом добавлены затемнённые текстовые двойники success-strong #256F46 и warning-strong #8A6410, тон сохранён. Все 15 мест text-success и 8 мест text-warning переведены на новые классы — 13 файлов: командный центр, биллинг и инциденты админки, система, тенанты, интеграция с поставщиком, карточка тенанта, диалог баланса, рекламный админ-экран, мастер рекламной кампании, массовые диалоги дней и регионов, реквизиты в настройках. Проверено: фронт 226 файлов / 1663 теста зелёные; Pa11y по всем 24 адресам — рекламные и ВСЕ админские экраны дают 0 ошибок. Побочно вскрылось 12 старых недочётов на клиентских экранах — записаны в находку, к этой правке отношения не имеют. Боевого не касается, в main не влито. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
97 lines
2.6 KiB
Vue
97 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
interface Stats {
|
|
total: number;
|
|
active: number;
|
|
trial: number;
|
|
overdue: number;
|
|
monthlyRevenueRub: number;
|
|
}
|
|
|
|
defineProps<{
|
|
stats: Stats;
|
|
loading: boolean;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
refresh: [];
|
|
}>();
|
|
|
|
function formatRub(v: number): string {
|
|
return new Intl.NumberFormat('ru-RU').format(v) + ' ₽';
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<header class="page-head">
|
|
<div>
|
|
<h1 class="text-h4 mb-2 page-title">Тенанты</h1>
|
|
<div class="page-stats text-body-2 text-medium-emphasis">
|
|
<span
|
|
><span class="num">{{ stats.total }}</span> всего</span
|
|
>
|
|
<span class="sep">·</span>
|
|
<span
|
|
><span class="num stat-success">{{ stats.active }}</span> активны</span
|
|
>
|
|
<span class="sep">·</span>
|
|
<span
|
|
><span class="num">{{ stats.trial }}</span> trial</span
|
|
>
|
|
<span class="sep">·</span>
|
|
<span
|
|
><span class="num text-warning-strong">{{ stats.overdue }}</span> просрочка</span
|
|
>
|
|
<span class="sep">·</span>
|
|
<span
|
|
>выручка месяц <span class="num text-primary">{{ formatRub(stats.monthlyRevenueRub) }}</span></span
|
|
>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex ga-2">
|
|
<v-btn
|
|
variant="outlined"
|
|
prepend-icon="mdi-refresh"
|
|
:loading="loading"
|
|
data-testid="reload-btn"
|
|
@click="emit('refresh')"
|
|
>
|
|
Обновить
|
|
</v-btn>
|
|
<v-btn variant="outlined" prepend-icon="mdi-download">Экспорт</v-btn>
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.page-head {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 16px;
|
|
}
|
|
.page-title {
|
|
font-variation-settings: 'opsz' 28;
|
|
letter-spacing: -0.018em;
|
|
}
|
|
.page-stats {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
align-items: center;
|
|
}
|
|
.page-stats .sep {
|
|
/* WCAG2AA 4.5:1 fix (was #92907b → 2.92:1 on ivory; #6b6356 → 5.33:1). */
|
|
color: #6b6356;
|
|
}
|
|
.num {
|
|
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
|
font-feature-settings: 'tnum';
|
|
font-weight: 500;
|
|
}
|
|
.stat-success {
|
|
/* WCAG2AA: #1b5e20 ≈ 7.1:1 на ivory #F6F3EC (брендовый text-success ≈ 3.83:1). */
|
|
color: #1b5e20;
|
|
}
|
|
</style>
|