Skip to content

Commit

Permalink
Temp pages
Browse files Browse the repository at this point in the history
  • Loading branch information
carletex committed Dec 6, 2023
1 parent be1dbb1 commit fb7d326
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 0 deletions.
65 changes: 65 additions & 0 deletions packages/nextjs/components/StreamContractInfo2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from "react";
import { BigNumber } from "ethers";
import { useAccount } from "wagmi";
import { BanknotesIcon, QuestionMarkCircleIcon } from "@heroicons/react/24/outline";
import { Address, Balance } from "~~/components/scaffold-eth";
import { useDeployedContractInfo, useScaffoldContractRead } from "~~/hooks/scaffold-eth";

export const StreamContractInfo2 = () => {
const { address } = useAccount();
const { data: streamContract } = useDeployedContractInfo("SandGardenStreams");

const { data: owner } = useScaffoldContractRead({
contractName: "SandGardenStreams",
functionName: "owner",
});

const { data: builderData } = useScaffoldContractRead({
contractName: "SandGardenStreams",
functionName: "streamedBuilders",
args: [address],
}) as {
data: { cap: BigNumber } | undefined;
};

const amIAStreamdBuilder = builderData?.cap.gt(0);

return (
<>
<div className="mt-16">
<p className="font-bold mb-2 text-secondary">
Stream Contract
<span
className="tooltip text-white font-normal"
data-tip="All streams and contributions are handled by a contract on Optimism"
>
<QuestionMarkCircleIcon className="h-5 w-5 inline-block ml-2" />
</span>
</p>
<div className="flex gap-2 items-baseline">
<div className="flex flex-col items-center">
<Address address={streamContract?.address} />
<span className="text-xs text-[#f01a37]">Optimism</span>
</div>{" "}
/
<Balance address={streamContract?.address} className="text-3xl" />
</div>
{address && amIAStreamdBuilder && (
<div className="mt-3">
<label
htmlFor="withdraw-modal"
className="btn btn-primary btn-sm px-2 rounded-full font-normal space-x-2 normal-case"
>
<BanknotesIcon className="h-4 w-4" />
<span>Withdraw</span>
</label>
</div>
)}
</div>
<div className="mt-8">
<p className="font-bold mb-2 text-secondary">Owner</p>
<Address address={owner} />
</div>
</>
);
};
174 changes: 174 additions & 0 deletions packages/nextjs/pages/members2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import React, { useEffect, useState } from "react";
import { ethers } from "ethers";
import type { NextPage } from "next";
import { StreamContractInfo2 } from "~~/components/StreamContractInfo2";
import { Address, EtherInput } from "~~/components/scaffold-eth";
import { useScaffoldContractRead, useScaffoldContractWrite, useScaffoldEventHistory } from "~~/hooks/scaffold-eth";

const Members: NextPage = () => {
const [reason, setReason] = useState("");
const [amount, setAmount] = useState("");
const [selectedAddress, setSelectedAddress] = useState("");
const [filteredEvents, setFilteredEvents] = useState<any[]>([]);

const [builderList, setBuilderList] = useState<string[]>([]);

const { data: allBuildersData, isLoading: isLoadingBuilderData } = useScaffoldContractRead({
contractName: "SandGardenStreams",
functionName: "allBuildersData",
args: [builderList],
});

const { writeAsync: doWithdraw } = useScaffoldContractWrite({
contractName: "SandGardenStreams",
functionName: "streamWithdraw",
args: [ethers.utils.parseEther(amount || "0"), reason],
});

const { data: withdrawEvents } = useScaffoldEventHistory({
contractName: "SandGardenStreams",
eventName: "Withdraw",
fromBlock: Number(process.env.NEXT_PUBLIC_DEPLOY_BLOCK) || 0,
blockData: true,
});

const { data: addBuilderEvents, isLoading: isLoadingBuilderEvents } = useScaffoldEventHistory({
contractName: "SandGardenStreams",
eventName: "AddBuilder",
fromBlock: Number(process.env.NEXT_PUBLIC_DEPLOY_BLOCK) || 0,
});

useEffect(() => {
if (addBuilderEvents && addBuilderEvents.length > 0) {
const fetchedBuilderList = addBuilderEvents.map((event: any) => event.args.to);
setBuilderList(fetchedBuilderList);
}
}, [addBuilderEvents]);

const sortedBuilders = allBuildersData && [...allBuildersData].reverse();

return (
<>
<div className="max-w-3xl px-4 py-8">
<h1 className="text-4xl font-bold mb-8 text-primary-content bg-primary inline-block p-2">Members</h1>
<div className="mb-16">
<p className="mt-0 mb-10">
These are the BG Sand Garden active builders and their streams. You can click on any builder to see their
detailed contributions.
</p>
{isLoadingBuilderData || isLoadingBuilderEvents ? (
<div className="m-10">
<div className="text-5xl animate-bounce mb-2">👾</div>
<div className="text-lg loading-dots">Loading...</div>
</div>
) : (
<div className="flex flex-col gap-6">
{sortedBuilders?.map(builderData => {
if (builderData.cap.isZero()) return;
const cap = ethers.utils.formatEther(builderData.cap || 0);
const unlocked = ethers.utils.formatEther(builderData.unlockedAmount || 0);
const percentage = Math.floor((parseFloat(unlocked) / parseFloat(cap)) * 100);
return (
<div className="flex flex-col md:flex-row gap-2 md:gap-6" key={builderData.builderAddress}>
<div className="flex flex-col md:items-center">
<div>
Ξ {parseFloat(unlocked).toFixed(4)} / {cap}
</div>
<progress
className="progress w-56 progress-primary bg-white"
value={percentage}
max="100"
></progress>
</div>
<div className="md:w-1/2 flex">
<label
htmlFor="withdraw-events-modal"
className="cursor-pointer"
onClick={() => {
setSelectedAddress(builderData.builderAddress);
setFilteredEvents(
withdrawEvents?.filter((event: any) => event.args.to === builderData.builderAddress) || [],
);
}}
>
<Address address={builderData.builderAddress} disableAddressLink={true} />
</label>
</div>
</div>
);
})}
</div>
)}
</div>
<StreamContractInfo2 />
</div>

<input type="checkbox" id="withdraw-modal" className="modal-toggle" />
<label htmlFor="withdraw-modal" className="modal cursor-pointer">
<label className="modal-box relative bg-primary">
{/* dummy input to capture event onclick on modal box */}
<input className="h-0 w-0 absolute top-0 left-0" />
<h3 className="text-xl font-bold mb-8">Withdraw from your stream</h3>
<label htmlFor="withdraw-modal" className="btn btn-ghost btn-sm btn-circle absolute right-3 top-3">
</label>
<div className="space-y-3">
<div className="flex flex-col gap-6 items-center">
<input
type="text"
className="input input-ghost focus:outline-none focus:bg-transparent focus:text-gray-400 h-[2.2rem] min-h-[2.2rem] px-4 w-full font-medium placeholder:text-accent/50 text-gray-400 border-2 border-base-300 bg-base-200 rounded-full text-accent"
placeholder="Reason for withdrawing & links"
value={reason}
onChange={event => setReason(event.target.value)}
/>
<EtherInput value={amount} onChange={value => setAmount(value)} />
<button className="btn btn-secondary btn-sm" onClick={doWithdraw}>
Withdraw
</button>
</div>
</div>
</label>
</label>
<input type="checkbox" id="withdraw-events-modal" className="modal-toggle" />
<label htmlFor="withdraw-events-modal" className="modal cursor-pointer">
<label className="modal-box relative">
{/* dummy input to capture event onclick on modal box */}
<input className="h-0 w-0 absolute top-0 left-0" />
<h3 className="text-xl font-bold mb-8">
<p className="mb-1">Contributions</p>
<Address address={selectedAddress} />
</h3>
<label htmlFor="withdraw-events-modal" className="btn btn-ghost btn-sm btn-circle absolute right-3 top-3">
</label>
<div className="space-y-3">
<ul>
{filteredEvents.length > 0 ? (
<div className="flex flex-col">
{filteredEvents.map(event => (
<div key={event.log.transactionHash} className="flex flex-col">
<div>
<span className="font-bold">Date: </span>
{new Date(event.block.timestamp * 1000).toISOString().split("T")[0]}
</div>
<div>
<span className="font-bold">Amount: </span>Ξ{" "}
{ethers.utils.formatEther(event.args.amount.toString())}
</div>
<div>{event.args.reason}</div>
<hr className="my-8" />
</div>
))}
</div>
) : (
<p>No contributions</p>
)}
</ul>
</div>
</label>
</label>
</>
);
};

export default Members;

0 comments on commit fb7d326

Please sign in to comment.