1
- import * as React from 'react' ;
2
- import AspectRatio from '@mui/joy/AspectRatio' ;
1
+ import React , { useState , useEffect } from 'react' ;
3
2
import Box from '@mui/joy/Box' ;
4
3
import Typography from '@mui/joy/Typography' ;
5
- import Card from '@mui/joy/Card' ;
6
-
7
- const data = [
8
- {
9
- src : 'https://images.unsplash.com/photo-1502657877623-f66bf489d236' ,
10
- title : 'Night view' ,
11
- description : '4.21M views' ,
12
- } ,
13
- {
14
- src : 'https://images.unsplash.com/photo-1527549993586-dff825b37782' ,
15
- title : 'Lake view' ,
16
- description : '4.74M views' ,
17
- } ,
18
- {
19
- src : 'https://images.unsplash.com/photo-1532614338840-ab30cf10ed36' ,
20
- title : 'Mountain view' ,
21
- description : '3.98M views' ,
22
- } ,
4
+ import { styled } from '@mui/joy/styles' ;
5
+ import { keyframes } from '@emotion/react' ;
6
+ import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward' ;
7
+ import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward' ;
8
+
9
+ const currencyData = [
10
+ { code : 'USD' , name : 'Dólar' , emoji : '🇺🇸' } ,
11
+ { code : 'EUR' , name : 'Euro' , emoji : '🇪🇺' } ,
12
+ { code : 'BTC' , name : 'Bitcoin' , emoji : '₿' } ,
13
+ { code : 'GBP' , name : 'Libra' , emoji : '🇬🇧' } ,
14
+ { code : 'ARS' , name : 'Peso Argentino' , emoji : '🇦🇷' } ,
15
+ { code : 'CLP' , name : 'Peso Chileno' , emoji : '🇨🇱' } ,
16
+ { code : 'JPY' , name : 'Iene' , emoji : '🇯🇵' }
23
17
] ;
24
18
25
- export default function CarouselRatio ( ) {
19
+ const slideAnimation = keyframes `
20
+ 0% {
21
+ transform: translateX(0);
22
+ }
23
+ 100% {
24
+ transform: translateX(-16%);
25
+ }
26
+ ` ;
27
+
28
+ const CarouselContainer = styled ( Box ) ( ( { theme } ) => ( {
29
+ width : '100%' ,
30
+ position : 'relative' ,
31
+ overflow : 'hidden' ,
32
+ height : '40px' ,
33
+ } ) ) ;
34
+
35
+ const CarouselTrack = styled ( Box ) ( {
36
+ display : 'inline-flex' ,
37
+ animation : `${ slideAnimation } 30s linear infinite` ,
38
+ width : '300%' ,
39
+ } ) ;
40
+
41
+ const CarouselCard = styled ( Box ) ( ( { theme } ) => ( {
42
+ flexShrink : 0 ,
43
+ width : 'auto' ,
44
+ minWidth : '250px' ,
45
+ marginRight : theme . spacing ( 2 ) ,
46
+ height : '30px' ,
47
+ display : 'flex' ,
48
+ alignItems : 'center' ,
49
+ justifyContent : 'space-around' ,
50
+ whiteSpace : 'nowrap' ,
51
+ } ) ) ;
52
+
53
+ export default function CurrencyCarousel ( ) {
54
+ const [ currencyRates , setCurrencyRates ] = useState ( [ ] ) ;
55
+
56
+ useEffect ( ( ) => {
57
+ const fetchCurrencyRates = async ( ) => {
58
+ try {
59
+ const response = await fetch ( 'https://economia.awesomeapi.com.br/last/USD-BRL,EUR-BRL,BTC-BRL,GBP-BRL,ARS-BRL,CLP-BRL,JPY-BRL' ) ;
60
+ const data = await response . json ( ) ;
61
+
62
+ const formattedRates = currencyData . map ( currency => {
63
+ const key = `${ currency . code } BRL` ;
64
+ const currencyInfo = data [ key ] ;
65
+
66
+ return {
67
+ ...currency ,
68
+ price : parseFloat ( currencyInfo . bid ) ,
69
+ variation : parseFloat ( currencyInfo . pctChange )
70
+ } ;
71
+ } ) ;
72
+
73
+ setCurrencyRates ( formattedRates ) ;
74
+ } catch ( error ) {
75
+ console . error ( 'Erro ao buscar cotações:' , error ) ;
76
+ }
77
+ } ;
78
+
79
+ fetchCurrencyRates ( ) ;
80
+
81
+ const intervalId = setInterval ( fetchCurrencyRates , 30 * 60 * 1000 ) ; // 30 minutos
82
+
83
+ return ( ) => clearInterval ( intervalId ) ;
84
+ } , [ ] ) ;
85
+
86
+ // Triplica os rates para criar loop infinito
87
+ const repeatedRates = [ ...currencyRates , ...currencyRates , ...currencyRates ] ;
88
+
26
89
return (
27
- < Box
28
- sx = { {
29
- display : 'flex' ,
30
- gap : 1 ,
31
- py : 1 ,
32
- overflow : 'auto' ,
33
- width : 343 ,
34
- scrollSnapType : 'x mandatory' ,
35
- '& > *' : {
36
- scrollSnapAlign : 'center' ,
37
- } ,
38
- '::-webkit-scrollbar' : { display : 'none' } ,
39
- } }
40
- >
41
- { data . map ( ( item ) => (
42
- < Card orientation = "horizontal" size = "sm" key = { item . title } variant = "outlined" >
43
- < AspectRatio ratio = "1" sx = { { minWidth : 60 } } >
44
- < img
45
- srcSet = { `${ item . src } ?h=120&fit=crop&auto=format&dpr=2 2x` }
46
- src = { `${ item . src } ?h=120&fit=crop&auto=format` }
47
- alt = { item . title }
48
- />
49
- </ AspectRatio >
50
- < Box sx = { { whiteSpace : 'nowrap' , mx : 1 } } >
51
- < Typography level = "title-md" > { item . title } </ Typography >
52
- < Typography level = "body-sm" > { item . description } </ Typography >
53
- </ Box >
54
- </ Card >
55
- ) ) }
56
- </ Box >
90
+ < CarouselContainer >
91
+ < CarouselTrack >
92
+ { repeatedRates . map ( ( currency , index ) => (
93
+ < CarouselCard key = { `${ currency . code } -${ index } ` } >
94
+ < Box display = "flex" alignItems = "center" justifyContent = "space-around" sx = { { padding : '10px' } } >
95
+ < Box display = "flex" alignItems = "center" gap = { 1 } >
96
+ < Typography > { currency . emoji } </ Typography >
97
+ < Typography variant = "body2" sx = { { fontWeight : 'bold' } } >
98
+ { currency . price . toLocaleString ( 'pt-BR' , {
99
+ style : 'currency' ,
100
+ currency : 'BRL' ,
101
+ minimumFractionDigits : currency . price <= 0.01 ? 4 : 2 ,
102
+ maximumFractionDigits : currency . price <= 0.01 ? 4 : 2
103
+ } ) }
104
+ </ Typography >
105
+ { currency . variation !== 0 && (
106
+ < Box display = "flex" alignItems = "center" color = { currency . variation > 0 ? 'green' : 'red' } >
107
+ { currency . variation > 0 ? < ArrowUpwardIcon /> : < ArrowDownwardIcon /> }
108
+ < Typography variant = "body2" sx = { { fontWeight : 'bold' } } >
109
+ { Math . abs ( currency . variation ) } %
110
+ </ Typography >
111
+ </ Box >
112
+ ) }
113
+ </ Box >
114
+ </ Box >
115
+ </ CarouselCard >
116
+ ) ) }
117
+ </ CarouselTrack >
118
+ </ CarouselContainer >
57
119
) ;
58
- }
120
+ }
0 commit comments