Preserve the local Ant UI work across views/components and add the new home dashboard chart panels before merging latest main.
45 lines
1.8 KiB
Vue
45 lines
1.8 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import { Empty as AEmpty, Progress as AProgress } from 'ant-design-vue';
|
|
import { toFaDigits } from '@/lib/jalali';
|
|
import type { HomeDashboardFunnelStageDto } from '@mento/shared';
|
|
|
|
const props = defineProps<{
|
|
funnel: HomeDashboardFunnelStageDto[];
|
|
formatAmount: (value: number) => string;
|
|
}>();
|
|
|
|
const rows = computed(() => props.funnel);
|
|
const hasData = computed(() => rows.value.some((r) => r.count > 0));
|
|
const openTotal = computed(() => rows.value.reduce((a, r) => a + r.count, 0));
|
|
|
|
function share(count: number) {
|
|
if (!openTotal.value) return 0;
|
|
return Math.round((count / openTotal.value) * 100);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<section class="bg-white rounded-2xl border border-slate-200/80 p-4 shadow-sm h-full">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="font-bold text-slate-800 text-base">قیف فروش باز</h3>
|
|
<span v-if="hasData" class="text-xs font-semibold text-slate-500">
|
|
{{ toFaDigits(openTotal) }} معامله باز
|
|
</span>
|
|
</div>
|
|
<a-empty v-if="!hasData" description="معاملهٔ بازی در مسیر فروش نیست" />
|
|
<div v-else class="space-y-4">
|
|
<div v-for="row in rows" :key="row.stageId ?? row.stageName">
|
|
<div class="flex items-center justify-between gap-2 mb-1">
|
|
<span class="text-xs font-bold text-slate-700">{{ row.stageName }}</span>
|
|
<span class="text-xs font-semibold text-slate-500">
|
|
{{ toFaDigits(row.count) }} · {{ toFaDigits(share(row.count)) }}٪
|
|
</span>
|
|
</div>
|
|
<a-progress :percent="share(row.count)" :show-info="false" stroke-color="#10b981" />
|
|
<div class="text-[11px] text-slate-400">{{ formatAmount(row.amount) }}</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|