33 v-if =" cryptoAmount == '~' && !assumedError"
44 class =" network-activity__total"
55 >
6- <balance-loader class =" network-activity__loader-one" />
7- <balance-loader class =" network-activity__loader-two" />
6+ <div >
7+ <balance-loader class =" network-activity__loader-one" />
8+ <balance-loader class =" network-activity__loader-two" />
9+ </div >
810 </div >
911 <div v-else-if =" assumedError" class =" network-activity__total-error" >
1012 <h3 >
1113 <span >Loading balance error. Please try again later</span >
1214 </h3 >
1315 </div >
1416 <div v-else class =" network-activity__total" >
15- <h3 >
16- {{ cryptoAmount }} <span >{{ symbol }}</span >
17- </h3 >
18- <p >
19- <span v-if =" subnetwork !== ''" >Chain {{ subnetwork }} · ; </span >
20- {{ $filters.parseCurrency(fiatAmount) }}
21- </p >
17+ <div class =" network-activity__total-info" >
18+ <h3 >
19+ {{ cryptoAmount }} <span >{{ symbol }}</span >
20+ </h3 >
21+ <p >
22+ <span v-if =" subnetwork !== ''" >Chain {{ subnetwork }} · ; </span >
23+ {{ $filters.parseCurrency(fiatAmount) }}
24+ </p >
25+ </div >
26+
27+ <div v-if =" tokenPrice !== '0.00'" class =" network-activity__total-market" >
28+ <div class =" network-activity__total-market-header" >
29+ <p >Price</p >
30+ <span
31+ v-if =" priceChangePercentage !== 0"
32+ :class =" {
33+ 'network-activity__total-price-change': true,
34+ 'is-positive': priceChangePercentage > 0,
35+ 'is-negative': priceChangePercentage < 0,
36+ }"
37+ >
38+ {{ priceChangePercentage > 0 ? '+' : ''
39+ }}{{ priceChangePercentage.toFixed(2) }}%
40+ </span >
41+ </div >
42+ <h4 >{{ $filters.parseCurrency(tokenPrice) }}</h4 >
43+ <div v-if =" sparkline !== ''" class =" network-activity__total-chart" >
44+ <v-chart :option =" chartOption" />
45+ </div >
46+ </div >
2247 </div >
2348</template >
2449
2550<script setup lang="ts">
2651import BalanceLoader from ' @action/icons/common/balance-loader.vue' ;
27- import { onBeforeMount , ref , watchEffect } from ' vue' ;
52+ import { onBeforeMount , ref , watchEffect , computed } from ' vue' ;
53+ import { use } from ' echarts/core' ;
54+ import { SVGRenderer } from ' echarts/renderers' ;
55+ import { LineChart } from ' echarts/charts' ;
56+ import { GridComponent } from ' echarts/components' ;
57+ import VChart from ' vue-echarts' ;
58+
59+ use ([SVGRenderer , LineChart , GridComponent ]);
2860
2961const props = defineProps ({
3062 cryptoAmount: {
@@ -43,11 +75,61 @@ const props = defineProps({
4375 type: String ,
4476 default: ' ' ,
4577 },
78+ tokenPrice: {
79+ type: String ,
80+ default: ' 0' ,
81+ },
82+ priceChangePercentage: {
83+ type: Number ,
84+ default: 0 ,
85+ },
86+ sparkline: {
87+ type: String ,
88+ default: ' ' ,
89+ },
4690});
4791
4892let timer: NodeJS .Timeout | null = null ;
4993const assumedError = ref (false );
5094
95+ const chartOption = computed (() => ({
96+ width: 90 ,
97+ height: 32 ,
98+ color: [props .priceChangePercentage >= 0 ? ' #16a34a' : ' #dc2626' ],
99+ grid: { show: false , left: 0 , top: 0 , right: 0 , bottom: 0 },
100+ xAxis: [
101+ {
102+ show: false ,
103+ type: ' category' ,
104+ boundaryGap: false ,
105+ },
106+ ],
107+ yAxis: [
108+ {
109+ show: false ,
110+ type: ' value' ,
111+ min: ' dataMin' ,
112+ max: ' dataMax' ,
113+ },
114+ ],
115+ series: [
116+ {
117+ type: ' line' ,
118+ smooth: true ,
119+ lineStyle: {
120+ width: 1.5 ,
121+ cap: ' round' ,
122+ },
123+ areaStyle: {
124+ opacity: 0.12 ,
125+ color: props .priceChangePercentage >= 0 ? ' #16a34a' : ' #dc2626' ,
126+ },
127+ showSymbol: false ,
128+ data: props .sparkline !== ' ' ? JSON .parse (props .sparkline ) : [],
129+ },
130+ ],
131+ }));
132+
51133watchEffect (() => {
52134 if (timer ) {
53135 clearTimeout (timer );
@@ -70,54 +152,91 @@ onBeforeMount(() => {
70152<style lang="less" scoped>
71153@import ' @action/styles/theme.less' ;
72154
73- @keyframes fadeIn {
155+ @keyframes fadeInUp {
74156 from {
75157 opacity : 0 ;
158+ transform : translateY (8px );
76159 }
77160 to {
78161 opacity : 1 ;
162+ transform : translateY (0 );
79163 }
80164}
81165
82166.network-activity {
83167 &__total-error {
84- padding : 0 24px 12px 24px ;
85- animation : fadeIn 0.3s ease-out ;
168+ padding : 16px 24px ;
169+ margin : 0 24px 16px 24px ;
170+ background : rgba (239 , 68 , 68 , 0.08 );
171+ border : 1.5px solid rgba (239 , 68 , 68 , 0.2 );
172+ border-radius : 16px ;
173+ animation : fadeInUp 300ms ease-out ;
86174
87175 h3 {
88176 margin : 0 ;
89177 font-size : 14px ;
90178 line-height : 20px ;
179+ font-weight : 500 ;
91180
92181 span {
93- color : @error ;
94- font-weight : 500 ;
182+ color : #dc2626 ;
183+ font-weight : 600 ;
95184 }
96185 }
97186 }
98187
99188 &__total {
100- padding : 0 24px 12px 24px ;
101- animation : fadeIn 0.3s ease-out ;
189+ padding : 20px ;
190+ margin : 0 24px 16px 24px ;
191+ background : linear-gradient (180deg , #ffffff 0% , #fafbfc 100% );
192+ border-radius : 16px ;
193+ box-shadow : 0 2px 8px rgba (0 , 0 , 0 , 0.04 );
194+ border : 1.5px solid rgba (0 , 0 , 0 , 0.06 );
195+ animation : fadeInUp 300ms ease-out ;
196+ display : flex ;
197+ flex-direction : row ;
198+ justify-content : space-between ;
199+ align-items : center ;
200+ position : relative ;
201+ overflow : hidden ;
202+
203+ & ::before {
204+ content : ' ' ;
205+ position : absolute ;
206+ top : 0 ;
207+ left : 0 ;
208+ right : 0 ;
209+ bottom : 0 ;
210+ background : linear-gradient (
211+ 135deg ,
212+ rgba (98 , 126 , 234 , 0.03 ) 0% ,
213+ rgba (138 , 100 , 220 , 0.02 ) 100%
214+ );
215+ pointer-events : none ;
216+ }
102217
103218 h3 {
104219 font-style : normal ;
105220 font-weight : 700 ;
106- font-size : 28px ;
107- line-height : 36px ;
221+ font-size : 26px ;
222+ line-height : 32px ;
223+ letter-spacing : -0.3px ;
108224 background : linear-gradient (135deg , #627eea 0% , #8a64dc 100% );
109225 -webkit-background-clip : text ;
110226 -webkit-text-fill-color : transparent ;
111227 background-clip : text ;
112228 margin : 0 ;
229+ position : relative ;
230+ z-index : 1 ;
113231
114232 span {
115- font-size : 18 px ;
233+ font-size : 15 px ;
116234 font-weight : 600 ;
235+ margin-left : 4px ;
117236 background : linear-gradient (
118237 135deg ,
119- rgba (98 , 126 , 234 , 0.7 ) 0% ,
120- rgba (138 , 100 , 220 , 0.7 ) 100%
238+ rgba (98 , 126 , 234 , 0.65 ) 0% ,
239+ rgba (138 , 100 , 220 , 0.65 ) 100%
121240 );
122241 -webkit-background-clip : text ;
123242 background-clip : text ;
@@ -127,28 +246,107 @@ onBeforeMount(() => {
127246 p {
128247 font-style : normal ;
129248 font-weight : 500 ;
130- font-size : 15 px ;
131- line-height : 22 px ;
249+ font-size : 14 px ;
250+ line-height : 20 px ;
132251 color : @secondaryLabel ;
133- margin : 4px 0 0 0 ;
252+ margin : 6px 0 0 0 ;
253+ position : relative ;
254+ z-index : 1 ;
134255 }
135256 }
136257
258+ &__total-info {
259+ position : relative ;
260+ z-index : 1 ;
261+ animation : fadeInUp 300ms ease-out ;
262+ animation-delay : 30ms ;
263+ animation-fill-mode : both ;
264+ }
265+
266+ &__total-market {
267+ display : flex ;
268+ flex-direction : column ;
269+ align-items : flex-end ;
270+ gap : 6px ;
271+ min-width : 110px ;
272+ position : relative ;
273+ z-index : 1 ;
274+ animation : fadeInUp 300ms ease-out ;
275+ animation-delay : 60ms ;
276+ animation-fill-mode : both ;
277+
278+ &-header {
279+ display : flex ;
280+ align-items : center ;
281+ gap : 8px ;
282+
283+ p {
284+ font-size : 11px ;
285+ line-height : 14px ;
286+ font-weight : 600 ;
287+ color : @tertiaryLabel ;
288+ text-transform : uppercase ;
289+ letter-spacing : 0.5px ;
290+ margin : 0 ;
291+ }
292+ }
293+
294+ h4 {
295+ font-size : 17px ;
296+ line-height : 22px ;
297+ font-weight : 700 ;
298+ color : @primaryLabel ;
299+ margin : 0 ;
300+ }
301+ }
302+
303+ &__total-price-change {
304+ display : inline-flex ;
305+ align-items : center ;
306+ font-size : 11px ;
307+ font-weight : 600 ;
308+ padding : 3px 8px ;
309+ border-radius : 10px ;
310+ letter-spacing : 0.02em ;
311+ transition : all 200ms ease-in-out ;
312+
313+ & .is-positive {
314+ color : #16a34a ;
315+ background : rgba (34 , 197 , 94 , 0.1 );
316+ }
317+
318+ & .is-negative {
319+ color : #dc2626 ;
320+ background : rgba (239 , 68 , 68 , 0.08 );
321+ }
322+ }
323+
324+ &__total-chart {
325+ width : 90px ;
326+ height : 32px ;
327+ margin-top : 2px ;
328+ animation : fadeInUp 300ms ease-out ;
329+ animation-delay : 90ms ;
330+ animation-fill-mode : both ;
331+ }
332+
137333 &__loader-one {
138- width : 120 px ;
139- height : 20 px ;
334+ width : 150 px ;
335+ height : 28 px ;
140336 margin-bottom : 12px ;
141- margin-top : 4px ;
142337 display : block !important ;
143- border-radius : 6px ;
338+ border-radius : 10px ;
339+ animation : fadeInUp 300ms ease-out ;
144340 }
145341
146342 &__loader-two {
147- width : 80 px ;
148- height : 14 px ;
343+ width : 100 px ;
344+ height : 18 px ;
149345 display : block !important ;
150- margin-bottom : 6px ;
151- border-radius : 4px ;
346+ border-radius : 8px ;
347+ animation : fadeInUp 300ms ease-out ;
348+ animation-delay : 30ms ;
349+ animation-fill-mode : both ;
152350 }
153351}
154352 </style >
0 commit comments