Adds register page.

This commit is contained in:
2022-06-05 16:15:01 +02:00
parent 65d2dece55
commit 6efccd631d
11 changed files with 316 additions and 77 deletions

View File

@@ -5,6 +5,7 @@ import Login from './components/Login';
import Gamenights from './components/Gamenights';
import Gamenight from './components/Gamenight';
import AdminPanel from './components/AdminPanel';
import Register from './components/Register';
import { get_gamenights, get_games, unpack_api_result, login } from './api/Api';
@@ -21,20 +22,21 @@ function App() {
const handleLogin = (input) => {
unpack_api_result(login(input), setFlashData)
.then(result => {
setUser(result.user);
localStorage.setItem(localStorageUserKey, JSON.stringify(result.user));
})
.then(() => setAppState('LoggedIn'))
if(result !== undefined) {
setUser(result.user);
localStorage.setItem(localStorageUserKey, JSON.stringify(result.user));
setAppState('LoggedIn')
}
});
};
useEffect(() => {
if(activeGamenightId !== null) {
setAppState('GamenightDetails');
} else {
setAppState('LoggedIn')
setAppState(user === null ? 'LoggedOut' : 'LoggedIn')
}
}, [activeGamenightId])
}, [activeGamenightId, user])
const onLogout = () => {
setUser(null);
@@ -50,8 +52,16 @@ function App() {
setAppState('UserPage')
}
const onRegister = () => {
setAppState('RegisterPage')
}
const onReset = () => {
setAppState('LoggedIn')
setAppState(user === null ? 'LoggedOut' : 'LoggedIn')
}
const onRegistered = (user) => {
setUser(user);
}
const setFlash = (data) => {
@@ -59,20 +69,28 @@ function App() {
};
const refetchGamenights = () => {
setUser({...user});
unpack_api_result(get_gamenights(user.jwt), setFlashData)
.then(result => {
if (result !== undefined) {
setGamenights(result.gamenights);
}
});
};
useEffect(() => {
if (appState === 'LoggedIn') {
unpack_api_result(get_gamenights(user.jwt), setFlashData)
.then(result => setGamenights(result.gamenights));
refetchGamenights()
}
}, [appState])
useEffect(() => {
if (appState === 'LoggedIn') {
unpack_api_result(get_games(user.jwt), setFlashData)
.then(result => setGames(result.games));
.then(result => {
if (result !== undefined) {
setGames(result.games)
}
});
}
}, [appState])
@@ -82,12 +100,22 @@ function App() {
let mainview;
if(appState === 'LoggedOut') {
return (
mainview = (
<div className="App">
<Login onChange={handleLogin}/>
</div>
);
} else if(appState === 'GamenightDetails') {
} else if(appState === 'RegisterPage') {
mainview = (
<Register
onRegistered={onRegistered}
setFlash={setFlash}/>
);
} else if(appState === 'UserPage') {
mainview = (
<span>UserPage</span>
)
}else if(appState === 'GamenightDetails') {
mainview = (
<Gamenight
gamenightId={activeGamenightId}
@@ -117,6 +145,7 @@ function App() {
<MenuBar
user={user}
onUser={onUser}
onRegister={onRegister}
onAdmin={onAdmin}
onLogout={onLogout}
onReset={onReset}/>

View File

@@ -2,21 +2,18 @@
import fetchResource from './FetchResource'
export function unpack_api_result(promise, onError) {
promise.then(result => {
return promise.then(result => {
if(result.result !== 'Ok') {
onError({
type: 'Error',
message: result.message
});
throw new Error(result.message);
}
return result;
})
.catch(error => {
onError({
onError({
type: 'Error',
message: `${error.status} ${error.message}`
message: `${error.status === null ?? error.status} ${error.message}`
});
});
return promise;
});
}
export function get_gamenights(token) {
@@ -116,4 +113,14 @@ export function delete_registration_token(token, registration_token_id) {
'Authorization': `Bearer ${token}`,
}
});
}
export function register(registration_token, input) {
return fetchResource(`api/register/${registration_token}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(input)
});
}

View File

@@ -47,11 +47,13 @@ function AddGameNight(props) {
unpack_api_result(post_gamenight(input, props.user.jwt), props.setFlash)
.then(result => {
setExpanded(false);
setGameName("");
setDate(null);
if(result !== undefined) {
setExpanded(false);
setGameName("");
setDate(null);
}
})
.then(() => props.refetchGamenights())
.then(() => props.refetchGamenights());
}
};

View File

@@ -38,14 +38,22 @@ function AdminPanel(props) {
const refetchTokens = () => {
if(props.user !== null) {
unpack_api_result(get_registration_tokens(props.user.jwt), props.setFlash)
.then(result => setRegistrationTokens(result.registration_tokens));
}
.then(result => {
if(result !== undefined) {
setRegistrationTokens(result.registration_tokens);
}
});
}
}
const deleteToken = (id) => {
if(props.user !== null) {
unpack_api_result(delete_registration_token(props.user.jwt, id), props.setFlash)
.then(() => refetchTokens())
.then(result => {
if(result !== undefined) {
refetchTokens();
}
});
}
}
@@ -57,7 +65,11 @@ function AdminPanel(props) {
if(props.user !== null) {
unpack_api_result(add_registration_token(props.user.jwt, input), props.setFlash)
.then(() => refetchTokens())
.then(result => {
if(result !== undefined) {
refetchTokens();
}
});
}
}
@@ -92,7 +104,7 @@ function AdminPanel(props) {
<div className="Add-GameNight">
<form autoComplete="off" onSubmit={e => { e.preventDefault(); }}>
<DateTimePicker
label="Gamenight date and time"
label="Token expires at"
variant="standard"
value={expires}
onChange={setExpires}
@@ -153,8 +165,8 @@ function AdminPanel(props) {
e.stopPropagation();
deleteToken(row.id)
}}>
<DeleteIcon />
</IconButton>
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
);

View File

@@ -19,7 +19,11 @@ function Gamenight(props) {
const fetchGamenight = () => {
if (props.user !== null) {
unpack_api_result(get_gamenight(props.gamenightId, props.user.jwt), props.setFlash)
.then(result => setGamenight(result.gamenight));
.then(result => {
if(result !== undefined) {
setGamenight(result.gamenight);
}
});
}
}
@@ -51,7 +55,11 @@ function Gamenight(props) {
};
unpack_api_result(patch_gamenight(gamenight.id, input, props.user.jwt), props.setFlash)
.then(() => fetchGamenight());
.then(result => {
if(result !== undefined) {
fetchGamenight();
}
});
};
const Leave = () => {
@@ -60,7 +68,11 @@ function Gamenight(props) {
};
unpack_api_result(patch_gamenight(gamenight.id, input, props.user.jwt), props.setFlash)
.then(() => fetchGamenight());
.then(result => {
if(result !== undefined) {
fetchGamenight();
}
});
};
let join_or_leave_button;

View File

@@ -18,7 +18,12 @@ function Gamenights(props) {
if (props.user !== null) {
const input = { game_id: game_id };
unpack_api_result(delete_gamenight(input, props.user.jwt), props.setFlash)
.then(() => props.refetchGamenights());
.then(result => {
if(result !== undefined) {
console.log("hello?");
props.refetchGamenights();
}
});
}
}

View File

@@ -8,19 +8,13 @@ import MenuIcon from '@mui/icons-material/Menu';
function MenuBar(props) {
let adminPanelButton = null;
if (props.user?.role === 'Admin') {
adminPanelButton = (
<Button
color="inherit"
onClick={props.onAdmin}>
AdminPanel
</Button>
);
}
let userButton = null;
if (props.user != null) {
let logoutButton = null;
let adminPanelButton = null;
let registerButton = null;
if (props.user !== null) {
userButton = (
<Button
color="inherit"
@@ -28,6 +22,30 @@ function MenuBar(props) {
{props.user.username}
</Button>
);
logoutButton = (
<Button
color="inherit"
onClick={props.onLogout}>
Logout
</Button>
);
if (props.user.role === 'Admin') {
adminPanelButton = (
<Button
color="inherit"
onClick={props.onAdmin}>
AdminPanel
</Button>
);
}
} else {
registerButton = (
<Button
color="inherit"
onClick={props.onRegister}>
Register
</Button>
)
}
return (
@@ -50,12 +68,9 @@ function MenuBar(props) {
Gamenight!
</Typography>
{userButton !== null && userButton}
{registerButton !== null && registerButton}
{adminPanelButton !== null && adminPanelButton}
<Button
color="inherit"
onClick={props.onLogout}>
Logout
</Button>
{logoutButton !== null && logoutButton}
</Toolbar>
</AppBar>
);

View File

@@ -0,0 +1,98 @@
import {useState} from 'react';
import FormControl from '@mui/material/FormControl';
import Input from '@mui/material/Input';
import FormHelperText from '@mui/material/FormHelperText';
import Button from '@mui/material/Button';
import {register, unpack_api_result} from '../api/Api';
function Register(props) {
const [registrationToken, setRegistrationToken] = useState("");
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [passwordRepeat, setPasswordRepeat] = useState("");
const onRegister = () => {
let input = {
username,
email,
password,
password_repeat: passwordRepeat
}
unpack_api_result(register(registrationToken, input), props.setFlash)
.then(result => {
if(result !== undefined) {
props.onRegistered(result.user);
}
});
}
return (
<FormControl>
<Input
id="registration_token"
aria-describedby="registration_token-helper-text"
value={registrationToken}
onChange={(e) => {setRegistrationToken(e.target.value)}} />
<FormHelperText
id="registration_token-helper-text">
Registration token given by a gamenight admin
</FormHelperText>
<Input
id="username"
aria-describedby="email-helper-text"
value={username}
onChange={(e) => {setUsername(e.target.value)}} />
<FormHelperText
id="username-helper-text">
Username to display everywhere
</FormHelperText>
<Input
id="email"
aria-describedby="email-helper-text"
value={email}
onChange={(e) => {setEmail(e.target.value)}} />
<FormHelperText
id="email-helper-text">
E-mail used for notifications and password resets
</FormHelperText>
<Input
id="password"
type="password"
aria-describedby="password-helper-text"
value={password}
onChange={(e) => {setPassword(e.target.value)}} />
<FormHelperText
id="password-helper-text">
Password atleast 10 characters long
</FormHelperText>
<Input
id="password_repeat"
type="password"
aria-describedby="password_repeat-helper-text"
value={passwordRepeat}
onChange={(e) => {setPasswordRepeat(e.target.value)}} />
<FormHelperText
id="password_repeat-helper-text">
Confirm your password
</FormHelperText>
<Button
variant="outlined"
color="success"
onClick={onRegister}>
Register
</Button>
</FormControl>
);
}
export default Register;