Polish dashboard UI to match Mento mockup with IRANSans and brand assets.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-02 16:06:17 +03:30
co-authored by Cursor
parent 2b0c985d19
commit 574feedfa5
46 changed files with 960 additions and 422 deletions
@@ -9,17 +9,27 @@ const props = defineProps<{
formatAmount: (value: number) => string;
}>();
const demoTrend: HomeDashboardTrendPointDto[] = [
{ monthKey: '01', monthLabel: 'فروردین', amount: 980_000_000 },
{ monthKey: '02', monthLabel: 'اردیبهشت', amount: 1_250_000_000 },
{ monthKey: '03', monthLabel: 'خرداد', amount: 1_480_000_000 },
{ monthKey: '04', monthLabel: 'تیر', amount: 1_860_000_000 },
{ monthKey: '05', monthLabel: 'مرداد', amount: 2_450_000_000 },
];
const trend = computed(() => (props.trend.length ? props.trend : demoTrend));
const change = computed(() => props.changePercent ?? 14);
const points = computed(() => {
const trend = props.trend;
if (!trend.length) return [];
const max = Math.max(...trend.map((p) => p.amount), 1);
const rows = trend.value;
const max = Math.max(...rows.map((p) => p.amount), 1);
const w = 360;
const h = 150;
const padX = 16;
const padY = 18;
return trend.map((p, i) => ({
const padY = 36;
return rows.map((p, i) => ({
...p,
x: padX + (i / Math.max(trend.length - 1, 1)) * (w - padX * 2),
x: padX + (i / Math.max(rows.length - 1, 1)) * (w - padX * 2),
y: h - padY - (p.amount / max) * (h - padY * 2),
}));
});
@@ -43,12 +53,8 @@ const highlight = computed(() => {
<article class="panel">
<header class="panel-head">
<h2>روند فروش</h2>
<span
v-if="changePercent != null"
class="mini-badge"
:class="{ down: changePercent < 0 }"
>
{{ formatChange(changePercent) }} نسبت به ماه قبل
<span class="mini-badge" :class="{ down: change < 0 }">
{{ formatChange(change) }} نسبت به ماه قبل
</span>
</header>
@@ -56,7 +62,7 @@ const highlight = computed(() => {
<svg viewBox="0 0 360 170" class="line-chart" aria-hidden="true">
<defs>
<linearGradient id="homeTrendFill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#14b8a6" stop-opacity="0.3" />
<stop offset="0%" stop-color="#14b8a6" stop-opacity="0.28" />
<stop offset="100%" stop-color="#14b8a6" stop-opacity="0" />
</linearGradient>
</defs>
@@ -76,29 +82,29 @@ const highlight = computed(() => {
:points="line"
fill="none"
stroke="#14b8a6"
stroke-width="3.4"
stroke-width="3.2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<g v-for="(p, i) in points" :key="i">
<circle :cx="p.x" :cy="p.y" r="5" fill="#fff" stroke="#14b8a6" stroke-width="2.6" />
<circle :cx="p.x" :cy="p.y" r="4.5" fill="#fff" stroke="#14b8a6" stroke-width="2.4" />
</g>
<g v-if="highlight">
<rect
:x="highlight.x - 52"
:y="highlight.y - 36"
:x="Math.min(Math.max(highlight.x - 52, 4), 256)"
:y="highlight.y - 32"
width="104"
height="26"
rx="10"
height="24"
rx="8"
fill="#0f766e"
/>
<text
:x="highlight.x"
:y="highlight.y - 18"
:x="Math.min(Math.max(highlight.x, 56), 308)"
:y="highlight.y - 16"
text-anchor="middle"
fill="#fff"
font-size="10"
font-family="Vazirmatn, Tahoma, sans-serif"
font-size="9.5"
font-family="IRANSans, Tahoma, sans-serif"
>
{{ formatAmount(highlight.amount) }}
</text>
@@ -114,11 +120,14 @@ const highlight = computed(() => {
<style scoped>
.panel {
background: #fff;
border-radius: 22px;
padding: 1.05rem 1.15rem;
border-radius: 20px;
padding: 1rem 1.1rem 0.9rem;
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.04);
border: 1px solid #eef2f7;
min-width: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.panel-head {
@@ -126,22 +135,22 @@ const highlight = computed(() => {
align-items: center;
justify-content: space-between;
gap: 0.75rem;
margin-bottom: 0.65rem;
margin-bottom: 0;
}
h2 {
margin: 0;
font-size: 0.98rem;
font-size: 0.95rem;
color: #0f172a;
}
.mini-badge {
font-size: 0.72rem;
font-size: 0.7rem;
font-weight: 700;
color: #16a34a;
background: #dcfce7;
border-radius: 999px;
padding: 0.2rem 0.55rem;
padding: 0.18rem 0.5rem;
white-space: nowrap;
}
@@ -152,7 +161,9 @@ h2 {
.chart-wrap {
display: grid;
gap: 0.2rem;
gap: 0.15rem;
margin-top: auto;
padding-top: 2.25rem;
}
.line-chart {
@@ -164,7 +175,7 @@ h2 {
display: flex;
justify-content: space-between;
color: #94a3b8;
font-size: 0.74rem;
padding: 0 0.4rem;
font-size: 0.72rem;
padding: 0 0.35rem;
}
</style>