Universal login and appbar improvements
This commit is contained in:
parent
cef7cfd1a7
commit
2c06a8adb2
|
@ -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 showSuccess = (message) => {};
|
||||||
let showError = (message) => {};
|
let showError = (message) => {};
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [user, setUser] = React.useState({});
|
const [user, setUser] = React.useState({});
|
||||||
let checkLogin = () => {
|
let fetchUser = () => {
|
||||||
fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`)
|
fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.status !== "OK") {
|
if (data.status !== "OK") {
|
||||||
setUser({ isManager: false, isLoggedIn: false });
|
setUser({ isManager: false, isLoggedIn: false });
|
||||||
console.log(data.data);
|
console.log(data.data); // "No user logged in"
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let u = data.data;
|
let u = data.data;
|
||||||
|
@ -255,7 +225,7 @@ export default function App() {
|
||||||
}
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
checkLogin();
|
fetchUser();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [openError, setOpenError] = React.useState(false);
|
const [openError, setOpenError] = React.useState(false);
|
||||||
|
|
|
@ -6,12 +6,20 @@ import ErrorSnackbar from "./components/ErrorSnackbar";
|
||||||
import {Button, Textfield, Stack, InputLabel, Paper, Typography} from '@mui/material';
|
import {Button, Textfield, Stack, InputLabel, Paper, Typography} from '@mui/material';
|
||||||
|
|
||||||
export default function LoginPage(props) {
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<Appbar user={props.user} pageTitle="Sign in" />
|
<Appbar user={props.user} pageTitle="Login" />
|
||||||
<Paper x={{width: "70vw", margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
|
<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'}>
|
<Stack direction="column" paddingTop={'0.5%'} alignItems={'center'}>
|
||||||
<Typography>Sign in with google</Typography>
|
|
||||||
<a href={process.env.REACT_APP_LOGIN_URL}>
|
<a href={process.env.REACT_APP_LOGIN_URL}>
|
||||||
<img src="/btn_google_signing_dark.png" alt="Sign in with google" />
|
<img src="/btn_google_signing_dark.png" alt="Sign in with google" />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||||
import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown';
|
import KeyboardDoubleArrowDownIcon from '@mui/icons-material/KeyboardDoubleArrowDown';
|
||||||
import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp';
|
import KeyboardDoubleArrowUpIcon from '@mui/icons-material/KeyboardDoubleArrowUp';
|
||||||
import Appbar from './components/AsuraBar';
|
import Appbar from './components/AsuraBar';
|
||||||
|
import LoginPage from './LoginPage';
|
||||||
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
|
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,16 +144,17 @@ function shorten(description, maxLength) {
|
||||||
</>;
|
</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TournamentHistory() {
|
export default function TournamentHistory(props) {
|
||||||
return (
|
if (!props.user.isLoggedIn) { return <LoginPage user={props.user} />; }
|
||||||
<>
|
return (
|
||||||
<Appbar pageTitle="Tournament History" />
|
<>
|
||||||
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
<Appbar user={props.user} pageTitle="Tournament History" />
|
||||||
<Box component={Stack} direction="row" align="center" justifyContent="space-between" alignItems="center" sx={{flexGrow: 1}}>
|
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
||||||
<Typography variant="h3">Past Tournaments</Typography>
|
<Box component={Stack} direction="row" align="center" justifyContent="space-between" alignItems="center" sx={{flexGrow: 1}}>
|
||||||
</Box>
|
<Typography variant="h3">Past Tournaments</Typography>
|
||||||
<TournamentList />
|
</Box>
|
||||||
</Container>
|
<TournamentList />
|
||||||
</>
|
</Container>
|
||||||
);
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
|
||||||
// import { AlertContainer, alert } from "react-custom-alert";
|
// import { AlertContainer, alert } from "react-custom-alert";
|
||||||
import Appbar from "./components/AsuraBar";
|
import Appbar from "./components/AsuraBar";
|
||||||
import TournamentBar from "./components/TournamentBar";
|
import TournamentBar from "./components/TournamentBar";
|
||||||
|
import LoginPage from "./LoginPage";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { Button, TextField, Grid, Box, Container, Paper, Stack } from "@mui/material";
|
import { Button, TextField, Grid, Box, Container, Paper, Stack } from "@mui/material";
|
||||||
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
|
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
|
||||||
|
@ -220,6 +221,11 @@ export default function TournamentManager(props) {
|
||||||
|
|
||||||
showError = props.showError;
|
showError = props.showError;
|
||||||
showSuccess = props.showSuccess;
|
showSuccess = props.showSuccess;
|
||||||
|
|
||||||
|
if (!props.user.isLoggedIn) {
|
||||||
|
return <LoginPage user={props.user} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Appbar user={props.user} pageTitle="Edit Tournament" />
|
<Appbar user={props.user} pageTitle="Edit Tournament" />
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import Appbar from './components/AsuraBar';
|
import Appbar from './components/AsuraBar';
|
||||||
import TournamentBar from "./components/TournamentBar";
|
import TournamentBar from "./components/TournamentBar";
|
||||||
|
import ErrorSnackbar from "./components/ErrorSnackbar";
|
||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
import { Button, IconButton, Paper, Stack, CircularProgress, Box, Grid, Typography, Container } from "@mui/material";
|
import { Button, IconButton, Paper, Stack, CircularProgress, Box, Grid, Typography, Container } from "@mui/material";
|
||||||
import "./components/tournamentBracket.css";
|
import "./components/tournamentBracket.css";
|
||||||
|
@ -10,17 +11,11 @@ import DoDisturbIcon from '@mui/icons-material/DoDisturb';
|
||||||
import BackspaceIcon from '@mui/icons-material/Backspace';
|
import BackspaceIcon from '@mui/icons-material/Backspace';
|
||||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||||
|
|
||||||
|
|
||||||
function showError(error) {
|
|
||||||
alert("Something went wrong. \n" + error);
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
function TournamentTier(props){
|
function TournamentTier(props){
|
||||||
let roundTypes = ["winner","finals", "semifinals", "quarterfinals", "eighthfinals", "sixteenthfinals", "thirtysecondfinals"];
|
let roundTypes = ["winner","finals", "semifinals", "quarterfinals", "eighthfinals", "sixteenthfinals", "thirtysecondfinals"];
|
||||||
let matches = [];
|
let matches = [];
|
||||||
for (let i = 0; i < props.matches.length; i++) {
|
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(
|
return(
|
||||||
<ul className={`round ${roundTypes[props.tier]}`}>
|
<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'}}>
|
<Typography className={`teamName`} align={'center'} sx={{fontSize:'1.5rem', maxWidth:'15vw', overflow:'hidden', wordWrap:'none'}}>
|
||||||
{team1Name}
|
{team1Name}
|
||||||
</Typography>
|
</Typography>
|
||||||
{ props.match.team1Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === 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> : null
|
<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 ?
|
{ 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> : null
|
<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) &&
|
{/* { props.match.winnerId && (props.match.team1Id === props.match.winnerId) &&
|
||||||
<EmojiEventsIcon alt="A trohpy" color="gold" />
|
<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'}}>
|
<Typography className={`teamName`} sx={{fontSize:'1.5rem', maxWidth:'15vw', overflow:'hidden', wordWrap:'none'}}>
|
||||||
{team2Name}
|
{team2Name}
|
||||||
</Typography>
|
</Typography>
|
||||||
{ props.match.team2Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === 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> : null
|
<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 ?
|
{ 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> : null
|
<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) &&
|
{/* { props.match.winnerId && (props.match.team2Id === props.match.winnerId) &&
|
||||||
<EmojiEventsIcon alt="A trohpy" color="gold" />
|
<EmojiEventsIcon alt="A trohpy" color="gold" />
|
||||||
|
@ -177,17 +172,26 @@ function BracketViewer(props){
|
||||||
<div className="bracket">
|
<div className="bracket">
|
||||||
{matches.map(tier => {
|
{matches.map(tier => {
|
||||||
let tierNum = tier[0].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>
|
</div>
|
||||||
: <Box sx={{display:'flex', justifyContent:'center', alignItems:'center', position:'relative', marginTop:'5%'}}><CircularProgress size={"20vw"}/></Box>
|
: <Box sx={{display:'flex', justifyContent:'center', alignItems:'center', position:'relative', marginTop:'5%'}}><CircularProgress size={"20vw"}/></Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let showError = (message) => {};
|
||||||
export default function TournamentOverview(props) {
|
export default function TournamentOverview(props) {
|
||||||
const { tournamentId } = useParams();
|
const { tournamentId } = useParams();
|
||||||
const [tournament, setTournament] = React.useState(false);
|
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(() => {
|
React.useEffect(() => {
|
||||||
fetch(process.env.REACT_APP_API_URL + `/tournament/${tournamentId}`)
|
fetch(process.env.REACT_APP_API_URL + `/tournament/${tournamentId}`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
|
@ -208,10 +212,10 @@ export default function TournamentOverview(props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Appbar user={props.user} pageTitle={tournament.name} />
|
<Appbar user={props.user} pageTitle={tournament.name} />
|
||||||
{ props.user.isLoggedIn && !tournament.hasEnded ?
|
{ props.user.isLoggedIn && !tournament.hasEnded &&
|
||||||
<TournamentBar tournamentId={tournamentId} viewTournament={true} /> : null
|
<TournamentBar tournamentId={tournamentId} viewTournament={true} />
|
||||||
}
|
}
|
||||||
<BracketViewer tournament={tournament} tournamentId={tournamentId} className="bracketViewer" />
|
<BracketViewer tournament={tournament} user={props.user} tournamentId={tournamentId} className="bracketViewer" />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as React from "react";
|
||||||
import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-router-dom";
|
import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-router-dom";
|
||||||
import Appbar from "./components/AsuraBar";
|
import Appbar from "./components/AsuraBar";
|
||||||
import TournamentBar from "./components/TournamentBar";
|
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 { 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 AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
@ -203,6 +204,8 @@ export default function TournamentTeams(props) {
|
||||||
getTeams()
|
getTeams()
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (!props.user.isLoggedIn) { return <LoginPage user={props.user} />; }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Appbar user={props.user} pageTitle="Edit teams" />
|
<Appbar user={props.user} pageTitle="Edit teams" />
|
||||||
|
|
|
@ -55,7 +55,9 @@ function NotLoggedInButton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Appbar(props) {
|
export default function Appbar(props) {
|
||||||
return (
|
console.log("Appbar-user:")
|
||||||
|
console.log(props.user);
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<AppBar position="static" color="primary">
|
<AppBar position="static" color="primary">
|
||||||
|
@ -79,7 +81,7 @@ export default function Appbar(props) {
|
||||||
<Grid item xs={8}>
|
<Grid item xs={8}>
|
||||||
<Typography component="div"><h2>{props.pageTitle || ""}</h2></Typography>
|
<Typography component="div"><h2>{props.pageTitle || ""}</h2></Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
{ props.pageTitle !== "Sign in" ?
|
{ props.pageTitle !== "Login" ?
|
||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
{ props.user.isLogggedIn ? <LoggedInMenu /> : <NotLoggedInButton /> }
|
{ props.user.isLogggedIn ? <LoggedInMenu /> : <NotLoggedInButton /> }
|
||||||
</Grid> :
|
</Grid> :
|
||||||
|
@ -91,5 +93,5 @@ export default function Appbar(props) {
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -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>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
|
export default function NoUserPage(props) {
|
||||||
|
return ("Skjerp deg")
|
||||||
|
}
|
Loading…
Reference in New Issue