Skip to content

Commit

Permalink
home page UI started
Browse files Browse the repository at this point in the history
  • Loading branch information
bluntbrain committed Aug 5, 2024
1 parent bfae732 commit 0d5359d
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 135 deletions.
225 changes: 173 additions & 52 deletions packages/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,187 @@
"use client";

import Link from "next/link";
import { useEffect, useState } from "react";
import axios from "axios";
import { ethers } from "ethers";
import type { NextPage } from "next";
import { useAccount } from "wagmi";
import { BugAntIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { Address } from "~~/components/scaffold-eth";
import { Balance } from "~~/components/scaffold-eth";
import { EtherInput } from "~~/components/scaffold-eth";
import { useDeployedContractInfo, useScaffoldContractWrite } from "~~/hooks/scaffold-eth";

const contractName = "RepoRewards";

const Home: NextPage = () => {
const { address: connectedAddress } = useAccount();
// const { address: connectedAddress } = useAccount();
const [repos, setRepos] = useState<any[]>([]);
const [issues, setIssues] = useState<any[]>([]);
const [selectedRepo, setSelectedRepo] = useState<string | null>(null);
const [repoId, setRepoId] = useState<number | null>(null);
const [amount, setAmount] = useState<string>("");
// const [error, setError] = useState<string | null>(null);
const { data: deployedContractData } = useDeployedContractInfo(contractName);
const { writeAsync: sendAddFundsTx, isMining: isAddingFunds } = useScaffoldContractWrite({
contractName,
functionName: "addFundToRepository",
args: [undefined],
});
const { writeAsync: sendAllocateRewardTx, isMining: isAllocatingReward } = useScaffoldContractWrite({
contractName,
functionName: "allocateIssueReward",
args: [undefined, undefined, undefined],
});

// const contractAddress = deployedContractData?.address;
// const contractAbi = deployedContractData?.abi;

useEffect(() => {
const fetchRepos = async () => {
try {
const res = await axios.get("https://api.github.com/users/ethereum-optimism/repos");
console.log("res.data repo ==", res.data);
setRepos(res.data);
} catch (err) {
// setError("Failed to fetch repositories. Please try again.");
setRepos([]);
}
};
fetchRepos();
}, []);

const handleFetchIssues = async (repoName: string, repoId: number) => {
try {
const res = await axios.get(`https://api.github.com/repos/ethereum-optimism/${repoName}/issues`);
setIssues(res.data);
setSelectedRepo(repoName);
setRepoId(repoId);
// fetchRepositoryDetails(repoId);
} catch (err) {
// setError("Failed to fetch issues. Please try again.");
setIssues([]);
}
};

// const fetchRepositoryDetails = async (repoId: number) => {
// try {
// const provider = new ethers.providers.Web3Provider((window as any).ethereum);
// const contract = new ethers.Contract(contractAddress, contractAbi, provider);
// const repoDetails = await contract.getRepository(repoId);
// const poolRewards = ethers.formatEther(repoDetails[2]);
// setRepos(prevRepos => prevRepos.map(repo => (repo.id === repoId ? { ...repo, poolRewards } : repo)));
// } catch (error) {
// console.error("Error fetching repository details:", error);
// }
// };

const handleAddFunds = async () => {
if (repoId && amount) {
try {
const tx = await sendAddFundsTx({
args: [BigInt(repoId)],
value: ethers.parseEther(amount),
});
console.log("Transaction successful:", tx);
} catch (error) {
console.error("Error adding funds:", error);
}
}
};

const handleAllocateIssueReward = async (issueId: number, rewardAmount: string) => {
if (repoId) {
try {
const tx = await sendAllocateRewardTx({
args: [BigInt(repoId), BigInt(issueId), BigInt(ethers.parseEther(rewardAmount))],
});
console.log("Reward allocation successful:", tx);
} catch (error) {
console.error("Error allocating reward:", error);
}
}
};

return (
<>
<div className="flex items-center flex-col flex-grow pt-10">
<div className="px-5">
<h1 className="text-center">
<span className="block text-2xl mb-2">Welcome to</span>
<span className="block text-4xl font-bold">Scaffold-OP 🏗🔴 </span>
</h1>
<div className="flex justify-center items-center space-x-2">
<p className="my-2 font-medium">Connected Address:</p>
<Address address={connectedAddress} />
<div className="flex flex-col flex-grow pt-10 px-5">
<div className="flex justify-between w-full mb-5">
<div className="flex">
<h2 className="text-xl font-bold">Organisation Balance:</h2>
<Balance address={deployedContractData?.address} className="px-3 min-h-[1rem] text-xl font-bold" />
</div>
<p className="text-center text-lg">
Get started by editing{" "}
<code className="italic bg-base-300 text-base font-bold max-w-full break-words break-all inline-block">
packages/nextjs/app/page.tsx
</code>
</p>
<p className="text-center text-lg">
Edit your smart contract{" "}
<code className="italic bg-base-300 text-base font-bold max-w-full break-words break-all inline-block">
YourContract.sol
</code>{" "}
in{" "}
<code className="italic bg-base-300 text-base font-bold max-w-full break-words break-all inline-block">
packages/hardhat/contracts
</code>
</p>
{repoId && (
<div className="text-right flex">
<div className="flex">
<EtherInput value={amount} onChange={amount => setAmount(amount)} />
</div>
<button onClick={handleAddFunds} className="btn rounded-two btn-primary ml-2">
{isAddingFunds ? "Adding Funds..." : `Add Funds to ${selectedRepo}`}
</button>
</div>
)}
</div>

<div className="flex-grow bg-base-300 w-full mt-16 px-8 py-12">
<div className="flex justify-center items-center gap-12 flex-col sm:flex-row">
<div className="flex flex-col bg-base-100 px-10 py-10 text-center items-center max-w-xs rounded-3xl">
<BugAntIcon className="h-8 w-8 fill-secondary" />
<p>
Tinker with your smart contract using the{" "}
<Link href="/debug" passHref className="link">
Debug Contracts
</Link>{" "}
tab.
</p>
</div>
<div className="flex flex-col bg-base-100 px-10 py-10 text-center items-center max-w-xs rounded-3xl">
<MagnifyingGlassIcon className="h-8 w-8 fill-secondary" />
<p>
Explore your local transactions with the{" "}
<Link href="/blockexplorer" passHref className="link">
Block Explorer
</Link>{" "}
tab.
</p>
</div>
<div className="flex flex-grow">
<div className="w-1/2 p-4 bg-base-300 rounded-md mx-2">
<h2 className="text-2xl font-bold mb-4">Repositories</h2>
{repos.length > 0 ? (
repos.map(repo => (
<div key={repo.id} className="card bg-base-100 shadow-lg p-4 mb-4">
<div className="flex flex-col" onClick={() => handleFetchIssues(repo.name, repo.id)}>
<a
href={repo.html_url}
target="_blank"
rel="noopener noreferrer"
className="link font-bold text-lg"
>
{repo.name} ({repo.id})
</a>
<p className="text-sm text-gray-500 mt-1">{repo.description}</p>
{repo.poolRewards && <p className="text-sm font-bold mt-1">Pool Rewards: {repo.poolRewards} ETH</p>}
</div>
</div>
))
) : (
<p>No repositories found.</p>
)}
</div>

<div className="w-1/2 p-4 bg-base-300 rounded-md">
{selectedRepo ? (
<>
<h2 className="text-2xl font-bold mb-4">
{issues.length} Open Issues in {selectedRepo}
</h2>
{issues.length > 0 ? (
<div>
{issues.map(issue => (
<div key={issue.id} className="card bg-base-100 shadow-lg p-4 mb-4 flex justify-between">
<div className="flex-grow">
<a href={issue.html_url} target="_blank" rel="noopener noreferrer" className="link font-bold">
{issue.title}
</a>
<p>{issue.body}</p>
</div>
<div className="flex items-center">
<EtherInput
value={issue.rewardAmount}
onChange={reward => handleAllocateIssueReward(issue.id, reward)}
/>
<button
onClick={() => handleAllocateIssueReward(issue.id, issue.rewardAmount)}
className="btn btn-primary self-start ml-2"
>
{isAllocatingReward ? "Allocating..." : "Allocate Reward"}
</button>
</div>
</div>
))}
</div>
) : (
<p>No issues found.</p>
)}
</>
) : (
<h2 className="text-2xl font-bold mb-4">Please select a repository to see issues</h2>
)}
</div>
</div>
</div>
Expand Down
68 changes: 7 additions & 61 deletions packages/nextjs/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import React from "react";
import Link from "next/link";
import { hardhat } from "viem/chains";
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { HeartIcon } from "@heroicons/react/24/outline";
import { SwitchTheme } from "~~/components/SwitchTheme";
import { BuidlGuidlLogo } from "~~/components/assets/BuidlGuidlLogo";
import { Faucet } from "~~/components/scaffold-eth";
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";

// import { hardhat } from "viem/chains";
// import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";

/**
* Site footer
*/
export const Footer = () => {
const { targetNetwork } = useTargetNetwork();
const isLocalNetwork = targetNetwork.id === hardhat.id;
// const { targetNetwork } = useTargetNetwork();
// const isLocalNetwork = targetNetwork.id === hardhat.id;

return (
<div className="min-h-0 py-5 px-1 mb-11 lg:mb-0">
Expand All @@ -25,67 +20,18 @@ export const Footer = () => {
<span>Dapp Developer Console</span>
</div>
</div> */}
{isLocalNetwork && (
{/* {isLocalNetwork && (
<>
<Faucet />
<Link href="/blockexplorer" passHref className="btn btn-primary btn-sm font-normal gap-1">
<MagnifyingGlassIcon className="h-4 w-4" />
<span>Block Explorer</span>
</Link>
</>
)}
)} */}
</div>
<SwitchTheme className={`pointer-events-auto ${isLocalNetwork ? "self-end md:self-auto" : ""}`} />
</div>
</div>
<div className="w-full">
<ul className="menu menu-horizontal w-full">
<div className="flex justify-center items-center gap-2 text-sm w-full">
<div className="text-center">
<a
href="https://github.com/ethereum-optimism/scaffold-op/"
target="_blank"
rel="noreferrer"
className="link"
>
Fork me
</a>
</div>
<span>·</span>
<div className="flex justify-center items-center gap-2">
<p className="m-0 text-center">
Built with <HeartIcon className="inline-block h-4 w-4" /> at
</p>
<a
className="flex justify-center items-center gap-1"
href="https://buidlguidl.com/"
target="_blank"
rel="noreferrer"
>
<BuidlGuidlLogo className="w-3 h-5 pb-1" />
<span className="link">BuidlGuidl</span>
</a>
</div>
<span>·</span>
<div className="text-center">
<a
href="https://github.com/ethereum-optimism/developers/discussions"
target="_blank"
rel="noreferrer"
className="link"
>
🔴 OP Dev Support
</a>
</div>
<span>·</span>
<div className="text-center">
<a href="https://t.me/joinchat/KByvmRe5wkR-8F_zz6AjpA" target="_blank" rel="noreferrer" className="link">
🏗️ BuidlGuidl Support
</a>
</div>
</div>
</ul>
</div>
</div>
);
};
17 changes: 11 additions & 6 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import React, { useCallback, useRef, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { SwitchTheme } from "./SwitchTheme";
import sunny from "./assets/sunny.svg";
import { Bars3Icon, BugAntIcon } from "@heroicons/react/24/outline";
import { hardhat } from "viem/chains";
import { Bars3Icon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import {
DappConsoleButton,
FaucetButton,
RainbowKitCustomConnectButton,
SuperchainFaucetButton,
} from "~~/components/scaffold-eth";
import { useOutsideClick } from "~~/hooks/scaffold-eth";
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";

type HeaderMenuLink = {
label: string;
Expand All @@ -26,9 +29,9 @@ export const menuLinks: HeaderMenuLink[] = [
href: "/",
},
{
label: "Debug Contracts",
href: "/debug",
icon: <BugAntIcon className="h-4 w-4" />,
label: "Block Explorer",
href: "/blockexplorer",
icon: <MagnifyingGlassIcon className="h-4 w-4" />,
},
];

Expand Down Expand Up @@ -64,6 +67,8 @@ export const HeaderMenuLinks = () => {
export const Header = () => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const burgerMenuRef = useRef<HTMLDivElement>(null);
const { targetNetwork } = useTargetNetwork();
const isLocalNetwork = targetNetwork.id === hardhat.id;
useOutsideClick(
burgerMenuRef,
useCallback(() => setIsDrawerOpen(false), []),
Expand Down Expand Up @@ -99,15 +104,15 @@ export const Header = () => {
<Image alt="SE2 logo" className="cursor-pointer" src={sunny} />
</div>
<div className="flex flex-col">
<span className="font-bold leading-tight">Scaffold-OP</span>
<span className="text-xs">Ethereum dev stack</span>
<span className="font-bold leading-tight">Repo Rewards</span>
</div>
</Link>
<ul className="hidden lg:flex lg:flex-nowrap menu menu-horizontal px-1 gap-2">
<HeaderMenuLinks />
</ul>
</div>
<div className="navbar-end flex-grow mr-4">
<SwitchTheme className={`pointer-events-auto ${isLocalNetwork ? "self-end md:self-auto" : ""}`} />
<RainbowKitCustomConnectButton />
<FaucetButton />
<SuperchainFaucetButton />
Expand Down
Loading

0 comments on commit 0d5359d

Please sign in to comment.