import { useCallback, useEffect, useState } from 'react'; import { getBaseApiReact } from '../../App'; import { Box, Tooltip, Typography, useTheme } from '@mui/material'; import { BarSpinner } from '../../common/Spinners/BarSpinner/BarSpinner'; import { formatDate } from '../../utils/time'; import { useTranslation } from 'react-i18next'; function getAverageLtcPerQort(trades) { let totalQort = 0; let totalLtc = 0; trades.forEach((trade) => { const qort = parseFloat(trade.qortAmount); const ltc = parseFloat(trade.foreignAmount); totalQort += qort; totalLtc += ltc; }); // Avoid division by zero if (totalQort === 0) return 0; // Weighted average price return parseFloat((totalLtc / totalQort).toFixed(8)); } function getTwoWeeksAgoTimestamp() { const now = new Date(); now.setDate(now.getDate() - 14); // Subtract 14 days return now.getTime(); // Get timestamp in milliseconds } function formatWithCommasAndDecimals(number) { return Number(number).toLocaleString(); } export const QortPrice = () => { const [ltcPerQort, setLtcPerQort] = useState(null); const [supply, setSupply] = useState(null); const [lastBlock, setLastBlock] = useState(null); const [loading, setLoading] = useState(true); const { t } = useTranslation(['core', 'tutorial']); const theme = useTheme(); const getPrice = useCallback(async () => { try { setLoading(true); const response = await fetch( `${getBaseApiReact()}/crosschain/trades?foreignBlockchain=LITECOIN&minimumTimestamp=${getTwoWeeksAgoTimestamp()}&limit=20&reverse=true` ); const data = await response.json(); setLtcPerQort(getAverageLtcPerQort(data)); } catch (error) { console.error(error); } finally { setLoading(false); } }, []); const getLastBlock = useCallback(async () => { try { setLoading(true); const response = await fetch(`${getBaseApiReact()}/blocks/last`); const data = await response.json(); setLastBlock(data); } catch (error) { console.error(error); } finally { setLoading(false); } }, []); const getSupplyInCirculation = useCallback(async () => { try { setLoading(true); const response = await fetch( `${getBaseApiReact()}/stats/supply/circulating` ); const data = await response.text(); formatWithCommasAndDecimals(data); setSupply(formatWithCommasAndDecimals(data)); } catch (error) { console.error(error); } finally { setLoading(false); } }, []); useEffect(() => { getPrice(); getSupplyInCirculation(); getLastBlock(); const interval = setInterval(() => { getPrice(); getSupplyInCirculation(); getLastBlock(); }, 900000); return () => clearInterval(interval); }, [getPrice]); return ( Based on the latest 20 trades } placement="bottom" arrow sx={{ fontSize: '24' }} slotProps={{ tooltip: { sx: { color: theme.palette.text.primary, backgroundColor: theme.palette.background.paper, }, }, arrow: { sx: { color: theme.palette.text.primary, }, }, }} > {t('core:price', { postProcess: 'capitalize' })} {!ltcPerQort ? ( ) : ( {ltcPerQort} LTC/QORT )} {t('core:supply', { postProcess: 'capitalize' })} {!supply ? ( ) : ( {supply} QORT )} {lastBlock?.timestamp && formatDate(lastBlock?.timestamp)} } placement="bottom" arrow sx={{ fontSize: '24' }} slotProps={{ tooltip: { sx: { color: theme.palette.text.primary, backgroundColor: theme.palette.background.paper, }, }, arrow: { sx: { color: theme.palette.text.primary, }, }, }} > {t('core:last_height', { postProcess: 'capitalize' })} {!lastBlock?.height ? ( ) : ( {lastBlock?.height} )} ); };