added LoginPage

This commit is contained in:
Wenszel 2023-11-23 21:20:44 +01:00
parent c999bfca39
commit ffaaf0b6f3
10 changed files with 228 additions and 29 deletions

View File

@ -15,5 +15,25 @@ module.exports = (io, socket) => {
io.to(socket.id).emit('room:data', JSON.stringify(room)); io.to(socket.id).emit('room:data', JSON.stringify(room));
} }
}; };
socket.on('room:data', getData);
const getRooms = async () => {
let rooms = await RoomModel.find({});
const response = [];
rooms.forEach(room => {
if (!room.isStarted && !room.isFull()) {
response.push({
_id: room._id,
name: room.name,
players: room.players,
isStarted: room.isStarted,
});
}
});
io.to(socket.id).emit('room:rooms', JSON.stringify(response));
};
socket.on('room:data', getData);
socket.on('room:rooms', getRooms);
}; };

View File

@ -6,6 +6,7 @@ const PawnSchema = require('./pawn');
const PlayerSchema = require('./player'); const PlayerSchema = require('./player');
const RoomSchema = new Schema({ const RoomSchema = new Schema({
name: String,
createDate: { type: Date, default: Date.now }, createDate: { type: Date, default: Date.now },
started: { type: Boolean, default: false }, started: { type: Boolean, default: false },
full: { type: Boolean, default: false }, full: { type: Boolean, default: false },
@ -66,6 +67,7 @@ RoomSchema.methods.startGame = function () {
this.nextMoveTime = Date.now() + 15000; this.nextMoveTime = Date.now() + 15000;
this.players.forEach(player => (player.ready = true)); this.players.forEach(player => (player.ready = true));
this.players[0].nowMoving = true; this.players[0].nowMoving = true;
this.timeoutID = setTimeout(makeRandomMove, 15000, this);
}; };
RoomSchema.methods.isFull = function () { RoomSchema.methods.isFull = function () {

View File

@ -1,9 +1,9 @@
import React, { useEffect, useState, createContext } from 'react'; import React, { useEffect, useState, createContext } from 'react';
import { io } from 'socket.io-client'; import { io } from 'socket.io-client';
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'; import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';
import ReactLoading from 'react-loading';
import Gameboard from './components/Gameboard'; import Gameboard from './components/Gameboard';
import NameInput from './components/NameInput'; import LoginPage from './components/LoginPage/LoginPage';
export const PlayerDataContext = createContext(); export const PlayerDataContext = createContext();
export const SocketContext = createContext(); export const SocketContext = createContext();
@ -32,7 +32,11 @@ function App() {
LOADING... LOADING...
</Route> </Route>
<Route path='/login'> <Route path='/login'>
<NameInput /> {playerSocket ? (
<LoginPage />
) : (
<ReactLoading type='spinningBubbles' color='white' height={667} width={375} />
)}
</Route> </Route>
<Route path='/game'> <Route path='/game'>
{playerData ? ( {playerData ? (

View File

@ -0,0 +1,76 @@
.login-page-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 50vh;
width: 400px;
position: relative;
padding: 20px;
border-radius: 5%;
border: 5px solid white;
background-color: rgba(0, 0, 0, 0.5);
}
h1 {
margin-right: 10px;
align-self: flex-start;
top: 0;
position: absolute;
color: white;
}
.rooms {
width: 98%;
height: 80%;
overflow-y: scroll;
overflow-x: hidden;
}
.room {
cursor: pointer;
justify-content: space-between;
display: flex;
flex-direction: row;
align-items: center;
color: white;
width: 90%;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.room-selected {
border: 1px solid white;
}
.room-selected,
.room:hover {
background-color: rgba(0, 0, 0, 0.5);
}
.number-of-players {
display: flex;
flex-direction: row;
align-items: center;
}
.number-of-players > img {
margin-right: 5px;
width: 20px;
height: 20px;
}
/* Firefox */
* {
scrollbar-width: auto;
scrollbar-color: #ffffff rgba(0, 0, 0, 0.1);
}
/* Chrome, Edge, and Safari */
*::-webkit-scrollbar {
width: 8px;
}
*::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0);
}
*::-webkit-scrollbar-thumb {
background-color: #ffffff;
border-radius: 10px;
border: 3px none #ffffff;
}

View File

@ -0,0 +1,54 @@
import React, { useContext, useEffect, useState } from 'react';
import NameInput from './NameInput/NameInput';
import { SocketContext } from '../../App';
import './LoginPage.css';
import userImage from '../../images/login-page/user.png';
const LoginPage = () => {
const socket = useContext(SocketContext);
const [rooms, setRooms] = useState([]);
const [selectedRoom, setSelectedRoom] = useState(null);
useEffect(async () => {
socket.emit('room:rooms');
socket.on('room:rooms', data => {
data = JSON.parse(data);
console.log(data);
setRooms(data);
});
}, []);
return (
<div className='login-page-container'>
<h1>Select room:</h1>
<div className='rooms'>
{rooms.map(room => {
return (
<div
className={selectedRoom && selectedRoom == room._id ? 'room-selected room' : 'room'}
onClick={() => {
if (selectedRoom && selectedRoom == room._id) {
setSelectedRoom(null);
} else {
setSelectedRoom(room._id);
}
}}
key={room.id}
>
<div>
<p>{room.name}</p>
{room.players.map(player => player.name + ' ')}
</div>
<div className='number-of-players'>
<img src={userImage} alt='' />
<span> {room.players.length}/4 </span>
</div>
</div>
);
})}
</div>
<NameInput />
</div>
);
};
export default LoginPage;

View File

@ -0,0 +1,47 @@
.name-input-container {
display: flex;
position: absolute;
bottom: 0;
flex-direction: row;
width: 80%;
margin: 20px;
}
input,
button {
padding: 0;
border: none;
outline: none;
box-sizing: border-box;
}
input {
width: 100%;
padding: 12px;
font-size: 16px;
border-radius: 8px;
color: white;
border: 1px solid #ccc;
background-color: rgba(0, 0, 0, 0.5);
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
}
input:focus {
color: black;
border-color: #4a90e2;
background-color: #fff;
}
button {
padding: 12px 20px;
font-size: 16px;
border-radius: 8px;
border: none;
color: #fff;
background-color: rgba(0, 0, 0, 0.5);
cursor: pointer;
transition: background-color 0.3s ease-in-out;
}
button:hover {
background-color: rgba(0, 0, 0, 1);
}

View File

@ -0,0 +1,21 @@
import React, { useState, useContext } from 'react';
import { SocketContext } from '../../../App';
import './NameInput.css';
const NameInput = () => {
const socket = useContext(SocketContext);
const [inputValue, setInputValue] = useState('');
const handleInputChange = e => {
setInputValue(e.target.value);
};
const handleButtonClick = () => {
socket.emit('player:login', { name: inputValue });
};
return (
<div className="name-input-container">
<input placeholder='Enter name' type='text' onChange={handleInputChange} />
<button onClick={handleButtonClick}>JOIN</button>
</div>
);
};
export default NameInput;

View File

@ -1,25 +0,0 @@
import React, { useState, useContext } from "react";
import { SocketContext } from "../App";
const NameInput = () => {
const socket = useContext(SocketContext);
const [inputValue, setInputValue] = useState("");
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
const handleButtonClick = () => {
socket.emit("player:login", { name: inputValue });
};
return (
<div>
<input
placeholder="Enter name"
type="text"
onChange={handleInputChange}
/>
<input type="submit" onClick={handleButtonClick} />
</div>
);
};
export default NameInput;

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB