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

ft: gate #25

Closed
wants to merge 5 commits into from
Closed
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
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@material-tailwind/react": "^2.1.9",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@starknet-react/chains": "^0.1.7",
"@starknet-react/core": "^2.8.0",
"class-variance-authority": "^0.7.0",
Expand Down
6 changes: 5 additions & 1 deletion client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { BrowserRouter, Routes, Route } from "react-router-dom"
import Home from "./pages/Home"
import Leaderboard from "./pages/Leaderboard"
import { Provider as JotaiProvider } from "jotai";
import { InjectedConnector } from "starknetkit/injected";
import { ArgentMobileConnector } from "starknetkit/argentMobile";
import { WebWalletConnector } from "starknetkit/webwallet";
import { mainnet } from "@starknet-react/chains";
import { StarknetConfig, publicProvider } from "@starknet-react/core";
import Gameplay from "./pages/Gameplay";
import Home from "./pages/Home";
import Lobby from "./pages/Lobby";

export default function App() {
const chains = [
Expand All @@ -28,7 +30,9 @@ export default function App() {
<BrowserRouter>
<Routes>
<Route index element={<Home />} />
<Route path="/lobby" element={<Lobby />} />
<Route path="/leaderboard" element={<Leaderboard />} />
<Route path="/gameplay" element={<Gameplay />} />
</Routes>
</BrowserRouter>
</JotaiProvider>
Expand Down
Binary file added client/src/assets/connect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/home-box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified client/src/assets/leaderboard-top.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/link-out.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/lobby-box-large.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/lobby-box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/assets/logo-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions client/src/atom/atoms.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { atom } from 'jotai'
import { ConnectedStarknetWindowObject } from 'starknetkit'

export const isPlaying = atom(false)
export const profileData = atom({})
export const address = atom('')
export const connection = atom<ConnectedStarknetWindowObject | undefined>(undefined)
136 changes: 136 additions & 0 deletions client/src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@

import { useEffect, useRef } from "react";
import { truncateString } from "../lib/utils";
import mancala from "../assets/logo.png";
import eniola from "../assets/eniola.png";
import muteImage from "../assets/mute.png";
import unmuteImage from "../assets/unmute.png";
import { useState } from "react";
import { connect, ConnectedStarknetWindowObject, disconnect } from 'starknetkit';
import { useAtom } from "jotai";
import { isPlaying as isPlayingAtom, profileData as profileDataAtom, address as addressAtom, connection as connectionAtom } from "../atom/atoms";
import audio from "../music/audio_1.mp3";
import { useProvider } from "@starknet-react/core";
import { StarknetIdNavigator } from "starknetid.js";
import { constants, type StarkProfile } from "starknet";
import { Button } from "@material-tailwind/react";
import { UserIcon } from "@heroicons/react/24/solid";

export default function Header() {
const [connection, setConnection] = useAtom(connectionAtom);
const [address, setAddress] = useAtom(addressAtom);
const [profileData, setProfileData] = useAtom<StarkProfile>(profileDataAtom)

const { provider } = useProvider();
const starknetIdNavigator = new StarknetIdNavigator(
provider,
constants.StarknetChainId.SN_MAIN
);

const connectWallet = async () => {
if (connection?.isConnected) {
disconnectWallet();
}
else {
const { wallet } = await connect({ modalMode: "canAsk" })
if (wallet && wallet.isConnected) {
setConnection(wallet);
setAddress(wallet.selectedAddress);
const starkProfile = await starknetIdNavigator.getProfileData(wallet.selectedAddress);
setProfileData(starkProfile)
}
}
}
const disconnectWallet = async () => {
await disconnect();
setConnection(undefined);
setAddress('');
setProfileData({});
}
const [isPlaying, setPlaying] = useAtom(isPlayingAtom);
const audioRef = useRef(new Audio(audio));
useEffect(() => {
if (isPlaying) {
try {
audioRef.current.play();
audioRef.current.loop = true;
} catch (error) {
console.error("Error playing the audio", error);
}
} else {
audioRef.current.pause();
}
if (!connection?.isConnected) {
connectWallet();
}
return () => {
audioRef.current.pause();
};
}, [isPlaying]);
const togglePlay = () => {
setPlaying(!isPlaying);
}
return (
<div className="flex flex-row items-center justify-between w-full">
<div className="flex-1 w-full -mr-10">
{
profileData.name != undefined ? (
<div className="flex flex-row space-x-2.5 items-center justify-end">
<div>
<h3 className="text-2xl text-right text-white">{profileData.name ? profileData.name : truncateString(address)}</h3>
<h4 className="text-sm text-[#F58229] text-right">Level 6</h4>
</div>
<div className="p-1 rounded-full bg-gradient-to-r bg-[#15181E] from-[#2E323A] via-[#4B505C] to-[#1D2026] relative">
<img src={profileData.profilePicture ? profileData.profilePicture : eniola} width={60} height={60} alt="Eniola" className="rounded-full" />
<div className="absolute bottom-0 right-0 h-6 w-6 bg-[#15171E] rounded-full flex flex-col items-center justify-center">
<div className="h-4 w-4 bg-[#00FF57] rounded-full" />
</div>
</div>
</div>
) : (
<div className="flex flex-row space-x-2.5 items-center justify-end">
<div>
<h3 className="text-2xl text-right text-white">Player</h3>
<h4 className="text-sm text-[#F58229] text-right">Guest</h4>
</div>
<div className="p-1 rounded-full bg-gradient-to-r bg-[#15181E] from-[#2E323A] via-[#4B505C] to-[#1D2026] relative">
<div className="bg-[#15171E] rounded-full p-2.5">
<UserIcon color="#F58229" className="w-8 h-8" />
<div className="absolute bottom-0 right-0 h-6 w-6 bg-[#15171E] rounded-full flex flex-col items-center justify-center">
<div className="h-4 w-4 bg-[#00FF57] rounded-full" />
</div>
</div>
</div>
</div>
)
}
</div>
<div className="h-[100px] w-[800px]">
<div className="bg-[url('./assets/leaderboard-top.png')] w-[800px] h-[100px] bg-contain bg-no-repeat flex flex-col items-center justify-center">
<a href="/" className="mb-4">
<img src={mancala} className="h-10 w-36" />
</a>
</div>
</div>
<div className="flex-1 w-full -ml-16">
<div className="flex flex-row space-x-2.5 items-center justify-start">
<Button className='p-0 bg-transparent rounded-full' onClick={togglePlay}>
<img src={isPlaying ? unmuteImage : muteImage} width={65} height={65} alt="restart" className='rounded-full' />
</Button>
{
connection?.isConnected ? <Button className="p-0" onClick={disconnectWallet}>
<div className="flex flex-row items-center">
<div className="px-3.5 py-4 bg-[#272A32] rounded-tl-lg rounded-bl-lg">
<img src={connection.icon} className="w-6 h-6" />
</div>
<div className="px-3.5 py-5 bg-[#171922] rounded-tr-lg rounded-br-lg"><p className="text-white">{truncateString(address)}</p></div>
</div>
</Button> : <Button className='w-40 bg-[#F58229] rounded-md' onClick={connectWallet}>
Connect Wallet
</Button>
}
</div>
</div>
</div>
)
}
53 changes: 53 additions & 0 deletions client/src/components/ui/tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"

import { cn } from "@/lib/utils"

const Tabs = TabsPrimitive.Root

const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
className
)}
{...props}
/>
))
TabsList.displayName = TabsPrimitive.List.displayName

const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
className
)}
{...props}
/>
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName

const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
className
)}
{...props}
/>
))
TabsContent.displayName = TabsPrimitive.Content.displayName

export { Tabs, TabsList, TabsTrigger, TabsContent }
Loading
Loading