import React, { useState, useEffect } from "react"; import { motion } from "framer-motion"; import { useNakama } from "./providers/NakamaProvider"; import Player from "./Player"; import { PlayerModel } from "./models/player"; import TicTacToeBoard from "./games/tictactoe/TicTacToeBoard"; export default function App() { // setting up a 2D game boards const [boards, setBoards] = useState>({}); const [turn, setTurn] = useState(0); const [winner, setWinner] = useState(null); const [gameOver, setGameOver] = useState(null); const [players, setPlayers] = useState([]); const { sendMatchData, onMatchData, matchId, session } = useNakama(); // ------------------------------------------ // MATCH DATA CALLBACK (from Player component) // ------------------------------------------ function onMatchDataCallback(msg: { opCode: number; data: any }) { console.log("[Match Data]", msg); if (msg.opCode === 2) { const state = msg.data; console.log("Match state:", state); setBoards(state.boards); setTurn(state.turn); setGameOver(state.game_over); if (state.winner >= 0) { setWinner(state.players[state.winner].username); // } else if (state.game_over) { // // Game ended but winner = -1 → draw // setWinner("draw"); } else { // Ongoing game, no winner setWinner(null); } setPlayers(state.players || []); } } useEffect(() => { document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = "auto"; }; }, []); useEffect(() => { onMatchData(onMatchDataCallback); }, [onMatchData]); // ------------------------------------------ // SEND A MOVE // ------------------------------------------ function handleCellClick(row: number, col: number) { if (!matchId) return; sendMatchData(matchId, 1, {data: {row, col}}); } return (
{/* ---------------- HEADER (always fixed at top) ---------------- */}
Tic Tac Toe
{/* ---------------- MAIN CONTENT (scrolls) ---------------- */}
); }