Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make create-fuels template app responsive #3011

Merged
merged 10 commits into from
Aug 29, 2024
5 changes: 5 additions & 0 deletions .changeset/tall-hairs-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-fuels": patch
---

feat: make `create-fuels` template app responsive
4 changes: 4 additions & 0 deletions templates/nextjs/public/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions templates/nextjs/public/hamburger.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 3 additions & 95 deletions templates/nextjs/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,8 @@
import toast, { Toaster } from "react-hot-toast";
import { Link } from "./Link";
import { Button } from "./Button";
import { CURRENT_ENVIRONMENT, NODE_URL, TESTNET_FAUCET_LINK } from "@/lib";
import { useConnectUI, useDisconnect } from "@fuels/react";
import { WalletDisplay } from "./WalletDisplay";
import { useBrowserWallet } from "@/hooks/useBrowserWallet";
import { useActiveWallet } from "@/hooks/useActiveWallet";
import { useFaucet } from "@/hooks/useFaucet";
import { Toaster } from "react-hot-toast";
import Head from "next/head";
import { bn } from "fuels";
import { useRouter } from "next/navigation";
import { Navbar } from "./Navbar";

export const Layout = ({ children }: { children: React.ReactNode }) => {
const { faucetWallet } = useFaucet();
const router = useRouter();

const {
wallet: browserWallet,
isConnected: isBrowserWalletConnected,
network: browserWalletNetwork,
} = useBrowserWallet();

const { connect } = useConnectUI();
const { disconnect } = useDisconnect();

const { wallet, refreshWalletBalance, walletBalance } = useActiveWallet();

const topUpWallet = async () => {
if (!wallet) {
return console.error("Unable to topup wallet because wallet is not set.");
}

/**
* If the current environment is local, transfer 5 ETH to the wallet
* from the local faucet wallet
*/
if (CURRENT_ENVIRONMENT === "local") {
if (!faucetWallet) {
return toast.error("Faucet wallet not found.");
}

const tx = await faucetWallet?.transfer(
wallet.address,
bn.parseUnits("5"),
);
await tx?.waitForResult();

toast.success("Wallet topped up!");

return await refreshWalletBalance?.();
}

// If the current environment is testnet, open the faucet page
if (CURRENT_ENVIRONMENT === "testnet") {
return router.push("/faucet");
}
};

const showTopUpButton = walletBalance?.lt(bn.parseUnits("5"));

const showAddNetworkButton =
browserWallet &&
browserWalletNetwork &&
browserWalletNetwork?.url !== NODE_URL;

const tryToAddNetwork = () => {
return alert(
`Please add the network ${NODE_URL} to your Fuel wallet, or swtich to it if you have it already, and refresh the page.`,
);
};

return (
<>
<Head>
Expand All @@ -78,32 +11,7 @@ export const Layout = ({ children }: { children: React.ReactNode }) => {
</Head>
<Toaster />
<div className="flex flex-col">
<nav className="flex justify-between items-center p-4 bg-black text-white gap-6">
<Link href="/">Home</Link>

<Link href="/faucet">Faucet</Link>

{isBrowserWalletConnected && (
<Button onClick={disconnect}>Disconnect Wallet</Button>
)}
{!isBrowserWalletConnected && (
<Button onClick={connect}>Connect Wallet</Button>
)}

{showAddNetworkButton && (
<Button onClick={tryToAddNetwork} className="bg-red-500">
Wrong Network
</Button>
)}

<div className="ml-auto">
<WalletDisplay />
</div>

{showTopUpButton && (
<Button onClick={() => topUpWallet()}>Top-up Wallet</Button>
)}
</nav>
<Navbar />

<div className="min-h-screen items-center p-24 flex flex-col gap-6">
{children}
Expand Down
162 changes: 162 additions & 0 deletions templates/nextjs/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { FC, useState } from "react";
import { Link } from "./Link";
import { CURRENT_ENVIRONMENT, NODE_URL, TESTNET_FAUCET_LINK } from "@/lib";
import { useConnectUI, useDisconnect } from "@fuels/react";
import { useBrowserWallet } from "@/hooks/useBrowserWallet";
import { useActiveWallet } from "@/hooks/useActiveWallet";
import { Button } from "./Button";
import { WalletDisplay } from "./WalletDisplay";
import { bn } from "fuels";
import { useFaucet } from "@/hooks/useFaucet";
import toast from "react-hot-toast";

export const Navbar: FC = () => {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);

const { faucetWallet } = useFaucet();

const {
wallet: browserWallet,
isConnected: isBrowserWalletConnected,
network: browserWalletNetwork,
} = useBrowserWallet();

const { connect } = useConnectUI();
const { disconnect } = useDisconnect();

const { wallet, refreshWalletBalance, walletBalance } = useActiveWallet();

const topUpWallet = async () => {
if (!wallet) {
return console.error("Unable to topup wallet because wallet is not set.");
}

/**
* If the current environment is local, transfer 5 ETH to the wallet
* from the local faucet wallet
*/
if (CURRENT_ENVIRONMENT === "local") {
if (!faucetWallet) {
return toast.error("Faucet wallet not found.");
}

const tx = await faucetWallet?.transfer(
wallet.address,
bn.parseUnits("5"),
);
await tx?.waitForResult();

toast.success("Wallet topped up!");

return await refreshWalletBalance?.();
}

// If the current environment is testnet, open the testnet faucet link in a new tab
if (CURRENT_ENVIRONMENT === "testnet") {
return window.open(
`${TESTNET_FAUCET_LINK}?address=${wallet.address.toAddress()}`,
"_blank",
);
}
};

const showTopUpButton = walletBalance?.lt(bn.parseUnits("5"));

const showAddNetworkButton =
browserWallet &&
browserWalletNetwork &&
browserWalletNetwork?.url !== NODE_URL;

const tryToAddNetwork = () => {
return alert(
`Please add the network ${NODE_URL} to your Fuel wallet, or swtich to it if you have it already, and refresh the page.`,
);
};

return (
<>
{/* Larger screens */}
<nav className="hidden md:flex justify-between items-center p-4 bg-black text-white gap-6">
<Link href="/">Home</Link>

<Link
href={
CURRENT_ENVIRONMENT === "local" ? "/faucet" : TESTNET_FAUCET_LINK
}
target={CURRENT_ENVIRONMENT === "local" ? "_self" : "_blank"}
>
Faucet
</Link>

{isBrowserWalletConnected && (
<Button onClick={disconnect}>Disconnect Wallet</Button>
)}
{!isBrowserWalletConnected && (
<Button onClick={connect}>Connect Wallet</Button>
)}

{showAddNetworkButton && (
<Button onClick={tryToAddNetwork} className="bg-red-500">
Wrong Network
</Button>
)}

<div className="ml-auto">
<WalletDisplay />
</div>

{showTopUpButton && (
<Button onClick={() => topUpWallet()}>Top-up Wallet</Button>
)}
</nav>

{/* Mobile. Should be a hamburger menu */}
<nav className="flex flex-col md:hidden p-4 bg-black text-white items-center gap-4">
<img
src={isMobileMenuOpen ? "/close.svg" : "/hamburger.svg"}
alt="menu"
className="w-8 h-8 ml-auto cursor-pointer"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
/>

{isMobileMenuOpen && (
<>
<Link href="/">Home</Link>

<Link
href={
CURRENT_ENVIRONMENT === "local"
? "/faucet"
: TESTNET_FAUCET_LINK
}
target={CURRENT_ENVIRONMENT === "local" ? "_self" : "_blank"}
>
Faucet
</Link>

{isBrowserWalletConnected && (
<Button onClick={disconnect}>Disconnect Wallet</Button>
)}
{!isBrowserWalletConnected && (
<Button onClick={connect}>Connect Wallet</Button>
)}

{showAddNetworkButton && (
<Button onClick={() => toast.success("Adding network")}>
Add Network
</Button>
)}

<div>
<WalletDisplay />
</div>

{showTopUpButton && (
<Button onClick={() => topUpWallet()}>Top-up Wallet</Button>
)}
</>
)}
</nav>
</>
);
};
4 changes: 4 additions & 0 deletions templates/vite/public/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions templates/vite/public/hamburger.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading