Skip to content

Commit 45e26c2

Browse files
authored
Merge pull request #968 from kleros/fix(web)/hardcoded-price-values
Fix(web)/hardcoded price values
2 parents 1fdb2e3 + a564786 commit 45e26c2

File tree

4 files changed

+79
-32
lines changed

4 files changed

+79
-32
lines changed

web/src/hooks/useCoinPrice.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import useSWR from "swr";
2+
3+
const fetchCoinPrice = async (...coinIds) => {
4+
const fetchData = async (coinId) => {
5+
const response = await fetch(`https://api.coingecko.com/api/v3/coins/${coinId}`);
6+
const data = await response.json();
7+
return data.market_data.current_price.usd;
8+
};
9+
10+
const prices = await Promise.all(coinIds.map(fetchData));
11+
return prices;
12+
};
13+
14+
export const useCoinPrice = (coinIds: string[]) => {
15+
const { data: prices, error } = useSWR<number[]>(coinIds, fetchCoinPrice);
16+
return {
17+
prices,
18+
error,
19+
};
20+
};

web/src/layout/Header/navbar/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const Container = styled.div<{ isOpen: boolean }>`
3535

3636
const NavBar: React.FC = () => {
3737
const [isSolutionsOpen, toggleSolution] = useToggle(false);
38-
3938
const { isOpen } = useOpenContext();
4039
useLockBodyScroll(isOpen);
4140

web/src/pages/Courts/CourtDetails/Stats.tsx

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ import styled from "styled-components";
33
import { formatUnits, formatEther } from "viem";
44
import { useParams } from "react-router-dom";
55
import { useCourtDetails, CourtDetailsQuery } from "queries/useCourtDetails";
6+
import { useCoinPrice } from "hooks/useCoinPrice";
67
import StatDisplay, { IStatDisplay } from "components/StatDisplay";
7-
import JurorIcon from "svgs/icons/user.svg";
88
import BalanceIcon from "svgs/icons/law-balance.svg";
99
import MinStake from "svgs/icons/min-stake.svg";
1010
import { commify } from "utils/commify";
1111
import VoteStake from "svgs/icons/vote-stake.svg";
1212
import PNKIcon from "svgs/icons/pnk.svg";
1313
import PNKRedistributedIcon from "svgs/icons/redistributed-pnk.svg";
1414
import EthereumIcon from "svgs/icons/ethereum.svg";
15+
import { isUndefined } from "~src/utils";
1516

1617
const StyledCard = styled.div`
1718
width: auto;
@@ -25,24 +26,29 @@ const StyledCard = styled.div`
2526

2627
interface IStat {
2728
title: string;
29+
coinId?: number;
2830
getText: (data: CourtDetailsQuery["court"]) => string;
29-
getSubtext: (data: CourtDetailsQuery["court"]) => string;
31+
getSubtext: (data: CourtDetailsQuery["court"], coinPrice?: number) => string;
3032
color: IStatDisplay["color"];
3133
icon: React.FC<React.SVGAttributes<SVGElement>>;
3234
}
3335

3436
const stats: IStat[] = [
3537
{
3638
title: "Min Stake",
39+
coinId: 0,
3740
getText: (data) => commify(formatUnits(data?.minStake, 18)),
38-
getSubtext: (data) => (parseInt(formatUnits(data?.minStake, 18)) * 0.029).toFixed(2).toString() + "$",
41+
getSubtext: (data, coinPrice) =>
42+
(parseInt(formatUnits(data?.minStake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
3943
color: "purple",
4044
icon: MinStake,
4145
},
4246
{
4347
title: "Vote Stake",
48+
coinId: 0,
4449
getText: (data) => commify(formatUnits(data?.minStake, 18)),
45-
getSubtext: (data) => (parseInt(formatUnits(data?.minStake, 18)) * 0.029).toFixed(2).toString() + "$",
50+
getSubtext: (data, coinPrice) =>
51+
(parseInt(formatUnits(data?.minStake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
4652
color: "purple",
4753
icon: VoteStake,
4854
},
@@ -55,8 +61,10 @@ const stats: IStat[] = [
5561
},
5662
{
5763
title: "PNK Staked",
64+
coinId: 0,
5865
getText: (data) => commify(formatUnits(data?.stake, 18)),
59-
getSubtext: (data) => (parseInt(formatUnits(data?.stake, 18)) * 0.029).toFixed(2).toString() + "$",
66+
getSubtext: (data, coinPrice) =>
67+
(parseInt(formatUnits(data?.stake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
6068
color: "purple",
6169
icon: PNKIcon,
6270
},
@@ -76,15 +84,19 @@ const stats: IStat[] = [
7684
},
7785
{
7886
title: "ETH paid to Jurors",
79-
getText: (data) => commify(formatEther(data?.paidETH)),
80-
getSubtext: (data) => (parseInt(formatUnits(data?.paidETH, 18)) * 1600).toFixed(2).toString() + "$",
87+
coinId: 1,
88+
getText: (data) => commify(formatEther(BigInt(data?.paidETH))),
89+
getSubtext: (data, coinPrice) =>
90+
(Number(formatUnits(data?.paidETH, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
8191
color: "blue",
8292
icon: EthereumIcon,
8393
},
8494
{
8595
title: "PNK redistributed",
96+
coinId: 0,
8697
getText: (data) => commify(formatUnits(data?.paidPNK, 18)),
87-
getSubtext: (data) => (parseInt(formatUnits(data?.paidPNK, 18)) * 0.029).toFixed(2).toString() + "$",
98+
getSubtext: (data, coinPrice) =>
99+
(parseInt(formatUnits(data?.paidPNK, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
88100
color: "purple",
89101
icon: PNKRedistributedIcon,
90102
},
@@ -93,16 +105,20 @@ const stats: IStat[] = [
93105
const Stats = () => {
94106
const { id } = useParams();
95107
const { data } = useCourtDetails(id);
108+
const { prices } = useCoinPrice(["kleros", "ethereum"]);
96109
return (
97110
<StyledCard>
98-
{stats.map(({ title, getText, getSubtext, color, icon }, i) => (
99-
<StatDisplay
100-
key={i}
101-
{...{ title, color, icon }}
102-
text={data ? getText(data.court) : "Fetching..."}
103-
subtext={data ? getSubtext(data.court) : "Fetching..."}
104-
/>
105-
))}
111+
{stats.map(({ title, coinId, getText, getSubtext, color, icon }, i) => {
112+
const coinPrice = prices && !isUndefined(coinId) ? prices[coinId] : undefined;
113+
return (
114+
<StatDisplay
115+
key={i}
116+
{...{ title, color, icon }}
117+
text={data ? getText(data.court) : "Fetching..."}
118+
subtext={data ? getSubtext(data.court, coinPrice) : "Fetching..."}
119+
/>
120+
);
121+
})}
106122
</StyledCard>
107123
);
108124
};

web/src/pages/Home/CourtOverview/Stats.tsx

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import PNKRedistributedIcon from "svgs/icons/redistributed-pnk.svg";
99
import JurorIcon from "svgs/icons/user.svg";
1010
import BalanceIcon from "svgs/icons/law-balance.svg";
1111
import { commify } from "utils/commify";
12+
import { isUndefined } from "utils/index";
1213
import { useHomePageContext, HomePageQuery, HomePageQueryDataPoints } from "hooks/useHomePageContext";
14+
import { useCoinPrice } from "hooks/useCoinPrice";
1315

1416
const StyledCard = styled(Card)`
1517
width: auto;
@@ -26,34 +28,40 @@ const getLastOrZero = (src: HomePageQuery["counters"], stat: HomePageQueryDataPo
2628

2729
interface IStat {
2830
title: string;
31+
coinId?: number;
2932
getText: (data: HomePageQuery["counters"]) => string;
30-
getSubtext: (data: HomePageQuery["counters"]) => string;
33+
getSubtext: (data: HomePageQuery["counters"], coinPrice?: number) => string;
3134
color: IStatDisplay["color"];
3235
icon: React.FC<React.SVGAttributes<SVGElement>>;
3336
}
3437

3538
const stats: IStat[] = [
3639
{
3740
title: "PNK staked",
41+
coinId: 0,
3842
getText: (counters) => commify(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)),
39-
getSubtext: (counters) =>
40-
(parseInt(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)) * 0.029).toFixed(2).toString() + "$",
43+
getSubtext: (counters, coinPrice) =>
44+
(parseInt(formatUnits(getLastOrZero(counters, "stakedPNK"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
4145
color: "purple",
4246
icon: PNKIcon,
4347
},
4448
{
4549
title: "ETH Paid to jurors",
50+
coinId: 1,
4651
getText: (counters) => commify(formatEther(getLastOrZero(counters, "paidETH"))),
47-
getSubtext: (counters) =>
48-
(parseInt(formatUnits(getLastOrZero(counters, "paidETH"), 18)) * 1650).toFixed(2).toString() + "$",
52+
getSubtext: (counters, coinPrice) =>
53+
(Number(formatUnits(getLastOrZero(counters, "paidETH"), 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
4954
color: "blue",
5055
icon: EthereumIcon,
5156
},
5257
{
5358
title: "PNK redistributed",
59+
coinId: 0,
5460
getText: (counters) => commify(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)),
55-
getSubtext: (counters) =>
56-
(parseInt(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)) * 0.029).toFixed(2).toString() + "$",
61+
getSubtext: (counters, coinPrice) =>
62+
(parseInt(formatUnits(getLastOrZero(counters, "redistributedPNK"), 18)) * (coinPrice ?? 0))
63+
.toFixed(2)
64+
.toString() + "$",
5765
color: "purple",
5866
icon: PNKRedistributedIcon,
5967
},
@@ -74,16 +82,20 @@ const stats: IStat[] = [
7482
];
7583
const Stats = () => {
7684
const { data } = useHomePageContext();
85+
const { prices } = useCoinPrice(["kleros", "ethereum"]);
7786
return (
7887
<StyledCard>
79-
{stats.map(({ title, getText, getSubtext, color, icon }, i) => (
80-
<StatDisplay
81-
key={i}
82-
{...{ title, color, icon }}
83-
text={data ? getText(data["counters"]) : "Fetching..."}
84-
subtext={data ? getSubtext(data["counters"]) : "Fetching..."}
85-
/>
86-
))}
88+
{stats.map(({ title, coinId, getText, getSubtext, color, icon }, i) => {
89+
const coinPrice = prices && !isUndefined(coinId) ? prices[coinId] : undefined;
90+
return (
91+
<StatDisplay
92+
key={i}
93+
{...{ title, color, icon }}
94+
text={data ? getText(data["counters"]) : "Fetching..."}
95+
subtext={data ? getSubtext(data["counters"], coinPrice) : "Fetching..."}
96+
/>
97+
);
98+
})}
8799
</StyledCard>
88100
);
89101
};

0 commit comments

Comments
 (0)