Skip to content

Commit

Permalink
Menu improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
luloxi committed Oct 19, 2024
1 parent 9f06208 commit b04599c
Show file tree
Hide file tree
Showing 12 changed files with 954 additions and 106 deletions.
1 change: 1 addition & 0 deletions packages/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import "@coinbase/onchainkit/styles.css";
import "@rainbow-me/rainbowkit/styles.css";
import { ScaffoldEthAppWithProviders } from "~~/components/ScaffoldEthAppWithProviders";
import { ThemeProvider } from "~~/components/ThemeProvider";
Expand Down
24 changes: 1 addition & 23 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,13 @@ import { PunkConnectButton } from "./punk-society/PunkConnectButton";
import { FaucetButton } from "./scaffold-eth";
import { useAccount } from "wagmi";
import { BellIcon, EnvelopeIcon, HomeIcon, MagnifyingGlassIcon } from "@heroicons/react/24/solid";
import { useScaffoldReadContract } from "~~/hooks/scaffold-eth";

/**
* Site header
*/
export const Header = () => {
const { address: connectedAddress } = useAccount();

const { data: profileInfo } = useScaffoldReadContract({
contractName: "PunkProfile",
functionName: "profiles",
args: [connectedAddress],
watch: true,
});

const defaultProfilePicture = "/guest-profile.jpg";

const profilePicture = profileInfo && profileInfo[2] ? profileInfo[2] : defaultProfilePicture;

const pathname = usePathname();

return (
Expand Down Expand Up @@ -125,24 +113,14 @@ export const Header = () => {
<PunkConnectButton />
</div>

<div className="mr-4">
<div className="">
<FaucetButton />
</div>
</div>
<div className="flex flex-row items-center justify-center gap-3">
{/* <div className="lg:mr-2"></div> */}

<div className="hidden lg:flex">
<Link href={`/profile/${connectedAddress}`} passHref>
<div
className="w-8 h-8 rounded-full flex items-center justify-center cursor-pointer"
style={{
backgroundImage: `url(${profilePicture})`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
></div>
</Link>
<div className="lg:ml-4">
<SwitchTheme />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { useRef, useState } from "react";
import Link from "next/link";
import { NetworkOptions } from "./NetworkOptions";
import CopyToClipboard from "react-copy-to-clipboard";
import { FundButton, getOnrampBuyUrl } from "@coinbase/onchainkit/fund";
import { getAddress } from "viem";
import { Address } from "viem";
import { useDisconnect } from "wagmi";
import { KeyIcon, LanguageIcon } from "@heroicons/react/20/solid";
import { useAccount, useDisconnect } from "wagmi";
import { KeyIcon as KeyIconOutline, UserIcon } from "@heroicons/react/24/outline";
import {
ArrowLeftOnRectangleIcon,
ArrowTopRightOnSquareIcon,
ArrowsRightLeftIcon,
CheckCircleIcon,
ChevronDownIcon,
DocumentDuplicateIcon,
QrCodeIcon,
} from "@heroicons/react/24/outline";
import { BlockieAvatar, isENS } from "~~/components/scaffold-eth";
import { useOutsideClick } from "~~/hooks/scaffold-eth";
import { ArrowUpLeftIcon, KeyIcon as KeyIconSolid, LanguageIcon, LinkIcon } from "@heroicons/react/24/solid";
import { isENS } from "~~/components/scaffold-eth";
import { useOutsideClick, useScaffoldReadContract } from "~~/hooks/scaffold-eth";
import { getTargetNetworks } from "~~/utils/scaffold-eth";

const allowedNetworks = getTargetNetworks();
Expand All @@ -27,18 +27,34 @@ type AddressInfoDropdownProps = {
ensAvatar?: string;
};

export const AddressInfoDropdown = ({
address,
ensAvatar,
displayName,
blockExplorerAddressLink,
}: AddressInfoDropdownProps) => {
export const AddressInfoDropdown = ({ address, displayName, blockExplorerAddressLink }: AddressInfoDropdownProps) => {
const [selectingNetwork, setSelectingNetwork] = useState(false);

const { disconnect } = useDisconnect();
const checkSumAddress = getAddress(address);
const { address: connectedAddress } = useAccount();

const [addressCopied, setAddressCopied] = useState(false);
const projectId = process.env.NEXT_PUBLIC_CDP_PROJECT_ID || "";

const onrampBuyUrl = getOnrampBuyUrl({
projectId,
addresses: { connectedAddress: ["base", "avalanche"] },
assets: ["USDC"],
presetFiatAmount: 5,
fiatCurrency: "USD",
});

const { data: profileInfo } = useScaffoldReadContract({
contractName: "PunkProfile",
functionName: "profiles",
args: [connectedAddress],
watch: true,
});

const defaultProfilePicture = "/guest-profile.jpg";

const profilePicture = profileInfo && profileInfo[2] ? profileInfo[2] : defaultProfilePicture;

const [selectingNetwork, setSelectingNetwork] = useState(false);
const dropdownRef = useRef<HTMLDetailsElement>(null);
const closeDropdown = () => {
setSelectingNetwork(false);
Expand All @@ -53,7 +69,15 @@ export const AddressInfoDropdown = ({
tabIndex={0}
className="btn btn-secondary bg-base-200 btn-sm pl-0 pr-2 shadow-md dropdown-toggle gap-0 !h-auto"
>
<BlockieAvatar address={checkSumAddress} size={30} ensImage={ensAvatar} />
<div
className="w-8 h-8 rounded-full flex items-center justify-center cursor-pointer"
style={{
backgroundImage: `url(${profilePicture})`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
></div>

<span className="ml-2 mr-1">
{isENS(displayName) ? displayName : checkSumAddress?.slice(0, 6) + "..." + checkSumAddress?.slice(-4)}
</span>
Expand All @@ -64,7 +88,7 @@ export const AddressInfoDropdown = ({
className="dropdown-content menu z-[2] p-2 mt-2 shadow-center shadow-accent bg-base-200 rounded-box gap-1"
>
<NetworkOptions hidden={!selectingNetwork} />
<li className={selectingNetwork ? "hidden" : ""}>
{/* <li className={selectingNetwork ? "hidden" : ""}>
{addressCopied ? (
<div className="btn-sm !rounded-xl flex gap-3 py-3">
<CheckCircleIcon
Expand Down Expand Up @@ -92,36 +116,63 @@ export const AddressInfoDropdown = ({
</div>
</CopyToClipboard>
)}
</li> */}
<li className={selectingNetwork ? "hidden" : ""}>
<Link className="p-0 flex items-center justify-center" href={`/profile/${connectedAddress}`} passHref>
<div className="btn-sm w-full !rounded-xl flex items-center justify-start gap-2 py-3 text-white bg-orange-600 hover:bg-orange-500 active:bg-orange-500">
<UserIcon className="text-xl font-normal h-6 w-4 cursor-pointer ml-2 sm:ml-0" aria-hidden="true" />
{/* <Link href={blockExplorerAddressLink} rel="noopener noreferrer" className="whitespace-nowrap"> */}
<Link href={`/profile/${connectedAddress}`} passHref>
Go to Profile
</Link>
</div>
</Link>
</li>
<li className={selectingNetwork ? "hidden" : ""}>
<label htmlFor="qrcode-modal" className="btn-sm !rounded-xl flex gap-3 py-3">
<label
htmlFor="qrcode-modal"
className="bg-[#4338CA] hover:bg-[#4f46e5] active:bg-[#4f46e5] btn-sm !rounded-xl flex gap-3 py-3"
>
<QrCodeIcon className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">View QR Code</span>
<span className="whitespace-nowrap">Receive USDC</span>
</label>
</li>
<li className={selectingNetwork ? "hidden" : ""}>
<label htmlFor="private-key-modal" className="btn-sm !rounded-xl flex gap-3 py-3">
<KeyIcon className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">View Private Key</span>
<label
htmlFor="send-usdc-modal"
className="bg-[#4338CA] hover:bg-[#4f46e5] active:bg-[#4f46e5] btn-sm !rounded-xl flex gap-3 py-3"
>
<ArrowUpLeftIcon className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">Send USDC</span>
</label>
</li>
<li className={selectingNetwork ? "hidden" : ""}>
<button className="menu-item btn-sm !rounded-xl flex gap-3 py-3" type="button">
<ArrowTopRightOnSquareIcon className="h-6 w-4 ml-2 sm:ml-0" />
<a
target="_blank"
href={blockExplorerAddressLink}
rel="noopener noreferrer"
className="whitespace-nowrap"
>
View on Block Explorer
</a>
</button>
<label
htmlFor="bridge-usdc-modal"
className="bg-[#4338CA] hover:bg-[#4f46e5] active:bg-[#4f46e5] btn-sm !rounded-xl flex gap-3 py-3"
>
<LinkIcon className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">Bridge USDC</span>
</label>
</li>
<li className={selectingNetwork ? "hidden" : ""}>
<label htmlFor="switch-language-modal" className="btn-sm !rounded-xl flex gap-3 py-3">
<LanguageIcon className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">Switch languages</span>
<FundButton
text="Buy USDC"
fundingUrl={onrampBuyUrl}
className="py-1 text-white px-6 md:px-3.5 gap-0.5 md:gap-1 text-md rounded-xl bg-[#4338CA] hover:bg-[#4f46e5] active:bg-[#4f46e5] justify-start font-normal "
/>
</li>

<li className={selectingNetwork ? "hidden" : ""}>
<label htmlFor="private-key-modal" className="btn-sm !rounded-xl flex gap-3 py-3">
<KeyIconOutline className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">View Private Key</span>
</label>
</li>
<li className={selectingNetwork ? "hidden" : ""}>
<label htmlFor="load-private-key-modal" className="btn-sm !rounded-xl flex gap-3 py-3">
<KeyIconSolid className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">Load Private Key</span>
</label>
</li>
{allowedNetworks.length > 1 ? (
Expand All @@ -137,6 +188,27 @@ export const AddressInfoDropdown = ({
</button>
</li>
) : null}
<li className={selectingNetwork ? "hidden" : ""}>
<label htmlFor="switch-language-modal" className="btn-sm !rounded-xl flex gap-3 py-3">
<LanguageIcon className="h-6 w-4 ml-2 sm:ml-0" />
<span className="whitespace-nowrap">Switch languages</span>
</label>
</li>

<li className={selectingNetwork ? "hidden" : ""}>
<button className="menu-item btn-sm !rounded-xl flex gap-3 py-3" type="button">
<ArrowTopRightOnSquareIcon className="h-6 w-4 ml-2 sm:ml-0" />
<a
target="_blank"
href={blockExplorerAddressLink}
rel="noopener noreferrer"
className="whitespace-nowrap"
>
View on Block Explorer
</a>
</button>
</li>

<li className={selectingNetwork ? "hidden" : ""}>
<button
className="menu-item text-error btn-sm !rounded-xl flex gap-3 py-3"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
import React, { useState } from "react";
import { QRCodeSVG } from "qrcode.react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { Address as AddressType } from "viem";
import { Address } from "~~/components/scaffold-eth";
import { notification } from "~~/utils/scaffold-eth";

type AddressQRCodeModalProps = {
address: AddressType;
modalId: string;
};

export const AddressQRCodeModal = ({ address, modalId }: AddressQRCodeModalProps) => {
const [copied, setCopied] = useState(false);

const handleCopy = () => {
setCopied(true);
notification.success("Address copied to clipboard");
setTimeout(() => setCopied(false), 2000); // Reset copied state after 2 seconds
};

return (
<>
<div>
<input type="checkbox" id={`${modalId}`} className="modal-toggle" />
<label htmlFor={`${modalId}`} className="modal cursor-pointer">
<label className="modal-box relative">
{/* dummy input to capture event onclick on modal box */}
<input className="h-0 w-0 absolute top-0 left-0" />
<label htmlFor={`${modalId}`} className="btn btn-ghost btn-sm btn-circle absolute right-3 top-3">
</label>
<div className="space-y-3 py-6 ">
<div className="flex flex-col items-center gap-6 ">
<div className="bg-white p-4 rounded-lg shadow-lg">
<QRCodeSVG value={address} size={256} />
</div>
<Address address={address} format="long" disableAddressLink />
<div className="flex flex-col justify-center items-center text-center">
<h2 className="text-xl font-bold mb-4">Your Address</h2>
<div className="bg-white p-4 rounded-lg shadow-lg mb-4">
<QRCodeSVG value={address} size={256} />
</div>
<div className="break-words whitespace-pre-wrap text-center w-full">{address}</div>
<CopyToClipboard text={address} onCopy={handleCopy}>
<button className="btn btn-primary bg-green-600 hover:bg-green-500 active:bg-green-500 mt-4">
{copied ? "Copied!" : "Copy Address"}
</button>
</CopyToClipboard>
<label
htmlFor={`${modalId}`}
className="btn text-xl rounded-full bg-red-600 hover:bg-red-500 btn-ghost btn-sm btn-circle absolute right-3 top-3"
>
</label>
</div>
</label>
</label>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Image from "next/image";

type BridgeUSDCModalProps = {
modalId: string;
};

export const BridgeUSDCModal = ({ modalId }: BridgeUSDCModalProps) => {
const handleBridgeUSDCClick = () => {
window.open("https://x.com/LuloxDev", "_blank");
};
return (
<>
<div>
<input type="checkbox" id={`${modalId}`} className="modal-toggle" />
<label htmlFor={`${modalId}`} className="modal cursor-pointer">
<label className="modal-box relative" htmlFor="">
<div className="flex flex-col justify-center items-center text-center">
<h2 className="text-xl font-bold mb-4 text-red-600">
Sorry, we can&apos;t bridge USDC from Avalanche yet.
</h2>

<button
onClick={handleBridgeUSDCClick}
className="btn btn-primary border-0 flex items-center bg-black hover:bg-green-600 active:bg-green-600"
>
<Image
src="/lulox.jpg"
alt="Import your key in Core!"
width={40}
height={40}
className="mr-2 rounded-full"
/>
Send me a DM and I&apos;ll get you started!
</button>
<label
htmlFor={`${modalId}`}
className="btn text-xl rounded-full bg-red-600 hover:bg-red-500 btn-ghost btn-sm btn-circle absolute right-3 top-3"
>
</label>
</div>
</label>
</label>
</div>
</>
);
};
Loading

0 comments on commit b04599c

Please sign in to comment.