Skip to content

Commit

Permalink
Merge pull request #31 from timi-codes/chore/ui-tweaks
Browse files Browse the repository at this point in the history
fix(dapp): implement horizaontal scroll for continents card
  • Loading branch information
timi-codes authored May 22, 2024
2 parents 11bba6c + 54cc021 commit f6e9252
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 54 deletions.
66 changes: 35 additions & 31 deletions client/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ConnectButton from "@/components/ConnectButton";
import useFetchContinents from "@/hooks/useFetchAuctions";
import { Bidder } from "@/components/Bidders";
import CardSkeloton from "@/components/CardSkeleton";
import { useHorizontalScroll } from "@/hooks/useHorizontalScroll";

export type EthereumAddress = `0x${string}`;
export interface Continent {
Expand Down Expand Up @@ -33,54 +34,57 @@ export interface Continent {

export default function Home() {
const { data: continents } = useFetchContinents();
const scrollRef = useHorizontalScroll();

return (
<main className="flex h-screen overflow-hidden flex-col items-center justify-between p-24 p-8 z-[-1] place-items-center after:-top-40 after:-left-52 after:rounded-full after:absolute after:-z-20 after:h-[400px] after:w-[400px] after:translate-x-1/3 after:bg-[#7D49EA]/15 after:content-[''] after:blur-2xl before:absolute before:h-[300px] before:w-full before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#7D49EA] after:dark:opacity-40 sm:before:w-[480px] sm:after:w-[400px] before:lg:h-[360px] before:-bottom-40 before:right-0 before:hidden">

<div className="flex justify-end items-center w-full min-h-[48px] space-x-6">
<div className="flex space-x-4">
<a href={`${process.env.NEXT_PUBLIC_OPENSEA_COLLECTION_URL}`} target="_blank">
<Image src="/opensea.svg" width={30} height={30} alt="logo" />
</a>
<a href={`https://base-sepolia.blockscout.com/address/${process.env.NEXT_PUBLIC_TOKEN_CONTRACT_ADDRESS}`} target="_blank" className="flex justify-center items-center bg-[#5353D3] rounded-full w-[30px] h-[30px]">
<Image src="/blockscout.svg" width={20} height={20} alt="logo" />
</a>
<main ref={scrollRef} className="flex h-screen overflow-hidden flex-col justify-between p-24 p-8 z-[-1] after:-top-40 after:-left-52 after:rounded-full after:absolute after:-z-20 after:h-[400px] after:w-[400px] after:translate-x-1/3 after:bg-[#7D49EA]/15 after:content-[''] after:blur-2xl before:absolute before:h-[300px] before:w-full before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#7D49EA] after:dark:opacity-40 sm:before:w-[480px] sm:after:w-[400px] before:lg:h-[360px] before:-bottom-40 before:right-0 before:hidden">
<div className="flex flex-col justify-between sticky -left-0 w-full -mt-4">
<div className="flex justify-end items-center w-full min-h-[48px] space-x-6 ">
<div className="flex space-x-4">
<a href={`${process.env.NEXT_PUBLIC_OPENSEA_COLLECTION_URL}`} target="_blank">
<Image src="/opensea.svg" width={30} height={30} alt="logo" />
</a>
<a href={`https://base-sepolia.blockscout.com/address/${process.env.NEXT_PUBLIC_TOKEN_CONTRACT_ADDRESS}`} target="_blank" className="flex justify-center items-center bg-[#5353D3] rounded-full w-[30px] h-[30px]">
<Image src="/blockscout.svg" width={20} height={20} alt="logo" />
</a>
</div>
<ConnectButton />
</div>
<ConnectButton />
</div>

<div className="relative z-[-1] flex flex-col text-center place-items-center ">
<div className="flex items-center mb-3 text-2xl 2xl:text-4xl font-semibold">
<span className="">WANNA OWN A PIECE OF THE W</span> <Image src="/earth.png" width={20} height={20} alt="logo" /><span className="mr-2">RLD?</span>
</div>
<p className="font-mono m-0 max-w-[60ch] text-sm 2xl:text-base opacity-80 mt-2">
Collect unique NFTs representing Africa, Asia, Europe, North America, South America, Australia, and Antarctica
</p>
<div className="relative z-[-1] flex flex-col text-center place-items-center ">
<div className="flex items-center mb-3 text-2xl 2xl:text-4xl font-semibold">
<span className="">WANNA OWN A PIECE OF THE W</span> <Image src="/earth.png" width={20} height={20} alt="logo" /><span className="mr-2">RLD?</span>
</div>
<p className="font-mono m-0 max-w-[60ch] text-sm 2xl:text-base opacity-80 mt-2">
Collect unique NFTs representing Africa, Asia, Europe, North America, South America, Australia, and Antarctica
</p>

</div>
</div>

<div className="py-8 text-center opacity-80">
<p><span className="font-bold">7</span> Continents, <span className="font-bold">7</span> NFTs, <span className="font-bold">7</span> Owners</p>
<p className="bg-gradient-to-r from-rose-600 via-amber-500 to-orange-400 inline-block text-transparent bg-clip-text">Auctioned: 4/7</p>
<div className="py-8 text-center opacity-80">
<p><span className="font-bold">7</span> Continents, <span className="font-bold">7</span> NFTs, <span className="font-bold">7</span> Owners</p>
<p className="bg-gradient-to-r from-rose-600 via-amber-500 to-orange-400 inline-block text-transparent bg-clip-text font-bold">Auctioned: 4/7</p>
</div>
</div>
<div>
<div className="flex wrap space-x-8 overflow-x">
<div className="flex flex-col">
<div className="flex self-start space-x-8 relative bottom-0 h-full content-end justify-self-end pr-8">
{
continents?.data && continents?.data.slice(0, 3).map((continent: Continent) => (
continents?.data && continents?.data.map((continent: Continent) => (
<ContinentCard continent={continent} key={continent.tokenId} />
))
}
{
!continents?.data && Array.from({ length: 3 }).map((_, index) => (
!continents?.data && Array.from({ length: 5 }).map((_, index) => (
<CardSkeloton key={index} />
))
}
</div>

<div className="flex flex-col pt-5 -mb-3 text-sm max-w-sm ">
<a href="https://www.github.com/timi-codes/world-nft" className="opacity-30" target="_blank">View on Github</a>
<a href="#" target="_blank" className="opacity-60">Designed & Developed by timicodes 🍁</a>
</div>

</div>
<div className="flex flex-col justify-center text-sm text-center sticky -left-0 w-full mt-4">
<a href="https://www.github.com/timi-codes/world-nft" className="opacity-30" target="_blank">View on Github</a>
<a href="#" target="_blank" className="opacity-60">Designed & Developed by timicodes 🍁</a>
</div>
</main>
);
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/CardSkeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const CardSkeloton = () => {
<div className="flex justify-center">
<Skeleton className="h-[250px] w-[250px] bg-[#545454]/5 rounded-full" />
</div>
<Skeleton className="h-6 w-[60px] bg-[#545454]/5 rounded-full" />
<Skeleton className="h-5 w-[60px] bg-[#545454]/5 rounded-full" />
</div>

<div className={`flex items-center justify-between py-3 px-3 border-t border-[0.5] border-[#545454]/20`}>
Expand Down
31 changes: 13 additions & 18 deletions client/src/components/ContinentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import Tilt from "react-parallax-tilt";
import avatar from "gradient-avatar"
import { Input } from "@/components/ui/input";
import { Continent, EthereumAddress } from '@/app/page';
import { shortenAddress, transformIPFSURL } from '@/utils';
import { useWriteContract, useSignMessage } from 'wagmi';
import { shortenAddress, showError, transformIPFSURL } from '@/utils';
import { useWriteContract, useSimulateContract } from 'wagmi';
import ContinentAuction from '@/contracts/ContinentAuction.json';
import ContinentToken from '@/contracts/ContinentToken.json';
import { formatEther, parseEther } from 'viem';
import { toast } from 'sonner';
import { Label } from './ui/label';
Expand All @@ -20,8 +21,6 @@ const TOKEN_CONTRACT_ADDRESS = (process.env.NEXT_PUBLIC_TOKEN_CONTRACT_ADDRESS?.

const ContinentCard = ({ continent }: { continent: Continent }) => {
const highestBid = formatEther(BigInt(continent.auction.highestBid));
const { signMessage } = useSignMessage()

const [bidAmount, setBidAmount] = React.useState(highestBid);
const [startPrice, setStartPrice] = React.useState("");
const [bidIncrement, setBidIncrement] = React.useState(0.001);
Expand All @@ -38,18 +37,7 @@ const ContinentCard = ({ continent }: { continent: Continent }) => {
onError(error, variables, context) {
console.log(error, variables, context)
console.error(error.message)
if (error.message.includes("insufficient funds")) {
toast.error("Insufficient funds", {
description: "You do not have enough funds to place this bid. Please top up your wallet and try again. The cost of transaction is calculated as `gas * gas fee + value`",
position: "top-left",
})
}
if (error.message.includes("Ownable: caller is not the owner")) {
toast.error("Transaction failed", {
description: "You can start an auction only if you own the continent",
position: "top-left",
})
}
showError(error.message)
},
}
})
Expand All @@ -67,14 +55,21 @@ const ContinentCard = ({ continent }: { continent: Continent }) => {
const createAuction = () => {
writeContract({
abi: ContinentAuction.abi,
address: AUCTION_CONTRACT_ADDRESS,
// address: AUCTION_CONTRACT_ADDRESS,
address: "0x0686b68Ed021883D5aCEeEE52c93E93937e1ed81",
functionName: 'createAuction',
args: [BigInt(continent.tokenId), parseEther(startPrice), parseEther(bidIncrement.toString()), BigInt(duration)],
})
}

const buyCitizenship = async () => {
//todo: implement buy citizenship
writeContract({
abi: ContinentToken.abi,
address: "0x8148b0Ee040B1CFBb573bE82DE3704A20C139ccE",
functionName: 'buyCitizenship',
args: [BigInt(continent.tokenId)],
value: parseEther("0.001")
})
}

return (
Expand Down
18 changes: 18 additions & 0 deletions client/src/hooks/useHorizontalScroll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useEffect, useRef } from "react";

export function useHorizontalScroll() {
const elRef = useRef<HTMLElement | null>(null);
useEffect(() => {
const el = elRef.current;
if (el) {
const onWheel = (e: WheelEvent) => {
if (e.deltaY == 0) return;
e.preventDefault();
el.scrollBy(e.deltaY, 0);
};
el.addEventListener("wheel", onWheel);
return () => el.removeEventListener("wheel", onWheel);
}
}, []);
return elRef;
}
45 changes: 41 additions & 4 deletions client/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { toast } from "sonner";

export function shortenAddress(address: string) {
console.log(address)
let shortenedAddress = address ? address.slice(0, 5) + "..." + address.slice(-5) : "";
return shortenedAddress;
}
Expand All @@ -25,15 +26,13 @@ export const transformIPFSURL = (url: string) => {
};



type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
export type FetchAPIResponse<T> = {
success: boolean;
data: T;
message?: string;
};


export const fetchAPI = async <T>(
path: string,
method: HttpMethod = "GET",
Expand All @@ -49,4 +48,42 @@ export const fetchAPI = async <T>(

const data = await response.json() as T;
return data as FetchAPIResponse<T>;;
};
};

export const showError = (message: string ) => {

if (message.includes("insufficient funds")) {
toast.error("Insufficient funds", {
description: "You do not have enough funds to place this bid. Please top up your wallet and try again. The cost of transaction is calculated as `gas * gas fee + value`",
position: "top-left",
})
}

if (message.includes("Ownable: caller is not the owner")) {
toast.error("Transaction failed", {
description: "You can start an auction only if you own the continent",
position: "top-left",
});
}

if (message.includes("Continent does not exist")) {
toast.error("Transaction failed", {
description: "Continent does not exist",
position: "top-left",
});
}

if (message.includes("You already own this continent")) {
toast.error("Transaction failed", {
description: "You already own this continent",
position: "top-left",
});
}

if (message.includes("Not enough Ether sent to cover citizenship tax")) {
toast.error("Transaction failed", {
description: "Not enough Ether sent to cover citizenship tax",
position: "top-left",
});
}
}

0 comments on commit f6e9252

Please sign in to comment.