Skip to content

Commit

Permalink
Modifications in menus, new config menu
Browse files Browse the repository at this point in the history
  • Loading branch information
luloxi committed Oct 20, 2024
1 parent e9d8317 commit 826cb6a
Show file tree
Hide file tree
Showing 17 changed files with 658 additions and 118 deletions.
4 changes: 3 additions & 1 deletion AVALANCHE-L1.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ It'll take some time to load, go take a walk or something

5. After it boots up the blockchain, for some reason port `9650` doesn't set itself automatically to public, so you gotta click `Ports` to the right of `Terminal`, find port 9650, right click it, Port visibility, Public

> NOTE: After 30 minutes (or if you close the tab/browser) your codespaces goes to sleep. To restart your blockchain after your codespace was sleep, run `avalanche network start`. Remember to set **Port 9650** to public again.
> NOTE: After 30 minutes (or if you close the tab/browser) your codespaces goes to sleep. To prevent this from happening, run this command: `while true; do echo "Ah ah ah ah, staying alive!"; sleep 900; done &` to ping the codespace every 15 minutes.
> NOTE: Remember [GitHub will provide users in the free plan](https://docs.github.com/es/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) (boo!) 120 core hours or 60 hours of run time on a 2 core codespace, plus 15 GB of storage each month. So remember to shut it down when you're not using it.
> NOTE for Ava Labs: Maybe a **function to set Port 9650 to public** could be a temporary improvement to open it until it's opened automatically by default.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ yarn install

4. Start a local Avalanche L1:

It'd be ideal to run it with one command like `yarn subnet`, but so far, **you gotta <a href="./AVALANCHE-L1.md" target="_blank">follow this instructions</a>**.
It'd be ideal to run it with one command like `yarn subnet` with a config file, but so far, **you gotta <a href="./AVALANCHE-L1.md" target="_blank">follow this instructions</a>**.

You'll start a local Avalanche L1 using [Ava Labs avalanche-starter-kit](https://github.com/ava-labs/avalanche-starter-kit). The network runs on your local machine and can be used for testing and development.

Expand Down
28 changes: 11 additions & 17 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,15 @@ import React from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { SwitchTheme } from "./SwitchTheme";
import { PunkBalance } from "./punk-society/PunkBalance";
import { ConfigMenu } from "./punk-society/ConfigMenu";
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";

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

const pathname = usePathname();

return (
Expand All @@ -37,7 +34,7 @@ export const Header = () => {
<div className="flex flex-row gap-3 ">
<Link href="/" passHref>
<button
className={`bg-transparent hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-xl ${
className={`bg-transparent hover:bg-transparent border-none hidden lg:flex flex-row items-center justify-center text-xl ${
pathname === "/" ? "text-blue-600" : ""
}`}
>
Expand All @@ -49,7 +46,7 @@ export const Header = () => {

<Link href="/search" passHref>
<button
className={`bg-transparent hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-xl ${
className={`bg-transparent hover:bg-bg-transparent border-none hidden lg:flex flex-row items-center justify-center text-xl ${
pathname === "/search" ? "text-blue-600" : ""
}`}
>
Expand All @@ -61,7 +58,7 @@ export const Header = () => {

<Link href="/not-found" passHref>
<button
className={`bg-transparent text-red-600 hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-xl ${
className={`bg-transparent text-red-600 hover:bg-transparent border-none hidden lg:flex flex-row items-center justify-center text-xl ${
pathname === "/notifications" ? "text-blue-600" : ""
}`}
>
Expand All @@ -73,7 +70,7 @@ export const Header = () => {

<Link href="/not-found" passHref>
<button
className={`bg-transparent text-red-600 hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-xl ${
className={`bg-transparent text-red-600 hover:bg-transparent border-none hidden lg:flex flex-row items-center justify-center text-xl ${
pathname === "/messages" ? "text-blue-600" : ""
}`}
>
Expand Down Expand Up @@ -103,27 +100,24 @@ export const Header = () => {
</div> */}
</div>

<div className="navbar-end relative lg:mr-2">
<div className="navbar-end relative ">
<div className="flex justify-center items-center ">
<div className="hidden md:flex lg:mr-2">
<PunkBalance address={connectedAddress} />
</div>

<div className="flex items-center justify-center">
<PunkConnectButton />
</div>

<div className="">
<div>
<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">
<div className="lg:ml-4">
<SwitchTheme />
</div>
<SwitchTheme />
</div>
<div className="mr-4">
<ConfigMenu />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { useRef, useState } from "react";
import { NetworkOptions } from "./NetworkOptions";
import { Address } from "viem";
import { useDisconnect } from "wagmi";
import { Cog6ToothIcon } from "@heroicons/react/20/solid";
import { KeyIcon as KeyIconOutline } from "@heroicons/react/24/outline";
import {
ArrowLeftOnRectangleIcon,
ArrowTopRightOnSquareIcon,
ArrowsRightLeftIcon,
QrCodeIcon,
} from "@heroicons/react/24/outline";
import { KeyIcon as KeyIconSolid, LanguageIcon } from "@heroicons/react/24/solid";
import { useOutsideClick } from "~~/hooks/scaffold-eth";
import { getTargetNetworks } from "~~/utils/scaffold-eth";

const allowedNetworks = getTargetNetworks();

type AddressInfoDropdownProps = {
address: Address;
blockExplorerAddressLink: string | undefined;
displayName: string;
ensAvatar?: string;
};

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

const { disconnect } = useDisconnect();

const dropdownRef = useRef<HTMLDetailsElement>(null);
const closeDropdown = () => {
setSelectingNetwork(false);
dropdownRef.current?.removeAttribute("open");
};
useOutsideClick(dropdownRef, closeDropdown);

return (
<>
<details ref={dropdownRef} className="dropdown dropdown-end leading-3">
<summary
tabIndex={0}
className="btn btn-secondary shadow-none bg-transparent border-0 btn-sm p-2 dropdown-toggle gap-0 !h-auto"
>
<Cog6ToothIcon className="h-5 w-5 ml-2 sm:ml-0" />
</summary>
<ul
tabIndex={0}
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" : ""}>
<label
htmlFor="qrcode-modal"
className="bg-red-600 text-white hover:bg-red-500 active:bg-red-500 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 your address</span>
</label>
</li>
<li className={selectingNetwork ? "hidden" : ""}>
<label
htmlFor="private-key-modal"
className="btn-sm bg-red-600 text-white hover:bg-red-500 active:bg-red-500 !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 bg-red-600 text-white hover:bg-red-500 active:bg-red-500 !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 ? (
<li className={selectingNetwork ? "hidden" : ""}>
<button
className="btn-sm !rounded-xl flex gap-3 py-3"
type="button"
onClick={() => {
setSelectingNetwork(true);
}}
>
<ArrowsRightLeftIcon className="h-4 w-4 ml-2 sm:ml-0" /> <span>Switch Network</span>
</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-red-600 dark:text-red-500 btn-sm !rounded-xl flex gap-3 py-3"
type="button"
onClick={() => disconnect()}
>
<ArrowLeftOnRectangleIcon className="h-6 w-4 ml-2 sm:ml-0" /> <span>Disconnect</span>
</button>
</li>
</ul>
</details>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useState } from "react";
import { QRCodeSVG } from "qrcode.react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { Address as AddressType } from "viem";
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">
<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>
</div>
</>
);
};
74 changes: 74 additions & 0 deletions packages/nextjs/components/punk-society/ConfigMenu/Balance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"use client";

import { Address, formatEther } from "viem";
import { useDisplayUsdMode } from "~~/hooks/scaffold-eth/useDisplayUsdMode";
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
import { useWatchBalance } from "~~/hooks/scaffold-eth/useWatchBalance";
import { useGlobalState } from "~~/services/store/store";

type BalanceProps = {
address?: Address;
className?: string;
usdMode?: boolean;
};

/**
* Display (ETH & USD) balance of an ETH address.
*/
export const Balance = ({ address, className = "", usdMode }: BalanceProps) => {
const { targetNetwork } = useTargetNetwork();
const nativeCurrencyPrice = useGlobalState(state => state.nativeCurrency.price);
const isNativeCurrencyPriceFetching = useGlobalState(state => state.nativeCurrency.isFetching);

const {
data: balance,
isError,
isLoading,
} = useWatchBalance({
address,
});

const { displayUsdMode, toggleDisplayUsdMode } = useDisplayUsdMode({ defaultUsdMode: usdMode });

if (!address || isLoading || balance === null || (isNativeCurrencyPriceFetching && nativeCurrencyPrice === 0)) {
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 (isError) {
return (
<div className={`border-2 border-gray-400 rounded-md px-2 flex flex-col items-center max-w-fit cursor-pointer`}>
<div className="text-warning">Error</div>
</div>
);
}

const formattedBalance = balance ? Number(formatEther(balance.value)) : 0;

return (
<button
className={`btn btn-sm btn-ghost flex flex-col font-normal items-center hover:bg-transparent ${className}`}
onClick={toggleDisplayUsdMode}
>
<div className="w-full flex items-center justify-center">
{displayUsdMode ? (
<>
<span className="text-[0.8em] font-bold mr-1">$</span>
<span>{(formattedBalance * nativeCurrencyPrice).toFixed(2)}</span>
</>
) : (
<>
<span>{formattedBalance.toFixed(4)}</span>
<span className="text-[0.8em] font-bold ml-1">{targetNetwork.nativeCurrency.symbol}</span>
</>
)}
</div>
</button>
);
};
Loading

0 comments on commit 826cb6a

Please sign in to comment.