Skip to content

Commit a90d4ad

Browse files
committed
- Scaffold structure for fetching GQL data
- Configure gql.tada - Auto fetch schemas - GQL Fragments for Hypercerts - Generate TS types for GQL queries - Functions for fetching hypercerts - Fetch hypercerts for explore page - Pagination for explore page
1 parent 5cce31d commit a90d4ad

19 files changed

+8662
-9692
lines changed

Diff for: .vscode/settings.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib",
3+
"typescript.enablePromptUseWorkspaceTsdk": true
4+
}

Diff for: app/explore/loading.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default function Loading() {
2+
return (
3+
<div className="flex items-center justify-center h-screen">
4+
<div className="animate-spin">
5+
<div className="h-12 w-12 border-t-4 border-b-4 border-blue-500 rounded-full"></div>
6+
</div>
7+
</div>
8+
);
9+
}

Diff for: app/explore/page.tsx

+37-54
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,30 @@
11
import HypercertCard, {
22
type HypercertCardProps,
33
} from "@/components/hypercert-card";
4+
import { getAllHypercerts } from "../../hypercerts/getAllHypercerts";
5+
import Pagination from "../../components/explore/Pagination";
6+
import { HYPERCERTS_PER_PAGE } from "../../configs/ui";
7+
import { Suspense } from "react";
8+
import Loading from "./loading";
49

510
export const metadata = {
611
title: "Explore",
712
description:
813
"The best place to discover and contribute to hypercerts and hyperboards.",
914
};
1015

11-
const cardData: HypercertCardProps[] = [
12-
{
13-
title: "Moslev's Supreme Treasure Hunt",
14-
description:
15-
"A treasure hunt to find the hidden treasure in the hypercerts.",
16-
hypercertId: "0x12234",
17-
banner:
18-
"https://www.kathrynwilking.com/wp-content/uploads/2018/03/Treasure-Box-blog-iStock-542285574.jpg",
19-
logo: "https://upload.wikimedia.org/wikipedia/commons/c/cc/Treasure_logo_2023.png",
20-
},
21-
{
22-
title: "Global Reforestation Initiative",
23-
description:
24-
"Join efforts to plant trees worldwide and combat deforestation.",
25-
hypercertId: "0x334455",
26-
banner: "https://images.unsplash.com/photo-1518837695005-2083093ee35b",
27-
logo: "https://upload.wikimedia.org/wikipedia/commons/2/21/The_logo_of_the_two_swords_and_the_palm_tree.jpg",
28-
},
29-
{
30-
title: "Ocean Cleanup Project",
31-
description: "Help remove plastics and other waste from our oceans.",
32-
hypercertId: "0x556677",
33-
banner: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e",
34-
logo: "https://upload.wikimedia.org/wikipedia/commons/5/5a/Nick_Mason_DW_%22Waves%22_Kit_2022.jpg",
35-
},
36-
{
37-
title: "Renewable Energy Research",
38-
description:
39-
"Support advancements in sustainable and renewable energy sources.",
40-
hypercertId: "0x778899",
41-
banner: "https://images.unsplash.com/photo-1504196606672-aef5c9cefc92",
42-
logo: "https://upload.wikimedia.org/wikipedia/commons/e/ef/Cristian_Sun_Logo_Transparente.png",
43-
},
44-
{
45-
title: "Wildlife Conservation Network",
46-
description:
47-
"Contribute to the protection of endangered species and their habitats.",
48-
hypercertId: "0x9900aa",
49-
banner: "https://images.unsplash.com/photo-1470770903676-69b98201ea1c",
50-
logo: "https://upload.wikimedia.org/wikipedia/commons/d/d1/Logo_du_groupe_wolf_pack.jpg",
51-
},
52-
{
53-
title: "Clean Air Initiative",
54-
description:
55-
"Promote projects that aim to reduce air pollution in urban areas.",
56-
hypercertId: "0xbbccdd",
57-
banner: "https://images.unsplash.com/photo-1495954484750-af469f2f9be5",
58-
logo: "https://upload.wikimedia.org/wikipedia/commons/4/40/Wind_logo_2017.svg",
59-
},
60-
];
16+
async function ExplorePageInner({
17+
searchParams,
18+
}: {
19+
searchParams: Record<string, string>;
20+
}) {
21+
const currentPage = Number(searchParams?.p) || 1;
22+
23+
const hypercerts = await getAllHypercerts({
24+
first: HYPERCERTS_PER_PAGE,
25+
offset: HYPERCERTS_PER_PAGE * (currentPage - 1),
26+
});
6127

62-
export default function Explore() {
6328
return (
6429
<>
6530
<main className="flex flex-col p-8 md:p-24 pb-24">
@@ -76,11 +41,29 @@ export default function Explore() {
7641

7742
<div className="p-3"></div>
7843
<div className="flex flex-wrap gap-5">
79-
{cardData.map((card) => (
80-
<HypercertCard {...card} key={card.hypercertId} />
81-
))}
44+
{hypercerts?.data?.map((hypercert) => {
45+
const props: HypercertCardProps = {
46+
hypercertId: hypercert.hypercert_id as string,
47+
title: hypercert.metadata?.name as string,
48+
description: hypercert.metadata?.description as string,
49+
};
50+
return <HypercertCard {...props} key={hypercert.hypercert_id} />;
51+
})}
8252
</div>
53+
<Pagination searchParams={searchParams} />
8354
</main>
8455
</>
8556
);
8657
}
58+
59+
export default async function ExplorePage({
60+
searchParams,
61+
}: {
62+
searchParams: Record<string, string>;
63+
}) {
64+
return (
65+
<Suspense fallback={<Loading />}>
66+
{ExplorePageInner({ searchParams })}
67+
</Suspense>
68+
);
69+
}

Diff for: components/explore/Pagination.tsx

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { HYPERCERTS_PER_PAGE } from "../../configs/ui";
2+
import PaginationButton from "./PaginationButton";
3+
import { getHypercertsTotal } from "../../hypercerts/getHypercertsTotal";
4+
5+
export default async function Pagination({
6+
searchParams,
7+
}: {
8+
searchParams: Record<string, string>;
9+
}) {
10+
const totalCount = await getHypercertsTotal();
11+
const totalPages = Math.ceil((totalCount || 0) / HYPERCERTS_PER_PAGE);
12+
const currentPage = Number(searchParams?.p) || 1;
13+
14+
const urlSearchParams = new URLSearchParams(searchParams);
15+
const navQs = (toPage: number) => {
16+
urlSearchParams.set("p", toPage.toString());
17+
return urlSearchParams.toString();
18+
};
19+
20+
return (
21+
<div className="flex items-center justify-between w-full border border-black p-5">
22+
<div className="flex items-center justify-start gap-2 w-[250px]">
23+
{currentPage > 1 && (
24+
<PaginationButton arrow="left" qs={navQs(1)}>
25+
First
26+
</PaginationButton>
27+
)}
28+
29+
{currentPage > 1 && (
30+
<PaginationButton arrow="left" qs={navQs(currentPage - 1)}>
31+
Previous
32+
</PaginationButton>
33+
)}
34+
</div>
35+
36+
<div className="pt-1 text-sm text-gray-500 whitespace-nowrap">
37+
{currentPage} of {totalPages}
38+
</div>
39+
40+
<div className="flex items-center justify-end gap-2 w-[250px]">
41+
{currentPage < totalPages && (
42+
<PaginationButton arrow="right" qs={navQs(currentPage + 1)}>
43+
Next
44+
</PaginationButton>
45+
)}
46+
47+
{currentPage < totalPages && (
48+
<PaginationButton arrow="right" qs={navQs(totalPages)}>
49+
Last
50+
</PaginationButton>
51+
)}
52+
</div>
53+
</div>
54+
);
55+
}

Diff for: components/explore/PaginationButton.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ChevronLeft, ChevronRight } from "lucide-react";
2+
3+
import { Button } from "../ui/button";
4+
import Link from "next/link";
5+
6+
export default function PaginationButton({
7+
qs,
8+
arrow,
9+
children,
10+
}: {
11+
qs: string;
12+
arrow: "left" | "right";
13+
children: string;
14+
}) {
15+
return (
16+
<Link href={`/?${qs}`} prefetch={true}>
17+
<Button aria-label={children} className="flex items-center gap-2">
18+
{arrow === "left" && (
19+
<ChevronLeft style={{ width: "10px", height: "10px" }} />
20+
)}
21+
{arrow === "right" && (
22+
<ChevronRight style={{ width: "10px", height: "10px" }} />
23+
)}
24+
{children}
25+
</Button>
26+
</Link>
27+
);
28+
}

Diff for: configs/hypercerts.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const HYPERCERTS_API_URL =
2+
"https://hypercerts-api-staging.up.railway.app/graphql";
3+
4+
export const HYPERCERTS_DEFAULT_CONTRACT =
5+
"0xa16dfb32eb140a6f3f2ac68f41dad8c7e83c4941";

Diff for: configs/ui.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const HYPERCERTS_PER_PAGE = 12;
2+
export const ATTESTORS_PER_PAGE = 10;

0 commit comments

Comments
 (0)