mirror of
https://github.com/System-End/site.git
synced 2026-04-19 19:45:07 +00:00
Make Stats Update Live + Deprecate Old v2 Helpers
This commit is contained in:
parent
8439e7e2df
commit
b1ad2fe4e2
5 changed files with 20 additions and 133 deletions
|
|
@ -1,9 +1,8 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { Text, Box } from 'theme-ui'
|
||||
import Stat from '../stat'
|
||||
import api from '../../lib/api'
|
||||
import { timeSince } from '../../lib/helpers'
|
||||
import { keyframes } from '@emotion/react'
|
||||
import { timeSince } from '../../lib/helpers'
|
||||
import useSWR from 'swr'
|
||||
import Stat from '../stat'
|
||||
|
||||
const renderMoney = amount =>
|
||||
Math.floor(amount / 100)
|
||||
|
|
@ -42,22 +41,16 @@ function Dot() {
|
|||
}
|
||||
|
||||
const Stats = props => {
|
||||
const [volume, setVolume] = useState(100 * 1000 * 1000) // 1MM default
|
||||
const [raised, setRaised] = useState(100 * 1000 * 500) // half million default
|
||||
const [lastUpdated, setLastUpdated] = useState(Date.now()) // now default
|
||||
|
||||
useEffect(() => {
|
||||
loadStats()
|
||||
const fetcher = (...args) => fetch(...args).then(res => res.json())
|
||||
const { data } = useSWR('https://bank.hackclub.com/stats', fetcher, {
|
||||
fallbackData: {
|
||||
volume: 100 * 1000 * 1000,
|
||||
raised: 100 * 1000 * 500,
|
||||
lastUpdated: Date.now()
|
||||
}
|
||||
})
|
||||
|
||||
const loadStats = () => {
|
||||
api.get('https://bank.hackclub.com/stats').then(stats => {
|
||||
setVolume(renderMoney(stats.transactions_volume))
|
||||
setRaised(renderMoney(stats.raised))
|
||||
setLastUpdated(stats.last_transaction_date * 1000)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Text
|
||||
|
|
@ -68,15 +61,14 @@ const Stats = props => {
|
|||
mb={[2, 3]}
|
||||
>
|
||||
<Dot />
|
||||
As of {timeSince(lastUpdated, false, true)}...
|
||||
As of {timeSince(data.last_transaction_date * 1000, false, true)}...
|
||||
</Text>
|
||||
|
||||
<Box as="div">
|
||||
<Stat {...props} value={raised} label="raised on Hack Club Bank" />
|
||||
<Box>
|
||||
<Stat {...props} value={renderMoney(data.raised)} label="raised on Hack Club Bank" />
|
||||
<Stat
|
||||
{...props}
|
||||
fontSize={[3, 4, 5]}
|
||||
value={volume}
|
||||
value={renderMoney(data.transactions_volume)}
|
||||
label="total amount transacted"
|
||||
/>
|
||||
</Box>
|
||||
|
|
|
|||
78
lib/api.js
78
lib/api.js
|
|
@ -1,78 +0,0 @@
|
|||
import storage from './storage'
|
||||
|
||||
export const url = 'https://api.hackclub.com/'
|
||||
const methods = ['GET', 'PUT', 'POST', 'PATCH', 'DELETE']
|
||||
|
||||
const generateMethod =
|
||||
method =>
|
||||
(path, options = {}, fetchOptions = {}) => {
|
||||
let filteredOptions = {}
|
||||
const authToken = storage.get('authToken')
|
||||
if (authToken) {
|
||||
options.authToken = authToken
|
||||
}
|
||||
|
||||
for (let [key, value] of Object.entries(options)) {
|
||||
switch (key) {
|
||||
case 'authToken':
|
||||
filteredOptions.headers = filteredOptions.headers || {}
|
||||
filteredOptions.headers['Authorization'] = `Bearer ${value}`
|
||||
break
|
||||
case 'data':
|
||||
if (value instanceof FormData) {
|
||||
filteredOptions.body = value
|
||||
} else {
|
||||
filteredOptions.body = JSON.stringify(value)
|
||||
filteredOptions.headers = filteredOptions.headers || {}
|
||||
filteredOptions.headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
break
|
||||
default:
|
||||
filteredOptions[key] = value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (fetchOptions.noAuth) {
|
||||
if (filteredOptions.headers && filteredOptions.headers['Authorization']) {
|
||||
delete filteredOptions.headers['Authorization']
|
||||
}
|
||||
}
|
||||
|
||||
const foreignUrl = path.startsWith('http')
|
||||
const urlPath = foreignUrl ? path : url + path
|
||||
|
||||
return fetch(urlPath, { method, ...filteredOptions })
|
||||
.then(res => {
|
||||
if (res.ok) {
|
||||
const contentType = res.headers.get('content-type')
|
||||
if (contentType && contentType.indexOf('application/json') !== -1) {
|
||||
return res.json()
|
||||
} else {
|
||||
return res.text()
|
||||
}
|
||||
} else {
|
||||
if (res.status === 422) {
|
||||
return res.json().then(json => {
|
||||
// eslint-disable-next-line
|
||||
throw { ...res, errors: json.errors }
|
||||
})
|
||||
} else {
|
||||
throw res
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
let api = {}
|
||||
|
||||
methods.forEach(method => {
|
||||
api[method.toLowerCase()] = generateMethod(method)
|
||||
})
|
||||
|
||||
api.currentUser = () => api.get(`v1/users/current`)
|
||||
|
||||
export default api
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
const stubbedStorage = {}
|
||||
'get set remove keys'
|
||||
.split(' ')
|
||||
.forEach(method => (stubbedStorage[method] = () => null))
|
||||
|
||||
let localStorage
|
||||
try {
|
||||
localStorage = window.localStorage
|
||||
} catch (e) {
|
||||
if (e instanceof ReferenceError) {
|
||||
localStorage = stubbedStorage
|
||||
}
|
||||
}
|
||||
|
||||
const storage = {
|
||||
get: key => {
|
||||
try {
|
||||
// (max@maxwofford.com) Values that were set before values were stringified might fail to parse, so we return the raw storage item if we can't parse it
|
||||
return JSON.parse(localStorage.getItem(key))
|
||||
} catch (e) {
|
||||
if (e.name === 'SyntaxError') {
|
||||
return localStorage.getItem(key)
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
},
|
||||
set: (key, value) => localStorage.setItem(key, JSON.stringify(value)),
|
||||
remove: key => localStorage.removeItem(key),
|
||||
keys: () => Object.keys(localStorage)
|
||||
}
|
||||
|
||||
export default storage
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
"react-tsparticles": "^1.40.1",
|
||||
"react-use-websocket": "3.0.0",
|
||||
"resnow": "^1.0.0",
|
||||
"swr": "^1.2.1",
|
||||
"theme-ui": "^0.13",
|
||||
"tinytime": "^0.2.6",
|
||||
"turndown": "^7.1.1"
|
||||
|
|
|
|||
|
|
@ -3285,6 +3285,11 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
swr@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/swr/-/swr-1.2.1.tgz#c21a4fe2139cb1c4630450589b5b5add947a9d41"
|
||||
integrity sha512-1cuWXqJqXcFwbgONGCY4PHZ8v05009JdHsC3CIC6u7d00kgbMswNr1sHnnhseOBxtzVqcCNpOHEgVDciRer45w==
|
||||
|
||||
tapable@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue