Teaching Assistant feedback + deployment
This commit is contained in:
parent
29f463f248
commit
e14db4b382
|
@ -4869,7 +4869,6 @@
|
|||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
|
@ -6117,8 +6116,7 @@
|
|||
"esprima": "^4.0.1",
|
||||
"estraverse": "^5.2.0",
|
||||
"esutils": "^2.0.2",
|
||||
"optionator": "^0.8.1",
|
||||
"source-map": "~0.6.1"
|
||||
"optionator": "^0.8.1"
|
||||
},
|
||||
"bin": {
|
||||
"escodegen": "bin/escodegen.js",
|
||||
|
@ -8726,7 +8724,6 @@
|
|||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"fsevents": "^2.3.2",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-regex-util": "^27.5.1",
|
||||
"jest-serializer": "^27.5.1",
|
||||
|
@ -10032,14 +10029,9 @@
|
|||
"integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==",
|
||||
"dependencies": {
|
||||
"copy-anything": "^2.0.1",
|
||||
"errno": "^0.1.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"image-size": "~0.5.0",
|
||||
"make-dir": "^2.1.0",
|
||||
"mime": "^1.4.1",
|
||||
"needle": "^2.5.2",
|
||||
"parse-node-version": "^1.0.1",
|
||||
"source-map": "~0.6.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -12415,7 +12407,6 @@
|
|||
"eslint-webpack-plugin": "^3.1.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"fsevents": "^2.3.2",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^27.4.3",
|
||||
|
@ -12835,9 +12826,6 @@
|
|||
"version": "2.70.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz",
|
||||
"integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==",
|
||||
"dependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
|
|
|
@ -114,7 +114,7 @@ function TournamentListItem(props) {
|
|||
|
||||
<Typography variant="h5" color="text.primary" gutterBottom> Particpants: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||
<Description />
|
||||
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trohpy" color="gold"/> Prize: {props.tournament.prize} </Typography>
|
||||
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trophy" color="gold"/> Prize: {props.tournament.prize} </Typography>
|
||||
<Countdown />
|
||||
|
||||
<Box sx={{flexGrow: 1, marginTop: "20px"}}>
|
||||
|
@ -205,36 +205,36 @@ let showError = (message) => {};
|
|||
|
||||
export default function App() {
|
||||
const [user, setUser] = React.useState({});
|
||||
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); // "No user logged in"
|
||||
return;
|
||||
}
|
||||
let u = data.data;
|
||||
u.isLoggedIn = true;
|
||||
console.log("User is logged in")
|
||||
setUser(u);
|
||||
})
|
||||
.catch((err) => {
|
||||
showError(err.message);
|
||||
setUser({ isManager: false, isLoggedIn: false });
|
||||
});
|
||||
}
|
||||
// // Debug mode, allow all:
|
||||
// let fetchUser = () => {
|
||||
// setUser({
|
||||
// name: "TEST USERTEST",
|
||||
// isManager: true,
|
||||
// isLoggedIn: true,
|
||||
// email: "testesen@gmail.com",
|
||||
// asuraId: "123456789",
|
||||
// googleId: "234"
|
||||
// });
|
||||
// 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); // "No user logged in"
|
||||
// return;
|
||||
// }
|
||||
// let u = data.data;
|
||||
// u.isLoggedIn = true;
|
||||
// console.log("User is logged in")
|
||||
// setUser(u);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// showError(err.message);
|
||||
// setUser({ isManager: false, isLoggedIn: false });
|
||||
// });
|
||||
// }
|
||||
// Debug mode, allow all:
|
||||
let fetchUser = () => {
|
||||
setUser({
|
||||
name: "TEST USERTEST",
|
||||
isManager: true,
|
||||
isLoggedIn: true,
|
||||
email: "testesen@gmail.com",
|
||||
asuraId: "123456789",
|
||||
googleId: "234"
|
||||
});
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
fetchUser();
|
||||
|
|
|
@ -56,7 +56,7 @@ function shorten(description, maxLength) {
|
|||
|
||||
<Typography variant="h5" color="text.primary" gutterBottom> Participants: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||
<Description />
|
||||
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trohpy" color="gold" align="vertical-center"/> Prize: {props.tournament.prize} </Typography>
|
||||
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trophy" color="gold" align="vertical-center"/> Prize: {props.tournament.prize} </Typography>
|
||||
|
||||
<Box sx={{flexGrow: 1, marginTop: "20px"}}>
|
||||
<Grid container spacing={4} justifyContent="center" wrap="wrap">
|
||||
|
@ -135,13 +135,13 @@ function shorten(description, maxLength) {
|
|||
}
|
||||
}
|
||||
|
||||
return <>
|
||||
<TextField type="text" id="searchInput" label="Search" placeholder="Tournament Name" InputLabelProps={{shrink: true}} onChange={search}/>
|
||||
return <Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px", alignContent:'center'}}>
|
||||
<TextField sx={{width: '50%', marginLeft: '25%', color: 'black', fontSize: '1.5em'}} size="large" type="text" id="searchInput" label="Search finished tournaments" placeholder="Tournament Name" InputLabelProps={{shrink: true}} onChange={search}/>
|
||||
<Stack spacing={3} sx={{margin: "10px auto"}}>
|
||||
{tournamentList && tournamentList.map((tournamentObject) => <TournamentListItem key={tournamentObject.id.toString()} tournament={tournamentObject} />)}
|
||||
</Stack>
|
||||
|
||||
</>;
|
||||
</Container>;
|
||||
}
|
||||
|
||||
export default function TournamentHistory(props) {
|
||||
|
@ -149,12 +149,7 @@ export default function TournamentHistory(props) {
|
|||
return (
|
||||
<>
|
||||
<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="center" alignItems="center" sx={{flexGrow: 1, margin:'2.5% 0'}}>
|
||||
<Typography sx={{fontSize:['1.5rem','2rem','2rem']}}>Past Tournaments</Typography>
|
||||
</Box>
|
||||
<TournamentList />
|
||||
</Container>
|
||||
<TournamentList />
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -91,7 +91,7 @@ function Match(props){
|
|||
{team1Name}
|
||||
</Typography>
|
||||
{ props.match.winnerId && (props.match.team1Id === props.match.winnerId) &&
|
||||
<EmojiEventsIcon alt="A trohpy" sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} />
|
||||
<EmojiEventsIcon alt="A trophy" sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} />
|
||||
}
|
||||
<Box component={Stack} direction={'row'} spacing={-1.25}>
|
||||
{ props.match.team1Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn &&
|
||||
|
@ -111,7 +111,7 @@ function Match(props){
|
|||
{team2Name}
|
||||
</Typography>
|
||||
{ props.match.winnerId && (props.match.team2Id === props.match.winnerId) &&
|
||||
<EmojiEventsIcon alt="A trohpy" sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} />
|
||||
<EmojiEventsIcon alt="A trophy" sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} />
|
||||
}
|
||||
{ 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="remove winner" component="span" onClick={curryUnsetContestant(props.match.team2Id)}><BackspaceIcon sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} /></IconButton>
|
||||
|
@ -162,7 +162,7 @@ function WinnerDisplay(props) {
|
|||
<Typography sx={{fontSize:['1em','1em','1.5em','2em']}} className="winner">
|
||||
{props.team.name}
|
||||
</Typography>
|
||||
<EmojiEventsIcon alt="A trohpy" />
|
||||
<EmojiEventsIcon alt="A trophy" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -71,17 +71,49 @@ function TeamList(props) {
|
|||
.catch(error => showError(error));
|
||||
}
|
||||
|
||||
function search() {
|
||||
let searchBase = []
|
||||
let searchResult = []
|
||||
let originalList = props.originalList
|
||||
originalList.map((tournament) => searchBase.push(tournament.name))
|
||||
let input = document.getElementById("searchInput")
|
||||
let inputUpperCase = input.value.toUpperCase()
|
||||
for (let i = 0; i < searchBase.length; i++) {
|
||||
let tournamentName = searchBase[i].toUpperCase()
|
||||
if(tournamentName.indexOf(inputUpperCase) >= 0) {
|
||||
searchResult.push(tournamentName)
|
||||
}
|
||||
}
|
||||
|
||||
let searchedList = []
|
||||
for (let i = 0; i < originalList.length; i++) {
|
||||
let name = originalList[i].name
|
||||
for (let j = 0; j < searchResult.length; j++) {
|
||||
if (name.toUpperCase() == searchResult[j]) {
|
||||
searchedList.push(originalList[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input.value == "") {
|
||||
props.setTeams(originalList)
|
||||
} else {
|
||||
props.setTeams(searchedList)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper sx={{minHeight: "30vh", width: "90vw", margin: "10px auto"}} component={Stack} direction="column" justifyContent="center">
|
||||
<div align="center" >
|
||||
<h2><b>Teams:</b></h2>
|
||||
{/* TODO: scroll denne menyen, eventuelt søkefelt */}
|
||||
{/* Make a horizontal stack */}
|
||||
<TextField sx={{margin:'2.5% 0 0 0', width: '50%'}} type="text" id="searchInput" label="Search" placeholder="Team Name" InputLabelProps={{shrink: true}} onChange={search}/>
|
||||
|
||||
<Table aria-label="simple table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Team Name</TableCell>
|
||||
<TableCell><h2>Team Name</h2></TableCell>
|
||||
{/* <TableCell align="right">Team Members</TableCell> */}
|
||||
<TableCell align="center">Actions</TableCell>
|
||||
<TableCell align="center"><h2>Actions</h2></TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
|
@ -91,7 +123,6 @@ function TeamList(props) {
|
|||
<TableCell component="th" scope="row"> <b>
|
||||
{team.name}
|
||||
</b></TableCell>
|
||||
{/* <TableCell align="right">{team.members}</TableCell> */}
|
||||
<TableCell align="center">
|
||||
<Button variant="contained" sx={{margin: "auto 5px"}} color="primary" onClick={() => {props.setSelectedTeamId(team.id); window.scrollTo(0, document.body.scrollHeight)}} endIcon={<EditIcon />}>Edit</Button>
|
||||
<Button variant="contained" sx={{margin: "auto 5px"}} color="error" onClick={() => {deleteTeam(team.id)}} endIcon={<DeleteIcon />}>Delete</Button>
|
||||
|
@ -184,6 +215,7 @@ let showError = (message) => {};
|
|||
export default function TournamentTeams(props) {
|
||||
const [teams, setTeams] = React.useState([]);
|
||||
const [selectedTeamId, setSelectedTeamId] = React.useState(-1);
|
||||
const [originalList, setOriginalList] = React.useState([])
|
||||
const { tournamentId } = useParams();
|
||||
|
||||
function getTeams() {
|
||||
|
@ -194,6 +226,7 @@ export default function TournamentTeams(props) {
|
|||
showError(data.data);
|
||||
}
|
||||
setTeams(data.data);
|
||||
setOriginalList(data.data)
|
||||
//setselectedTeamId(teams[0].id);
|
||||
})
|
||||
.catch((err) => showError(err));
|
||||
|
@ -218,7 +251,7 @@ export default function TournamentTeams(props) {
|
|||
<TournamentBar pageTitle="Manage Teams" />
|
||||
<div className="tournamentTeams">
|
||||
<TeamCreator tournamentId={tournamentId} teams={teams} onTeamCreated={getTeams} />
|
||||
<TeamList teams={teams} setTeams={setTeams} selectedTeamId={selectedTeamId} setSelectedTeamId={setSelectedTeamId} />
|
||||
<TeamList teams={teams} setTeams={setTeams} selectedTeamId={selectedTeamId} setSelectedTeamId={setSelectedTeamId} originalList={originalList} setOriginalList={setOriginalList} />
|
||||
<TeamEditor teams={teams} setTeams={setTeams} selectedTeamId={selectedTeamId} setSelectedTeamId={setSelectedTeamId} />
|
||||
</div>
|
||||
<ErrorSnackbar message={errorMessage} open={openError} setOpen={setOpenError} />
|
||||
|
|
|
@ -25,11 +25,11 @@ function LoggedInMenu(props) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Link to="/profile"><Button sx={{color:'white', marginTop:'5px'}} startIcon={<AccountCircleIcon />}>{props.user.name}</Button></Link>
|
||||
<IconButton size="large" edge="start" color="inherit" aria-label="menu" onClick={handleClick}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
<Menu anchorEl={anchorEl} open={open} onClose={handleClose} MenuListProps={{'aria-labelledby': 'basic-button',}} sx={{position:"absolute"}}>
|
||||
<Link to="/profile" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<AccountCircleIcon />}>{props.user.name}</Button></MenuItem></Link>
|
||||
<Link to="/history" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<HistoryIcon />}>History</Button></MenuItem></Link>
|
||||
{ props.user.isManager &&
|
||||
<Link to="/admins" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<EditIcon />} >Admins</Button></MenuItem></Link>
|
||||
|
@ -71,7 +71,7 @@ export default function Appbar(props) {
|
|||
</Link>
|
||||
{ props.pageTitle !== "Asura Tournaments" &&
|
||||
<Link to="/" style={{color:"white"}}>
|
||||
<Typography component="div" align="center" sx={{fontSize:['1em','1em','1.5em','2em']}}>
|
||||
<Typography component="div" align="center" sx={{fontSize:['1em','1em','1.5em']}}>
|
||||
Home
|
||||
</Typography>
|
||||
</Link>
|
||||
|
|
|
@ -48,13 +48,13 @@ function ButtonLink(props) {
|
|||
export default function TournamentBar(props) {
|
||||
const { tournamentId } = useParams();
|
||||
return (
|
||||
<Paper sx={{width: ["90vw",], fontSize:['1rem','1rem','1.5rem','2rem'], margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
|
||||
<Paper sx={{width: ["90vw",], fontSize:['1rem','1rem','1.5rem'], margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
|
||||
<Stack direction="row" paddingTop={'0.5%'} sx={{fontSize:['1rem','1rem','1.5rem','2rem'], margin:'1.5%'}} spacing={2}>
|
||||
<ButtonLink targetPath="" tournamentId={tournamentId} activeTitle={props.pageTitle} title="View Tournament" viewTournament={props.viewTournament}/>
|
||||
<ButtonLink targetPath="/manage" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Edit Tournament" />
|
||||
<ButtonLink targetPath="/teams" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Manage Teams" />
|
||||
</Stack>
|
||||
<Stack direction="row" paddingBottom={'0.5%'}>
|
||||
<Stack direction="row" paddingBottom={'0.5%'} component={Stack}>
|
||||
<ClipboardButton clipboardContent={"https://discord.gg/asura"} name="Discord Invite Link" />
|
||||
<ClipboardButton clipboardContent={"https://asura.feal.no/tournament/" + tournamentId} name="Tournament Link" />
|
||||
</Stack>
|
||||
|
|
|
@ -43,14 +43,16 @@ app.use(require('express-log-url'));
|
|||
// #region frontend
|
||||
|
||||
// Serve static files from the React app
|
||||
app.use('/', express.static(path.join(__dirname, 'clientbuild')));
|
||||
app.use('/login', express.static(path.join(__dirname, 'clientbuild', 'index.html')));
|
||||
app.use('/history', express.static(path.join(__dirname, 'clientbuild', 'index.html')));
|
||||
app.use('/admins', express.static(path.join(__dirname, 'clientbuild', 'index.html')));
|
||||
app.use('/profile', express.static(path.join(__dirname, 'clientbuild', 'index.html')));
|
||||
app.use('/tournament/*', express.static(path.join(__dirname, 'clientbuild', 'index.html')));
|
||||
app.use('/static', express.static(path.join(__dirname, 'clientbuild/static')));
|
||||
app.use('/static/*', express.static(path.join(__dirname, 'clientbuild/static')));
|
||||
const indexhtmlPath = path.join(process.env.CLIENT_BUILD_DIR, "index.html");
|
||||
const staticPath = path.join(process.env.CLIENT_BUILD_DIR, "static");
|
||||
app.use('/', express.static(process.env.CLIENT_BUILD_DIR));
|
||||
app.use('/login', express.static(indexhtmlPath));
|
||||
app.use('/history', express.static(indexhtmlPath));
|
||||
app.use('/admins', express.static(indexhtmlPath));
|
||||
app.use('/profile', express.static(indexhtmlPath));
|
||||
app.use('/tournament/*', express.static(indexhtmlPath));
|
||||
app.use('/static', express.static(staticPath));
|
||||
app.use('/static/*', express.static(staticPath));
|
||||
// #endregion
|
||||
|
||||
// #region PASSPORT / OAUTH
|
||||
|
|
Loading…
Reference in New Issue