diff --git a/leaky-ships/components/Lobby/LobbyFrame.tsx b/leaky-ships/components/Lobby/LobbyFrame.tsx
index 7d1ffac..56af2ef 100644
--- a/leaky-ships/components/Lobby/LobbyFrame.tsx
+++ b/leaky-ships/components/Lobby/LobbyFrame.tsx
@@ -1,18 +1,17 @@
-import { gameContext } from "../../pages/_app"
import Icon from "./Icon"
import Player from "./Player"
-import { Fragment, useContext, useEffect, useState } from "react"
+import useGameState from "@lib/hooks/useGameState"
+import { Fragment, useEffect, useState } from "react"
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
- const [gameProps, setGameProps] = useContext(gameContext)
- const { enemy } = gameProps
+ const { gameProps } = useGameState()
const [dots, setDots] = useState(1)
useEffect(() => {
- if (enemy) return
+ if (gameProps.enemy) return
const interval = setInterval(() => setDots((e) => (e % 3) + 1), 1000)
return () => clearInterval(interval)
- }, [enemy])
+ }, [gameProps.enemy])
return (
@@ -33,8 +32,11 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
edit={true}
/>
VS
- {enemy ? (
-
+ {gameProps.enemy ? (
+
) : (
Warte auf Spieler 2 {Array.from(Array(dots), () => ".").join("")}
diff --git a/leaky-ships/lib/backend/sendResponse.ts b/leaky-ships/lib/backend/sendResponse.ts
index 718f1f5..d57a729 100644
--- a/leaky-ships/lib/backend/sendResponse.ts
+++ b/leaky-ships/lib/backend/sendResponse.ts
@@ -1,4 +1,4 @@
-import logging, { Logging } from "../logging"
+import logging, { Logging } from "./logging"
import { NextApiRequest, NextApiResponse } from "next"
export interface Result {
diff --git a/leaky-ships/lib/zodSchemas.ts b/leaky-ships/lib/zodSchemas.ts
index 758362a..41c2a94 100644
--- a/leaky-ships/lib/zodSchemas.ts
+++ b/leaky-ships/lib/zodSchemas.ts
@@ -1,3 +1,4 @@
+import { GameState } from "@prisma/client"
import { z } from "zod"
export const createSchema = z.object({
@@ -5,7 +6,7 @@ export const createSchema = z.object({
id: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
- running: z.boolean(),
+ state: z.nativeEnum(GameState),
}),
pin: z.string().optional(),
player: z.object({
diff --git a/leaky-ships/pages/_app.tsx b/leaky-ships/pages/_app.tsx
index f3f372b..f5b430e 100644
--- a/leaky-ships/pages/_app.tsx
+++ b/leaky-ships/pages/_app.tsx
@@ -1,5 +1,5 @@
import "../styles/App.scss"
-import "../styles/globals.css"
+import "../styles/globals.scss"
import "../styles/grid2.scss"
import "../styles/grid.scss"
import { SessionProvider } from "next-auth/react"
diff --git a/leaky-ships/pages/api/auth/[...nextauth].ts b/leaky-ships/pages/api/auth/[...nextauth].ts
index 596c6c5..aa849b0 100644
--- a/leaky-ships/pages/api/auth/[...nextauth].ts
+++ b/leaky-ships/pages/api/auth/[...nextauth].ts
@@ -8,7 +8,6 @@ import {
uniqueNamesGenerator,
Config,
adjectives,
- colors,
animals,
NumberDictionary,
} from "unique-names-generator"
@@ -22,7 +21,6 @@ const customConfig: Config = {
}
const options: NextAuthOptions = {
- debug: true,
providers: [
EmailProvider({
server: process.env.EMAIL_SERVER,
diff --git a/leaky-ships/pages/api/game/create.ts b/leaky-ships/pages/api/game/create.ts
index 84bebb3..12604bc 100644
--- a/leaky-ships/pages/api/game/create.ts
+++ b/leaky-ships/pages/api/game/create.ts
@@ -1,5 +1,7 @@
import { authOptions } from "../auth/[...nextauth]"
+import { getAnyRunningGame } from "./running"
import sendResponse from "@backend/sendResponse"
+import { rejectionErrors } from "@lib/backend/errors"
import prisma from "@lib/prisma"
import { createSchema } from "@lib/zodSchemas"
import type { NextApiRequest, NextApiResponse } from "next"
@@ -14,20 +16,8 @@ export default async function create(
) {
const session = await getServerSession(req, res, authOptions)
- if (!session) {
- return sendResponse(req, res, {
- message: "Unauthorized",
- statusCode: 401,
- type: ["error"],
- })
- }
-
- if (!session.user) {
- return sendResponse(req, res, {
- message: "Unauthorized - No User",
- statusCode: 401,
- type: ["error"],
- })
+ if (!session?.user) {
+ return sendResponse(req, res, rejectionErrors.unauthorized)
}
const { email, id, name } = session.user
@@ -38,20 +28,7 @@ export default async function create(
let created = false
- let game = await prisma.game.findFirst({
- where: {
- running: true,
- users: {
- some: {
- userId: id,
- },
- },
- },
- include: {
- gamePin: true,
- users: true,
- },
- })
+ let game = await getAnyRunningGame(id)
if (!game) {
created = true
game = await prisma.game.create({
diff --git a/leaky-ships/pages/api/game/running.ts b/leaky-ships/pages/api/game/running.ts
new file mode 100644
index 0000000..0868730
--- /dev/null
+++ b/leaky-ships/pages/api/game/running.ts
@@ -0,0 +1,58 @@
+import { authOptions } from "../auth/[...nextauth]"
+import sendResponse from "@backend/sendResponse"
+import { rejectionErrors } from "@lib/backend/errors"
+import prisma from "@lib/prisma"
+import { Game } from "@prisma/client"
+import type { NextApiRequest, NextApiResponse } from "next"
+import { getServerSession } from "next-auth"
+
+type Data = { game: Game }
+
+export const getAnyRunningGame = (id: string) =>
+ prisma.game.findFirst({
+ where: {
+ NOT: {
+ state: "ended",
+ },
+ users: {
+ some: {
+ userId: id,
+ },
+ },
+ },
+ include: {
+ gamePin: true,
+ users: true,
+ },
+ })
+
+export default async function create(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const session = await getServerSession(req, res, authOptions)
+
+ if (!session?.user) {
+ return sendResponse(req, res, rejectionErrors.unauthorized)
+ }
+
+ const { email, id } = session.user
+
+ const game = await getAnyRunningGame(id)
+
+ if (!game)
+ return sendResponse(req, res, {
+ message: `User <${email}> is in no game.`,
+ statusCode: 204,
+ type: ["debug", "infoCyan"],
+ })
+
+ return sendResponse(req, res, {
+ message: `User <${email}> asked for game: ${game.id}`,
+ statusCode: 200,
+ body: {
+ game,
+ },
+ type: ["debug", "infoCyan"],
+ })
+}
diff --git a/leaky-ships/pages/start.tsx b/leaky-ships/pages/start.tsx
index f30fff0..7b2cc78 100644
--- a/leaky-ships/pages/start.tsx
+++ b/leaky-ships/pages/start.tsx
@@ -35,6 +35,19 @@ export function isAuthenticated(res: Response) {
return Promise.reject()
}
+const handleConfirmation = () => {
+ const toastId = "confirm"
+ toast.warn(
+
+
You are already in another round, do you want to:
+
+ or
+
+
,
+ { autoClose: false, toastId }
+ )
+}
+
export default function Home({ q }: Props) {
const [otp, setOtp] = useState("")
const { gameProps, setGameProps } = useGameState()
diff --git a/leaky-ships/prisma/schema.prisma b/leaky-ships/prisma/schema.prisma
index e22edad..53b81ff 100644
--- a/leaky-ships/prisma/schema.prisma
+++ b/leaky-ships/prisma/schema.prisma
@@ -69,11 +69,17 @@ enum TokenType {
ACCESS
}
+enum GameState {
+ launching
+ running
+ ended
+}
+
model Game {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
- running Boolean @default(true)
+ state GameState @default(launching)
gamePin Gamepin?
users User_Game[]
}
diff --git a/leaky-ships/styles/globals.css b/leaky-ships/styles/globals.scss
similarity index 81%
rename from leaky-ships/styles/globals.css
rename to leaky-ships/styles/globals.scss
index d4323cc..da24cf0 100644
--- a/leaky-ships/styles/globals.css
+++ b/leaky-ships/styles/globals.scss
@@ -26,6 +26,15 @@ button {
cursor: none;
}
+#toast-confirm {
+ button {
+ margin: 0 1rem;
+ padding: 0 1rem;
+ border: 2px solid gray;
+ border-radius: 0.5rem;
+ }
+}
+
@media (pointer: fine) {
button {
cursor: pointer;