Skip to content

Commit

Permalink
Merge pull request #177 from sopra-fs24-group-09/dev
Browse files Browse the repository at this point in the history
Deploy test
  • Loading branch information
yixuan-zhou-uzh authored May 17, 2024
2 parents f19a55d + 96ee553 commit 5e70923
Show file tree
Hide file tree
Showing 10 changed files with 414 additions and 124 deletions.
47 changes: 47 additions & 0 deletions src/components/ui/CustomNumberInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import "../../styles/ui/CustomNumberInput.scss";

interface CustomNumberInputProps {
min: number;
max: number;
value: number;
onChange: (value: number) => void;
}

const CustomNumberInput: React.FC<CustomNumberInputProps> = ({ min, max, value, onChange }) => {
const handleDecrement = () => {
if (value > min) {
onChange(value - 1);
}
};

const handleIncrement = () => {
if (value < max) {
onChange(value + 1);
}
};

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = parseInt(e.target.value, 10);
if (!isNaN(newValue) && newValue >= min && newValue <= max) {
onChange(newValue);
}
};

return (
<div className="custom-number-input">
<button onClick={handleDecrement} disabled={value <= min}>-</button>
<input
type="number"
value={value}
onChange={handleChange}
readOnly
min={min}
max={max}
/>
<button onClick={handleIncrement} disabled={value >= max}>+</button>
</div>
);
};

export default CustomNumberInput;
56 changes: 32 additions & 24 deletions src/components/views/Lobby.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useCallback, useRef, useEffect, useState } from "react";
import { api } from "helpers/api";
import CustomNumberInput from "components/ui/CustomNumberInput";
import { Button } from "components/ui/Button";
import { throttle } from "lodash";
import { useNavigate } from "react-router-dom";
Expand Down Expand Up @@ -286,7 +287,6 @@ const Lobby = () => {
: changeAvatarPopRef.current.showModal();
};


const toggleInfoPop = () => {
// if the ref is not set, do nothing
if (!infoPopRef.current) {
Expand Down Expand Up @@ -382,7 +382,7 @@ const Lobby = () => {

if (Room.roomPlayersList.length === Room.roomMaxNum) {
showToast("Room is Full, please enter another room!", "error");
} else if (Room.status === "In Game") {
} else if (Room.status !== "WAITING") {
showToast("Game is already started, please enter another room!", "error");
} else {
navigate(`/rooms/${Room.roomId}`);
Expand All @@ -402,26 +402,40 @@ const Lobby = () => {
return rooms.map((Room) => {
const playerSlots = [];

// 生成玩家头像或空白框,总数等于房间最大玩家数
// generate players avatar
for (let i = 0; i < Room.roomMaxNum; i++) {
if (i < Room.roomPlayersList.length) {
const user = Room.roomPlayersList[i];
playerSlots.push(
<div className="player" key={i}>
<i className={`twa twa-${user.avatar}`} style={{ fontSize: "3.8rem" }} />
<i className={`twa twa-${user.avatar}`}
style={{
fontSize: "3.5rem",
marginTop:"5px"
}}
/>
<div className="name">{user.userName}</div>
</div>
);
} else {
// 空白框
// plus avatar
playerSlots.push(
<div className="player" key={i}>

<div className="plus-player" key={i}>
<i className="twa twa-plus" style={{
fontSize: "3rem",
marginTop: "18.5px",
opacity: "0.4"
}} />
</div>
);
}
}

// don't render the room if there is no player in the room or the game is over
if (Room.roomPlayersList.length === 0 || Room.status === "GAMEOVER") {
return ;
}

return (
<div className="room-container" key={Room.roomId} onClick={handleRoomClick(Room)}>
<div className="room-players">
Expand Down Expand Up @@ -457,11 +471,9 @@ const Lobby = () => {
cursor: "pointer"
}} />
<div className="name">{user.username}</div>
<div className="btn-logout-container">
<Button className="logout-btn" onClick={logout}>Logout</Button>
</div>
</div>
)}
<Button className="logout-btn" onClick={logout}>Logout</Button>
<div className="title-container">
<div className="big-title">Kaeps</div>
<div className="information" onClick={toggleInfoPop}>i</div>
Expand Down Expand Up @@ -495,6 +507,7 @@ const Lobby = () => {
>
Edit
</Button>
<Button className="out" onClick={logout}>Logout</Button>
</>)
}
>
Expand Down Expand Up @@ -560,8 +573,8 @@ const Lobby = () => {
<Button
disabled={
roomName === "" ||
maxRoomPlayers < DEFAULT_MIN_PLAYERS ||
maxRoomPlayers > DEFAULT_MAX_PLAYERS ||
// maxRoomPlayers < DEFAULT_MIN_PLAYERS ||
// maxRoomPlayers > DEFAULT_MAX_PLAYERS ||
roomTheme === "" ||
isNaN(maxRoomPlayers) ||
specialCharactersRegex.test(roomName)
Expand All @@ -580,23 +593,18 @@ const Lobby = () => {
value={roomName}
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_ROOM_NAME_LENGTH) { // 检查输入值的长度
setRoomName(inputValue); // 如果长度小于或等于 MAX_ROOM_NAME_LENGTH,更新状态
if (inputValue.length <= MAX_ROOM_NAME_LENGTH) {
setRoomName(inputValue);
}
}}
/>
<div>Number of Maximum Players: </div>
<input
type="number"
placeholder={`Between ${DEFAULT_MIN_PLAYERS} and ${DEFAULT_MAX_PLAYERS}`}
value={maxRoomPlayers}
onChange={e => {
const value = parseInt(e.target.value);
// console.error("Value:", value);
SetMaxRoomPlayers(value);
}}
<CustomNumberInput
className="custom-number-input"
min={DEFAULT_MIN_PLAYERS}
max={DEFAULT_MAX_PLAYERS}
value={maxRoomPlayers}
onChange={SetMaxRoomPlayers}
/>
<Dropdown
className="theme-dropdown"
Expand Down Expand Up @@ -643,7 +651,7 @@ const Lobby = () => {
<li><strong>Turns:</strong> The game is played in rounds. Each round has one speaker and several challengers. Players alternate roles as the Speaker to ensure fairness.</li>
</ul>
<p>Click <b>GUIDE</b> for more detailed instructions.</p>
<p>Join a room or create one to play with friends!</p>
<p className="important-note">Before you start, please enable your browser&apos;s microphone privacy settings.</p>

</div>
</Popup>
Expand Down
22 changes: 14 additions & 8 deletions src/components/views/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState } from "react";
import { api, handleError } from "helpers/api";
import { api } from "helpers/api";
import User from "models/User";
import {Link, useNavigate} from "react-router-dom";
import { Button } from "components/ui/Button";
import "styles/views/Login.scss";
import BaseContainer from "components/ui/BaseContainer";
import PropTypes from "prop-types";
import { MAX_USERNAME_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { MAX_USERNAME_LENGTH, MAX_PASSWORD_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { showToast} from "../../helpers/toastService";

/*
Expand All @@ -24,7 +24,7 @@ const FormField = (props) => {
placeholder="enter here.."
value={props.value}
type={props.type}
onChange={(e) => props.onChange(e.target.value)}
onChange={(e) => props.onChange(e)}
/>
</div>
);
Expand Down Expand Up @@ -58,7 +58,7 @@ const Login = () => {
showToast("Login successful!", "success");
navigate("/lobby");
} catch (error) {
let message = "An unexpected error occurred during login.";
let message;
if (error.response) {
switch (error.response.status) {
case HTTP_STATUS.NOT_FOUND:
Expand Down Expand Up @@ -87,16 +87,22 @@ const Login = () => {
label="Username"
value={username}
type="text"
onChange={(un: string) => {
if (un.length <= MAX_USERNAME_LENGTH) setUsername(un)
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_USERNAME_LENGTH) {
setUsername(inputValue);
}
}}
/>
<FormField
label="Password"
value={password}
type="password"
onChange={(n: any) => {
if (n.length <= MAX_USERNAME_LENGTH) setPassword(n)
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_PASSWORD_LENGTH) {
setPassword(inputValue);
}
}}
/>
<div className="login button-container">
Expand Down
28 changes: 17 additions & 11 deletions src/components/views/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState } from "react";
import { api, handleError } from "helpers/api";
import { api } from "helpers/api";
import User from "models/User";
import {Link, useNavigate} from "react-router-dom";
import { Button } from "components/ui/Button";
import "styles/views/Register.scss";
import BaseContainer from "components/ui/BaseContainer";
import PropTypes from "prop-types";
import { MAX_USERNAME_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { MAX_USERNAME_LENGTH, MAX_PASSWORD_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { showToast} from "../../helpers/toastService";
/*
It is possible to add multiple components inside a single file,
Expand All @@ -24,7 +24,7 @@ const FormField = (props) => {
placeholder="enter here.."
value={props.value}
type={props.type}
onChange={(e) => props.onChange(e.target.value)}
onChange={(e) => props.onChange(e)}
/>
</div>
);
Expand Down Expand Up @@ -55,10 +55,10 @@ const Register = () => {
sessionStorage.setItem("id", user.id);
sessionStorage.setItem("username", user.username);
// Register successfully worked --> navigate to the route /game in the LobbyRouter
showToast("Register successful!", "success");
navigate("/lobby");
showToast("Register successful!\nWelcome to this guide for newbies!", "success");
navigate("/guide");
} catch (error) {
let message = "An unexpected error occurred during Register.";
let message;
if (error.response) {
switch (error.response.status) {
case HTTP_STATUS.CONFLICT:
Expand All @@ -84,22 +84,28 @@ const Register = () => {
label="Username"
value={username}
type="text"
onChange={(un: string) => {
if (un.length <= MAX_USERNAME_LENGTH) setUsername(un);
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_USERNAME_LENGTH) {
setUsername(inputValue);
}
}}
/>
<FormField
label="Password"
value={password}
type="password"
onChange={(n: any) => {
if (n.length <= MAX_USERNAME_LENGTH) setPassword(n)
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_PASSWORD_LENGTH) {
setPassword(inputValue);
}
}}
/>
<div className="register button-container">
<Button
disabled={!username || !password ||password.indexOf(" ") !== CHAR_NOT_FOUND || username.indexOf(" ") !== CHAR_NOT_FOUND }
width="75%"
width="100%"
onClick={() => doRegister()}
style={{ color: "black"}}
>
Expand Down
Loading

0 comments on commit 5e70923

Please sign in to comment.