11<template >
2- <el-card class =" summary-card"
3- :class =" { active }"
4- @click =" handleClick" >
5-
6- <div class =" card" >
7- <span class =" title" >{{ title }}</span >
8- <h2 >{{ value }}건</h2 >
9- <small >{{ sub }}</small >
10- </div >
11- </el-card >
2+ <div
3+ class =" kpi-box"
4+ :class =" [typeClass, { active }]"
5+ @click =" handleClick"
6+ >
7+ <span class =" kpi-title" >{{ title }}</span >
8+ <span class =" kpi-count" :class =" countClass" >
9+ {{ value ?? 0 }}건
10+ </span >
11+ <span class =" kpi-sub" >{{ sub }}</span >
12+ </div >
1213</template >
1314
1415<script setup>
15- const props = defineProps ({ title: String , value: Number , sub: String , type: String , active: Boolean })
16+ import { computed } from ' vue'
17+
18+ const props = defineProps ({
19+ title: String ,
20+ value: Number ,
21+ sub: String ,
22+ type: String ,
23+ active: Boolean
24+ })
1625
1726const emit = defineEmits ([' click' ])
1827
19- const handleClick = () => { emit (' click' , props .type ) }
28+ const handleClick = () => {
29+ emit (' click' , props .type )
30+ }
31+
32+ /* 타입별 배경 */
33+ const typeClass = computed (() => {
34+ switch (props .type ) {
35+ case ' IMMINENT' :
36+ return ' warning-box'
37+ case ' COMPLETED' :
38+ return ' success-box'
39+ case ' IN_PROGRESS' :
40+ return ' info-box'
41+ default :
42+ return ' '
43+ }
44+ })
45+
46+ /* 타입별 숫자 색상 */
47+ const countClass = computed (() => {
48+ switch (props .type ) {
49+ case ' IMMINENT' :
50+ return ' warning'
51+ case ' COMPLETED' :
52+ return ' success'
53+ case ' IN_PROGRESS' :
54+ return ' info'
55+ default :
56+ return ' '
57+ }
58+ })
2059 </script >
2160
2261<style scoped>
23- .summary-card { cursor : pointer ; transition : all 0.2s ease ; }
24- .summary-card.active { border : 2px solid #409eff ; background-color : #ecf5ff ; }
25- .card { text-align : center ; }
26- .title { color : #666 ; }
27- .summary-card.active .title { color : #409eff ; }
28- </style >
62+ /* 공통 카드 */
63+ .kpi-box {
64+ background : #fff ;
65+ padding : 24px ;
66+ border : 1px solid #eee ;
67+ border-radius : 8px ;
68+ cursor : pointer ;
69+ transition : all 0.15s ease ;
70+ }
71+
72+ .kpi-box :hover {
73+ box-shadow : 0 4px 10px rgba (0 ,0 ,0 ,0.06 );
74+ transform : translateY (-2px );
75+ }
76+
77+ /* 텍스트 */
78+ .kpi-title {
79+ font-size : 14px ;
80+ color : #666 ;
81+ margin-bottom : 10px ;
82+ display : block ;
83+ font-weight : 500 ;
84+ }
85+
86+ .kpi-count {
87+ font-size : 28px ;
88+ font-weight : 800 ;
89+ color : #333 ;
90+ }
91+
92+ .kpi-sub {
93+ display : block ;
94+ margin-top : 6px ;
95+ font-size : 13px ;
96+ color : #888 ;
97+ }
98+
99+ /* 숫자 색상 */
100+ .warning { color : #ef4444 ; }
101+ .success { color : #22c55e ; }
102+ .info { color : #3b82f6 ; }
103+
104+ /* 배경 강조 */
105+ .warning-box {
106+ background-color : #fef2f2 ;
107+ border-color : #fee2e2 ;
108+ }
109+
110+ .success-box {
111+ background-color : #ecfdf5 ;
112+ border-color : #d1fae5 ;
113+ }
114+
115+ .info-box {
116+ background-color : #eff6ff ;
117+ border-color : #dbeafe ;
118+ }
119+
120+ /* 선택 상태 */
121+ .kpi-box.active {
122+ outline : 2px solid #2563eb ;
123+ outline-offset : -2px ;
124+ }
125+ </style >
0 commit comments