Skip to content

Commit

Permalink
Merge pull request #20 from pbkompasz/feat/members-list
Browse files Browse the repository at this point in the history
feat: members list
  • Loading branch information
phipsae authored Nov 4, 2024
2 parents e609518 + d5ac1d5 commit 18c7775
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
16 changes: 16 additions & 0 deletions packages/nextjs/app/builders/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { promises as fs } from "fs";
import type { NextPage } from "next";
import BuildersList from "~~/components/BuildersList";

const Builders: NextPage = async () => {
const file = await fs.readdir(process.cwd() + "/app/builders");
const builderProfiles = file.filter((file: string) => file.startsWith("0x") && file.length == 42);

return (
<>
<BuildersList builderProfiles={builderProfiles} />
</>
);
};

export default Builders;
112 changes: 112 additions & 0 deletions packages/nextjs/components/BuildersList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"use client";

import { useEffect, useRef, useState } from "react";
import Link from "next/link";
import { Address } from "~~/components/scaffold-eth";
import { useScaffoldEventHistory } from "~~/hooks/scaffold-eth";

type Builder = {
address: string;
hasPersonalPage: boolean;
};

export default function Page({ builderProfiles }: { builderProfiles: string[] }) {
const [builders, setBuilders] = useState([] as Builder[]);
const [isLoading, setIsLoading] = useState(true);
const elementRef = useRef(null);

const { data: events } = useScaffoldEventHistory({
contractName: "BatchRegistry",
eventName: "CheckedIn",
fromBlock: 126461494n,
});

useEffect(() => {
if (elementRef.current) {
setIsLoading(false);
}
}, []);

useEffect(() => {
const fetchBuilders = async () => {
if (!events) return;

// Filter out duplicate addresses
const filteredAddresses: string[] = [];
events.forEach(event => {
const address = event.args.builder;
if (!address) return;
if (!filteredAddresses.find(addr => address === addr)) filteredAddresses.push(address);
});

const builders = await Promise.all(
filteredAddresses.map(async address => {
if (address)
return {
address,
// Check if the builder has a personal page
hasPersonalPage: !!builderProfiles.find(bp => bp === address),
};
}),
);
setBuilders(
builders
.filter(builder => !!builder)
// Sort by personal apge availability
.sort((a, b) => +(b.hasPersonalPage === true) - +(a.hasPersonalPage === true)),
);
};

fetchBuilders().catch(console.error);
}, [events]);

return (
<div>
<div className="flex items-center flex-col flex-grow pt-10" ref={elementRef}>
<div className="px-5">
<h1 className="text-center">
<span className="block text-4xl font-bold">Builders</span>
</h1>
</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="overflow-x-auto">
{isLoading ? (
<span className="animate-pulse text-xl">Loading builder pages</span>
) : (
<table className="table">
<thead>
<tr>
<th></th>
<th>ENS or Address</th>
<th>Builder Page</th>
</tr>
</thead>
<tbody>
{builders.map((builder, id) => (
<tr key={id} className="items-center">
<th>{id + 1}</th>
<td className="text-lg">
<Address address={builder.address} />
</td>
<td className="text-lg">
{builder.hasPersonalPage ? (
<Link className="underline" href={`/builders/${builder.address}`}>
Builder Page
</Link>
) : (
<>Not available</>
)}
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</div>
</div>
</div>
</div>
);
}
6 changes: 6 additions & 0 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useCallback, useRef, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { FaUsers } from "react-icons/fa";
import { Bars3Icon, BugAntIcon } from "@heroicons/react/24/outline";
import { FaucetButton, RainbowKitCustomConnectButton } from "~~/components/scaffold-eth";
import { useOutsideClick } from "~~/hooks/scaffold-eth";
Expand All @@ -24,6 +25,11 @@ export const menuLinks: HeaderMenuLink[] = [
href: "/debug",
icon: <BugAntIcon className="h-4 w-4" />,
},
{
label: "Builders",
href: "/builders",
icon: <FaUsers className="h-4 w-4" />,
},
];

export const HeaderMenuLinks = () => {
Expand Down

0 comments on commit 18c7775

Please sign in to comment.