Skip to content

Commit

Permalink
Frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
damianmarti committed Nov 9, 2023
1 parent dea6b7b commit c6c091a
Show file tree
Hide file tree
Showing 11 changed files with 1,444 additions and 64 deletions.
135 changes: 135 additions & 0 deletions packages/nextjs/components/BettingRoomAddress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useEffect, useState } from "react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { isAddress } from "viem";
import { useEnsAvatar, useEnsName } from "wagmi";
import { CheckCircleIcon, DocumentDuplicateIcon, ShareIcon } from "@heroicons/react/24/outline";
import { BlockieAvatar } from "~~/components/scaffold-eth";
import scaffoldConfig from "~~/scaffold.config";

type TAddressProps = {
address?: string;
disableAddressLink?: boolean;
format?: "short" | "long";
size?: "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl";
};

const blockieSizeMap = {
xs: 6,
sm: 7,
base: 8,
lg: 9,
xl: 10,
"2xl": 12,
"3xl": 15,
};

/**
* Displays an address (or ENS) with a Blockie image and option to copy address.
*/
export const BettingRoomAddress = ({ address, disableAddressLink, format, size = "base" }: TAddressProps) => {
const [ens, setEns] = useState<string | null>();
const [ensAvatar, setEnsAvatar] = useState<string | null>();
const [addressCopied, setAddressCopied] = useState(false);
const [linkCopied, setLinkCopied] = useState(false);

const { data: fetchedEns } = useEnsName({ address, enabled: isAddress(address ?? ""), chainId: 1 });
const { data: fetchedEnsAvatar } = useEnsAvatar({
name: fetchedEns,
enabled: Boolean(fetchedEns),
chainId: 1,
cacheTime: 30_000,
});

// We need to apply this pattern to avoid Hydration errors.
useEffect(() => {
setEns(fetchedEns);
}, [fetchedEns]);

useEffect(() => {
setEnsAvatar(fetchedEnsAvatar);
}, [fetchedEnsAvatar]);

// Skeleton UI
if (!address) {
return (
<div className="animate-pulse flex space-x-4">
<div className="rounded-md bg-slate-300 h-6 w-6"></div>
<div className="flex items-center space-y-6">
<div className="h-2 w-28 bg-slate-300 rounded"></div>
</div>
</div>
);
}

if (!isAddress(address)) {
return <span className="text-error">Wrong address</span>;
}

const blockExplorerAddressLink = `/rooms/${address}`;
const blockExplorerAddressUrl = `${scaffoldConfig.liveUrl}${blockExplorerAddressLink}`;
let displayAddress = address?.slice(0, 5) + "..." + address?.slice(-4);

if (ens) {
displayAddress = ens;
} else if (format === "long") {
displayAddress = address;
}

return (
<div className="flex items-center">
<div className="flex-shrink-0">
<BlockieAvatar
address={address}
ensImage={ensAvatar}
size={(blockieSizeMap[size] * 24) / blockieSizeMap["base"]}
/>
</div>
{disableAddressLink ? (
<span className={`ml-1.5 text-${size} font-normal`}>{displayAddress}</span>
) : (
<a className={`ml-1.5 text-${size} font-normal`} href={blockExplorerAddressLink}>
{displayAddress}
</a>
)}
{addressCopied ? (
<CheckCircleIcon
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
aria-hidden="true"
/>
) : (
<CopyToClipboard
text={address}
onCopy={() => {
setAddressCopied(true);
setTimeout(() => {
setAddressCopied(false);
}, 800);
}}
>
<DocumentDuplicateIcon
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
aria-hidden="true"
/>
</CopyToClipboard>
)}
{linkCopied ? (
<CheckCircleIcon
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
aria-hidden="true"
/>
) : (
<CopyToClipboard
text={blockExplorerAddressUrl}
onCopy={() => {
setLinkCopied(true);
setTimeout(() => {
setLinkCopied(false);
}, 800);
}}
>
<ShareIcon className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer" aria-hidden="true" />
</CopyToClipboard>
)}
</div>
);
};
4 changes: 4 additions & 0 deletions packages/nextjs/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import Link from "next/link";
import { hardhat } from "viem/chains";
import { useBlockNumber } from "wagmi";
import { CurrencyDollarIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { HeartIcon } from "@heroicons/react/24/outline";
import { SwitchTheme } from "~~/components/SwitchTheme";
Expand All @@ -16,6 +17,8 @@ export const Footer = () => {
const nativeCurrencyPrice = useGlobalState(state => state.nativeCurrencyPrice);
const isLocalNetwork = getTargetNetwork().id === hardhat.id;

const { data: blockNumber, isError: isErrorBlockNumber, isLoading: isLoadingBlockNumber } = useBlockNumber();

return (
<div className="min-h-0 py-5 px-1 mb-11 lg:mb-0">
<div>
Expand All @@ -38,6 +41,7 @@ export const Footer = () => {
</Link>
</>
)}
<div>BlockNumber: {isErrorBlockNumber || isLoadingBlockNumber ? "..." : blockNumber?.toString()}</div>
</div>
<SwitchTheme className={`pointer-events-auto ${isLocalNetwork ? "self-end md:self-auto" : ""}`} />
</div>
Expand Down
4 changes: 4 additions & 0 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export const menuLinks: HeaderMenuLink[] = [
label: "Home",
href: "/",
},
{
label: "Rooms Created",
href: "/rooms",
},
{
label: "Debug Contracts",
href: "/debug",
Expand Down
Loading

0 comments on commit c6c091a

Please sign in to comment.