195 lines
6.4 KiB
Vue
195 lines
6.4 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* BalanceCard — 3 wallet-cards в одной строке: Кошелёк ₽ (dark) +
|
|
* ≈ Лиды (affordable_leads) + Тариф. Данные — из GET /api/billing/wallet (E3).
|
|
* Billing v2 Spec A: affordable_leads вместо leadsBalance; currentTierPriceRub вместо tariffPrice.
|
|
* tariff* допускают null (тенант без назначенного тарифа — trial).
|
|
*/
|
|
import { computed } from 'vue';
|
|
|
|
const props = defineProps<{
|
|
walletRub: number;
|
|
affordableLeads: number;
|
|
currentTierPriceRub: string;
|
|
tariffName: string | null;
|
|
tariffFeatures: string[];
|
|
}>();
|
|
|
|
defineEmits<{ topup: [] }>();
|
|
|
|
const walletText = computed(() => new Intl.NumberFormat('ru-RU').format(props.walletRub));
|
|
</script>
|
|
|
|
<template>
|
|
<v-row dense class="wallet-row mt-4">
|
|
<v-col cols="12" md="4">
|
|
<v-card variant="flat" color="secondary" class="wallet-card primary pa-4">
|
|
<div class="wallet-h">
|
|
<span class="wallet-label">Кошелёк ₽</span>
|
|
<v-chip size="x-small" color="primary" variant="elevated">LIVE</v-chip>
|
|
</div>
|
|
<div class="wallet-amount mt-2">
|
|
<span class="num">{{ walletText }}</span>
|
|
<span class="ru"> ₽</span>
|
|
</div>
|
|
<div class="wallet-foot mt-3">мин. пополнение <strong>100 ₽</strong></div>
|
|
<div class="wallet-actions mt-3">
|
|
<v-btn
|
|
color="primary"
|
|
variant="flat"
|
|
prepend-icon="mdi-plus"
|
|
size="small"
|
|
@click="$emit('topup')"
|
|
>Пополнить</v-btn
|
|
>
|
|
<v-tooltip text="Автопополнение будет доступно после подключения платёжного шлюза.">
|
|
<template #activator="{ props: tipProps }">
|
|
<span v-bind="tipProps" class="d-inline-flex">
|
|
<v-btn variant="outlined" prepend-icon="mdi-autorenew" size="small" disabled>
|
|
Автопополнение
|
|
</v-btn>
|
|
</span>
|
|
</template>
|
|
</v-tooltip>
|
|
</div>
|
|
</v-card>
|
|
</v-col>
|
|
|
|
<v-col cols="12" md="4">
|
|
<v-card variant="outlined" class="wallet-card pa-4">
|
|
<div class="wallet-h">
|
|
<span class="wallet-label">≈ Лиды</span>
|
|
</div>
|
|
<div class="wallet-amount mt-2">
|
|
<span class="num">≈ {{ affordableLeads }}</span>
|
|
<span class="ru-text"> лидов</span>
|
|
</div>
|
|
<div class="wallet-foot mt-2">сейчас по {{ currentTierPriceRub }} ₽/лид
|
|
<v-tooltip text="Точный расчёт по текущим ценам. Меняется при переходе ступеней.">
|
|
<template #activator="{ props: tipProps }">
|
|
<v-icon v-bind="tipProps" size="14" class="ml-1">mdi-information-outline</v-icon>
|
|
</template>
|
|
</v-tooltip>
|
|
</div>
|
|
</v-card>
|
|
</v-col>
|
|
|
|
<v-col cols="12" md="4">
|
|
<v-card variant="outlined" class="wallet-card pa-4 d-flex flex-column">
|
|
<span class="wallet-label">Тариф</span>
|
|
<template v-if="tariffName">
|
|
<div class="tariff-name mt-1">{{ tariffName }}</div>
|
|
<ul v-if="tariffFeatures.length" class="tariff-feats mt-3">
|
|
<li v-for="f in tariffFeatures" :key="f">
|
|
<v-icon size="14" color="success" class="mr-1">mdi-check</v-icon>{{ f }}
|
|
</li>
|
|
</ul>
|
|
</template>
|
|
<div v-else class="tariff-empty mt-2">Тариф не выбран</div>
|
|
<v-tooltip text="Самостоятельная смена тарифа появится после запуска биллинга.">
|
|
<template #activator="{ props: tipProps }">
|
|
<span v-bind="tipProps" class="mt-auto d-inline-flex">
|
|
<v-btn variant="outlined" size="small" disabled>Сменить тариф →</v-btn>
|
|
</span>
|
|
</template>
|
|
</v-tooltip>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.num {
|
|
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
|
font-feature-settings: 'tnum';
|
|
font-weight: 500;
|
|
}
|
|
|
|
.wallet-card {
|
|
height: 100%;
|
|
background: #fff;
|
|
}
|
|
.wallet-card.primary {
|
|
color: #fff;
|
|
background: #012019 !important;
|
|
}
|
|
.wallet-h {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.wallet-label {
|
|
font-size: 12px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
color: #7a8c87;
|
|
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
|
}
|
|
.wallet-card:not(.primary) .wallet-label {
|
|
color: #66635c;
|
|
}
|
|
.wallet-amount {
|
|
font-size: 32px;
|
|
font-weight: 600;
|
|
line-height: 1.1;
|
|
}
|
|
.wallet-amount .num {
|
|
color: inherit;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
.wallet-amount .ru,
|
|
.wallet-amount .ru-text {
|
|
color: #66635c;
|
|
font-weight: 500;
|
|
font-size: 18px;
|
|
}
|
|
.wallet-card.primary .wallet-amount .ru {
|
|
color: #7a8c87;
|
|
}
|
|
.wallet-foot {
|
|
color: inherit;
|
|
opacity: 0.7;
|
|
font-size: 12px;
|
|
}
|
|
.wallet-card.primary .wallet-foot {
|
|
color: #b1c2bd;
|
|
opacity: 1;
|
|
}
|
|
.wallet-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
|
|
.tariff-name {
|
|
font-weight: 600;
|
|
font-size: 17px;
|
|
color: #081319;
|
|
}
|
|
.tariff-price {
|
|
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
|
color: #0f6e56;
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
margin-left: 4px;
|
|
}
|
|
.tariff-empty {
|
|
color: #66635c;
|
|
font-size: 14px;
|
|
}
|
|
.tariff-feats {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
flex: 1;
|
|
}
|
|
.tariff-feats li {
|
|
font-size: 13px;
|
|
color: #343c41;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
</style>
|