Files
portal/app/resources/js/components/dashboard/DashboardBalance.vue
T
Дмитрий e280edd431 style(frontend): apply prettier --write — fix formatting drift
4 files reformatted (import list expansion, line-length wrapping).
Vitest 88/683+3sk green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:30:51 +03:00

126 lines
3.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
/**
* DashboardBalance — карта баланса с runway-bar (segments по дням).
* Класс `.runway-fill` сохранён — Vitest тест считает их количество.
*
* Sprint 4 Phase B/3 — split DashboardView (audit O-refactor-04 закрытие).
*/
export interface Balance {
amount: string;
runwayDays: number;
runwayMax: number;
runwayLeads: number;
}
defineProps<{
balance: Balance;
}>();
</script>
<template>
<v-col cols="12" sm="6" md="3">
<v-card variant="flat" color="secondary" class="balance-card pa-4">
<div class="balance-row1">
<span class="balance-label">Баланс</span>
<v-chip size="x-small" color="primary" variant="elevated" class="ml-2">LIVE</v-chip>
</div>
<div class="balance-amount">
<span class="num">{{ balance.amount }}</span>
<span class="ru">&nbsp;</span>
</div>
<div class="runway mt-3">
<div
class="runway-bar"
role="img"
:aria-label="`Хватит на ${balance.runwayDays} дня из ${balance.runwayMax}`"
>
<span
v-for="i in balance.runwayMax"
:key="i"
class="runway-fill"
:class="{ filled: i <= balance.runwayDays }"
/>
</div>
<div class="runway-foot text-caption">
<span
> {{ balance.runwayLeads }} лидов · хватит на
<strong>{{ balance.runwayDays }} дня</strong></span
>
<a href="/billing" class="ml-2 runway-action">пополнить </a>
</div>
</div>
</v-card>
</v-col>
</template>
<style scoped>
.balance-card {
color: #fff;
background: #012019 !important;
height: 100%;
}
.balance-row1 {
display: flex;
align-items: center;
}
.balance-label {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: #7a8c87;
font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.balance-amount {
margin-top: 8px;
font-size: 32px;
font-weight: 600;
line-height: 1.1;
}
.balance-amount .num {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-feature-settings: 'tnum';
color: #fff;
letter-spacing: -0.01em;
}
.balance-amount .ru {
color: #7a8c87;
font-weight: 500;
}
.runway-bar {
display: flex;
gap: 4px;
}
.runway-fill {
flex: 1;
height: 6px;
border-radius: 3px;
background: rgba(255, 255, 255, 0.08);
}
.runway-fill.filled {
background: #32c8a9;
}
.runway-foot {
display: flex;
justify-content: space-between;
margin-top: 6px;
color: #7a8c87;
font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.runway-foot strong {
color: #fff;
font-weight: 500;
}
.runway-action {
color: #32c8a9;
text-decoration: none;
}
.runway-action:hover {
color: #fff;
}
</style>