Skip to content

Commit

Permalink
[web] Display balance in THB and USD
Browse files Browse the repository at this point in the history
  • Loading branch information
dnjooiopa committed Apr 30, 2024
1 parent 89c728c commit f0e2fca
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 9 deletions.
7 changes: 5 additions & 2 deletions web/src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import Providers from './providers'
import MenuDropdown from '@/components/MenuDropdown'
import { AppContextProvider } from '@/contexts/AppContext'
import Providers from './providers'

const Layout = ({ children }: Readonly<{ children: React.ReactNode }>) => {
return (
<Providers>
<div className="p-4">
<MenuDropdown />
<main className="mt-16 px-8 max-w-md mx-auto text-center">{children}</main>
<main className="mt-16 px-8 max-w-md mx-auto text-center">
<AppContextProvider>{children}</AppContextProvider>
</main>
</div>
</Providers>
)
Expand Down
42 changes: 35 additions & 7 deletions web/src/components/Balance.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
'use client'

import { FC, useEffect, useState } from 'react'
import { FC, useEffect, useMemo, useState } from 'react'

import { BalanceUnit } from '@/enums'
import useIsMounted from '@/hooks/useIsMounted'
import { LnFService } from '@/services/lnf'
import { useAppContext } from '@/contexts/AppContext'

interface IBalanceProps {
unit: BalanceUnit
}
interface IBalanceProps {}

const unitList = [BalanceUnit.SATS, BalanceUnit.THB, BalanceUnit.USD]

const HundredMillion = 100000000

const Balance: FC<IBalanceProps> = ({ unit }) => {
const Balance: FC<IBalanceProps> = ({}) => {
const isMounted = useIsMounted()
const { priceTHB, priceUSD } = useAppContext()
const [isLoading, setIsLoading] = useState(true)
const [balanceSat, setBalanceSat] = useState(0)
const [balanceUnitIdx, setBalanceUnitIdx] = useState(0)

const fetchBalance = async () => {
try {
Expand All @@ -34,9 +39,32 @@ const Balance: FC<IBalanceProps> = ({ unit }) => {
return () => {}
}, [isMounted])

const unit = useMemo(() => unitList[balanceUnitIdx], [balanceUnitIdx])

const displayBalance = useMemo(() => {
switch (unit) {
case BalanceUnit.SATS:
return balanceSat
case BalanceUnit.THB:
const blTHB = (balanceSat * priceTHB) / HundredMillion
return balanceSat > 0 && blTHB <= 0 ? '...' : blTHB.toFixed(2)
case BalanceUnit.USD:
const blUSD = (balanceSat * priceUSD) / HundredMillion
return balanceSat > 0 && blUSD <= 0 ? '...' : blUSD.toFixed(2)
default:
return balanceSat
}
}, [balanceSat, unit])

return (
<div>
<h1 className="text-6xl">{isLoading ? '...' : balanceSat}</h1>
<div
onClick={() => {
setBalanceUnitIdx((prev) => {
return prev + 1 >= unitList.length ? 0 : prev + 1
})
}}
>
<h1 className="text-6xl">{isLoading ? '...' : displayBalance}</h1>
<p className="mt-2 text-lg">{unit}</p>
</div>
)
Expand Down
46 changes: 46 additions & 0 deletions web/src/contexts/AppContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use client'

import { FC, PropsWithChildren, createContext, useContext, useEffect, useMemo, useState } from 'react'

import { PriceService } from '@/services/price'
import useIsMounted from '@/hooks/useIsMounted'

interface IAppContext {
priceTHB: number
priceUSD: number
}

export const AppContext = createContext<IAppContext>({
priceTHB: 0,
priceUSD: 0,
})

interface IAppContextProviderProps extends PropsWithChildren {}

export const AppContextProvider: FC<IAppContextProviderProps> = ({ children }) => {
const isMounted = useIsMounted()
const [priceTHB, setPriceTHB] = useState(0)
const [priceUSD, setPriceUSD] = useState(0)

const fetchPrice = async () => {
try {
const res = await PriceService.getPrice()
setPriceTHB(res?.bitcoin['thb'] ?? 0)
setPriceUSD(res?.bitcoin['usd'] ?? 0)
} catch (e) {
console.error('error:', e)
}
}

useEffect(() => {
if (!isMounted) return

fetchPrice()
}, [isMounted])

const value: IAppContext = useMemo(() => ({ priceTHB, priceUSD }), [priceTHB, priceUSD])

return <AppContext.Provider value={value}>{children}</AppContext.Provider>
}

export const useAppContext = () => useContext(AppContext)
9 changes: 9 additions & 0 deletions web/src/services/price.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { AxiosRequestConfig } from 'axios'

import BaseService from './base'

export class PriceService extends BaseService {
static getPrice(config: AxiosRequestConfig = {}): Promise<GetPriceResult> {
return this._post('/price.get', {}, config)
}
}
3 changes: 3 additions & 0 deletions web/src/types/price.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface GetPriceResult {
bitcoin: Record<string, number>
}

0 comments on commit f0e2fca

Please sign in to comment.