From ca082484ec8f8b0b5d452c6b7eb0152110ab3a2b Mon Sep 17 00:00:00 2001 From: mhzrerfani Date: Mon, 14 Oct 2024 21:24:12 +0330 Subject: [PATCH] Add great stuff, jeton is responsive now --- apps/web/src/app/@modal/(.)create/page.tsx | 11 +- .../games/[id]/components/GameStatusBox.tsx | 24 +- .../app/games/[id]/components/LogsSidebar.tsx | 69 +++++ .../web/src/app/games/[id]/components/Pot.tsx | 2 +- .../games/[id]/components/PrivateCards.tsx | 20 +- .../app/games/[id]/components/PublicCards.tsx | 9 +- .../src/app/games/[id]/components/Seat.tsx | 69 +++-- .../src/app/games/[id]/components/Table.tsx | 4 +- apps/web/src/app/games/[id]/page.tsx | 13 +- apps/web/src/app/globals.css | 239 +++++++++--------- apps/web/src/app/page.tsx | 12 +- apps/web/src/components/Modal.tsx | 6 +- apps/web/src/lib/constants/mocks.ts | 16 ++ 13 files changed, 297 insertions(+), 197 deletions(-) create mode 100644 apps/web/src/app/games/[id]/components/LogsSidebar.tsx diff --git a/apps/web/src/app/@modal/(.)create/page.tsx b/apps/web/src/app/@modal/(.)create/page.tsx index 32ebb0d..c4f4715 100644 --- a/apps/web/src/app/@modal/(.)create/page.tsx +++ b/apps/web/src/app/@modal/(.)create/page.tsx @@ -21,10 +21,9 @@ import { JetonContext } from "@src/components/JetonContextProvider"; import useCheckIn from "@src/hooks/useCheckIn"; const INITIAL_FORM_VALUES: FormValues = { - smallBlind: 0, - numberOfRaises: 0, + smallBlind: 1, + numberOfRaises: 2, minPlayers: 2, - maxPlayers: 10, minBuyIn: 100, maxBuyIn: 1000, waitingTimeout: 3600, @@ -35,10 +34,8 @@ const INPUT_FIELDS = [ { label: "Small Blind", name: "smallBlind" }, { label: "Number of Raises", name: "numberOfRaises" }, { label: "Minimum Players", name: "minPlayers" }, - { label: "Maximum Players", name: "maxPlayers" }, { label: "Minimum Buy-in", name: "minBuyIn" }, { label: "Maximum Buy-in", name: "maxBuyIn" }, - { label: "Waiting timeOut(seconds)", name: "waitingTimeOut" }, ]; export default function GameCreateModal() { @@ -68,13 +65,15 @@ export default function GameCreateModal() { if (!createTable) throw new Error("create Table must exist"); if (!checkIn) throw new Error("Check in you must do"); + const TIMEOUT = 300; // 5 minutes + const jeton = await createTable( formValues.smallBlind, formValues.numberOfRaises, formValues.minPlayers, formValues.minBuyIn, formValues.maxBuyIn, - formValues.waitingTimeout, + TIMEOUT, formValues.chipUnit, checkIn, account!.address, diff --git a/apps/web/src/app/games/[id]/components/GameStatusBox.tsx b/apps/web/src/app/games/[id]/components/GameStatusBox.tsx index 83696db..1805db0 100644 --- a/apps/web/src/app/games/[id]/components/GameStatusBox.tsx +++ b/apps/web/src/app/games/[id]/components/GameStatusBox.tsx @@ -7,6 +7,7 @@ import { selectMyCards$, selectShufflingPlayer$, } from "../state/selectors/gameSelectors"; +import LogsButton from "./LogsSidebar"; export default function GameStatusBox() { const gameStatus = useSelector(selectGameStatus$()); @@ -29,15 +30,18 @@ export default function GameStatusBox() { } return ( - -

{statusMessage}

-
+
+ + +

{statusMessage}

+
+
); } diff --git a/apps/web/src/app/games/[id]/components/LogsSidebar.tsx b/apps/web/src/app/games/[id]/components/LogsSidebar.tsx new file mode 100644 index 0000000..5ad97fa --- /dev/null +++ b/apps/web/src/app/games/[id]/components/LogsSidebar.tsx @@ -0,0 +1,69 @@ +import CloseIcon from "@src/assets/icons/close.svg"; +import Image from "next/image"; +import { useState } from "react"; + +export default function LogsButton() { + const [isSidebarOpen, setIsSidebarOpen] = useState(false); + + const handleToggleSidebar = () => { + setIsSidebarOpen(!isSidebarOpen); + }; + + const logs = [ + { description: "Player A shuffled", link: "https://example.com/tx/12345" }, + { + description: "Player B placed a bet", + link: "https://example.com/tx/67890", + }, + { description: "Player C folded", link: "" }, + { + description: "Player D won the hand", + link: "https://example.com/tx/54321", + }, + ]; + + return ( +
+ + +
+
+

Game Logs

+ +
+
+ {logs.map((log, index) => ( +
+

+ {index + 1}. {log.description} +

+ {log.link && ( + + Transaction + + )} +
+ ))} +
+
+
+ ); +} diff --git a/apps/web/src/app/games/[id]/components/Pot.tsx b/apps/web/src/app/games/[id]/components/Pot.tsx index 6dec623..5d3f3b5 100644 --- a/apps/web/src/app/games/[id]/components/Pot.tsx +++ b/apps/web/src/app/games/[id]/components/Pot.tsx @@ -12,7 +12,7 @@ export default function Pot() { return ( <>
diff --git a/apps/web/src/app/games/[id]/components/PrivateCards.tsx b/apps/web/src/app/games/[id]/components/PrivateCards.tsx index a9ebb94..22dc466 100644 --- a/apps/web/src/app/games/[id]/components/PrivateCards.tsx +++ b/apps/web/src/app/games/[id]/components/PrivateCards.tsx @@ -9,7 +9,7 @@ export default function PrivateCards({ }: { playersPrivateCards: Record | null; }) { - const [startRevealing, setStartRevealing] = useState(false); + const [receivedCards, setReceivedCards] = useState(true); const [revealedCards, setRevealedCards] = useState(false); const [dealCards, setDealCards] = useState([]); const dealCardEffect = useAudio(dealCardSound, "effect"); @@ -35,6 +35,12 @@ export default function PrivateCards({ }); }, [seats, dealCardEffect]); + useEffect(() => { + setTimeout(() => { + setRevealedCards(true); + }, 3000); + }, []); + return ( <> {seats.map((seat, i) => { @@ -53,7 +59,7 @@ export default function PrivateCards({ (cardName, i) => CARDS_MAP[cardName] && (
diff --git a/apps/web/src/app/games/[id]/components/PublicCards.tsx b/apps/web/src/app/games/[id]/components/PublicCards.tsx index 825acfa..55f0b86 100644 --- a/apps/web/src/app/games/[id]/components/PublicCards.tsx +++ b/apps/web/src/app/games/[id]/components/PublicCards.tsx @@ -1,7 +1,12 @@ +import { useSelector } from "@legendapp/state/react"; import { CARDS_MAP } from "@src/lib/constants/cards"; +import { mockPublicCards } from "@src/lib/constants/mocks"; +import { selectPublicCards$ } from "../state/selectors/gameSelectors"; import Card from "./Card"; -export default function PublicCards({ cards }: { cards: number[] }) { +export default function PublicCards() { + const cards = useSelector(selectPublicCards$); + return (
{cards.map((cardIndex) => { @@ -9,7 +14,7 @@ export default function PublicCards({ cards }: { cards: number[] }) { return ( cardName && ( diff --git a/apps/web/src/app/games/[id]/components/Seat.tsx b/apps/web/src/app/games/[id]/components/Seat.tsx index 787ef95..dd80eac 100644 --- a/apps/web/src/app/games/[id]/components/Seat.tsx +++ b/apps/web/src/app/games/[id]/components/Seat.tsx @@ -64,13 +64,18 @@ export default function Seat({ const shufflingPlayer = useSelector(selectShufflingPlayer$()); const awaitingBetFrom = useSelector(selectAwaitingBetFrom$()); const isPlayerTurn = awaitingBetFrom?.id === player.id; - const myCards = useSelector(selectMyCards$()); + // const myCards = useSelector(selectMyCards$()); + const myCards = [1, 2]; const dealer = useSelector(selectDealer$()); const gameStatus = useSelector(selectGameStatus$()); const [lastAction, setLastAction] = useState(""); const isWinner = false; + const isMainPlayer = useMemo(() => { + return seatNumber === 1 && myCards && myCards.length > 0; + }, [seatNumber]); + useEffect(() => { if (mounted.current) return; @@ -89,7 +94,7 @@ export default function Seat({ return (
Math.random() ? "z-[501]" : ""} ${ @@ -98,21 +103,31 @@ export default function Seat({ }`} style={{ animationDelay: `${seatNumber * 100 + 100}ms` }} > - avatar +
0 ? "-translate-x-5" : "" + }`} + > + avatar +
+ {player.id.slice(2, 8)} ${player.balance} +
+
+ {isWinner && ( +

{player.status === PlayerStatus.folded ? "Folded" : lastAction}

@@ -130,15 +145,20 @@ export default function Seat({ )} {dealer?.id === player.id && } - {seatNumber === 1 && myCards && myCards.length > 0 && ( -
+ {isMainPlayer && ( +
{myCards?.map( (cardName, i) => CARDS_MAP[cardName] && ( @@ -146,9 +166,6 @@ export default function Seat({ )}
)} -
- {player.id.slice(2, 8)} ${player.balance} -
); } diff --git a/apps/web/src/app/games/[id]/components/Table.tsx b/apps/web/src/app/games/[id]/components/Table.tsx index 1e80933..2770511 100644 --- a/apps/web/src/app/games/[id]/components/Table.tsx +++ b/apps/web/src/app/games/[id]/components/Table.tsx @@ -5,11 +5,11 @@ import type { ReactNode } from "react"; export function Table({ children }: { children: ReactNode }) { return (
-
+
table(); - while (cards.size < 2) { - cards.add(Math.floor(Math.random() * 52)); - } - return Array.from(cards); -} - export default function PlayPage({ params }: { params: { id: string } }) { const { game, joinTable } = useContext(JetonContext); const players = useSelector(selectGamePlayers$()); const [toffState, setToffState] = useState(false); const shufflingPlayer = useSelector(selectShufflingPlayer$()); - const cards = useSelector(selectPublicCards$); const gameStatus = useSelector(selectGameStatus$()); const [drawPrivateCards, setDrawPrivateCards] = useState(false); const myCards = useSelector(selectMyCards$()); @@ -104,7 +95,7 @@ export default function PlayPage({ params }: { params: { id: string } }) { )} {shufflingPlayer?.id && }
- {cards.length > 0 && } + {gameStatus === GameStatus.AwaitingStart && }
@@ -116,7 +107,7 @@ export default function PlayPage({ params }: { params: { id: string } }) { )} - + {/* */} ); diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index c477e56..ef686e3 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -78,52 +78,51 @@ } /* Cards near the center of the table */ - .cards-2 { - top: 68%; - left: 30%; + top: 68% !important; + left: 33% !important; transform: translateX(-50%); } .cards-3 { - top: 55%; - left: 15%; + top: 55% !important; + left: 15% !important; transform: translateX(-50%); } .cards-4 { - top: 35%; - left: 15%; + top: 35% !important; + left: 15% !important; transform: translateX(-50%); } .cards-5 { - top: 20%; - left: 30%; + top: 20% !important; + left: 33% !important; transform: translateX(-50%); } .cards-6 { - top: 20%; - left: 65%; + top: 20% !important; + left: 67% !important; transform: translateX(-50%); } .cards-7 { - top: 35%; - left: 82%; + top: 35% !important; + left: 82% !important; transform: translateX(-50%); } .cards-8 { - top: 60%; - left: 82%; + top: 60% !important; + left: 82% !important; transform: translateX(-50%); } .cards-9 { - top: 70%; - left: 70%; + top: 68% !important; + left: 70% !important; transform: translateX(-50%); } @@ -189,131 +188,125 @@ } } -.pot { - top: 80%; - left: 50%; - transform: translateX(-50%); -} +@media (max-width: 768px) { + .cards-center { + top: 50% !important; + left: 50% !important; + } -.seat-1 { - top: 110%; - left: 50%; - transform: translateX(-50%); -} + .pot { + top: 75%; + left: 50%; + transform: translateX(-50%); + } -.seat-1 .cards, -.seat-1 .chips { - top: -50%; - left: 50%; - transform: translateX(-50%); -} + .seat-1 { + top: 105%; + left: 50%; + transform: translateX(-50%); + } -.seat-2 { - top: 100%; - left: 20%; - transform: translateY(-50%); -} + .seat-2 { + top: 100%; + left: 24%; + transform: translateY(-50%); + } -.seat-2 .cards, -.seat-2 .chips { - top: -35%; - right: 10%; - transform: translate(50%); -} + .seat-3 { + top: 70%; + left: 24%; + transform: translateY(-50%); + } -.seat-3 { - top: 70%; - left: 20%; - transform: translateY(-50%); -} + .seat-4 { + top: 28%; + left: 24%; + transform: translateY(-50%); + } -.seat-3 .cards, -.seat-3 .chips { - bottom: 50%; - right: -40%; - transform: translate(50%); -} + .seat-5 { + top: -10%; + left: 25%; + transform: translateY(-50%); + } -.seat-4 { - top: 30%; - left: 20%; - transform: translateY(-50%); -} + .seat-6 { + top: -10%; + left: 64%; + transform: translateY(-50%); + } -.seat-4 .cards, -.seat-4 .chips { - bottom: -20%; - right: -60%; - transform: translate(-50%); -} + .seat-7 { + top: 28%; + left: 67%; + transform: translateY(-50%); + } -.seat-5 { - top: -10%; - left: 25%; - transform: translateY(-50%); -} + .seat-8 { + top: 70%; + left: 67%; + transform: translateY(-50%); + } -.seat-5 .cards, -.seat-5 .chips { - bottom: -45%; - right: 10%; - transform: translate(-50%); -} + .seat-9 { + top: 100%; + left: 67%; + transform: translateY(-50%); + } -.seat-6 { - top: -10%; - left: 68%; - transform: translateY(-50%); -} + .seat-dealer { + top: -5% !important; + left: 45% !important; + transform: translate(0); + } -.seat-6 .cards, -.seat-6 .chips { - bottom: -45%; - right: 20%; - transform: translate(-50%); -} + .cards-2 { + top: 89%; + left: 40%; + transform: translateX(-50%); + } -.seat-7 { - top: 30%; - left: 72%; - transform: translateY(-50%); -} + .cards-3 { + top: 63%; + left: 40%; + transform: translateX(-50%); + } -.seat-7 .cards { - left: -40%; - transform: translate(-50%); -} + .cards-4 { + top: 20%; + left: 40%; + transform: translateX(-50%); + } -.seat-8 { - top: 70%; - left: 72%; - transform: translateY(-50%); -} + .cards-5 { + top: 0%; + left: 40%; + transform: translateX(-50%); + } -.seat-8 .cards, -.seat-8 .chips { - bottom: 60%; - left: -50%; - transform: translate(-50%); -} + .cards-6 { + top: 0%; + left: 60%; + transform: translateX(-50%); + } -.seat-9 { - top: 100%; - left: 72%; - transform: translateY(-50%); -} + .cards-7 { + top: 20%; + left: 60%; + transform: translateX(-50%); + } -.seat-9 .cards, -.seat-9 .chips { - top: -50%; - left: 20%; - transform: translate(-50%); -} + .cards-8 { + top: 63%; + left: 60%; + transform: translateX(-50%); + } -.seat-dealer { - top: -5% !important; - left: 45% !important; - transform: translate(0); + .cards-9 { + top: 89%; + left: 60%; + transform: translateX(-50%); + } } .rotate-y-180 { diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 73a2618..fe5b8e9 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -54,20 +54,20 @@ export default function LandingPage() {
- - Jeton + Jeton
- Decentralized Poker Game -
+

Decentralized Poker Game

+ {closeButton && ( )} {children} diff --git a/apps/web/src/lib/constants/mocks.ts b/apps/web/src/lib/constants/mocks.ts index bffbb7b..d6edaf7 100644 --- a/apps/web/src/lib/constants/mocks.ts +++ b/apps/web/src/lib/constants/mocks.ts @@ -3,6 +3,22 @@ import { useEffect, useState } from "react"; export const mockPublicKey: Uint8Array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +export const mockPublicCards = [2, 51, 45, 33, 21]; + +export const mockMyCards = [51, 49]; + +export const mockPrivateCards: Record = { + 1: [1, 2], + 2: [1, 2], + 3: [3, 4], + 4: [5, 6], + 5: [3, 4], + 6: [5, 6], + 7: [3, 4], + 8: [5, 6], + 9: [5, 6], +}; + export const mockPlayers: Player[] = [ { id: "player123",