Skip to content

Commit f1a9698

Browse files
committed
feat: add custom hook for price fetching
1 parent 8e53da5 commit f1a9698

File tree

3 files changed

+109
-70
lines changed

3 files changed

+109
-70
lines changed

web/src/hooks/useCoinPrice.tsx

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

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import styled from "styled-components";
33
import { useLockBodyScroll, useToggle } from "react-use";
4+
import { useCoinPrice } from "hooks/useCoinPrice";
45
import ConnectButton from "components/ConnectButton";
56
import LightButton from "components/LightButton";
67
import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg";
@@ -35,7 +36,8 @@ const Container = styled.div<{ isOpen: boolean }>`
3536

3637
const NavBar: React.FC = () => {
3738
const [isSolutionsOpen, toggleSolution] = useToggle(false);
38-
39+
const { prices } = useCoinPrice(["kleros", "ethereum"]);
40+
console.log("🚀 ~ file: index.tsx:40 ~ prices:", prices!);
3941
const { isOpen } = useOpenContext();
4042
useLockBodyScroll(isOpen);
4143

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

Lines changed: 85 additions & 69 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,84 +26,99 @@ 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

34-
const stats: IStat[] = [
35-
{
36-
title: "Min Stake",
37-
getText: (data) => commify(formatUnits(data?.minStake, 18)),
38-
getSubtext: (data) => (parseInt(formatUnits(data?.minStake, 18)) * 0.029).toFixed(2).toString() + "$",
39-
color: "purple",
40-
icon: MinStake,
41-
},
42-
{
43-
title: "Vote Stake",
44-
getText: (data) => commify(formatUnits(data?.minStake, 18)),
45-
getSubtext: (data) => (parseInt(formatUnits(data?.minStake, 18)) * 0.029).toFixed(2).toString() + "$",
46-
color: "purple",
47-
icon: VoteStake,
48-
},
49-
{
50-
title: "Active Jurors",
51-
getText: (data) => data?.numberStakedJurors,
52-
getSubtext: () => "",
53-
color: "purple",
54-
icon: PNKRedistributedIcon,
55-
},
56-
{
57-
title: "PNK Staked",
58-
getText: (data) => commify(formatUnits(data?.stake, 18)),
59-
getSubtext: (data) => (parseInt(formatUnits(data?.stake, 18)) * 0.029).toFixed(2).toString() + "$",
60-
color: "purple",
61-
icon: PNKIcon,
62-
},
63-
{
64-
title: "Cases",
65-
getText: (data) => data?.numberDisputes,
66-
getSubtext: () => "",
67-
color: "orange",
68-
icon: BalanceIcon,
69-
},
70-
{
71-
title: "In Progress",
72-
getText: (data) => data?.numberDisputes,
73-
getSubtext: () => "",
74-
color: "orange",
75-
icon: BalanceIcon,
76-
},
77-
{
78-
title: "ETH paid to Jurors",
79-
getText: (data) => commify(formatEther(data?.paidETH)),
80-
getSubtext: (data) => (parseInt(formatUnits(data?.paidETH, 18)) * 1600).toFixed(2).toString() + "$",
81-
color: "blue",
82-
icon: EthereumIcon,
83-
},
84-
{
85-
title: "PNK redistributed",
86-
getText: (data) => commify(formatUnits(data?.paidPNK, 18)),
87-
getSubtext: (data) => (parseInt(formatUnits(data?.paidPNK, 18)) * 0.029).toFixed(2).toString() + "$",
88-
color: "purple",
89-
icon: PNKRedistributedIcon,
90-
},
91-
];
92-
9336
const Stats = () => {
37+
const stats: IStat[] = [
38+
{
39+
title: "Min Stake",
40+
coinId: 0,
41+
getText: (data) => commify(formatUnits(data?.minStake, 18)),
42+
getSubtext: (data, coinPrice) =>
43+
(parseInt(formatUnits(data?.minStake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
44+
color: "purple",
45+
icon: MinStake,
46+
},
47+
{
48+
title: "Vote Stake",
49+
coinId: 0,
50+
getText: (data) => commify(formatUnits(data?.minStake, 18)),
51+
getSubtext: (data, coinPrice) =>
52+
(parseInt(formatUnits(data?.minStake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
53+
color: "purple",
54+
icon: VoteStake,
55+
},
56+
{
57+
title: "Active Jurors",
58+
getText: (data) => data?.numberStakedJurors,
59+
getSubtext: () => "",
60+
color: "purple",
61+
icon: PNKRedistributedIcon,
62+
},
63+
{
64+
title: "PNK Staked",
65+
coinId: 0,
66+
getText: (data) => commify(formatUnits(data?.stake, 18)),
67+
getSubtext: (data, coinPrice) =>
68+
(parseInt(formatUnits(data?.stake, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
69+
color: "purple",
70+
icon: PNKIcon,
71+
},
72+
{
73+
title: "Cases",
74+
getText: (data) => data?.numberDisputes,
75+
getSubtext: () => "",
76+
color: "orange",
77+
icon: BalanceIcon,
78+
},
79+
{
80+
title: "In Progress",
81+
getText: (data) => data?.numberDisputes,
82+
getSubtext: () => "",
83+
color: "orange",
84+
icon: BalanceIcon,
85+
},
86+
{
87+
title: "ETH paid to Jurors",
88+
coinId: 1,
89+
getText: (data) => commify(formatEther(data?.paidETH)),
90+
getSubtext: (data, coinPrice) =>
91+
(parseInt(formatUnits(data?.paidETH, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
92+
color: "blue",
93+
icon: EthereumIcon,
94+
},
95+
{
96+
title: "PNK redistributed",
97+
coinId: 0,
98+
getText: (data) => commify(formatUnits(data?.paidPNK, 18)),
99+
getSubtext: (data, coinPrice) =>
100+
(parseInt(formatUnits(data?.paidPNK, 18)) * (coinPrice ?? 0)).toFixed(2).toString() + "$",
101+
color: "purple",
102+
icon: PNKRedistributedIcon,
103+
},
104+
];
105+
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].usd : 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
};

0 commit comments

Comments
 (0)