Universal login and appbar improvements

This commit is contained in:
Felix Albrigtsen 2022-04-24 13:01:19 +02:00
parent cef7cfd1a7
commit 2c06a8adb2
10 changed files with 89 additions and 70 deletions

View File

@ -199,48 +199,18 @@ function Home(props) {
}
// class LoginManager {
// checkLogin() {
// fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`)
// .then(res => res.json())
// .then(data => {
// if (data.status !== "OK") {
// console.error(data.data);
// return;
// }
// console.log(data);
// setUser(data.data);
// return user;
// })
// .catch((err) => console.log(err.message));
// }
// isLoggedIn() {
// let loggedIn = user.googleId !== "" && user.asuraId !== -1;
// console.log(loggedIn);
// return loggedIn;
// }
// isManager() {
// return this.isLoggedIn() && user.isManager;
// }
// }
// let login = new LoginManager();
// login.checkLogin();
let showSuccess = (message) => {};
let showError = (message) => {};
export default function App() {
const [user, setUser] = React.useState({});
let checkLogin = () => {
let fetchUser = () => {
fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`)
.then(res => res.json())
.then(data => {
if (data.status !== "OK") {
setUser({ isManager: false, isLoggedIn: false });
console.log(data.data);
console.log(data.data); // "No user logged in"
return;
}
let u = data.data;
@ -255,7 +225,7 @@ export default function App() {
}
React.useEffect(() => {
checkLogin();
fetchUser();
}, []);
const [openError, setOpenError] = React.useState(false);

View File

@ -6,12 +6,20 @@ import ErrorSnackbar from "./components/ErrorSnackbar";
import {Button, Textfield, Stack, InputLabel, Paper, Typography} from '@mui/material';
export default function LoginPage(props) {
if (props.user.isLoggedIn) {
//Redirect to the front page if the user is logged in
window.location.href = "/";
return;
}
return (
<>
<Appbar user={props.user} pageTitle="Sign in" />
<Paper x={{width: "70vw", margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
<Appbar user={props.user} pageTitle="Login" />
<Paper sx={{width: "70vw", margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
<Typography variant="h4" component="h4">
You must be logged in to access administrator features.
</Typography>
<Stack direction="column" paddingTop={'0.5%'} alignItems={'center'}>
<Typography>Sign in with google</Typography>
<a href={process.env.REACT_APP_LOGIN_URL}>
<img src="/btn_google_signing_dark.png" alt="Sign in with google" />
</a>

View File

@ -5,6 +5,7 @@ import AddCircleIcon from '@mui/icons-material/AddCircle';
import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown';
import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp';
import Appbar from './components/AsuraBar';
import LoginPage from './LoginPage';
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
@ -143,10 +144,11 @@ function shorten(description, maxLength) {
</>;
}
export default function TournamentHistory() {
export default function TournamentHistory(props) {
if (!props.user.isLoggedIn) { return <LoginPage user={props.user} />; }
return (
<>
<Appbar pageTitle="Tournament History" />
<Appbar user={props.user} pageTitle="Tournament History" />
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
<Box component={Stack} direction="row" align="center" justifyContent="space-between" alignItems="center" sx={{flexGrow: 1}}>
<Typography variant="h3">Past Tournaments</Typography>

View File

@ -3,6 +3,7 @@ import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
// import { AlertContainer, alert } from "react-custom-alert";
import Appbar from "./components/AsuraBar";
import TournamentBar from "./components/TournamentBar";
import LoginPage from "./LoginPage";
import { useParams } from "react-router-dom";
import { Button, TextField, Grid, Box, Container, Paper, Stack } from "@mui/material";
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
@ -220,6 +221,11 @@ export default function TournamentManager(props) {
showError = props.showError;
showSuccess = props.showSuccess;
if (!props.user.isLoggedIn) {
return <LoginPage user={props.user} />;
}
return (
<>
<Appbar user={props.user} pageTitle="Edit Tournament" />

View File

@ -2,6 +2,7 @@ import * as React from "react";
import { Link } from "react-router-dom";
import Appbar from './components/AsuraBar';
import TournamentBar from "./components/TournamentBar";
import ErrorSnackbar from "./components/ErrorSnackbar";
import { useParams } from 'react-router-dom'
import { Button, IconButton, Paper, Stack, CircularProgress, Box, Grid, Typography, Container } from "@mui/material";
import "./components/tournamentBracket.css";
@ -10,17 +11,11 @@ import DoDisturbIcon from '@mui/icons-material/DoDisturb';
import BackspaceIcon from '@mui/icons-material/Backspace';
import AddCircleIcon from '@mui/icons-material/AddCircle';
function showError(error) {
alert("Something went wrong. \n" + error);
console.error(error);
}
function TournamentTier(props){
let roundTypes = ["winner","finals", "semifinals", "quarterfinals", "eighthfinals", "sixteenthfinals", "thirtysecondfinals"];
let matches = [];
for (let i = 0; i < props.matches.length; i++) {
matches.push(<Match tournament={props.tournament} teams={props.teams} match={props.matches[i]} key={i} />);
matches.push(<Match tournament={props.tournament} user={props.user} teams={props.teams} match={props.matches[i]} key={i} />);
}
return(
<ul className={`round ${roundTypes[props.tier]}`}>
@ -94,11 +89,11 @@ function Match(props){
<Typography className={`teamName`} align={'center'} sx={{fontSize:'1.5rem', maxWidth:'15vw', overflow:'hidden', wordWrap:'none'}}>
{team1Name}
</Typography>
{ props.match.team1Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null ?
<IconButton color="error" aria-label="remmove winner" component="span" onClick={curryUnsetContestant(props.match.team1Id)}><BackspaceIcon /></IconButton> : null
{ props.match.team1Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn &&
<IconButton color="error" aria-label="remmove winner" component="span" onClick={curryUnsetContestant(props.match.team1Id)}><BackspaceIcon /></IconButton>
}
{ props.match.team1Id !== null && props.match.winnerId === null && !props.tournament.hasEnded ?
<IconButton onClick={setWinner(props.match.team1Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon /></IconButton> : null
{ props.match.team1Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn &&
<IconButton onClick={setWinner(props.match.team1Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon /></IconButton>
}
{/* { props.match.winnerId && (props.match.team1Id === props.match.winnerId) &&
<EmojiEventsIcon alt="A trohpy" color="gold" />
@ -112,11 +107,11 @@ function Match(props){
<Typography className={`teamName`} sx={{fontSize:'1.5rem', maxWidth:'15vw', overflow:'hidden', wordWrap:'none'}}>
{team2Name}
</Typography>
{ props.match.team2Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null ?
<IconButton color="error" aria-label="remmove winner" component="span" onClick={curryUnsetContestant(props.match.team2Id)}><BackspaceIcon /></IconButton> : null
{ props.match.team2Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn &&
<IconButton color="error" aria-label="remmove winner" component="span" onClick={curryUnsetContestant(props.match.team2Id)}><BackspaceIcon /></IconButton>
}
{ props.match.team2Id !== null && props.match.winnerId === null && !props.tournament.hasEnded ?
<IconButton onClick={setWinner(props.match.team2Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon /></IconButton> : null
{ props.match.team2Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn &&
<IconButton onClick={setWinner(props.match.team2Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon /></IconButton>
}
{/* { props.match.winnerId && (props.match.team2Id === props.match.winnerId) &&
<EmojiEventsIcon alt="A trohpy" color="gold" />
@ -177,17 +172,26 @@ function BracketViewer(props){
<div className="bracket">
{matches.map(tier => {
let tierNum = tier[0].tier;
return <TournamentTier tournament={props.tournament} key={tierNum} tier={tierNum} matches={tier} teams={teams} />
return <TournamentTier user={props.user} tournament={props.tournament} key={tierNum} tier={tierNum} matches={tier} teams={teams} />
})}
</div>
: <Box sx={{display:'flex', justifyContent:'center', alignItems:'center', position:'relative', marginTop:'5%'}}><CircularProgress size={"20vw"}/></Box>
);
}
let showError = (message) => {};
export default function TournamentOverview(props) {
const { tournamentId } = useParams();
const [tournament, setTournament] = React.useState(false);
const [openError, setOpenError] = React.useState(false);
const [errorMessage, setErrorMessage] = React.useState("");
showError = (message) => {
setOpenError(false);
setErrorMessage(message);
setOpenError(true);
}
React.useEffect(() => {
fetch(process.env.REACT_APP_API_URL + `/tournament/${tournamentId}`)
.then(res => res.json())
@ -208,10 +212,10 @@ export default function TournamentOverview(props) {
return (
<>
<Appbar user={props.user} pageTitle={tournament.name} />
{ props.user.isLoggedIn && !tournament.hasEnded ?
<TournamentBar tournamentId={tournamentId} viewTournament={true} /> : null
{ props.user.isLoggedIn && !tournament.hasEnded &&
<TournamentBar tournamentId={tournamentId} viewTournament={true} />
}
<BracketViewer tournament={tournament} tournamentId={tournamentId} className="bracketViewer" />
<BracketViewer tournament={tournament} user={props.user} tournamentId={tournamentId} className="bracketViewer" />
</>
);
}

View File

@ -2,6 +2,7 @@ import * as React from "react";
import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-router-dom";
import Appbar from "./components/AsuraBar";
import TournamentBar from "./components/TournamentBar";
import LoginPage from "./LoginPage";
import { Button, TextField, Stack, MenuItem, Box, InputLabel, Select, Container, TableContainer, Table, TableBody, TableHead, TableCell, TableRow, Paper, Typography} from "@mui/material";
import AddCircleIcon from '@mui/icons-material/AddCircle';
import DeleteIcon from '@mui/icons-material/Delete';
@ -203,6 +204,8 @@ export default function TournamentTeams(props) {
getTeams()
}, []);
if (!props.user.isLoggedIn) { return <LoginPage user={props.user} />; }
return (
<>
<Appbar user={props.user} pageTitle="Edit teams" />

View File

@ -55,6 +55,8 @@ function NotLoggedInButton() {
}
export default function Appbar(props) {
console.log("Appbar-user:")
console.log(props.user);
return (
<>
<CssBaseline />
@ -79,7 +81,7 @@ export default function Appbar(props) {
<Grid item xs={8}>
<Typography component="div"><h2>{props.pageTitle || ""}</h2></Typography>
</Grid>
{ props.pageTitle !== "Sign in" ?
{ props.pageTitle !== "Login" ?
<Grid item xs={2}>
{ props.user.isLogggedIn ? <LoggedInMenu /> : <NotLoggedInButton /> }
</Grid> :

View File

@ -0,0 +1,19 @@
import * as React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import { Typography } from '@mui/material'
export default function NoSuchPage() {
return(
<>
<Typography type="h3">
You are not logged in
</Typography>
<Typography type="h4">
You dont have access to this page, you can log in here: <Link to="/login">Login</Link>
</Typography>
<Link to="/">
Return to the home page
</Link>
</>
)
}

View File

@ -0,0 +1,5 @@
export default function NoUserPage(props) {
return ("Skjerp deg")
}