fix: dashboard

This commit is contained in:
sajjadtalkhabi
2026-06-27 15:45:07 +03:30
parent a4432a30cb
commit 2c617258f4
12 changed files with 727 additions and 41 deletions
+12
View File
@@ -0,0 +1,12 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="11.625" stroke="#EEEEEE" stroke-width="0.75"/>
<g clip-path="url(#clip0_1_21196)">
<path d="M15.375 15.375L8.625 8.625" stroke="#B2B2B2" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.1094 8.625H8.625V14.1094" stroke="#B2B2B2" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_21196">
<rect width="13.5" height="13.5" fill="white" transform="translate(5.25 5.25)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 604 B

+11
View File
@@ -0,0 +1,11 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_21191)">
<path d="M6.5 11.375C9.19239 11.375 11.375 9.19239 11.375 6.5C11.375 3.80761 9.19239 1.625 6.5 1.625C3.80761 1.625 1.625 3.80761 1.625 6.5C1.625 9.19239 3.80761 11.375 6.5 11.375Z" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.5 3.65625V6.5H9.34375" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_21191">
<rect width="12.75" height="12.75" fill="white" transform="scale(1.01961)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 666 B

+10
View File
@@ -0,0 +1,10 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_21269)">
<path d="M5.625 3.1154V16.8841C5.62704 16.994 5.65802 17.1014 5.7148 17.1955C5.77158 17.2896 5.85217 17.367 5.94843 17.42C6.0447 17.473 6.15323 17.4997 6.2631 17.4974C6.37297 17.4951 6.48028 17.4638 6.57422 17.4068L17.8305 10.5224C17.9204 10.468 17.9947 10.3913 18.0463 10.2998C18.0979 10.2082 18.1251 10.1049 18.1251 9.99977C18.1251 9.89467 18.0979 9.79135 18.0463 9.69979C17.9947 9.60823 17.9204 9.53154 17.8305 9.47711L6.57422 2.59274C6.48028 2.53571 6.37297 2.50447 6.2631 2.50214C6.15323 2.49982 6.0447 2.52651 5.94843 2.57951C5.85217 2.63252 5.77158 2.70996 5.7148 2.80405C5.65802 2.89813 5.62704 3.00552 5.625 3.1154Z" stroke="#848484" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_21269">
<rect width="19.5" height="19.5" fill="white" transform="scale(1.02564)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 988 B

+11
View File
@@ -0,0 +1,11 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_21319)">
<path d="M11.8125 2.625H2.1875C1.94588 2.625 1.75 2.82088 1.75 3.0625V10.9375C1.75 11.1791 1.94588 11.375 2.1875 11.375H11.8125C12.0541 11.375 12.25 11.1791 12.25 10.9375V3.0625C12.25 2.82088 12.0541 2.625 11.8125 2.625Z" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.1875 4.8125C9.1875 5.39266 8.95703 5.94906 8.5468 6.3593C8.13656 6.76953 7.58016 7 7 7C6.41984 7 5.86344 6.76953 5.4532 6.3593C5.04297 5.94906 4.8125 5.39266 4.8125 4.8125" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_21319">
<rect width="13.5" height="13.5" fill="white" transform="scale(1.03704)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 855 B

+13
View File
@@ -0,0 +1,13 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_21209)">
<path d="M5.48438 8.53125C7.16712 8.53125 8.53125 7.16712 8.53125 5.48438C8.53125 3.80163 7.16712 2.4375 5.48438 2.4375C3.80163 2.4375 2.4375 3.80163 2.4375 5.48438C2.4375 7.16712 3.80163 8.53125 5.48438 8.53125Z" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.21875 10.5625C2.2623 9.3209 3.73547 8.53125 5.48438 8.53125C7.23328 8.53125 8.70645 9.3209 9.75 10.5625" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.1562 3.49096C10.4243 4.12144 10.5625 4.79952 10.5625 5.48463C10.5625 6.16975 10.4243 6.84782 10.1562 7.47831" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.6468 2.84375C12.0033 3.67846 12.1871 4.57672 12.1871 5.48438C12.1871 6.39203 12.0033 7.29029 11.6468 8.125" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_21209">
<rect width="12.75" height="12.75" fill="white" transform="scale(1.01961)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+12
View File
@@ -0,0 +1,12 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_21228)">
<path d="M8.125 5.6875L5.6875 4.0625V7.3125L8.125 5.6875Z" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.9688 2.4375H2.03125C1.80688 2.4375 1.625 2.61938 1.625 2.84375V8.53125C1.625 8.75562 1.80688 8.9375 2.03125 8.9375H10.9688C11.1931 8.9375 11.375 8.75562 11.375 8.53125V2.84375C11.375 2.61938 11.1931 2.4375 10.9688 2.4375Z" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.625 10.5625H11.375" stroke="#B8B8B8" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_21228">
<rect width="12.75" height="12.75" fill="white" transform="scale(1.01961)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 863 B

+6
View File
@@ -8,6 +8,7 @@ export type IconName =
| 'bell'
| 'book'
| 'calendar'
| 'card-corner-arrow'
| 'caret-down'
| 'caret-left'
| 'caret-right'
@@ -15,6 +16,7 @@ export type IconName =
| 'chat-centered-dots'
| 'check'
| 'check-square'
| 'clock'
| 'close'
| 'copy'
| 'eye'
@@ -33,16 +35,20 @@ export type IconName =
| 'paper-plane-right'
| 'pencil'
| 'phone'
| 'play'
| 'plus'
| 'scroll'
| 'shopping-bag'
| 'spinner'
| 'square'
| 'telegram'
| 'trash'
| 'upload'
| 'user'
| 'user-sound'
| 'users'
| 'users-three'
| 'video'
| 'warning'
export const iconNames: readonly IconName[]
@@ -1,69 +1,226 @@
<template>
<div class="student-dashboard">
<div class="student-dashboard__welcome">
<img :src="flower" alt="flower" class="student-dashboard__flower" />
<div>
<p class="student-dashboard__hi">سلام بر شما</p>
<p class="student-dashboard__greeting">به سامانه موسسه بانو خوش آمدید.</p>
<div class="dashboard">
<div class="dashboard__main">
<!-- گزارش عملکرد -->
<section class="dashboard__section">
<BoxedIconTitleBlock title="گزارش عملکرد" desc="مروری بر شاخص‌های آموزشی و فعالیت‌های شما.">
<template #icon>
<SvgIcon name="heart" :size="24" color="var(--color-primary)" />
</template>
</BoxedIconTitleBlock>
<div class="dashboard__stats">
<DashboardStatCard
v-for="(stat, i) in performanceStats"
:key="i"
:icon="stat.icon"
:label="stat.label"
:value="stat.value"
:unit="stat.unit"
:subtitle="stat.subtitle"
/>
</div>
</section>
<!-- فعالیت های اخیر -->
<section class="dashboard__section">
<BoxedIconTitleBlock
title="فعالیت های اخیر"
desc="گزارشی از جدیدترین خریدها و دوره‌های تکمیل‌شده"
>
<template #icon>
<SvgIcon name="heart" :size="24" color="var(--color-primary)" />
</template>
</BoxedIconTitleBlock>
<div class="dashboard__activities">
<div v-for="(act, i) in activities" :key="i" class="dashboard__activity">
<div class="dashboard__pill">
<SvgIcon :name="act.pillIcon" :size="'1.125rem'" class="dashboard__pill-icon" />
<span class="dashboard__pill-label">{{ act.pillLabel }}</span>
</div>
<DashboardActivityCard :title="act.title" :meta="act.meta" :meta-icon="act.metaIcon" />
</div>
</div>
</section>
</div>
<p class="student-dashboard__placeholder">این بخش در مراحل بعدی توسعه مییابد.</p>
<aside class="dashboard__aside">
<DashboardProfileCard
:name="profile.name"
:location="profile.location"
:stats="profile.stats"
/>
<DashboardCalendar :month-label="calendar.month" :days="calendar.days" />
</aside>
</div>
</template>
<script setup>
import { gallery } from '@/utils/gallery'
import SvgIcon from '@/components/icons/SvgIcon.vue'
import BoxedIconTitleBlock from '@/components/blocks/BoxedIconTitleBlock.vue'
import DashboardStatCard from '@/features/student/pages/components/DashboardStatCard.vue'
import DashboardCalendar from '@/features/student/pages/components/DashboardCalendar.vue'
import DashboardProfileCard from '@/features/student/pages/components/DashboardProfileCard.vue'
import DashboardActivityCard from '@/features/student/pages/components/DashboardActivityCard.vue'
const flower = gallery.registrationCompleteFlower
const performanceStats = [
{
icon: 'clock',
label: 'ساعات آموزشی سپری‌شده',
value: '۲۵',
unit: 'ساعت',
subtitle: 'گذرانده شده',
},
{
icon: 'video',
label: 'دوره های خریداری شده',
value: '۶',
unit: 'دوره',
subtitle: 'خریداری شده',
},
{
icon: 'user-sound',
label: 'تعداد جلسات اعزام شده',
value: '۱۲',
unit: 'جلسه',
subtitle: 'اعزام شده است',
},
]
const activities = [
{
pillIcon: 'shopping-bag',
pillLabel: 'آخرین دوره خریداری شده',
title: 'دوره تاریخچه ایران قدیم',
metaIcon: 'calendar',
meta: [
{ label: 'تاریخ شروع:', value: '۱۴۰۰/۷/۱۹, ۸:۳۰', numeric: true },
{ label: 'استاد:', value: 'علیرضا حسنی' },
{ label: 'تاریخ پایان:', value: '۱۴۰۰/۱۱/۱۰, ۸:۳۰', numeric: true },
],
},
{
pillIcon: 'video',
pillLabel: 'اخرین جلسه دیده شده',
title: 'دوره تخصصی تربیت مبلغ بین الملل',
metaIcon: 'video',
meta: [
{ label: 'جلسه:', value: 'بیستم و دوم' },
{ label: 'استاد:', value: 'علیرضا حسنی' },
],
},
]
const profile = {
name: 'سید احمد علیزاده',
location: 'قم، ایران',
stats: [
{ label: 'مدت عضویت', value: '۲۳', unit: 'روز' },
{ label: 'دوره‌های تکمیل‌شده', value: '۱۲', unit: 'عدد' },
{ label: 'دوره‌های فعال', value: '۵', unit: 'عدد' },
],
}
const calendar = {
month: 'شهریور ماه',
days: [
{ weekday: 'شنبه', day: '۱۵' },
{ weekday: 'یکشنبه', day: '۱۴' },
{ weekday: 'دوشنبه', day: '۱۳', marker: true },
{ weekday: 'سه شنبه', day: '۱۲' },
{ weekday: 'چهارشنبه', day: '۱۱', selected: true },
{ weekday: 'پنجشنبه', day: '۱۰' },
{ weekday: 'جمعه', day: '۹' },
],
}
</script>
<style lang="scss" scoped>
.student-dashboard {
.dashboard {
display: flex;
flex-direction: column-reverse;
gap: 2rem;
@media (min-width: 1024px) {
flex-direction: row;
align-items: flex-start;
}
&__main {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2rem;
}
&__section {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
&__stats {
display: grid;
grid-template-columns: 1fr;
gap: 0.875rem;
@media (min-width: 640px) {
grid-template-columns: repeat(3, 1fr);
}
}
&__activities {
display: grid;
grid-template-columns: 1fr;
gap: 1.25rem;
@media (min-width: 768px) {
grid-template-columns: repeat(2, 1fr);
}
}
&__activity {
display: flex;
flex-direction: column;
gap: 1rem;
}
&__pill {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 0.5rem;
padding: 0.75rem 1.25rem;
background: rgba(255, 255, 255, 58%);
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
border-radius: 0.9375rem;
}
&__pill-icon {
order: 2;
}
&__pill-label {
order: 1;
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 1.125rem;
color: #4b4b4b;
}
&__aside {
display: flex;
flex-direction: column;
gap: 1.5rem;
&__welcome {
display: flex;
align-items: flex-start;
justify-content: flex-start;
gap: 0.625rem;
}
&__flower {
object-fit: contain;
max-height: 2.75rem;
}
&__hi {
font-family: var(--font-family-fa);
font-weight: 400;
font-size: 1rem;
color: var(--color-prim-gray);
margin: 0;
}
&__greeting {
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 1rem;
margin: 0;
@media (min-width: 1024px) {
font-size: 1.5rem;
width: 19.625rem;
flex-shrink: 0;
border-inline-start: 1px solid #e6e6e6;
padding-inline-start: 2rem;
}
}
&__placeholder {
font-family: var(--font-family-fa);
font-size: 0.875rem;
color: var(--color-prim-gray);
text-align: center;
padding: 3rem 0;
background: #fff;
border-radius: 1rem;
margin: 0;
}
}
</style>
@@ -0,0 +1,126 @@
<template>
<div class="activity-card">
<SvgIcon name="card-corner-arrow" :size="'1.5rem'" class="activity-card__corner" />
<div class="activity-card__thumb">
<SvgIcon name="play" :size="'1.5rem'" />
</div>
<div class="activity-card__body">
<p class="activity-card__title">{{ title }}</p>
<div class="activity-card__meta">
<SvgIcon :name="metaIcon" :size="'0.875rem'" class="activity-card__meta-icon" />
<div class="activity-card__rows">
<p v-for="(row, i) in meta" :key="i" class="activity-card__row">
<span class="activity-card__row-label">{{ row.label }}</span>
<span
class="activity-card__row-value"
:class="{ 'activity-card__row-value--num': row.numeric }"
>
{{ row.value }}
</span>
</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import SvgIcon from '@/components/icons/SvgIcon.vue'
defineProps({
title: { type: String, default: '' },
/** rows of { label, value, numeric? } */
meta: { type: Array, default: () => [] },
/** @type {import('vue').PropType<import('@/components/icons/icon-names').IconName>} */
metaIcon: { type: String, default: 'calendar' },
})
</script>
<style lang="scss" scoped>
.activity-card {
position: relative;
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.875rem 1rem;
min-height: 5.9375rem;
background: rgba(255, 255, 255, 58%);
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
border-radius: 0.9375rem;
&__corner {
position: absolute;
inset-block-start: 0.75rem;
inset-inline-end: 1rem;
}
&__thumb {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 3.6875rem;
height: 3.6875rem;
background: #f4f4f4;
border-radius: 0.9375rem;
}
&__body {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.625rem;
text-align: start;
min-width: 0;
}
&__title {
margin: 0;
font-family: var(--font-family-fa);
font-weight: 400;
font-size: 0.875rem;
color: #4b4b4b;
}
&__meta {
display: flex;
align-items: flex-start;
justify-content: flex-start;
gap: 0.375rem;
}
&__meta-icon {
order: 2;
margin-top: 0.125rem;
}
&__rows {
order: 1;
display: flex;
flex-direction: column;
gap: 0.25rem;
}
&__row {
display: flex;
align-items: center;
gap: 0.375rem;
margin: 0;
font-family: var(--font-family-fa);
font-weight: 400;
font-size: 0.6875rem;
color: #4b4b4b;
}
&__row-value {
&--num {
font-family: var(--font-family-number-fa);
direction: ltr;
}
}
}
</style>
@@ -0,0 +1,99 @@
<template>
<div class="calendar">
<p class="calendar__title">{{ monthLabel }}</p>
<div class="calendar__week">
<div
v-for="(d, i) in days"
:key="i"
class="calendar__day"
:class="{ 'calendar__day--active': d.selected }"
>
<span v-if="d.marker" class="calendar__marker" />
<span class="calendar__weekday">{{ d.weekday }}</span>
<span class="calendar__date">{{ d.day }}</span>
</div>
</div>
</div>
</template>
<script setup>
defineProps({
monthLabel: { type: String, default: '' },
/** ordered right-to-left: { weekday, day, selected?, marker? } */
days: { type: Array, default: () => [] },
})
</script>
<style lang="scss" scoped>
.calendar {
display: flex;
flex-direction: column;
gap: 0.75rem;
padding: 1.125rem 1rem;
background: rgba(255, 255, 255, 58%);
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
border-radius: 0.9375rem;
&__title {
margin: 0;
text-align: start;
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 1.25rem;
color: #000;
}
&__week {
display: flex;
justify-content: space-between;
gap: 0.125rem;
}
&__day {
position: relative;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 0.375rem 0.125rem;
border-radius: 999px;
&--active {
background: var(--color-secondary);
box-shadow: 0 9px 9.75px rgba(0, 112, 116, 19%);
.calendar__weekday,
.calendar__date {
color: #fff;
}
}
}
&__marker {
position: absolute;
inset-block-start: 0.125rem;
inset-inline-start: 0.25rem;
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
background: var(--color-secondary);
}
&__weekday {
font-family: var(--font-family-fa);
font-weight: 400;
font-size: 0.625rem;
color: #828282;
white-space: nowrap;
}
&__date {
font-family: var(--font-family-number-fa);
font-weight: 700;
font-size: 0.875rem;
color: #717171;
}
}
</style>
@@ -0,0 +1,121 @@
<template>
<div class="profile-card">
<div class="profile-card__avatar">
<img v-if="avatarUrl" :src="avatarUrl" :alt="name" />
</div>
<p class="profile-card__name">{{ name }}</p>
<div class="profile-card__location">
<SvgIcon name="map-pin-simple-area" :size="'0.9375rem'" />
<span>{{ location }}</span>
</div>
<div class="profile-card__stats">
<div v-for="(stat, i) in stats" :key="i" class="profile-card__stat">
<span class="profile-card__stat-label">{{ stat.label }}</span>
<span class="profile-card__stat-value">
{{ stat.value }}
<span class="profile-card__stat-unit">{{ stat.unit }}</span>
</span>
</div>
</div>
</div>
</template>
<script setup>
import SvgIcon from '@/components/icons/SvgIcon.vue'
defineProps({
name: { type: String, default: '' },
location: { type: String, default: '' },
avatarUrl: { type: String, default: '' },
/** mini-stats of { label, value, unit } */
stats: { type: Array, default: () => [] },
})
</script>
<style lang="scss" scoped>
.profile-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
padding: 2rem 1.25rem 1.5rem;
background: rgba(255, 255, 255, 58%);
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
border-radius: 0.9375rem;
&__avatar {
width: 7.75rem;
height: 7.75rem;
border-radius: 50%;
background: #f4f4f4;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
&__name {
margin: 0;
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 1.25rem;
color: #000;
}
&__location {
display: flex;
align-items: center;
gap: 0.25rem;
font-family: var(--font-family-fa);
font-weight: 400;
font-size: 0.875rem;
color: #989898;
}
&__stats {
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 100%;
margin-top: 0.5rem;
}
&__stat {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
flex: 1;
}
&__stat-label {
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 0.6875rem;
color: #a7a7a7;
}
&__stat-value {
display: inline-flex;
align-items: baseline;
gap: 0.25rem;
font-family: var(--font-family-number-fa);
font-weight: 400;
font-size: 1.5625rem;
color: #818181;
}
&__stat-unit {
font-family: var(--font-family-fa);
font-weight: 300;
font-size: 0.75rem;
color: #929292;
}
}
</style>
@@ -0,0 +1,108 @@
<template>
<div class="stat-card">
<SvgIcon name="card-corner-arrow" :size="'1.5rem'" class="stat-card__corner" />
<div class="stat-card__head">
<SvgIcon :name="icon" :size="'1.0625rem'" class="stat-card__head-icon" />
<span class="stat-card__label">{{ label }}</span>
</div>
<div class="stat-card__body">
<span class="stat-card__value">{{ value }}</span>
<div class="stat-card__meta">
<span class="stat-card__unit">{{ unit }}</span>
<span class="stat-card__subtitle">{{ subtitle }}</span>
</div>
</div>
</div>
</template>
<script setup>
import SvgIcon from '@/components/icons/SvgIcon.vue'
defineProps({
/** @type {import('vue').PropType<import('@/components/icons/icon-names').IconName>} */
icon: { type: String, required: true },
label: { type: String, default: '' },
value: { type: [String, Number], default: '' },
unit: { type: String, default: '' },
subtitle: { type: String, default: '' },
})
</script>
<style lang="scss" scoped>
.stat-card {
position: relative;
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1.125rem 1.25rem;
min-height: 8.75rem;
background: rgba(255, 255, 255, 58%);
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
border-radius: 0.9375rem;
&__corner {
position: absolute;
inset-block-start: 0.875rem;
inset-inline-end: 1.125rem;
}
&__head {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 0.375rem;
}
&__head-icon {
order: 2;
}
&__label {
order: 1;
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 1.125rem;
color: #4b4b4b;
}
&__body {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 0.625rem;
margin-top: auto;
}
&__value {
font-family: var(--font-family-number-fa);
font-weight: 700;
font-size: 4rem;
line-height: 1;
color: var(--color-primary);
text-shadow: 0 5.25px 8.625px rgba(243, 102, 117, 18%);
}
&__meta {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.125rem;
}
&__unit {
font-family: var(--font-family-fa);
font-weight: 300;
font-size: 1.125rem;
color: #6e6e6e;
}
&__subtitle {
font-family: var(--font-family-fa);
font-weight: 500;
font-size: 1.25rem;
color: #6e6e6e;
}
}
</style>