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: connect and disconnect #104

Merged
merged 1 commit into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions frontend/app/layout.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import Header from "@/components/Header";
import { StarknetProvider } from "@/components/starknet-provider";

const geistSans = Geist({
variable: "--font-geist-sans",
Expand All @@ -14,19 +15,21 @@ const geistMono = Geist_Mono({

export const metadata = {
title: "LyricFlip",
description: "Play LyricFlip, the on-chain card game powered by Starknet! Guess songs from partial lyrics, explore genres & decades, wager tokens, and relive music nostalgia.",
description:
"Play LyricFlip, the on-chain card game powered by Starknet! Guess songs from partial lyrics, explore genres & decades, wager tokens, and relive music nostalgia.",
};

export default function RootLayout({ children }) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<Header />
{children}

</body>
<StarknetProvider>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<Header />
{children}
</body>
</StarknetProvider>
</html>
);
}
34 changes: 34 additions & 0 deletions frontend/components/AddressBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { useAccount, useDisconnect } from "@starknet-react/core";
import { useState } from "react";

const AddressBar = () => {
const { address } = useAccount();
const { disconnect } = useDisconnect();
const [displayAddress, setDisplayAddress] = useState(true);

return (
<button
className="flex w-[203px] items-center justify-center gap-x-3 rounded-[4px] bg-[#70E3C7] py-[12px] text-center text-base font-medium text-[#490878] disabled:cursor-not-allowed"
onMouseEnter={() => setDisplayAddress(false)}
onMouseLeave={() => setDisplayAddress(true)}
onClick={disconnect}
>
{!displayAddress ? (
"Disconnect Wallet"
) : (
<>
<img src="/img/argent.svg" className="h-[24px] w-[24px]" alt="" />
<span>
{address
? address.slice(0, 7).concat("...").concat(address.slice(-4))
: ""}
</span>
</>
)}
</button>
);
};

export default AddressBar;
183 changes: 96 additions & 87 deletions frontend/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import Link from "next/link";
import Image from "next/image";
import { MdOutlineMenu } from "react-icons/md";
import { IoMdClose } from "react-icons/io";
import WalletBar from "./WalletBar";
import LockBodyScroll from "./LockBodyScroll";
import { createPortal } from "react-dom";
import { WalletModal } from "./WalletModal";

const navigation = [
{ name: "Play Now", href: "#game", isScroll: true },
Expand All @@ -26,110 +30,115 @@ const handleScroll = (e, isScroll) => {
};

const Header = () => {
const [connectModalIsOpen, setConnectModalIsOpen] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);

return (
<div className="fixed w-full bg-custom-gradient z-10">
<header className="">
<nav
aria-label="Global"
className="flex items-center justify-between p-3 lg:px-8"
>
<div className="flex lg:flex-1">
<Link href="#" className="-m-1.5 p-1.5">
<span className="sr-only">LyricsFlip</span>
<Image
alt=""
src="/img/LyricsFlipLogo.png"
className="h-14 w-[50px]"
width={100}
height={100}
/>
</Link>
</div>
<div className="flex lg:hidden">
<button
type="button"
onClick={() => setMobileMenuOpen(true)}
className="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700"
>
<span className="sr-only">Open main menu</span>
<MdOutlineMenu aria-hidden="true" className="size-6" />
</button>
</div>
<div className="hidden lg:flex lg:gap-x-12">
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
onClick={(e) => handleScroll(e, item.isScroll)}
className="text-sm/6 font-semibold text-white"
>
{item.name}
</Link>
))}
</div>
{/* <div className="hidden lg:flex lg:flex-1 lg:justify-end">
<Link
href="#"
className="text-sm/6 font-semibold text-[#490878] px-3 py-1.5 text-center rounded-lg bg-[#70E3C7]"
>
Connect Wallet
</Link>
</div> */}
</nav>
<Dialog
open={mobileMenuOpen}
onClose={setMobileMenuOpen}
className="lg:hidden"
>
<div className="fixed inset-0 z-50" />
<DialogPanel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
<div className="flex items-center justify-between">
<>
<LockBodyScroll lock={connectModalIsOpen || mobileMenuOpen} />

{connectModalIsOpen &&
createPortal(
<WalletModal setIsOpen={setConnectModalIsOpen} />,
document.body
)}
<div className="fixed w-full bg-custom-gradient z-10">
<header className="">
<nav
aria-label="Global"
className="flex items-center justify-between p-3 lg:px-8"
>
<div className="flex">
<Link href="#" className="-m-1.5 p-1.5">
<span className="sr-only">Your Company</span>
<img
<span className="sr-only">LyricsFlip</span>
<Image
alt=""
src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600"
className="h-8 w-auto"
src="/img/LyricsFlipLogo.png"
className="h-14 w-[50px]"
width={100}
height={100}
/>
</Link>
</div>
<div className="flex lg:hidden">
<button
type="button"
onClick={() => setMobileMenuOpen(false)}
className="-m-2.5 rounded-md p-2.5 text-gray-700"
onClick={() => setMobileMenuOpen(true)}
className="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700"
>
<span className="sr-only">Close menu</span>
<IoMdClose aria-hidden="true" className="size-6" />
<span className="sr-only">Open main menu</span>
<MdOutlineMenu aria-hidden="true" className="size-6" />
</button>
</div>
<div className="mt-6 flow-root">
<div className="-my-6 divide-y divide-gray-500/10">
<div className="space-y-2 py-6">
{navigation.map((item) => (
<div className="hidden lg:flex lg:gap-x-12">
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
onClick={(e) => handleScroll(e, item.isScroll)}
className="text-sm/6 font-semibold text-white"
>
{item.name}
</Link>
))}
</div>
<WalletBar
toggleModal={() => setConnectModalIsOpen((prev) => !prev)}
/>
</nav>
<Dialog
open={mobileMenuOpen}
onClose={setMobileMenuOpen}
className="lg:hidden"
>
<div className="fixed inset-0 z-50" />
<DialogPanel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
<div className="flex items-center justify-between">
<Link href="#" className="-m-1.5 p-1.5">
<span className="sr-only">Your Company</span>
<img
alt=""
src="https://tailwindui.com/plus/img/logos/mark.svg?color=indigo&shade=600"
className="h-8 w-auto"
/>
</Link>
<button
type="button"
onClick={() => setMobileMenuOpen(false)}
className="-m-2.5 rounded-md p-2.5 text-gray-700"
>
<span className="sr-only">Close menu</span>
<IoMdClose aria-hidden="true" className="size-6" />
</button>
</div>
<div className="mt-6 flow-root">
<div className="-my-6 divide-y divide-gray-500/10">
<div className="space-y-2 py-6">
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-gray-900 hover:bg-gray-50"
>
{item.name}
</Link>
))}
</div>
<div className="py-6">
<Link
key={item.name}
href={item.href}
className="-mx-3 block rounded-lg px-3 py-2 text-base/7 font-semibold text-gray-900 hover:bg-gray-50"
href="#"
className="-mx-3 block rounded-lg px-3 py-2.5 text-base/7 font-semibold text-gray-900 hover:bg-gray-50"
>
{item.name}
Log in
</Link>
))}
</div>
<div className="py-6">
<Link
href="#"
className="-mx-3 block rounded-lg px-3 py-2.5 text-base/7 font-semibold text-gray-900 hover:bg-gray-50"
>
Log in
</Link>
</div>
</div>
</div>
</div>
</DialogPanel>
</Dialog>
</header>
</div>
</DialogPanel>
</Dialog>
</header>
</div>
</>
);
};

Expand Down
2 changes: 1 addition & 1 deletion frontend/components/HowToPlay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const HowItWorks = () => {
{/* Steps Grid */}
<div className="grid gap-8 md:grid-cols-3 my-16">
{steps.map((step, index) => (
<div className="space-y-4 my-10">
<div className="space-y-4 my-10" key={index}>
<h3
key={index}
className="text-2xl font-bold text-[#FFFFFF] lg:text-3xl pb-3"
Expand Down
28 changes: 28 additions & 0 deletions frontend/components/LockBodyScroll.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useEffect } from "react";

export default function LockBodyScroll({ lock }) {
useEffect(() => {
const originalOverflow = document.body.style.overflow;
const originalHeight = document.body.style.height;

if (lock) {
window.scrollTo({ top: 0, behavior: "smooth" });

document.body.style.transition = "all 0.3s ease-in-out";
document.body.style.overflow = "hidden";
document.body.style.height = "100vh";
} else {
document.body.style.transition = "all 0.3s ease-in-out";
document.body.style.overflow = originalOverflow;
document.body.style.height = originalHeight;
}

return () => {
document.body.style.transition = "";
document.body.style.overflow = originalOverflow;
document.body.style.height = originalHeight;
};
}, [lock]);

return null;
}
24 changes: 24 additions & 0 deletions frontend/components/WalletBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";
import { useAccount } from "@starknet-react/core";
import AddressBar from "./AddressBar";

function WalletBar({ toggleModal }) {
const { address } = useAccount();

return (
<div className="flex items-center justify-center">
{address ? (
<AddressBar />
) : (
<button
onClick={toggleModal}
className="text-sm/6 font-semibold text-[#490878] px-3 py-1.5 text-center rounded-lg bg-[#70E3C7]"
>
Connect Wallet
</button>
)}
</div>
);
}

export default WalletBar;
Loading