Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign /nfts page #10

Merged
merged 1 commit into from
May 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/nfts/[slug]/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";

export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
return (
<div className="min-h-screen text-white flex flex-col space-y-10 justify-center items-center">
<h2 className="text-2xl font-bold">Something went wrong!</h2>
<p className="text-sm">{error.message}</p>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
14 changes: 14 additions & 0 deletions app/nfts/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Header from "@/components/Header";

export default function NFTsLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="min-h-screen bg-[url('/images/background.jpg')] bg-cover bg-fixed bg-black/80 bg-blend-multiply">
<Header />
{children}
</div>
);
}
11 changes: 11 additions & 0 deletions app/nfts/[slug]/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import NFTCardSkeleton from "@/components/NFTCardSkeleton";

export default function Loading() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5 mx-24 mt-20 py-10">
{[...Array(8)].map((_, i) => (
<NFTCardSkeleton key={i} />
))}
</div>
);
}
66 changes: 66 additions & 0 deletions app/nfts/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";
import NFTCard from "@/components/NFTCard";
import { NFT } from "@/typings";
import { ethers } from "ethers";
import abi from "@/artifacts/contracts/ByteBunch.sol/ByteBunch.json";

type Props = {
params: {
slug: string;
};
};

const ipfsToHttps = (ipfs: string) => {
const gateway = "https://ipfs.io/ipfs/";
const url = ipfs.replace("ipfs://", gateway);
return url;
};

const getData = async (address: string) => {
try {
const signer = new ethers.InfuraProvider(
"sepolia",
process.env.INFURA_API_KEY
);
const contract = new ethers.Contract(
process.env.NEXT_PUBLIC_CONTRACT_ADDRESS!,
abi.abi,
signer
);

const tokens = await contract.walletOfOwner(address);

const data = await Promise.all(
tokens.map(async (token: any) => {
const metadata = await contract.tokenURI(token);
const metadataJSON = await fetch(ipfsToHttps(metadata));
const metadataJSONParsed = await metadataJSON.json();
metadataJSONParsed.image = ipfsToHttps(metadataJSONParsed.image);
return metadataJSONParsed;
})
);

return data;
} catch (error: any) {
throw new Error(error.message);
}
};

const NFTs = async ({ params }: Props) => {
const address = params.slug;

const data: NFT[] = await getData(address);
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5 mx-24 mt-20 py-10">
{data.length > 0 ? (
data.map((item) => <NFTCard key={item.name} data={item} />)
) : (
<div className="text-center text-2xl text-gray-50 col-span-4">
No NFTs found for address {address}
</div>
)}
</div>
);
};

export default NFTs;
165 changes: 0 additions & 165 deletions app/nfts/page.tsx

This file was deleted.

22 changes: 22 additions & 0 deletions components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Link from "next/link";

export default function Header() {
return (
<header className="bg-gray-900 shadow fixed top-0 w-full z-50">
<nav
className="mx-auto flex max-w-7xl items-center p-6 lg:px-8"
aria-label="Global"
>
<div className="flex-1 flex justify-around">
<Link href="/" className="-m-1.5 p-1.5">
<h1 className="text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl">
<span className="text-cyan-500">Byte</span>{" "}
<span className="text-amber-500">Bunch</span>
</h1>
<span className="sr-only">Byte Bunch</span>
</Link>
</div>
</nav>
</header>
);
}
33 changes: 33 additions & 0 deletions components/NFTCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { NFT } from "@/typings";
import Image from "next/image";
import Link from "next/link";
import React from "react";

type Props = {
data: NFT;
};

const NFTCard = ({ data }: Props) => {
return (
<Link href={`/nfts/${data.name}`}>
<div className="max-w-sm mx-auto bg-gradient-to-l from-cyan-900 to-cyan-900 bg-black/70 bg-blend-multiply border border-cyan-950 rounded-lg shadow hover:shadow-md group transition-all duration-300 ease-in-out">
<div className="w-full h-80 overflow-hidden rounded-t-lg shadow">
<Image
className="h-full w-full object-cover rounded-t-lg group-hover:scale-110 transition-all duration-300 ease-in-out"
src={data.image}
alt={data.name}
width={500}
height={500}
/>
</div>
<div className="p-5">
<h5 className="mb-2 text-xl font-bold tracking-tight text-gray-50">
{data.name}
</h5>
</div>
</div>
</Link>
);
};

export default NFTCard;
18 changes: 18 additions & 0 deletions components/NFTCardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const NFTCardSkeleton = () => {
return (
<div className="max-w-sm w-full mx-auto bg-gradient-to-l from-cyan-900 to-cyan-900 bg-black/70 bg-blend-multiply border border-cyan-950 rounded-lg shadow hover:shadow-md group transition-all duration-300 ease-in-out">
<div className="w-full h-80 overflow-hidden rounded-t-lg shadow">
<div className="w-full h-full bg-gray-800 animate-pulse"></div>
</div>
<div className="p-5">
<h5 className="mb-2 text-xl font-bold tracking-tight text-gray-50">
<div className="h-full w-full rounded-full bg-gray-800 animate-pulse text-transparent">
&nbsp;
</div>
</h5>
</div>
</div>
);
};

export default NFTCardSkeleton;
14 changes: 14 additions & 0 deletions typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type NFT = {
dna: string;
name: string;
description: string;
image: string;
edition: number;
date: number;
attributes: Attribute[];
};

export type Attribute = {
trait_type: string;
value: string;
};