Skip to content

Commit

Permalink
add wallet address display to header (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
Spencer-Sch authored Dec 2, 2023
1 parent 2df70ff commit de8a996
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 2 deletions.
38 changes: 36 additions & 2 deletions packages/nextjs/components/dash-wind/containers/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import Bars3Icon from "@heroicons/react/24/outline/Bars3Icon";
import BellIcon from "@heroicons/react/24/outline/BellIcon";
import MoonIcon from "@heroicons/react/24/outline/MoonIcon";
import SunIcon from "@heroicons/react/24/outline/SunIcon";
import UserIcon from "@heroicons/react/24/outline/UserIcon";
// import UserIcon from "@heroicons/react/24/outline/UserIcon";
import { MyState, useMyDispatch, useMySelector } from "~~/components/dash-wind/app/store";
import { Address } from "~~/components/web-3-crew/Address";

function Header() {
const dispatch = useMyDispatch();
Expand Down Expand Up @@ -94,6 +95,39 @@ function Header() {

{/* Profile icon, opening menu on click */}
<div className="dropdown dropdown-end ml-4">
<label tabIndex={0} className="btn btn-ghost">
<div className="flex justify-center items-center">
{/* Wallet Address Display */}
<Address
address="0xB9555E2f3e34aDfDB5d033C5af73de6e2385A770"
disableAddressLink={true}
format="short"
size="base"
/>
</div>
</label>
<ul
tabIndex={0}
className="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52"
>
<li className="justify-between">
<Link href="/dapp/settings-profile">
Profile Settings
<span className="badge">New</span>
</Link>
</li>
<li className="">
<Link href="/dapp/settings-billing">Bill History</Link>
</li>
<div className="divider mt-0 mb-0"></div>
<li>
<a onClick={logoutUser}>Logout</a>
</li>
</ul>
</div>

{/* Profile icon, opening menu on click */}
{/* <div className="dropdown dropdown-end ml-4">
<label tabIndex={0} className="btn btn-ghost btn-circle avatar">
<div className="flex justify-center items-center rounded-full">
<UserIcon className="h-6 w-6 inline-block" />
Expand All @@ -117,7 +151,7 @@ function Header() {
<a onClick={logoutUser}>Logout</a>
</li>
</ul>
</div>
</div> */}
</div>
</div>
</>
Expand Down
129 changes: 129 additions & 0 deletions packages/nextjs/components/web-3-crew/Address.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { useEffect, useState } from "react";
import Link from "next/link";
// import { CopyToClipboard } from "react-copy-to-clipboard";
import { isAddress } from "viem";
import { hardhat } from "viem/chains";
import { useEnsAvatar, useEnsName } from "wagmi";
// import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
import { BlockieAvatar } from "~~/components/scaffold-eth";
import { getBlockExplorerAddressLink, getTargetNetwork } from "~~/utils/scaffold-eth";

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,
};

/**
* Edit of Scaffold-Eth-2 `Address` components
*/
/**
* Displays an address (or ENS) with a Blockie image and option to copy address.
*/
export const Address = ({ address, disableAddressLink, format, size = "base" }: TAddressProps) => {
const [ens, setEns] = useState<string | null>();
const [ensAvatar, setEnsAvatar] = useState<string | null>();
// const [addressCopied, setAddressCopied] = 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 = getBlockExplorerAddressLink(getTargetNetwork(), address);
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>
) : getTargetNetwork().id === hardhat.id ? (
<span className={`ml-1.5 text-${size} font-normal`}>
<Link href={blockExplorerAddressLink}>{displayAddress}</Link>
</span>
) : (
<a
className={`ml-1.5 text-${size} font-normal`}
target="_blank"
href={blockExplorerAddressLink}
rel="noopener noreferrer"
>
{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>
)} */}
</div>
);
};

0 comments on commit de8a996

Please sign in to comment.