Add error messages in landing page for create lobby error

landing-page-layout
MiguelMLorente 2025-02-09 21:14:27 +01:00
parent e982f782cb
commit 1d777f74ff
7 changed files with 45 additions and 5 deletions

View File

@ -14,10 +14,10 @@ import {
CreateLobbyEvent,
emitUpdateLobbyEvent,
JoinLobbyEvent,
ServerEvent,
} from 'interface';
import { createWsExceptionFilter } from './websocket-exception-filter';
import {
InvalidPlayerNameException,
MissingPlayerNameException,
PlayerNotFoundException,
} from './exceptions';
@ -39,6 +39,7 @@ export class AppService implements OnGatewayConnection {
createWsExceptionFilter([
PlayerNotFoundException,
MissingPlayerNameException,
InvalidPlayerNameException,
]),
)
@SubscribeMessage(ClientEvent.CREATE_LOBBY)
@ -60,6 +61,7 @@ export class AppService implements OnGatewayConnection {
createWsExceptionFilter([
PlayerNotFoundException,
MissingPlayerNameException,
InvalidPlayerNameException,
]),
)
@SubscribeMessage(ClientEvent.JOIN_LOBBY)

View File

@ -16,6 +16,12 @@ export class MissingPlayerNameException extends WebSocketException {
}
}
export class InvalidPlayerNameException extends WebSocketException {
constructor(userName: string) {
super('Invalid player name: ' + userName, ErrorCode.INVALID_USER_NAME);
}
}
export class PlayerNotFoundException extends WebSocketException {
constructor(playerId: string) {
super(

View File

@ -1,6 +1,7 @@
import { Injectable, Logger } from '@nestjs/common';
import { Player } from './player';
import {
InvalidPlayerNameException,
MissingPlayerNameException,
PlayerNotFoundException,
} from 'src/exceptions';
@ -10,6 +11,7 @@ import { Socket } from 'socket.io/dist/socket';
export class PlayerService {
private readonly logger = new Logger(PlayerService.name);
private readonly players: Map<string, Player> = new Map();
private readonly userNameValidator: RegExp = /(^[a-zA-Z]){1,20}$/;
createPlayer(socket: Socket) {
const player: Player = new Player(socket);
@ -20,6 +22,9 @@ export class PlayerService {
if (!userName) {
throw new MissingPlayerNameException();
}
if (!this.userNameValidator.test(userName)) {
throw new InvalidPlayerNameException(userName);
}
this.players.get(socketId).userName = userName;
}

View File

@ -1,4 +1,4 @@
import { Socket } from "socket.io";
import { Socket } from 'socket.io';
export class Player {
socketId: string;

View File

@ -6,5 +6,6 @@ export enum ServerError {
export enum ErrorCode {
PLAYER_NOT_FOUND = "player-not-found",
GAME_NOT_FOUND = "game-not-found",
MISSING_USER_NAME = "player-user-name-not-found",
MISSING_USER_NAME = "missing-player-name",
INVALID_USER_NAME = "invalid-player-name",
}

View File

@ -26,6 +26,10 @@
margin: auto;
width: 20%;
min-width: 300px;
#error-message {
color: #222;
}
}
> div {

View File

@ -1,10 +1,12 @@
import {
attachHandlerToCreateLobbyError,
CreateLobbyEvent,
ErrorCode,
handleCreateLobby,
handleJoinLobby,
JoinLobbyEvent,
} from "interface";
import React, { ChangeEvent } from "react";
import React, { ChangeEvent, useState } from "react";
import { Socket } from "socket.io-client";
import "./LandingPage.scss";
@ -24,6 +26,21 @@ const LandingPage = (props: LandingPageProps) => {
const registerLobbyId = (event: ChangeEvent<HTMLInputElement>) =>
(joinLobbyPayload.lobbyId = event.target.value);
const [receivedError, setReceivedError] = useState("" as ErrorCode);
const userNameErrorCodesToMessageMap = new Map([
[ErrorCode.MISSING_USER_NAME, "Introduce your player name"],
[
ErrorCode.INVALID_USER_NAME,
"Player name must be letters or spaces only and up to 25 characters",
],
]);
const userNameErrorMessage =
userNameErrorCodesToMessageMap.get(receivedError);
attachHandlerToCreateLobbyError(socket, (event) =>
setReceivedError(event.error),
);
return (
<div className="landing-page">
<div>
@ -34,7 +51,11 @@ const LandingPage = (props: LandingPageProps) => {
<input
placeholder="Enter username"
onChange={registerUsername}
maxLength={20}
></input>
{userNameErrorMessage && (
<small id="error-message">{userNameErrorMessage}</small>
)}
<button onClick={() => handleCreateLobby(socket, createLobbyPayload)}>
Create Lobby
</button>
@ -43,6 +64,7 @@ const LandingPage = (props: LandingPageProps) => {
<input
placeholder="Enter Lobby Id"
onChange={registerLobbyId}
maxLength={5}
></input>
<button
className="secondary"