@@ -19,37 +19,83 @@ const isPositive = controlledComputed(
1919 () => props .change ,
2020 () => Math .sign (props .change || 0 ) === 1
2121);
22+
23+ const colorClasses = {
24+ primary: {
25+ bg: ' bg-indigo-100 dark:bg-indigo-500/10' ,
26+ text: ' text-indigo-500' ,
27+ glow: ' shadow-indigo-500/20' ,
28+ },
29+ success: {
30+ bg: ' bg-emerald-100 dark:bg-emerald-500/10' ,
31+ text: ' text-emerald-500' ,
32+ glow: ' shadow-emerald-500/20' ,
33+ },
34+ warning: {
35+ bg: ' bg-amber-100 dark:bg-amber-500/10' ,
36+ text: ' text-amber-500' ,
37+ glow: ' shadow-amber-500/20' ,
38+ },
39+ error: {
40+ bg: ' bg-red-100 dark:bg-red-500/10' ,
41+ text: ' text-red-500' ,
42+ glow: ' shadow-red-500/20' ,
43+ },
44+ info: {
45+ bg: ' bg-sky-100 dark:bg-sky-500/10' ,
46+ text: ' text-sky-500' ,
47+ glow: ' shadow-sky-500/20' ,
48+ },
49+ };
50+
51+ const getColorClass = (type : ' bg' | ' text' | ' glow' ) => {
52+ const colors = colorClasses [props .color as keyof typeof colorClasses ] || colorClasses .primary ;
53+ return colors [type ];
54+ };
2255 </script >
2356
2457<template >
25- <div class =" bg-base-100 shadow rounded p-4" >
26- <div class =" flex items-center justify-center" >
27- <div v-if =" props.icon" class =" relative w-9 h-9 rounded overflow-hidden flex items-center justify-center" >
28- <Icon :class =" [`text-${props?.color}`]" :icon =" props.icon" size =" 32" />
29- <div class =" absolute top-0 left-0 bottom-0 right-0 opacity-20" :class =" [`bg-${props?.color}`]" ></div >
58+ <div class =" card-modern p-5 group" >
59+ <div class =" flex items-start justify-between mb-4" >
60+ <!-- Icon -->
61+ <div
62+ v-if =" props.icon"
63+ class =" w-12 h-12 rounded-xl flex items-center justify-center transition-transform duration-300 group-hover:scale-110"
64+ :class =" [getColorClass('bg'), 'shadow-lg', getColorClass('glow')]"
65+ >
66+ <Icon :class =" [getColorClass('text')]" :icon =" props.icon" class =" text-2xl" />
3067 </div >
3168
69+ <!-- Change indicator -->
3270 <div
33- v-if =" props.change"
34- :class =" isPositive ? 'text-success' : 'text-error'"
35- class =" flex items-center text-sm font-semibold"
71+ v-if =" props.change !== undefined && props.change !== 0"
72+ class =" flex items-center gap-0.5 text-sm font-semibold px-2 py-1 rounded-lg"
73+ :class =" isPositive
74+ ? 'bg-emerald-100 dark:bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'
75+ : 'bg-red-100 dark:bg-red-500/10 text-red-600 dark:text-red-400'"
3676 >
77+ <Icon
78+ :icon =" isPositive ? 'mdi:trending-up' : 'mdi:trending-down'"
79+ class =" text-base"
80+ />
3781 <span >{{ isPositive ? `+${props.change}` : props.change }}%</span >
38- <Icon :icon =" isPositive ? 'mdi-chevron-up' : 'mdi-chevron-down'" />
3982 </div >
4083 </div >
4184
42- <div class =" " >
43- <h6 class =" text-lg text-center font-semibold mt-2 mb-1" >
85+ <!-- Stats Value -->
86+ <div class =" space-y-1" >
87+ <h3 class =" text-2xl font-bold text-slate-900 dark:text-white" >
4488 {{ props.stats || '-' }}
45- </h6 >
46- <p class =" text-sm text-center " >
89+ </h3 >
90+ <p class =" text-sm font-medium text-slate-500 dark:text-slate-400 " >
4791 {{ props.title }}
4892 </p >
49-
50- <div v-if =" props.subtitle" size =" x-small" class =" font-semibold" >
51- <span class =" truncate" >{{ props.subtitle }}</span >
52- </div >
93+ <p
94+ v-if =" props.subtitle"
95+ class =" text-xs text-slate-400 dark:text-slate-500 truncate"
96+ >
97+ {{ props.subtitle }}
98+ </p >
5399 </div >
54100 </div >
55101</template >
0 commit comments