Skip to content

Commit

Permalink
Admin page: skeleton + read data
Browse files Browse the repository at this point in the history
  • Loading branch information
carletex committed Feb 18, 2024
1 parent 7e3a868 commit f2f7d5c
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 1 deletion.
43 changes: 43 additions & 0 deletions packages/nextjs/app/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

import { useEffect, useState } from "react";
import { GrantData } from "~~/services/database/schema";
import { notification } from "~~/utils/scaffold-eth";

// ToDo. "Protect" with address header or PROTECT with signing the read.
const AdminPage = () => {
const [grants, setGrants] = useState<GrantData[]>([]);

useEffect(() => {
const getGrants = async () => {
try {
const response = await fetch("/api/grants/review");
const grants: GrantData[] = (await response.json()).data;
setGrants(grants);
} catch (error) {
notification.error("Error getting grants for review");
}
};

getGrants();
}, []);

return (
<div className="container mx-auto max-w-screen-md mt-12">
<h1 className="text-4xl font-bold">Admin page</h1>
{grants && (
<>
<h2 className="font-bold mt-8">All grants that need review:</h2>
{grants.map(grant => (
<div key={grant.id} className="border p-4 my-4">
<h3 className="font-bold">{grant.title}</h3>
<p>{grant.description}</p>
</div>
))}
</>
)}
</div>
);
};

export default AdminPage;
8 changes: 8 additions & 0 deletions packages/nextjs/app/api/grants/review/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { NextResponse } from "next/server";
import { getAllGrantsForReview } from "~~/services/database/grants";

export async function GET() {
const grants = await getAllGrantsForReview();

return NextResponse.json({ data: grants });
}
53 changes: 52 additions & 1 deletion packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,72 @@
import React from "react";
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";

type HeaderMenuLink = {
label: string;
href: string;
icon?: React.ReactNode;
};

export const menuLinks: HeaderMenuLink[] = [
{
label: "Home",
href: "/",
},
// ToDo. Show only on admins
{
label: "Admin",
href: "/admin",
icon: <LockClosedIcon className="h-4 w-4" />,
},
];

export const HeaderMenuLinks = () => {
const pathname = usePathname();

return (
<>
{menuLinks.map(({ label, href, icon }) => {
const isActive = pathname === href;
return (
<li key={href}>
<Link
href={href}
passHref
className={`${
isActive ? "underline" : ""
} hover:bg-secondary hover:shadow-md focus:!bg-secondary active:!text-neutral py-1.5 px-3 text-sm rounded-full gap-2 grid grid-flow-col`}
>
{icon}
<span>{label}</span>
</Link>
</li>
);
})}
</>
);
};

/**
* Site header
*/
export const Header = () => {
return (
<div className="navbar items-start bg-base-200 px-5 py-4">
<div className="navbar-start">
<div className="navbar-start gap-10">
<Link href="/" passHref className="flex items-center">
<div className="flex relative w-[130px] md:w-[150px] h-[36px]">
<Image alt="SE2 logo" className="cursor-pointer" fill src="/logo.svg" />
</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 z-10">
<RainbowKitCustomConnectButton />
</div>
Expand Down
16 changes: 16 additions & 0 deletions packages/nextjs/services/database/grants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@ export const getAllGrants = async () => {
}
};

export const getAllGrantsForReview = async () => {
try {
const grantsSnapshot = await grantsCollection
.where("status", "in", [PROPOSAL_STATUS.PROPOSED, PROPOSAL_STATUS.SUBMITTED])
.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 completed grants:", error);
throw error;
}
};

export const getAllCompletedGrants = async () => {
try {
const grantsSnapshot = await grantsCollection.where("status", "==", PROPOSAL_STATUS.COMPLETED).get();
Expand Down

0 comments on commit f2f7d5c

Please sign in to comment.