Skip to content

Instantly share code, notes, and snippets.

@jdaly13
Last active September 2, 2024 22:53
Show Gist options
  • Save jdaly13/60e3069341a7fbd46f2d1959bcd2e86e to your computer and use it in GitHub Desktop.
Save jdaly13/60e3069341a7fbd46f2d1959bcd2e86e to your computer and use it in GitHub Desktop.
Navbar component
import { useState, useEffect } from "react";
import { Link, useFetcher } from "@remix-run/react";
import { createWallet, injectedProvider } from "thirdweb/wallets";
import { checksumAddress } from "thirdweb/utils";
import { useActiveWallet, useActiveAccount, useDisconnect, ConnectButton, useAutoConnect } from "thirdweb/react";
import { signLoginPayload } from "thirdweb/auth";
import LoginModal from "./LoginModal";
function truncateAddress(address) {
if (address && address.length > 25) {
return address.substring(0, 5) + "..." + address.substring(address.length - 5);
} else {
return address;
}
}
export default function NavBar({ user, authEmail, authError, client, jwt, authenticatedViaEmail }) {
const wallets = [createWallet("io.metamask"), createWallet("com.coinbase.wallet"), createWallet("me.rainbow")];
const { disconnect } = useDisconnect();
const wallet = useActiveWallet();
const activeAccount = useActiveAccount();
console.log({ activeAccount });
const loginFetcher = useFetcher();
const [loginModalOpen, setLoginModal] = useState(false);
const [url, setURL] = useState("");
const [showConnect, setShowConnect] = useState(false);
useEffect(() => {
if (user && user.id) {
setLoginModal(false);
}
}, [user]);
useEffect(() => {
setURL(window.location.href);
setShowConnect(true);
}, []);
useEffect(() => {
if (activeAccount?.address && user?.addressOrEmail) {
console.log(activeAccount.address, user.addressOrEmail);
if (checksumAddress(activeAccount.address) !== checksumAddress(user.addressOrEmail)) {
logout();
}
}
}, [activeAccount, user]);
const logout = async () => {
// console.log({ wallet });
// disconnect(wallet);
if (jwt) {
const jwtResponse = await fetch(`/api/logout?page=${window.location.href}`, {
method: "POST",
body: JSON.stringify({
id: user.addressOrEmail,
}),
});
console.log({ jwtResponse });
disconnect(wallet);
if (jwtResponse.redirected) {
console.log("testing");
window.location.reload();
}
return;
}
const response = await fetch(`/api/logout?page=${window.location.href}`);
console.log({ response });
if (response.redirected) {
window.location = response.url;
}
};
const disconnectUsersWallet = async () => {
disconnect(wallet);
// logout();
};
const signTransaction = async () => {
const account = wallet.getAccount();
console.log({ account });
const payloadResponse = await fetch(`/api/siwe?address=${account.address}&payload=true`);
console.log({ payloadResponse });
const payload = await payloadResponse.json();
console.log({ payload }, { activeAccount });
const signatureResult = await signLoginPayload({ account, payload });
const response = await fetch("/api/siwe", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
payload: signatureResult,
}),
});
const responseJson = await response.json();
console.log(responseJson);
console.log({ activeAccount });
window.location.reload();
};
function copyText() {
//Should be active account lookinto TODO
navigator.clipboard.writeText(activeAccount?.address || user.addressOrEmail || "");
}
return (
<>
<div className="navbar fixed top-0 left-0 right-0 z-[99] bg-base-300 ">
{showConnect && (
<ConnectButton
connectButton={{
label: "wallet login",
className: `${authenticatedViaEmail ? "!hidden" : ""} !btn !btn-primary !text-slate-200 !min-w-[120px] !bg-blue-600`,
}}
wallets={wallets}
detailsButton={{
className: "!hidden",
}}
signInButton={{
className: "!hidden",
}}
connectModal={{ size: "wide" }}
// onConnect={onWalletConnect}
client={client}
//TODO make this dynamic
chain={{
id: 11155111,
name: "sepolia",
}}
/>
)}
{activeAccount && !user && (
<>
<div className="hidden sm:flex flex-col mr-2">
<p className="text-xs font-bold">sign transaction to login!</p>
<p className="text-xs">
Connected with {truncateAddress(activeAccount.address)}
<span
data-tip="copy address"
onClick={copyText}
className="tooltip tooltip-bottom tooltip-info cursor-pointer pl-1"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 32 32"
strokeWidth={1}
stroke="currentColor"
className="inline h-6 w-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75"
/>
</svg>
</span>
</p>
</div>
<button onClick={() => disconnectUsersWallet()} className="btn btn-primary btn-sm">
Disconnect
</button>
<span className="px-4">or</span>
<button onClick={() => signTransaction()} className="btn btn-primary px uppercase">
sign to login
</button>
</>
)}
{!user && !activeAccount && <span className="pl-4">or</span>}
{!user && !activeAccount && (
<button onClick={() => setLoginModal(true)} className="btn btn-primary ml-4">
email login
</button>
)}
{user && (
<>
<a onClick={() => logout()} className="btn btn-primary">
Logout
</a>
<div className="flex flex-wrap">
<p className="ml-4 text-xs w-full">You are logged in as </p>
<p className="ml-4 text-xs w-full">
{truncateAddress(user?.addressOrEmail)}
<span
data-tip="copy address"
onClick={copyText}
className="tooltip tooltip-bottom tooltip-info cursor-pointer pl-1"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 32 32"
strokeWidth={1}
stroke="currentColor"
className="inline h-6 w-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75"
/>
</svg>
</span>
</p>
</div>
</>
)}
<div className="absolute right-2 top-2 sm:right-5 sm:top-2">
<Link to="/">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-10 w-10"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
/>
</svg>
</Link>
</div>
</div>
<LoginModal
authEmail={authEmail}
user={user}
authError={authError}
loginModalOpen={loginModalOpen}
setLoginModal={setLoginModal}
loginFetcher={loginFetcher}
url={url}
logout={logout}
></LoginModal>
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment