Skip to content

Commit

Permalink
Update ShieldedPoolDashboard.tsx
Browse files Browse the repository at this point in the history
  • Loading branch information
zksquirrel authored Nov 24, 2024
1 parent f68685a commit 2ed2b54
Showing 1 changed file with 123 additions and 69 deletions.
192 changes: 123 additions & 69 deletions src/app/dashboard/ShieldedPoolDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
import Button from "@/components/Button/Button";
import Checkbox from "@/components/Checkbox/Checkbox";
import Tools from "@/components/tools";
import ZecToZatsConverter from "@/components/Converter/ZecToZatsConverter"; // Import Zec to Zats Converter
import ZecToZatsConverter from "@/components/Converter/ZecToZatsConverter";
import useExportDashboardAsPNG from "@/hooks/useExportDashboardAsPNG";
import dynamic from "next/dynamic";

Expand Down Expand Up @@ -81,6 +81,68 @@ interface ShieldedTxCount {
timestamp: string;
}

async function getBlockchainData(): Promise<BlockchainInfo | null> {
try {
const response = await fetch(
"https://api.blockchair.com/zcash/stats?key=A___8A4ebOe3KJT9bqiiOHWnJbCLpDUZ"
);
if (!response.ok) {
console.error("Failed to fetch blockchain data:", response.statusText);
return null;
}
const data = await response.json();
return data.data as BlockchainInfo;
} catch (error) {
console.error("Error fetching blockchain data:", error);
return null;
}
}

async function getBlockchainInfo(): Promise<number | null> {
try {
const response = await fetch(blockchainInfoUrl, { mode: "cors" });
if (!response.ok) {
console.error("Failed to fetch blockchain info:", response.statusText);
return null;
}
const data = await response.json();
return data.chainSupply?.chainValue ?? null;
} catch (error) {
console.error("Error fetching blockchain info:", error);
return null;
}
}

async function getSupplyData(url: string): Promise<SupplyData[]> {
try {
const response = await fetch(url);
if (!response.ok) {
console.error("Failed to fetch supply data:", response.statusText);
return [];
}
const data = await response.json();
return data as SupplyData[];
} catch (error) {
console.error("Error fetching supply data:", error);
return [];
}
}

async function getLastUpdatedDate(): Promise<string> {
try {
const response = await fetch(apiUrl);
if (!response.ok) {
console.error("Failed to fetch last updated date:", response.statusText);
return "N/A";
}
const data = await response.json();
return data[0]?.commit?.committer?.date ?? "N/A";
} catch (error) {
console.error("Error fetching last updated date:", error);
return "N/A";
}
}

const ShieldedPoolDashboard = () => {
const [selectedPool, setSelectedPool] = useState("default");
const [blockchainInfo, setBlockchainInfo] = useState<BlockchainInfo | null>(
Expand All @@ -91,15 +153,11 @@ const ShieldedPoolDashboard = () => {
const [saplingSupply, setSaplingSupply] = useState<SupplyData | null>(null);
const [orchardSupply, setOrchardSupply] = useState<SupplyData | null>(null);
const [lastUpdated, setLastUpdated] = useState<string | null>(null);
const [shieldedTxCount, setShieldedTxCount] =
useState<ShieldedTxCount | null>(null);

const [selectedTool, setSelectedTool] = useState<string>("supply");
const [selectedToolName, setSelectedToolName] = useState<string>(
"Shielded Supply Chart (ZEC)"
);
const [cumulativeCheck, setCumulativeCheck] = useState(true);
const [filterSpamCheck, setFilterSpamCheck] = useState(false);

const { divChartRef, handleSaveToPng } = useExportDashboardAsPNG();

Expand All @@ -111,8 +169,6 @@ const ShieldedPoolDashboard = () => {
return saplingUrl;
case "orchard":
return orchardUrl;
case "hashrate":
return hashrateUrl;
default:
return defaultUrl;
}
Expand All @@ -132,112 +188,110 @@ const ShieldedPoolDashboard = () => {
};

const getTotalShieldedSupply = () => {
const totalSupply =
return (
(sproutSupply?.supply ?? 0) +
(saplingSupply?.supply ?? 0) +
(orchardSupply?.supply ?? 0);
return totalSupply;
};

const handleToolChange = (tool: string) => {
setSelectedTool(tool);
switch (tool) {
case "supply":
setSelectedPool("default");
setSelectedToolName("Shielded Supply Chart (ZEC)");
break;
case "transaction":
setSelectedPool("default");
setSelectedToolName("Shielded Transactions Chart (ZEC)");
break;
}
(orchardSupply?.supply ?? 0)
);
};

useEffect(() => {
const fetchLastUpdatedDate = async () => {
const fetchBlockchainInfo = async () => {
try {
const response = await fetch(defaultUrl);
const data = await response.json();
setBlockchainInfo(data);
} catch (error) {
console.error("Error fetching blockchain info:", error);
}
};

const fetchLastUpdated = async () => {
try {
const response = await fetch(apiUrl);
if (!response.ok) {
console.error("Failed to fetch last updated date:", response.statusText);
setLastUpdated("N/A");
return;
}
const data = await response.json();
setLastUpdated(data[0]?.commit?.committer?.date ?? "N/A");
} catch (error) {
console.error("Error fetching last updated date:", error);
setLastUpdated("N/A");
}
};

fetchLastUpdatedDate();
fetchBlockchainInfo();
fetchLastUpdated();
}, []);

return (
<div>
<h2 className="font-bold mt-8 mb-4">{selectedToolName}</h2>
<div className="border p-3 rounded-lg">
<Tools onToolChange={handleToolChange} />
<Tools onToolChange={(tool) => setSelectedTool(tool)} />
<div className="relative">
<div ref={divChartRef}>
{selectedTool === "supply" && (
<ShieldedPoolChart dataUrl={getDataUrl()} color={getDataColor()} />
<ShieldedPoolChart
dataUrl={getDataUrl()}
color={getDataColor()}
/>
)}
{selectedTool === "transaction" && (
<TransactionSummaryChart
dataUrl={txsummaryUrl}
pool={selectedPool}
cumulative={cumulativeCheck}
filter={filterSpamCheck}
/>
)}
</div>
</div>
<div className="flex justify-end gap-12 text-right mt-4 text-sm text-gray-500">
<span className="px-3 py-2">
<span>
Last updated:{" "}
{lastUpdated ? new Date(lastUpdated).toLocaleDateString() : "N/A"}
</span>
<Button
text="Export (PNG)"
className="px-3 py-2 border text-white border-slate-300 rounded-md shadow-sm bg-[#1984c7]"
className="bg-blue-500 text-white px-3 py-2 rounded-lg"
onClick={() =>
handleSaveToPng(selectedPool, { sproutSupply, saplingSupply, orchardSupply }, selectedTool)
handleSaveToPng(selectedPool, { sproutSupply, saplingSupply })
}
/>
</div>
</div>
{selectedTool === "supply" && (
<div className="mt-8 flex flex-col items-center">
<div className="flex justify-center space-x-4">
<Button
text="Total Shielded"
className={`rounded-[0.4rem] py-2 px-4 text-white ${
selectedPool === "default" ? "bg-[#1984c7]" : "bg-gray-400"
}`}
onClick={() => setSelectedPool("default")}
/>
<Button
text="Sprout Pool"
className={`rounded-[0.4rem] py-2 px-4 text-white ${
selectedPool === "sprout" ? "bg-[#1984c7]" : "bg-gray-400"
}`}
onClick={() => setSelectedPool("sprout")}
/>
</div>
<div
className="mt-8 w-full max-w-md"
style={{
background: "rgba(255, 255, 255, 0.85)",
borderRadius: "10px",
boxShadow: "0px 4px 6px rgba(0, 0, 0, 0.1)",
padding: "20px",
}}
>
<ZecToZatsConverter />
</div>

<div className="mt-8 flex flex-col items-center">
<div className="flex justify-center space-x-4">
<Button
text="Total Shielded"
className={`rounded-md py-2 px-4 text-white ${
selectedPool === "default" ? "bg-blue-500" : "bg-gray-400"
}`}
onClick={() => setSelectedPool("default")}
/>
<Button
text="Sprout Pool"
className={`rounded-md py-2 px-4 text-white ${
selectedPool === "sprout" ? "bg-blue-500" : "bg-gray-400"
}`}
onClick={() => setSelectedPool("sprout")}
/>
<Button
text="Sapling Pool"
className={`rounded-md py-2 px-4 text-white ${
selectedPool === "sapling" ? "bg-blue-500" : "bg-gray-400"
}`}
onClick={() => setSelectedPool("sapling")}
/>
<Button
text="Orchard Pool"
className={`rounded-md py-2 px-4 text-white ${
selectedPool === "orchard" ? "bg-blue-500" : "bg-gray-400"
}`}
onClick={() => setSelectedPool("orchard")}
/>
</div>

<div className="mt-8 w-full max-w-md p-6 bg-white shadow-lg rounded-lg">
<ZecToZatsConverter />
</div>
)}
</div>
</div>
);
};
Expand Down

0 comments on commit 2ed2b54

Please sign in to comment.