diff --git a/leaky-ships/components/Gamefield/EventBar.tsx b/leaky-ships/components/Gamefield/EventBar.tsx
index cc5f092..3805910 100644
--- a/leaky-ships/components/Gamefield/EventBar.tsx
+++ b/leaky-ships/components/Gamefield/EventBar.tsx
@@ -14,7 +14,7 @@ function EventBar({
{ icon: "burger-menu", text: "Menu" },
{ icon: "radar", text: "Radar scan", mode: 0, amount: 1 },
{ icon: "torpedo", text: "Fire torpedo", mode: 1, amount: 1 },
- { icon: "scope", text: "Fire missile", mode: 2 },
+ { icon: "scope", text: "Fire missile", mode: 3 },
{ icon: "gear", text: "Settings" },
]
return (
diff --git a/leaky-ships/components/Lobby/LobbyFrame.tsx b/leaky-ships/components/Lobby/LobbyFrame.tsx
index bc71f1d..04eb11c 100644
--- a/leaky-ships/components/Lobby/LobbyFrame.tsx
+++ b/leaky-ships/components/Lobby/LobbyFrame.tsx
@@ -5,7 +5,7 @@ import { Fragment, useContext, useEffect, useState } from "react"
function LobbyFrame({ openSettings }: { openSettings: () => void }) {
const [gameProps, setGameProps] = useContext(gameContext)
- const [enemy, setEnemy] = useState(false)
+ const { enemy } = gameProps
const [dots, setDots] = useState(1)
useEffect(() => {
@@ -28,18 +28,13 @@ function LobbyFrame({ openSettings }: { openSettings: () => void }) {
-
setEnemy((e) => !e)}
- >
- VS
-
+
VS
{enemy ? (
-
+
) : (
Warte auf Spieler 2 {Array.from(Array(dots), () => ".").join("")}
diff --git a/leaky-ships/lib/backend/components/createTokenDB.ts b/leaky-ships/lib/backend/components/createTokenDB.ts
index f81d194..d6dd7c7 100644
--- a/leaky-ships/lib/backend/components/createTokenDB.ts
+++ b/leaky-ships/lib/backend/components/createTokenDB.ts
@@ -11,7 +11,7 @@ export interface IdToken {
type: TokenType
}
-const tokenLifetime = {
+export const tokenLifetime = {
REFRESH: 172800,
ACCESS: 15,
}
diff --git a/leaky-ships/lib/backend/components/getPinFromBody.ts b/leaky-ships/lib/backend/components/getPinFromBody.ts
index a674f45..dc75de3 100644
--- a/leaky-ships/lib/backend/components/getPinFromBody.ts
+++ b/leaky-ships/lib/backend/components/getPinFromBody.ts
@@ -1,4 +1,3 @@
-import { rejectionErrors } from "../errors"
import sendError, { API } from "./sendError"
async function getPinFromBody(context: API, next: (pin: string) => void) {
@@ -9,7 +8,13 @@ async function getPinFromBody(context: API, next: (pin: string) => void) {
!("pin" in body) ||
typeof body.pin !== "string"
)
- return sendError(context, rejectionErrors.noUsername)
+ return sendError(context, {
+ rejected: true,
+ message: "No pin in request body!",
+ statusCode: 401,
+ solved: true,
+ type: "warn",
+ })
const { pin } = body
return next(pin)
diff --git a/leaky-ships/lib/backend/components/getTokenDB.ts b/leaky-ships/lib/backend/components/getTokenDB.ts
index 17e4fc2..6303dfc 100644
--- a/leaky-ships/lib/backend/components/getTokenDB.ts
+++ b/leaky-ships/lib/backend/components/getTokenDB.ts
@@ -3,6 +3,7 @@ import { rejectionErrorFns, rejectionErrors } from "../errors"
import type { IdToken } from "./createTokenDB"
import sendError, { API } from "./sendError"
import type { Token } from "@prisma/client"
+import { deleteCookie } from "cookies-next"
async function getTokenDB(
context: API,
@@ -17,7 +18,10 @@ async function getTokenDB(
id,
},
})
- if (!tokenDB) return sendError(context, rejectionErrorFns.tokenNotFound(type))
+ if (!tokenDB) {
+ deleteCookie("token", { ...context, path: "/api" })
+ return sendError(context, rejectionErrorFns.tokenNotFound(type))
+ }
if (tokenDB.used && !ignoreChecks)
return sendError(context, rejectionErrors.tokenUsed)
diff --git a/leaky-ships/lib/backend/components/getTokenFromBody.ts b/leaky-ships/lib/backend/components/getTokenFromBody.ts
index 4ad43f2..a39a968 100644
--- a/leaky-ships/lib/backend/components/getTokenFromBody.ts
+++ b/leaky-ships/lib/backend/components/getTokenFromBody.ts
@@ -18,6 +18,7 @@ async function getTokenFromBody(
const value = body.token
return next({ value, type })
}
+ console.log(body)
return sendError(context, rejectionErrorFns.noToken(type))
}
diff --git a/leaky-ships/lib/backend/components/getTokenFromCookie.ts b/leaky-ships/lib/backend/components/getTokenFromCookie.ts
index 9ccbe45..3ba7ce7 100644
--- a/leaky-ships/lib/backend/components/getTokenFromCookie.ts
+++ b/leaky-ships/lib/backend/components/getTokenFromCookie.ts
@@ -1,32 +1,24 @@
import createPlayerDB from "./createPlayerDB"
import createTokenDB, { RawToken } from "./createTokenDB"
import type { API } from "./sendError"
-import { setCookie } from "cookies-next"
+import { Player, Token } from "@prisma/client"
async function getTokenFromCookie(
context: API,
- next: (refreshToken: RawToken) => void
+ next: (
+ refreshToken: RawToken,
+ newPlayer?: { player: Player; newToken: RawToken; newTokenDB: Token }
+ ) => void
) {
const type = "REFRESH"
- const { req, res } = context
- const value = req.cookies.token
+ const value = context.req.cookies.token
// Checking for cookie presens, because it is necessary
if (!value) {
return createPlayerDB((player) =>
- createTokenDB(player, type, (newToken) => {
- // Set login cookie
- setCookie("token", newToken.value, {
- req,
- res,
- maxAge: 172800,
- httpOnly: true,
- sameSite: true,
- secure: true,
- path: "/api",
- })
- return next(newToken)
- })
+ createTokenDB(player, type, (newToken, newTokenDB) =>
+ next(newToken, { player, newToken, newTokenDB })
+ )
)
}
return next({ value, type })
diff --git a/leaky-ships/lib/backend/components/sendResponse.ts b/leaky-ships/lib/backend/components/sendResponse.ts
index a884de3..5525f4e 100644
--- a/leaky-ships/lib/backend/components/sendResponse.ts
+++ b/leaky-ships/lib/backend/components/sendResponse.ts
@@ -1,15 +1,39 @@
import logging, { Logging } from "../logging"
+import { RawToken, tokenLifetime } from "./createTokenDB"
import type { API } from "./sendError"
+import { deleteCookie, setCookie } from "cookies-next"
export interface Result {
message: string
statusCode?: number
body?: T
type?: Logging[]
+ cookie?: string
}
export default function sendResponse(context: API, result: Result) {
const { req, res } = context
+ if (typeof result.cookie === "string") {
+ if (result.cookie) {
+ console.log(1)
+ setCookie("token", result.cookie, {
+ req,
+ res,
+ maxAge: tokenLifetime.REFRESH,
+ httpOnly: true,
+ sameSite: true,
+ secure: true,
+ path: "/api",
+ })
+ } else {
+ console.log(2)
+ deleteCookie("token", {
+ req,
+ res,
+ path: "/api",
+ })
+ }
+ }
res.status(result.statusCode ?? 200)
result.body ? res.json(result.body) : res.end()
logging(result.message, result.type ?? ["debug"], req)
diff --git a/leaky-ships/lib/backend/errors.ts b/leaky-ships/lib/backend/errors.ts
index 6c101bf..641ac35 100644
--- a/leaky-ships/lib/backend/errors.ts
+++ b/leaky-ships/lib/backend/errors.ts
@@ -69,6 +69,12 @@ export const rejectionErrors: rejectionErrors = {
solved: true,
type: "warn",
},
+ gameNotFound: {
+ rejected: true,
+ message: "Game not found!",
+ statusCode: 403,
+ solved: true,
+ },
}
export const rejectionErrorFns: rejectionErrorFns = {
diff --git a/leaky-ships/lib/frontend/getAccessToken.ts b/leaky-ships/lib/frontend/getAccessToken.ts
index 9e941b5..571b2bf 100644
--- a/leaky-ships/lib/frontend/getAccessToken.ts
+++ b/leaky-ships/lib/frontend/getAccessToken.ts
@@ -1,18 +1,42 @@
+import status from "http-status"
+import { toast } from "react-toastify"
+import { ZodError, z } from "zod"
+
+const tokenSchema = z.object({
+ token: z.string(),
+})
+
+export function successfulResponse(res: Response) {
+ if (status[`${res.status}_CLASS`] === status.classes.SUCCESSFUL)
+ return res.json()
+
+ const resStatus = status[`${res.status}_CLASS`]
+ if (typeof resStatus !== "string") return
+
+ toast(status.classes[resStatus] + ": " + status[res.status], {
+ position: "top-center",
+ type: "error",
+ theme: "colored",
+ })
+ return Promise.reject()
+}
+
async function getAccessToken() {
- const response = await fetch("/api/user/auth", {
+ return fetch("/api/user/auth", {
method: "GET",
})
- const res = await response.json()
+ .then(successfulResponse)
+ .then((response) => {
+ try {
+ const token = tokenSchema.parse(response)
- if (
- typeof res === "object" &&
- res &&
- "token" in res &&
- typeof res.token === "string"
- )
- return res.token
-
- throw new Error("Access token not found")
+ return token
+ } catch (err: any) {
+ const error = err as ZodError
+ toast(JSON.stringify(error))
+ return Promise.reject()
+ }
+ })
}
export default getAccessToken
diff --git a/leaky-ships/package.json b/leaky-ships/package.json
index 3949f52..7fe186a 100644
--- a/leaky-ships/package.json
+++ b/leaky-ships/package.json
@@ -25,11 +25,14 @@
"cookies-next": "^2.1.1",
"eslint": "8.31.0",
"eslint-config-next": "13.1.1",
+ "http-status": "^1.6.2",
"jsonwebtoken": "^9.0.0",
"next": "13.1.1",
"prisma": "^4.12.0",
"react": "18.2.0",
"react-dom": "18.2.0",
+ "react-otp-input": "^3.0.0",
+ "react-toastify": "^9.1.2",
"socket.io": "^4.6.1",
"socket.io-client": "^4.6.1",
"typescript": "4.9.4",
diff --git a/leaky-ships/pages/_app.tsx b/leaky-ships/pages/_app.tsx
index 821c654..1bd28e7 100644
--- a/leaky-ships/pages/_app.tsx
+++ b/leaky-ships/pages/_app.tsx
@@ -4,11 +4,18 @@ import "../styles/grid2.scss"
import "../styles/grid.scss"
import type { AppProps } from "next/app"
import { Dispatch, SetStateAction, createContext, useState } from "react"
+import { ToastContainer } from "react-toastify"
+import "react-toastify/dist/ReactToastify.css"
interface gameContext {
pin?: string
game?: {
- id: ""
+ id: string
+ }
+ player?: {
+ id: string
+ username?: string
+ isOwner?: boolean
}
enemy?: {
id: string
@@ -25,6 +32,7 @@ export default function App({ Component, pageProps }: AppProps) {
return (
+
)
}
diff --git a/leaky-ships/pages/api/game/create.ts b/leaky-ships/pages/api/game/create.ts
index f03b900..c024d73 100644
--- a/leaky-ships/pages/api/game/create.ts
+++ b/leaky-ships/pages/api/game/create.ts
@@ -2,18 +2,33 @@ import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse"
import getPlayer from "@lib/backend/components/getPlayer"
import prisma from "@lib/prisma"
+import { Game, Gamepin, Player_Game } from "@prisma/client"
import type { NextApiRequest, NextApiResponse } from "next"
import { z } from "zod"
-const returnSchema = z.object({
+export const createSchema = z.object({
game: z.object({
id: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
running: z.boolean(),
}),
+ pin: z.string().optional(),
+ player: z.object({
+ id: z.string(),
+ username: z.string().optional(),
+ isOwner: z.boolean().optional(),
+ }),
+ enemy: z
+ .object({
+ id: z.string(),
+ username: z.string().optional(),
+ isOwner: z.boolean().optional(),
+ })
+ .optional(),
})
-type Data = z.infer
+
+type Data = z.infer
export default async function create(
req: NextApiRequest,
@@ -26,16 +41,20 @@ export default async function create(
const pin = Math.floor(Math.random() * 10000)
.toString()
.padStart(4, "0")
- const game = await prisma.game.create({
- data: {
- pin: {
- create: {
- pin,
- },
- },
+
+ let created = false
+ let game:
+ | (Game & {
+ pin: Gamepin | null
+ players: Player_Game[]
+ })
+ | null
+
+ game = await prisma.game.findFirst({
+ where: {
+ running: true,
players: {
- create: {
- isOwner: true,
+ some: {
playerId: player.id,
},
},
@@ -45,10 +64,41 @@ export default async function create(
players: true,
},
})
+ if (!game) {
+ created = true
+ game = await prisma.game.create({
+ data: {
+ pin: {
+ create: {
+ pin,
+ },
+ },
+ players: {
+ create: {
+ isOwner: true,
+ playerId: player.id,
+ },
+ },
+ },
+ include: {
+ pin: true,
+ players: true,
+ },
+ })
+ }
return sendResponse(context, {
message: `Player: ${player.id} created game: ${game.id}`,
- body: { game },
+ statusCode: created ? 201 : 200,
+ body: {
+ game,
+ pin: game.pin?.pin,
+ player: {
+ id: player.id,
+ username: player.username ?? undefined,
+ isOwner: true,
+ },
+ },
type: ["debug", "infoCyan"],
})
}).catch((err) => sendError(context, err))
diff --git a/leaky-ships/pages/api/game/join.ts b/leaky-ships/pages/api/game/join.ts
index c2c63d0..2a8f431 100644
--- a/leaky-ships/pages/api/game/join.ts
+++ b/leaky-ships/pages/api/game/join.ts
@@ -2,6 +2,7 @@ import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse"
import getPinFromBody from "@lib/backend/components/getPinFromBody"
import getPlayer from "@lib/backend/components/getPlayer"
+import { rejectionErrors } from "@lib/backend/errors"
import prisma from "@lib/prisma"
import type { Game } from "@prisma/client"
import type { NextApiRequest, NextApiResponse } from "next"
@@ -18,30 +19,61 @@ export default async function join(
return getPinFromBody(context, (pin) =>
getPlayer(context, async (player) => {
- const { game } = await prisma.gamepin.update({
- where: {
- pin,
- },
- data: {
- game: {
- update: {
- players: {
- create: {
- isOwner: false,
- playerId: player.id,
+ try {
+ const pinDB = await prisma.gamepin.update({
+ where: {
+ pin,
+ },
+ data: {
+ game: {
+ update: {
+ players: {
+ create: {
+ isOwner: false,
+ playerId: player.id,
+ },
},
},
},
},
- },
- include: { game: true },
- })
+ include: {
+ game: {
+ include: {
+ players: {
+ include: {
+ player: true,
+ },
+ },
+ },
+ },
+ },
+ })
- sendResponse(context, {
- message: `Player: ${player.id} joined game: ${game.id}`,
- body: { game },
- type: ["debug", "infoCyan"],
- })
+ const enemy = pinDB.game.players.find(
+ (enemy) => enemy.player.id !== player.id
+ )
+ return sendResponse(context, {
+ message: `Player: ${player.id} joined game: ${pinDB.game.id}`,
+ body: {
+ game: pinDB.game,
+ pin: pinDB.pin,
+ player: {
+ id: player.id,
+ username: player.username ?? undefined,
+ isOwner: true,
+ },
+ enemy: {
+ id: enemy?.player.id,
+ username: enemy?.player.username ?? undefined,
+ isOwner: false,
+ },
+ },
+ type: ["debug", "infoCyan"],
+ })
+ } catch (err: any) {
+ console.log("HERE".red, err.code, err.meta, err.message)
+ return sendError(context, rejectionErrors.gameNotFound)
+ }
})
).catch((err) => sendError(context, err))
}
diff --git a/leaky-ships/pages/api/user/auth.ts b/leaky-ships/pages/api/user/auth.ts
index af98864..0e3c4ad 100644
--- a/leaky-ships/pages/api/user/auth.ts
+++ b/leaky-ships/pages/api/user/auth.ts
@@ -5,6 +5,7 @@ import getTokenDB from "@backend/components/getTokenDB"
import getTokenFromCookie from "@backend/components/getTokenFromCookie"
import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse"
+import { Player, Token } from "@prisma/client"
import type { NextApiRequest, NextApiResponse } from "next"
interface Data {
@@ -18,19 +19,24 @@ export default async function auth(
const context = { req, res }
const type = "ACCESS"
- return getTokenFromCookie(context, (refreshToken) =>
- checkTokenIsValid(context, refreshToken, (token) =>
- getTokenDB(context, token, (tokenDB) =>
- getPlayerByIdDB(context, tokenDB, (player) =>
- createTokenDB(player, type, (newToken, newTokenDB) =>
- sendResponse(context, {
- message: `Access-Token generated: ${newTokenDB.id} with Refreshtoken-Token: ${tokenDB.id}`,
- body: { token: newToken.value },
- type: ["debug", "infoCyan"],
- })
- )
+ return getTokenFromCookie(context, (refreshToken, newPlayer) => {
+ const next = (player: Player, tokenDB: Token, cookie?: string) =>
+ createTokenDB(player, type, (newToken, newTokenDB) =>
+ sendResponse(context, {
+ message: `Access-Token generated: ${newTokenDB.id} with Refreshtoken-Token: ${tokenDB.id}`,
+ body: { token: newToken.value },
+ type: ["debug", "infoCyan"],
+ cookie,
+ })
+ )
+ if (!newPlayer) {
+ return checkTokenIsValid(context, refreshToken, (token) =>
+ getTokenDB(context, token, (tokenDB) =>
+ getPlayerByIdDB(context, tokenDB, (player) => next(player, tokenDB))
)
)
- )
- ).catch((err) => sendError(context, err))
+ }
+ const { player, newToken, newTokenDB } = newPlayer
+ return next(player, newTokenDB, newToken.value)
+ }).catch((err) => sendError(context, err))
}
diff --git a/leaky-ships/pages/api/user/login.ts b/leaky-ships/pages/api/user/login.ts
index 7546478..d1e1c7c 100644
--- a/leaky-ships/pages/api/user/login.ts
+++ b/leaky-ships/pages/api/user/login.ts
@@ -26,17 +26,6 @@ export default async function login(
getPlayerByNameDB(context, username, (player) => {
checkPasswordIsValid(context, player, password, () => {
createTokenDB(player, "REFRESH", (newToken, newTokenDB) => {
- // Set login cookie
- setCookie("token", newToken.value, {
- req,
- res,
- maxAge: 172800,
- httpOnly: true,
- sameSite: true,
- secure: true,
- path: "/api",
- })
-
sendResponse(context, {
message:
"User " +
@@ -45,6 +34,7 @@ export default async function login(
newTokenDB.id,
body: { loggedIn: true },
type: ["debug", "infoCyan"],
+ cookie: newToken.value,
})
})
})
diff --git a/leaky-ships/pages/api/user/logout.ts b/leaky-ships/pages/api/user/logout.ts
index d479186..11cde18 100644
--- a/leaky-ships/pages/api/user/logout.ts
+++ b/leaky-ships/pages/api/user/logout.ts
@@ -3,7 +3,6 @@ import getTokenFromCookie from "@backend/components/getTokenFromCookie"
import sendError from "@backend/components/sendError"
import sendResponse from "@backend/components/sendResponse"
import decodeToken from "@lib/backend/components/decodeToken"
-import { deleteCookie } from "cookies-next"
import type { NextApiRequest, NextApiResponse } from "next"
interface Data {
@@ -12,7 +11,7 @@ interface Data {
export default async function logout(
req: NextApiRequest,
- res: NextApiResponse
+ res: NextApiResponse
) {
const context = { req, res }
@@ -22,13 +21,11 @@ export default async function logout(
context,
token,
(tokenDB) => {
- // Set login cookie
- deleteCookie("token", { req, res })
-
return sendResponse(context, {
message: "User of Token " + tokenDB.id + " logged out.",
body: { loggedOut: true },
type: ["debug", "infoCyan"],
+ cookie: "",
})
},
true
diff --git a/leaky-ships/pages/dev/index.tsx b/leaky-ships/pages/dev/index.tsx
index 0519f32..49388c7 100644
--- a/leaky-ships/pages/dev/index.tsx
+++ b/leaky-ships/pages/dev/index.tsx
@@ -1,104 +1,222 @@
import BurgerMenu from "../../components/BurgerMenu"
import Logo from "../../components/Logo"
import OptionButton from "../../components/OptionButton"
+import { gameContext } from "../_app"
import { faEye, faLeftLong } from "@fortawesome/pro-regular-svg-icons"
import { faPlus, faUserPlus } from "@fortawesome/pro-solid-svg-icons"
import { faCirclePlay } from "@fortawesome/pro-thin-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
-import getAccessToken from "@lib/frontend/getAccessToken"
+import getAccessToken, {
+ successfulResponse,
+} from "@lib/frontend/getAccessToken"
import { GetServerSideProps } from "next"
import { useRouter } from "next/router"
-import { useState } from "react"
+import { useCallback, useContext, useEffect, useState } from "react"
+import OtpInput from "react-otp-input"
+import { toast } from "react-toastify"
import { z } from "zod"
interface Props {
- start: boolean
+ q: string | string[] | undefined
+}
+function isInputOnlyNumbers(input: string) {
+ return /^\d+$/.test(input)
}
-export default function Home({ start }: Props) {
+export default function Home({ q }: Props) {
+ const [otp, setOtp] = useState("")
+ const [gameProps, setGameProps] = useContext(gameContext)
const router = useRouter()
+
+ const gameFetch = useCallback(
+ async (pin?: string) => {
+ const createSchema = z.object({
+ game: z.object({
+ id: z.string(),
+ }),
+ pin: z.string().optional(),
+ player: z.object({
+ id: z.string(),
+ username: z.string().optional(),
+ isOwner: z.boolean().optional(),
+ }),
+ enemy: z
+ .object({
+ id: z.string(),
+ username: z.string().optional(),
+ isOwner: z.boolean().optional(),
+ })
+ .optional(),
+ })
+ const gamePromise = getAccessToken().then((token) => {
+ console.log(otp, { ...token, pin })
+ return fetch("/api/game/" + (!pin ? "create" : "join"), {
+ method: "POST",
+ body: JSON.stringify({ ...token, pin: pin }),
+ })
+ .then(successfulResponse)
+ .then((game) => createSchema.parse(game))
+ })
+
+ const res = await toast.promise(gamePromise, {
+ pending: {
+ render: "Raum wird " + (!pin ? "erstellt" : "angefragt"),
+ },
+ success: {
+ render: "Raum " + (!pin ? "erstellt" : "angefragt") + " 👌",
+ type: "info",
+ theme: "colored",
+ },
+ error: {
+ render: "Es ist ein Fehler aufgetreten 🤯",
+ type: "error",
+ theme: "colored",
+ },
+ })
+
+ setGameProps(res)
+
+ await toast.promise(router.push("/dev/lobby"), {
+ pending: {
+ render: "Raum wird beigetreten",
+ },
+ success: {
+ render: "Raum begetreten 👌",
+ type: "info",
+ },
+ error: {
+ render: "Es ist ein Fehler aufgetreten 🤯",
+ type: "error",
+ },
+ })
+ },
+ [router, setGameProps]
+ )
+
+ useEffect(() => {
+ if (otp.length !== 4) return
+ if (!isInputOnlyNumbers(otp)) {
+ toast("Der Code darf nur Zahlen beinhalten!", {
+ type: "warning",
+ theme: "dark",
+ })
+ return
+ }
+ gameFetch(otp)
+ }, [otp])
+
return (
- {!start ? (
- <>
-
-
-
-
- >
- ) : (
-
-
-
- {
- const token = await getAccessToken()
- const game = await fetch("/api/game/create", {
- method: "POST",
- body: JSON.stringify({ token }),
- })
- const gameSchema = z.object({
- game: z.object({
- id: z.string(),
- createdAt: z.date(),
- updatedAt: z.date(),
- running: z.boolean(),
- }),
- })
-
- const check = gameSchema.safeParse(game)
-
- if (check.success) {
- const gameData = check.data
- console.log(gameData)
- } else {
- console.error(check.error)
- }
-
- // const warst = result.game
-
- router.push("/dev/lobby")
- }}
- icon={faPlus}
- >
- Raum erstellen
-
- Raum beitreten
- Zuschauen
-
-
- )}
+ {(() => {
+ switch (q) {
+ case "join":
+ return (
+
+
+
+ Raum erstellen
+ {
+ router.push({
+ pathname: router.pathname,
+ query: { q: "join" },
+ })
+ }}
+ icon={faUserPlus}
+ >
+ -}
+ renderInput={(props) => }
+ />
+
+ Zuschauen
+
+
+ )
+ case "start":
+ return (
+
+
+
+ gameFetch()} icon={faPlus}>
+ Raum erstellen
+
+ {
+ router.push({
+ pathname: router.pathname,
+ query: { q: "join" },
+ })
+ }}
+ icon={faUserPlus}
+ >
+ Raum beitreten
+
+ Zuschauen
+
+
+ )
+ default:
+ return (
+ <>
+
+
+
+
+ >
+ )
+ }
+ })()}
)
@@ -107,10 +225,7 @@ export default function Home({ start }: Props) {
export const getServerSideProps: GetServerSideProps = async (
context
) => {
- const { start } = context.query
+ const { q } = context.query
- // Convert the `start` query parameter to a boolean
- const isStart = start === "true"
-
- return { props: { start: isStart } }
+ return { props: { q: q ? q : "" } }
}
diff --git a/leaky-ships/pnpm-lock.yaml b/leaky-ships/pnpm-lock.yaml
index eea794c..e9c81c5 100644
--- a/leaky-ships/pnpm-lock.yaml
+++ b/leaky-ships/pnpm-lock.yaml
@@ -49,6 +49,9 @@ dependencies:
eslint-config-next:
specifier: 13.1.1
version: 13.1.1(eslint@8.31.0)(typescript@4.9.4)
+ http-status:
+ specifier: ^1.6.2
+ version: 1.6.2
jsonwebtoken:
specifier: ^9.0.0
version: 9.0.0
@@ -64,6 +67,12 @@ dependencies:
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
+ react-otp-input:
+ specifier: ^3.0.0
+ version: 3.0.0(react-dom@18.2.0)(react@18.2.0)
+ react-toastify:
+ specifier: ^9.1.2
+ version: 9.1.2(react-dom@18.2.0)(react@18.2.0)
socket.io:
specifier: ^4.6.1
version: 4.6.1
@@ -1010,6 +1019,11 @@ packages:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
dev: false
+ /clsx@1.2.1:
+ resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
+ engines: {node: '>=6'}
+ dev: false
+
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -1920,6 +1934,11 @@ packages:
dependencies:
function-bind: 1.1.1
+ /http-status@1.6.2:
+ resolution: {integrity: sha512-oUExvfNckrpTpDazph7kNG8sQi5au3BeTo0idaZFXEhTaJKu7GNJCLHI0rYY2wljm548MSTM+Ljj/c6anqu2zQ==}
+ engines: {node: '>= 0.4.0'}
+ dev: false
+
/https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
@@ -2785,6 +2804,27 @@ packages:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: false
+ /react-otp-input@3.0.0(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-TgTE3PbHhu4VxsAA9JUACzhtxwuZ8OSle9kiwK0Ne7fCv7wOXTtIRWQWPoNlfOZ/sxGsXjMexqwrQdB9yy0qEQ==}
+ peerDependencies:
+ react: '>=16.8.6 || ^17.0.0 || ^18.0.0'
+ react-dom: '>=16.8.6 || ^17.0.0 || ^18.0.0'
+ dependencies:
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /react-toastify@9.1.2(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-PBfzXO5jMGEtdYR5jxrORlNZZe/EuOkwvwKijMatsZZm8IZwLj01YvobeJYNjFcA6uy6CVrx2fzL9GWbhWPTDA==}
+ peerDependencies:
+ react: '>=16'
+ react-dom: '>=16'
+ dependencies:
+ clsx: 1.2.1
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}