I have a simple project where you start at a register page which has validation checks. When you finally register you should have your session saved (not implemented yet, should be done with React locally I think) and go to another page where you can play tic tac toe.
I have the register page and the tic tac toe page. I’m pretty new to React. I’m just trying to practice by implementing it with React, but I can’t get it to work. And I’m still puzzled about the local session saving and I’m not quite sure how to do that either.
Code:
REGISTER PAGE:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script type="text/javascript" src="script.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
<title>Project</title>
</head>
<body>
<div id="error" class="noerror"></div>
<div class="container">
<form onsubmit="return validate()" action="tictactoe.html" method="post" class="regform">
<span class="registration">Registration</span>
<input type="user" id="user" name="user" placeholder="Username">
<input type="password" id="password" name="password" placeholder="Password">
<input type="password" id="password2" name="password2" placeholder="Confirm password">
<input type="submit" id="submit" value="Register">
</form>
</div>
</body>
</html>
styles.css:
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 95vh;
}
.regform {
display: flex;
flex-flow: column wrap;
width: 400px;
padding: 20px;
background-color: whitesmoke;
border: 1px solid black;
}
.registration {
background-color: yellowgreen;
color: white;
text-align: center;
padding: 10px;
margin: -21px -21px 10px -21px;
text-transform: uppercase;
font-weight: bold;
}
.error {
word-wrap: normal;
background-color: orangered;
font-weight: bold;
text-align: center;
padding: 10px;
margin-left: 5%;
margin-right: 5%;
}
.noerror {
display: hidden;
}
input {
padding: 10px;
margin: 10px 0px;
border: 1px solid lightgrey;
}
input#submit {
background-color: yellowgreen;
color: white;
}
* {
font-family: Arial, Helvetica, sans-serif;
}
script.js:
function validate() {
var user = document.getElementById('user').value;
var pass = document.getElementById('password').value;
var pass2 = document.getElementById('password2').value;
if(!/^[a-zA-Z0-9_]{3,16}$/.test(user)) {
var msg = 'Username must be between 3 and 16 symbols. Can only contain lowercase and uppercase letters, one number and "_"!';
showError(msg);
return false;
}
if(!/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,256}$/.test(pass)) {
var msg = 'Password must be between 8 and 256 symbols. Must contain atleast one lowercase and uppercase letter, one number and one symbol!';
showError(msg);
return false;
}
if(pass != pass2) {
var msg = 'Passwords must match.';
showError(msg);
return false;
}
}
function showError(msg) {
document.getElementById('error').innerHTML = msg;
document.getElementById('error').classList.add('error');
document.getElementById('error').classList.remove('noerror');
}
TIC TAC TOE PAGE:
tictactoe_script.js:
var x = '10006';
var o = '9898';
var firstPlayerMove;
var gameWon;
var moves;
function showMsg(msg) {
document.getElementById("msg").innerHTML = msg;
}
function setup() {
firstPlayerMove = true;
gameWon = false;
moves = 0;
showMsg("It's X's turn.");
}
function restart() {
Array.prototype.forEach.call(document.getElementsByClassName("tile"), function(element) {
element.innerHTML = "";
});
setup();
}
function makeMove(tile) {
if(gameWon) {
return false;
}
if(isValidMove(tile)) {
moves++;
if(firstPlayerMove) {
tile.innerHTML = '&#' + x + ';';
}
else {
tile.innerHTML = '&#' + o + ';';
}
if(checkWin()) {
return true;
}
if(moves == 9) {
showMsg("Draw.");
return true;
}
firstPlayerMove = !firstPlayerMove;
if(firstPlayerMove) {
showMsg("It's X's turn.");
}
else {
showMsg("It's O's turn.");
}
}
}
function isValidMove(tile) {
return tile.innerHTML === '';
}
function checkWin() {
var tiles = document.getElementsByClassName("tile");
var xTiles = new Array(9);
var oTiles = new Array(9);
for(var i = 0; i < tiles.length; i++) {
if(tiles[i].innerHTML === String.fromCharCode(x)) {
xTiles[i] = 1;
}
if(tiles[i].innerHTML === String.fromCharCode(o)) {
oTiles[i] = 1;
}
}
if(hasWinningPattern(xTiles)) {
showMsg("Player 1 (X) won.");
return true;
}
if(hasWinningPattern(oTiles)) {
showMsg("Player 2 (O) won.");
return true;
}
return false;
}
function hasWinningPattern(tiles) {
var winningPatterns = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for(var i = 0; i < winningPatterns.length; i++) {
var pattern = winningPatterns[i];
var win = true;
for(var j = 0; j < pattern.length; j++) {
if(tiles[pattern[j]] != 1) {
win = false;
}
}
if(win) {
gameWon = true;
return true;
}
}
return false;
}
tictactoe_styles.css:
.board, .start, .msg {
position: absolute;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.board {
margin-top: 110px;
width: 600px;
height: 600px;
border: 1px solid lightgrey;
font-size: 0px;
max-width: 100%;
max-height: 100%;
}
.row {
width: 600px;
height: 200px;
font-size: 0px;
}
.tile {
border: 1px solid lightgrey;
width: 198px;
height: 200px;
display: inline-block;
font-size: 150px;
text-align: center;
vertical-align: middle;
line-height: 200px;
}
.tile:hover {
background-color: grey;
}
.start {
width: 100px;
height: 50px;
margin-top: 50px;
}
.msg {
width: 300px;
height: 50px;
margin-top: 10px;
font-size: 32px;
font-weight: bold;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}
tictactoe.html:
<html>
<head>
<meta charset="UTF-8" />
<title>Project</title>
<link rel="stylesheet" type="text/css" href="tictactoe_styles.css">
<script src="tictactoe_script.js"></script>
</head>
<body onload="setup()">
<button onclick="restart()" class="start">Restart</button>
<div class="board">
<div class="row">
<div onclick="makeMove(this)" class="tile"></div>
<div onclick="makeMove(this)" class="tile"></div>
<div onclick="makeMove(this)" class="tile"></div>
</div>
<div class="row">
<div onclick="makeMove(this)" class="tile"></div>
<div onclick="makeMove(this)" class="tile"></div>
<div onclick="makeMove(this)" class="tile"></div>
</div>
<div class="row">
<div onclick="makeMove(this)" class="tile"></div>
<div onclick="makeMove(this)" class="tile"></div>
<div onclick="makeMove(this)" class="tile"></div>
</div>
</div>
<div class="msg" id="msg"></div>
</body>
</html>
This is all of the code and it works fine. Here is how I tried to implement the register page on react but failed:
index.js:
//import React, { Fragment } from 'react';
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
//import App from './App';
import reportWebVitals from './reportWebVitals';
import { useState } from 'react';
function Register() {
const[msg, setMessage] = useState('');
const [user, setUser] = useState('');
const [pass, setPass] = useState('');
const [pass2, setPass2] = useState('');
function validate() {
if(!/^[a-zA-Z0-9_]{3,16}$/.test(user)) {
setMessage('Username must be between 3 and 16 symbols. Can only contain lowercase and uppercase letters, one number and "_"!');
}
if(!/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,256}$/.test(pass)) {
setMessage('Password must be between 8 and 256 symbols. Must contain atleast one lowercase and uppercase letter, one number and one symbol!');
}
if(pass !== pass2) {
setMessage('Passwords must match.');
}
}
return (<>
<div class="container">
<div id="error" class="error">{msg}</div>
<span class="registration">Registration</span>
<input onchange={()=>setUser} type="user" id="user" name="user" placeholder="Username"/>
<input onchange={()=>setPass} type="password" id="password" name="password" placeholder="Password"/>
<input onchange={()=>setPass2} type="password" id="password2" name="password2" placeholder="Repeat Password"/>
<input onchange={()=>validate()} type="button" id="submit" value="Register"/>
</div>
</>)
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Register/>
);
If someone could help me implement the code in React that would be great! Any help is greatly appreciated! Thanks in advance!