/ src / components / ShieldedPool / Metric.tsx
Metric.tsx
  1  import { useInMobile } from "../hooks/useInMobile";
  2  import { useEffect, useState } from "react";
  3  import { MetricCard, MetricCardSkeleton } from "../ZcashMetrics/MetricCard";
  4  
  5  // interface CoinData {
  6  //   usd?: number;
  7  //   btc?: number;
  8  //   usd_market_cap?: number;
  9  //   usd_24h_vol?: number;
 10  //   usd_24h_change?: number;
 11  // }
 12  
 13  interface BlockchainInfo {
 14    market_cap_usd: number;
 15    market_price_usd: number;
 16    market_price_btc: number;
 17    blocks: number;
 18    transactions_24h: number;
 19  }
 20  
 21  const CryptoMetrics = ({ selectedCoin }: { selectedCoin: string }) => {
 22    // const [coinData, setCoinData] = useState<CoinData | null>(null);
 23    const [blockchainInfo, setBlockchainInfo] = useState<BlockchainInfo | null>({
 24      market_cap_usd: 0,
 25      market_price_usd: 0,
 26      market_price_btc: 0,
 27      blocks: Math.floor(Math.random() * 2000000),
 28      transactions_24h: 0,
 29    });
 30    const [circulation, setCirculation] = useState<number | null>(null);
 31    const [loading, setLoading] = useState(true);
 32    const [error, setError] = useState<string | null>(null);
 33    const isMobile = useInMobile();
 34  
 35    useEffect(() => {
 36      let name = selectedCoin;
 37      const fetchCoinData = async () => {
 38        // Skip fetch for Namada and Zcash (or handle differently)
 39        if (selectedCoin === "Zcash") {
 40          setLoading(false);
 41          return;
 42        }
 43  
 44        if (selectedCoin === "Atom") {
 45          name = "Cosmos Hub";
 46        } else if (selectedCoin === "Tia") {
 47          name = "Celestia";
 48        } else if (selectedCoin === "Osmo") {
 49          name = "Osmosis";
 50        } else if (selectedCoin === "stOsmo") {
 51          name = "Stride Staked Osmo";
 52        } else if (selectedCoin === "stTia") {
 53          name = "Stride Staked TIA";
 54        } else if (selectedCoin === "stAtom") {
 55          name = "Stride Staked Atom";
 56        } else if (selectedCoin === "Um") {
 57          name = "Penumbra";
 58        } else if (selectedCoin === "Ntrn") {
 59          name = "Neutron";
 60        }
 61  
 62        try {
 63          setLoading(true);
 64          setError(null);
 65  
 66          // Fetch CoinGecko data
 67          const options = {
 68            method: "GET",
 69            headers: {
 70              accept: "application/json",
 71              "x-cg-demo-api-key": "CG-C7uDKWaJaNy8ZTtVb6bWv19d",
 72            },
 73          };
 74  
 75          const response = await fetch(
 76            `https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd%2Cbtc&names=${encodeURIComponent(
 77              name.toLowerCase()
 78            )}&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true`,
 79            options
 80          );
 81  
 82          if (!response.ok) {
 83            throw new Error(`Failed to fetch data: ${response.status}`);
 84          }
 85  
 86          const data = await response.json();
 87  
 88          if (name == "Usdc") {
 89            name = "USDC";
 90          }
 91          const coinInfo = data[name];
 92          // setCoinData(coinInfo);
 93  
 94          // Mock blockchain data (replace with actual API calls)
 95          setBlockchainInfo({
 96            market_cap_usd: coinInfo?.usd_market_cap || 0,
 97            market_price_usd: coinInfo?.usd || 0,
 98            market_price_btc: coinInfo?.btc || 0,
 99            blocks: Math.floor(Math.random() * 2000000),
100            transactions_24h: coinInfo?.usd_24h_vol || 0,
101          });
102  
103          setCirculation(
104            Math.floor(
105              coinInfo?.usd_market_cap
106                ? coinInfo?.usd_market_cap / coinInfo?.usd
107                : 0
108            )
109          );
110        } catch (err) {
111          console.error("Failed to fetch coin data:", err);
112          setError(err instanceof Error ? err.message : "Unknown error occurred");
113        } finally {
114          setLoading(false);
115        }
116      };
117  
118      fetchCoinData();
119    }, [selectedCoin]);
120  
121    const metricsObj = [
122      {
123        label: "Market Cap",
124        value: blockchainInfo?.market_cap_usd
125          ? `$${blockchainInfo?.market_cap_usd.toLocaleString()}`
126          : "N/A",
127      },
128      {
129        label: "Circulation",
130        value: circulation
131          ? `${circulation?.toLocaleString()}  ${selectedCoin}`
132          : "N/A",
133      },
134      {
135        label: "Market Price (USD)",
136        value: blockchainInfo?.market_price_usd
137          ? `$${blockchainInfo?.market_price_usd.toFixed(2)}`
138          : "N/A",
139      },
140      {
141        label: "Market Price (BTC)",
142        value: blockchainInfo?.market_price_btc
143          ? isMobile
144            ? Number(blockchainInfo?.market_price_btc).toFixed(4)
145            : Number(blockchainInfo?.market_price_btc).toFixed(8)
146          : "N/A",
147      },
148      {
149        label: "Blocks",
150        value: blockchainInfo?.blocks
151          ? blockchainInfo?.blocks.toLocaleString()
152          : "N/A",
153      },
154      {
155        label: "24h Transactions",
156        value: Number(blockchainInfo?.transactions_24h)
157          ? blockchainInfo?.transactions_24h.toLocaleString()
158          : "N/A",
159      },
160    ];
161  
162    return (
163      <div className="my-12">
164        <h2 className="font-bold text-xl text-slate-700 dark:text-slate-100">
165          {loading ? (
166            <div className="h-7 bg-gray-200 dark:bg-slate-700 rounded w-24 mb-2" />
167          ) : (
168            `${selectedCoin} Metrics`
169          )}
170        </h2>
171  
172        <div className="grid grid-cols-1 imd:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mt-8">
173          {loading
174            ? metricsObj.map(({ label, value }) => (
175                <MetricCardSkeleton key={label} />
176              ))
177            : metricsObj.map(({ label, value }) => (
178                <MetricCard label={label} value={value!} key={label} />
179              ))}
180        </div>
181        {error && (
182          <p className="flex items-center bg-red-300 text-red-400 mt-8 p-4">
183            Error loading {selectedCoin} chart.
184          </p>
185        )}
186      </div>
187    );
188  };
189  
190  export default CryptoMetrics;