-
Notifications
You must be signed in to change notification settings - Fork 192
/
Copy pathstats.js
126 lines (114 loc) · 2.77 KB
/
stats.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { Text, Box, Flex } from 'theme-ui'
import { useEffect, useState } from 'react'
const easeInOutExpo = x =>
x === 0
? 0
: x === 1
? 1
: x < 0.5
? Math.pow(2, 20 * x - 10) / 2
: (2 - Math.pow(2, -20 * x + 10)) / 2
function startMoneyAnimation(
setBalance,
amount,
duration = 2_000,
moneyFormatter
) {
const startTime = performance.now()
function animate() {
const time = performance.now() - startTime
const progress = time / duration
const easedProgress = easeInOutExpo(progress)
setBalance(moneyFormatter(amount * easedProgress))
if (progress < 1) {
requestAnimationFrame(animate)
} else {
setBalance(moneyFormatter(amount))
}
}
requestAnimationFrame(animate)
}
function formatMoney(amount) {
const normalisedAmount = amount / 100
return normalisedAmount
.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
.split('.')
}
const Stats = ({ stats }) => {
if (stats.transactions_volume === undefined) {
return null
}
const [balance, setBalance] = useState(0) // A formatted balance string, split by decimal
useEffect(() => {
let observer = new IntersectionObserver(
e => {
if (e[0].isIntersecting) {
console.info('intersecting')
startMoneyAnimation(
setBalance,
stats.transactions_volume,
2_500,
formatMoney
)
}
},
{ threshold: 1.0 }
)
observer.observe(document.querySelector('#parent'))
return () => observer.disconnect()
}, [stats.transactions_volume])
return (
<Box id="parent">
<Flex sx={{ flexDirection: 'column', alignItems: 'center' }}>
<Text sx={{ fontSize: [3, 4] }}>So far we have enabled</Text>
{stats ? (
<>
<Text
variant="title"
color="green"
sx={{
color: 'green',
fontSize: [5, 6]
}}
>
{balance[0]}
<Text sx={{ fontSize: [3, 4] }}>.{balance[1]}</Text>
</Text>
</>
) : (
<Text
variant="title"
color="green"
sx={{
color: 'green',
fontSize: [5, 6]
}}
>
...
</Text>
)}
<Text sx={{ fontSize: [3, 4] }}>in transactions</Text>
</Flex>
</Box>
)
}
export async function getStaticProps(context) {
const res = await fetch(`https://hcb.hackclub.com/stats`)
try {
const stats = await res.json()
return {
props: {
stats
},
revalidate: 10
}
} catch (e) {
return {
props: {
stats: {}
},
revalidate: 10
}
}
}
export default Stats