Skip to content

Commit

Permalink
Merge pull request #2 from ItaloMedici/1-add-button-to-restart-game
Browse files Browse the repository at this point in the history
1 add button to restart game
  • Loading branch information
ItaloMedici authored Jul 20, 2024
2 parents aaf187c + f583520 commit d76b2ee
Show file tree
Hide file tree
Showing 18 changed files with 234 additions and 43 deletions.
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=SOME_RANDOM_SECRET

DATABASE_URL="DATABASE_URL"

NEXT_PUBLIC_SITE_URL=http://localhost:3000

GOOGLE_CLIENT_ID=GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET=GOOGLE_CLIENT_SECRET

MAXIMUM_PLAYERS_PER_BOARD=99999
31 changes: 31 additions & 0 deletions .github/workflows/build-lint-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Build, Lint and Test

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run lint
run: npm run lint

- name: Setup Prisma
run: npx prisma generate

- name: Setup Environment
run: cp .env.example .env

- name: Build
run: npm run build --if-present
19 changes: 19 additions & 0 deletions .github/workflows/release-it.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release It

on: workflow_dispatch

jobs:
release:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'

- name: Release
run: npm install --global release-it@14.11.6 @release-it/conventional-changelog@3.3.0 && release-it
16 changes: 16 additions & 0 deletions .release-it.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"git": {
"commitMessage": "chore(release): v${version}",
"tagName": "v${version}",
"requireCommits": true
},
"npm": {
"publish": false
},
"plugins": {
"@release-it/conventional-changelog": {
"preset": "angular",
"infile": "CHANGELOG.md"
}
}
}
2 changes: 1 addition & 1 deletion app/(dashboard)/(home)/_components/nav-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { UserButton } from "@/components/user-button";
import { cn } from "@/lib/utils";
import { Poppins } from "next/font/google";
import Image from "next/image";
import Link from "next/link";
import { UserButton } from "./user-buttom";

const poppins = Poppins({ subsets: ["latin"], weight: ["600"] });

Expand Down
4 changes: 3 additions & 1 deletion app/(dashboard)/room/[roomId]/_components/board-navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { Button, buttonVariants } from "@/components/ui/button";
import { UserButton } from "@/components/user-button";
import { buildInviteUrl } from "@/use-cases/invite/build-invite-url";
import { CheckIcon, ChevronLeft, PlusIcon } from "lucide-react";
import Link from "next/link";
Expand Down Expand Up @@ -36,7 +37,7 @@ export const BoardNavbar = () => {
const Icon = copiedInvite ? CheckIcon : PlusIcon;

return (
<nav className="fixed top-0 right-0 left-0 max-w-screen-lg">
<nav className="fixed top-0 right-0 left-0 mx-auto">
<div className="flex items-center justify-between p-4 mx-auto">
<Link className={buttonVariants({ variant: "ghost" })} href={"/"}>
<ChevronLeft className="w-4 h-4 mr-2" />
Expand All @@ -51,6 +52,7 @@ export const BoardNavbar = () => {
<Icon className="w-4 h-4 mr-2" />
Convidar jogadores
</Button>
<UserButton />
</div>
</nav>
);
Expand Down
18 changes: 16 additions & 2 deletions app/(dashboard)/room/[roomId]/_components/players-cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useBoard } from "@/context/board";
import { PlayerCard } from "./player-card";

export const PlayersCards = () => {
const { others, self, handleRevealCards, revealCards } = useBoard();
const { others, self, handleRevealCards, revealCards, handleReset } =
useBoard();

const players = [self, ...others];

Expand All @@ -16,16 +17,29 @@ export const PlayersCards = () => {
);
}

const onRevealClick = () => {
if (revealCards) {
handleReset();
}
handleRevealCards();
};

return (
<div className="flex flex-col gap-6">
<div className="flex items-center justify-center flex-wrap gap-4">
{players.map((player) => (
<PlayerCard key={player.id} player={player} />
))}
</div>
<Button onClick={handleRevealCards}>
{/* <div className="flex items-center gap-2"> */}
<Button onClick={onRevealClick}>
{revealCards ? "Iniciar outro jogo" : "Revelar cartas 👀"}
</Button>

{/* </div> */}
<Button variant={"ghost"} onClick={handleReset}>
Limpar
</Button>
</div>
);
};
29 changes: 2 additions & 27 deletions app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
import { env } from "@/env";
import NextAuth, { AuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";

export const authOptions: AuthOptions = {
providers: [
GoogleProvider({
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
}),
],
pages: {
signIn: "/login",
},
callbacks: {
async jwt({ token, account }) {
if (account) {
token.accessToken = account.access_token;
}
return token;
},
async session({ session, token, user }) {
(session as any).accessToken = token.accessToken;
return session;
},
},
};
import { authOptions } from "@/authOptions";
import NextAuth from "next-auth";

const handler = NextAuth(authOptions);

Expand Down
27 changes: 27 additions & 0 deletions authOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { env } from "@/env";
import { AuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";

export const authOptions: AuthOptions = {
providers: [
GoogleProvider({
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
}),
],
pages: {
signIn: "/login",
},
callbacks: {
async jwt({ token, account }) {
if (account) {
token.accessToken = account.access_token;
}
return token;
},
async session({ session, token, user }) {
(session as any).accessToken = token.accessToken;
return session;
},
},
};
File renamed without changes.
37 changes: 32 additions & 5 deletions context/board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
joinBoardKey,
leaveBoardKey,
playerChoiceKey,
resetBoardKey,
} from "@/use-cases/event-keys/board";
import { useRouter } from "next/navigation";
import {
Expand All @@ -28,6 +29,7 @@ type BoardContextProps = {
choiceOptions: ChoiceOptions;
handleChoice: (choice: string) => Promise<void>;
handleRevealCards: () => Promise<void>;
handleReset: () => Promise<void>;
};

export const BoardContext = createContext<BoardContextProps>(
Expand Down Expand Up @@ -74,11 +76,8 @@ export const BoardProvider = ({
joinBoard();
}, []);

console.log({ self, others });

const leaveBoard = async () => {
if (!selfRef.current?.boardId) return;
console.log("leave board", selfRef.current);

await http.post("/leave-board", {
playerId: selfRef.current.id,
Expand Down Expand Up @@ -134,14 +133,14 @@ export const BoardProvider = ({
console.log(`[${choiceEventKey}] for ${self.name}:`, message);
if (!message?.player) return;

const updatedPlayer = message.player;
const updatedPlayer = message.player as Player;

if (updatedPlayer.id === self.id) {
return;
}

setOthers((prev) =>
prev.map((p) => (p.id === updatedPlayer.id ? updatedPlayer : p))
prev.map((p) => (p.email === updatedPlayer.email ? updatedPlayer : p))
);
});

Expand All @@ -152,10 +151,31 @@ export const BoardProvider = ({
setRevealCards(message.reveal);
});

const resetBoardEventKey = resetBoardKey(self.boardId);

socket.on(resetBoardEventKey, (message) => {
console.log(`[${resetBoardEventKey}] for ${self.name}:`, message);
if (!message?.players?.length) return;

const players = message.players as Array<Player>;

const _self = players.find((_player) => _player.id === self.id);
const _others = players.filter((_player) => _player.id !== self.id);

if (!_self) return;

setOthers(_others);
setSelf(_self);

setRevealCards(false);
});

return () => {
socket.off(joinBoardEventKey);
socket.off(leaveBoardEventKey);
socket.off(choiceEventKey);
socket.off(revealCardsEventKey);
socket.off(resetBoardEventKey);
};
}, [others, roomId, self, socket]);

Expand All @@ -181,6 +201,12 @@ export const BoardProvider = ({
});
};

const handleReset = async () => {
await http.post("/reset-board", {
boardId: self.boardId,
});
};

return (
<BoardContext.Provider
value={{
Expand All @@ -191,6 +217,7 @@ export const BoardProvider = ({
handleChoice,
revealCards,
handleRevealCards,
handleReset,
}}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion pages/api/join-board.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use server";

import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { authOptions } from "@/authOptions";
import { ResponseWithSocket } from "@/types/response-with-socket";
import { joinBoardKey } from "@/use-cases/event-keys/board";
import { getPlayersByBoardId } from "@/use-cases/player/get-players-by-board-id";
Expand Down
4 changes: 2 additions & 2 deletions pages/api/leave-board.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { authOptions } from "@/authOptions";
import { ResponseWithSocket } from "@/types/response-with-socket";
import { leaveBoard } from "@/use-cases/board/leave-board";
import { leaveBoardKey } from "@/use-cases/event-keys/board";
Expand Down Expand Up @@ -36,7 +36,7 @@ const leaveBoardHandler = async (

res.status(200).json({ message: "Succefully leave board" });
} catch (error: any) {
return res.status(400).json({ message: error?.message });
return res.redirect("/");
}
};

Expand Down
2 changes: 1 addition & 1 deletion pages/api/make-choice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const makeChoiceHandler = async (

return res.status(200).json(updatedPlayer);
} catch (error: any) {
return res.status(500).json({ message: error.message });
return res.status(500).json({ message: error.message ?? error });
}
};

Expand Down
49 changes: 49 additions & 0 deletions pages/api/reset-board.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { authOptions } from "@/authOptions";
import { ResponseWithSocket } from "@/types/response-with-socket";
import { resetBoard } from "@/use-cases/board/reset-board";
import { resetBoardKey } from "@/use-cases/event-keys/board";
import { getPlayersByBoardId } from "@/use-cases/player/get-players-by-board-id";
import { NextApiRequest } from "next";
import { getServerSession } from "next-auth";

const resetBoardHandler = async (
req: NextApiRequest,
res: ResponseWithSocket
) => {
if (req.method !== "POST") {
res.status(405).json({ message: "Method Not Allowed" });
return;
}

try {
const { boardId } = req.body;

if (!boardId) {
res.status(400).json({ message: "Board ID is required" });
return;
}

const session = await getServerSession(req, res, authOptions);

if (!session?.user) {
return res.status(401).json({ message: "Unauthorized" });
}

const result = await resetBoard({ boardId });

if (!result.count)
return res.status(404).json({ message: "Error while reseting board" });

const eventKey = resetBoardKey(boardId);

const players = await getPlayersByBoardId({ boardId });

const message = { boardId, players };

res.socket?.server?.io?.emit(eventKey, message);
} catch (error: any) {
return res.status(500).json({ message: error.message });
}
};

export default resetBoardHandler;
Loading

0 comments on commit d76b2ee

Please sign in to comment.