feat: migrate CRM screens to Ant Design Vue and expand home dashboard
Preserve the local Ant UI work across views/components and add the new home dashboard chart panels before merging latest main.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { toFaDigits } from '@/lib/jalali';
|
||||
import type { HomeDashboardSeriesPointDto } from '@mento/shared';
|
||||
import UiChart, { type UiChartOption } from '@/components/ui/UiChart.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
series: HomeDashboardSeriesPointDto[];
|
||||
}>();
|
||||
|
||||
const points = computed(() => props.series);
|
||||
const hasData = computed(() => points.value.some((p) => p.value > 0));
|
||||
const total = computed(() => points.value.reduce((a, p) => a + p.value, 0));
|
||||
|
||||
const option = computed<UiChartOption>(() => ({
|
||||
animationDuration: 450,
|
||||
grid: { top: 36, right: 12, bottom: 28, left: 12, containLabel: true },
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
textStyle: { fontFamily: 'IRANSans, Tahoma, sans-serif' },
|
||||
formatter: (params) => {
|
||||
const row = Array.isArray(params) ? params[0] : params;
|
||||
const point = points.value[row.dataIndex ?? 0];
|
||||
if (!point) return '';
|
||||
return `${point.monthLabel}<br/><strong>${toFaDigits(point.value)}</strong> مشتری جدید`;
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: points.value.map((p) => p.monthLabel),
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: {
|
||||
color: '#94a3b8',
|
||||
fontFamily: 'IRANSans, Tahoma, sans-serif',
|
||||
fontSize: 11,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
minInterval: 1,
|
||||
...(hasData.value ? {} : { max: 1 }),
|
||||
splitLine: { lineStyle: { color: '#e5e7eb', type: 'dashed' } },
|
||||
axisLabel: { show: false },
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
data: points.value.map((p) => p.value),
|
||||
barMaxWidth: 32,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#34d399' },
|
||||
{ offset: 1, color: '#059669' },
|
||||
],
|
||||
},
|
||||
borderRadius: [8, 8, 0, 0],
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
color: '#64748b',
|
||||
fontFamily: 'IRANSans, Tahoma, sans-serif',
|
||||
fontSize: 11,
|
||||
formatter: (p) => toFaDigits(Number(p.value ?? 0)),
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
data: points.value.map((p) => p.value),
|
||||
smooth: 0.35,
|
||||
symbol: 'none',
|
||||
lineStyle: { color: '#0f766e', width: 2, opacity: 0.55 },
|
||||
},
|
||||
],
|
||||
}));
|
||||
</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-bold bg-emerald-50 text-emerald-700 px-2.5 py-1 rounded-lg">
|
||||
{{ toFaDigits(total) }} در ۱۲ ماه
|
||||
</span>
|
||||
</div>
|
||||
<div class="h-56">
|
||||
<UiChart :option="option" height="224px" />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user