Skip to content

Commit

Permalink
My grants page
Browse files Browse the repository at this point in the history
  • Loading branch information
carletex committed Feb 19, 2024
1 parent ae8d7f2 commit 7f11ce3
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
17 changes: 17 additions & 0 deletions packages/nextjs/app/api/builders/[builderAddress]/grants/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NextResponse } from "next/server";
import { getAllGrantsForUser } from "~~/services/database/grants";

export async function GET(_request: Request, { params }: { params: { builderAddress: string } }) {
try {
const builderAddress = params.builderAddress;
const grants = await getAllGrantsForUser(builderAddress);
return NextResponse.json(grants);
} catch (error) {
return NextResponse.json(
{ message: "Internal Server Error" },
{
status: 500,
},
);
}
}
56 changes: 56 additions & 0 deletions packages/nextjs/app/my-grants/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"use client";

import { useEffect, useState } from "react";
import { NextPage } from "next";
import { useAccount } from "wagmi";
import { GrantData } from "~~/services/database/schema";
import { PROPOSAL_STATUS } from "~~/utils/grants";

const badgeBgColor = {
[PROPOSAL_STATUS.PROPOSED]: "bg-warning",
[PROPOSAL_STATUS.APPROVED]: "bg-success",
[PROPOSAL_STATUS.SUBMITTED]: "bg-warning",
[PROPOSAL_STATUS.COMPLETED]: "bg-success",
[PROPOSAL_STATUS.REJECTED]: "bg-error",
};

// ToDo. Action (v1.0 = submit grant after completion)
// ToDo. Loading states
const MyGrants: NextPage = () => {
const { address } = useAccount();
const [builderGrants, setBuilderGrants] = useState<GrantData[]>([]);

useEffect(() => {
const fetchBuilderGrants = async () => {
try {
const response = await fetch(`/api/builders/${address}/grants`);
const data = await response.json();
setBuilderGrants(data);
} catch (error) {
console.error("Failed to fetch builder grants", error);
}
};

if (address) {
fetchBuilderGrants();
}
}, [address]);

return (
<div className="container mx-auto max-w-screen-md mt-12">
<h1 className="text-4xl font-bold">My grants</h1>
{builderGrants.map(grant => (
<div key={grant.id} className="border p-4 my-4">
<h3 className="font-bold">
{grant.title}
<span className="text-sm text-gray-500 ml-2">({grant.id})</span>
</h3>
<p>{grant.description}</p>
<p className={`badge ${badgeBgColor[grant.status]}`}>{grant.status}</p>
</div>
))}
</div>
);
};

export default MyGrants;
8 changes: 5 additions & 3 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { RainbowKitCustomConnectButton } from "./scaffold-eth";
import { LockClosedIcon } from "@heroicons/react/24/outline";
import { AcademicCapIcon, LockClosedIcon } from "@heroicons/react/24/outline";
import { useGlobalState } from "~~/services/store/store";

type HeaderMenuLink = {
Expand All @@ -14,8 +14,9 @@ type HeaderMenuLink = {

export const menuLinks: HeaderMenuLink[] = [
{
label: "Home",
href: "/",
label: "My Grants",
href: "/my-grants",
icon: <AcademicCapIcon className="h-4 w-4" />,
},
{
label: "Admin",
Expand All @@ -33,6 +34,7 @@ export const HeaderMenuLinks = () => {
{menuLinks.map(({ label, href, icon }) => {
const isActive = pathname === href;
if (href === "/admin" && builderData?.role !== "admin") return null;
if (href === "/my-grants" && !builderData) return null;
return (
<li key={href}>
<Link
Expand Down
14 changes: 14 additions & 0 deletions packages/nextjs/services/database/grants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ export const getAllGrants = async () => {
}
};

export const getAllGrantsForUser = async (userAddress: string) => {
try {
const grantsSnapshot = await grantsCollection.where("builder", "==", userAddress).get();
const grants: GrantData[] = [];
grantsSnapshot.forEach(doc => {
grants.push({ id: doc.id, ...doc.data() } as GrantData);
});
return grants;
} catch (error) {
console.error("Error getting all grants for user:", error);
throw error;
}
};

export const getAllGrantsForReview = async () => {
try {
const grantsSnapshot = await grantsCollection
Expand Down

0 comments on commit 7f11ce3

Please sign in to comment.