added UI to contest page for correct flags

main
Alex 5 months ago
parent 490f740190
commit 51521d9a4a

@ -6,12 +6,18 @@ import { getEmail, updateContainer, gotoPage } from './Helpers';
import { TerminalService } from './terminal.service'; import { TerminalService } from './terminal.service';
import { SocketIOService } from '../notifications/socket-io.service'; import { SocketIOService } from '../notifications/socket-io.service';
import { Socket } from 'socket.io-client'; import { Socket } from 'socket.io-client';
import { AddFlagComponent } from '../add-flag/add-flag.component';
import { Submission } from '../models/submission.model';
import { User } from '../models/user.model';
let subs: Submission[] = [];
let UserID: number = 0;
export async function loadPage(renderer: Renderer2, el: ElementRef, ts: any): Promise<void> { export async function loadPage(renderer: Renderer2, el: ElementRef, ts: any): Promise<void> {
const isPractice = window.location.href.includes("Prac"); const isPractice = window.location.href.includes("Prac");
const taskbar: HTMLElement = document.getElementById('Taskbar')!; const taskbar: HTMLElement = document.getElementById('Taskbar')!;
// basics for use in multiple methods
// basics for use in multiple methods
const elements = { const elements = {
flagName: el.nativeElement.querySelector('#Flag_Name') as HTMLElement, flagName: el.nativeElement.querySelector('#Flag_Name') as HTMLElement,
desc: el.nativeElement.querySelector('#Desc') as HTMLElement, desc: el.nativeElement.querySelector('#Desc') as HTMLElement,
@ -31,6 +37,21 @@ export function getAdmin(): string | null {
return params.get('admin'); return params.get('admin');
} }
// get the user
async function getUser() {
const data = { email: getEmail() };
const res = await fetch('api/users/getUser', {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
},
body: JSON.stringify(data)
});
if (res.ok) {
let user = await res.json();
UserID = user.UserID;
}
}
// load the current active contest // load the current active contest
async function LoadContest(el: ElementRef, elements: any, ts: any) { async function LoadContest(el: ElementRef, elements: any, ts: any) {
const contestID = new URLSearchParams(window.location.search).get('contestID'); const contestID = new URLSearchParams(window.location.search).get('contestID');
@ -120,6 +141,8 @@ async function LoadElements(contest: Contest, el: ElementRef, elements: any, ts:
if(submitFlag) submitFlag.classList.add('hidden'); if(submitFlag) submitFlag.classList.add('hidden');
hintStuff.classList.add('hidden'); hintStuff.classList.add('hidden');
getUser();
await getSubs();
flagdata.forEach(flag => { flagdata.forEach(flag => {
console.log(flag); console.log(flag);
@ -129,11 +152,36 @@ async function LoadElements(contest: Contest, el: ElementRef, elements: any, ts:
li.onclick = () => setNewFlag(flag, el, elements, ts); li.onclick = () => setNewFlag(flag, el, elements, ts);
// add to list // add to list
CheckIfCorrect(li,flag);
li.appendChild(a); li.appendChild(a);
UL.appendChild(li); UL.appendChild(li);
}); });
} }
// get all of the submissions
async function getSubs() {
const res = await fetch('api/submissions/getSubs', {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
});
if (res.ok) {
subs = await res.json();
}
}
// checks whether to add the correct class to the flag
async function CheckIfCorrect(li: HTMLLIElement, flag: Flag) {
for (let i=0; i < subs.length; i++) {
if (subs[i].FlagID === flag.FlagID) {
if (subs[i].UserID == UserID && subs[i].IsCorrect == true) {
li.classList.add('CorrectSub');
}
}
}
}
// get the active flag of a user // get the active flag of a user
async function getActiveFlag(email: string, contest: number, el: ElementRef, elements: any) { async function getActiveFlag(email: string, contest: number, el: ElementRef, elements: any) {
const data = { email: email }; const data = { email: email };
@ -294,16 +342,32 @@ async function checkSubmission(isPractice: boolean, el: ElementRef, socket: Sock
} }
result = await res.json(); result = await res.json();
// correct flag
if(result.correct){ if(result.correct){
resultelement.classList.add('Correct'); resultelement.classList.add('Correct');
resultelement.classList.remove('Incorrect'); resultelement.classList.remove('Incorrect');
resultelement.textContent = 'Correct! :)'; resultelement.textContent = 'Correct! :)';
// change flag li to green
const flaglist = document.getElementById('FlagList') as HTMLUListElement;
for (let i=0; i < flaglist.children.length; i++) {
// grab the li and add a classlist of correct
let flag = flaglist.childNodes[i] as HTMLLIElement;
if (flag.firstChild?.textContent === flagName) {
flag.classList.add('CorrectSub');
console.log('added correct color');
console.log(flag.firstChild);
}
}
console.log("SENDING NOTIF", email, flagName); console.log("SENDING NOTIF", email, flagName);
/*socket.emit('submission-notification', { /*socket.emit('submission-notification', {
email, flagName, time: new Date().toISOString() email, flagName, time: new Date().toISOString()
});*/ });*/
} }
// incorrect flag
else{ else{
resultelement.classList.add('Incorrect'); resultelement.classList.add('Incorrect');
resultelement.classList.remove('Correct'); resultelement.classList.remove('Correct');

@ -2,22 +2,19 @@ html {
background-color: green; background-color: green;
} }
body { body {
background-color: white; background-color: lightgreen;
height: 90vh;
} }
form { form {
text-align: center; text-align: center;
} }
h1, h3 { h1 {
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
background-color: green;
padding: 10px;
} }
#Inputs {
display: grid;
grid-template-columns: max-content max-content;
grid-gap: 5px;
margin-left: 25%;
margin-top: 25%;
}
label { label {
text-align: right; text-align: right;
} }
@ -26,79 +23,13 @@ label {
align-items: center; align-items: center;
text-align: center; text-align: center;
} }
#submit * { #Submit * {
width: 15%; margin: 10px;
height: 5%;
} }
#Submit button { #AddContest {
background-color: red; background-color: lawngreen;
font-weight: bold;
} }
button {
#hint1Text, #hint2Text, #hint3Text {
display: none;
}
/* Show the respective hint fields based on the selected radio button */
#hint1:checked ~ #hint1Text {
display: block;
}
#hint2:checked ~ #hint1Text,
#hint2:checked ~ #hint2Text {
display: block;
}
#hint3:checked ~ #hint1Text,
#hint3:checked ~ #hint2Text,
#hint3:checked ~ #hint3Text{
display: block;
}
/* for Create Image */
#body {
display: grid;
grid-template-rows: 25% auto auto auto auto auto 25%;
grid-template-columns: 20% 20% 20% 20% 20%;
justify-items: center;
}
#labels {
grid-row: 1/2;
grid-column: 3/4;
}
#Butts {
grid-row: 2/3;
grid-column: 3/4;
align-self: flex-end;
}
#TextBox {
grid-row: 3/6;
grid-column: 1/3;
}
textarea {
resize: none;
}
#DropBox {
grid-row: 3/6;
grid-column: 3/4;
border: 3px black dashed;
align-content: center;
justify-items: center;
}
#SendFile {
grid-row: 6/7;
grid-column: 3/4;
}
#FileTree {
grid-row: 3/6;
grid-column: 4/6;
}
#Submition {
grid-row: 7/8;
grid-column: 3/4;
}
.selected-node {
background-color: #f0f0f0;
font-weight: bold; font-weight: bold;
color: #333; width: 30%;
} }

@ -12,10 +12,17 @@
<body> <body>
<h1> Add Contest </h1> <h1> Add Contest </h1>
<br>
<br>
<br>
<br>
<!-- form for inserting the contest --> <!-- form for inserting the contest -->
<form id="Inputs"> <form id="Inputs">
<label> Name: </label> <label> Name: </label>
<input id="Name" type="text" align="middle" required> <input id="Name" type="text" align="middle" required>
<br>
<br>
<label> Description: </label> <label> Description: </label>
<input id="Desc" type="text" align="middle" required> <input id="Desc" type="text" align="middle" required>
</form> </form>
@ -24,8 +31,7 @@
<!-- submitting and closing --> <!-- submitting and closing -->
<div id="Submit"> <div id="Submit">
<input id="AddContest" type="button" value="Add Contest" (click)="AddContest();"> <button id="AddContest" (click)="AddContest();">Add Contest</button>
<button onclick="self.close();"> Cancel </button>
</div> </div>
</body> </body>
</html> </html>

@ -15,6 +15,12 @@ export class AddContestComponent {
const descInput = document.getElementById("Desc") as HTMLTextAreaElement; const descInput = document.getElementById("Desc") as HTMLTextAreaElement;
const name = nameInput.value; const name = nameInput.value;
const desc = descInput.value; const desc = descInput.value;
// character limit on contest name
if (name.length > 20) {
alert('Name of Contest must be 20 characters or below');
return;
}
console.log("Name entered: ", name); console.log("Name entered: ", name);
console.log("Description entered: ", desc); console.log("Description entered: ", desc);
const isActive = 0; const isActive = 0;

@ -50,16 +50,10 @@
<!-- image of the flag to create container --> <!-- image of the flag to create container -->
<label> Image: </label> <label> Image: </label>
<<<<<<< HEAD
<select id="Images"> <select id="Images">
<option *ngFor="let image of images"> <option *ngFor="let image of images">
{{ image.Name }} {{ image.Name }}
</option> </option>
=======
<select id="Images" [(ngModel)]="selectedImage">
<option> ubuntu </option>
<option *ngFor="let image of allImages" [value] ="image.Name">{{image.Name}}</option>
>>>>>>> 39ac6351e5793d9f00c090384c69686e0baa4a6c
</select> </select>
<br><br> <br><br>

@ -2,103 +2,34 @@ html {
background-color: green; background-color: green;
} }
body { body {
background-color: white; background-color: lightgreen;
height: 90vh;
} }
form { form {
text-align: center; text-align: center;
} }
h1, h3 { h1 {
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
background-color: green;
padding: 10px;
} }
#Inputs {
display: grid;
grid-template-columns: max-content max-content;
grid-gap: 5px;
margin-left: 25%;
margin-top: 25%;
}
label { label {
text-align: right; text-align: center;
} }
#Submit { #Submit {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
text-align: center; text-align: center;
} }
#submit * { #Submit * {
width: 15%; margin: 10px;
height: 5%;
} }
#Submit button { #AddStudent {
background-color: red; background-color: lawngreen;
font-weight: bold;
} }
button {
#hint1Text, #hint2Text, #hint3Text {
display: none;
}
/* Show the respective hint fields based on the selected radio button */
#hint1:checked ~ #hint1Text {
display: block;
}
#hint2:checked ~ #hint1Text,
#hint2:checked ~ #hint2Text {
display: block;
}
#hint3:checked ~ #hint1Text,
#hint3:checked ~ #hint2Text,
#hint3:checked ~ #hint3Text{
display: block;
}
/* for Create Image */
#body {
display: grid;
grid-template-rows: 25% auto auto auto auto auto 25%;
grid-template-columns: 20% 20% 20% 20% 20%;
justify-items: center;
}
#labels {
grid-row: 1/2;
grid-column: 3/4;
}
#Butts {
grid-row: 2/3;
grid-column: 3/4;
align-self: flex-end;
}
#TextBox {
grid-row: 3/6;
grid-column: 1/3;
}
textarea {
resize: none;
}
#DropBox {
grid-row: 3/6;
grid-column: 3/4;
border: 3px black dashed;
align-content: center;
justify-items: center;
}
#SendFile {
grid-row: 6/7;
grid-column: 3/4;
}
#FileTree {
grid-row: 3/6;
grid-column: 4/6;
}
#Submition {
grid-row: 7/8;
grid-column: 3/4;
}
.selected-node {
background-color: #f0f0f0;
font-weight: bold; font-weight: bold;
color: #333; width: 30%;
} }

@ -11,18 +11,25 @@
<body> <body>
<h1> Add Student </h1> <h1> Add Student </h1>
<br>
<br>
<!-- form for adding a student --> <!-- form for adding a student -->
<form id="Inputs"> <form id="Inputs">
<label> Name: </label> <label> Name: </label>
<input id="Name" type="text" [(ngModel)]="Uname" name="Uname" align="middle"> <input id="Name" type="text" [(ngModel)]="Uname" name="Uname" align="middle">
<bR>
<label> Email: </label> <label> Email: </label>
<input id="EM" type="text" [(ngModel)]="email" name="email" align="middle"> <input id="EM" type="text" [(ngModel)]="email" name="email" align="middle">
<br>
<label> Password: </label> <label> Password: </label>
<input *ngIf="!showPass" id="PS1" type="password" [(ngModel)]="password" name="password" align="middle"> <input *ngIf="!showPass" id="PS1" type="password" [(ngModel)]="password" name="password" align="middle">
<input *ngIf="showPass" id="PS1" type="text" [(ngModel)]="password" name="password" align="middle"> <input *ngIf="showPass" id="PS1" type="text" [(ngModel)]="password" name="password" align="middle">
<br>
<label> Confirm Password: </label> <label> Confirm Password: </label>
<input *ngIf="!showPass" id="PS2" type="password" [(ngModel)]="confirmPassword" name="confirmPassword" align="middle"> <input *ngIf="!showPass" id="PS2" type="password" [(ngModel)]="confirmPassword" name="confirmPassword" align="middle">
<input *ngIf="showPass" id="PS2" type="text" [(ngModel)]="confirmPassword" name="confirmPassword" align="middle"> <input *ngIf="showPass" id="PS2" type="text" [(ngModel)]="confirmPassword" name="confirmPassword" align="middle">
<br>
<label> Show Password </label> <label> Show Password </label>
<input type="checkbox" (click)="ShowPassword()" id="ShowPass"> <input type="checkbox" (click)="ShowPassword()" id="ShowPass">
</form> </form>
@ -31,8 +38,7 @@
<!-- submitting or closing--> <!-- submitting or closing-->
<div id="Submit"> <div id="Submit">
<input id="AddStudent" type="submit" (click)="AddStudent()"> <button id="AddStudent" (click)="AddStudent()">Add Student</button>
<button onclick="self.close();"> Cancel </button>
</div> </div>
</body> </body>
</html> </html>

@ -17,9 +17,9 @@ body {
/* Name of the contest at the top left */ /* Name of the contest at the top left */
#Contest_Name { #Contest_Name {
grid-row: 1/2; grid-row: 1/2;
grid-column: 1/3; grid-column: 1/4;
text-align: center; text-align: left;
font-weight: bold; font-weight: bold;
font-size: 175%; font-size: 175%;
} }

@ -17,9 +17,9 @@ body {
/* Name of the contest at the top left */ /* Name of the contest at the top left */
#Contest_Name { #Contest_Name {
grid-row: 1/2; grid-row: 1/2;
grid-column: 1/3; grid-column: 1/4;
text-align: center; text-align: left;
font-weight: bold; font-weight: bold;
font-size: 175%; font-size: 175%;
} }
@ -53,18 +53,12 @@ body {
text-align: center; text-align: center;
} }
#notificationMessage { #Notifications {
background-color: rgba(65, 145, 55, 0.511);
margin-left: 50%;
grid-row: 3/4;
grid-column: 3/5;
}
.notificationMessage {
background-color: rgba(65, 145, 55, 0.511); background-color: rgba(65, 145, 55, 0.511);
margin-left: 50%; margin-left: 50%;
grid-row: 3/4; grid-row: 3/4;
grid-column: 3/5; grid-column: 3/5;
display: none;
} }
#Notifications.show { #Notifications.show {
@ -72,16 +66,6 @@ body {
} }
.notification-banner {
background-color: rgba(65, 145, 55, 0.511);
margin-left: 50%;
grid-row: 3/4;
grid-column: 3/5;
border-radius: 5px;
text-align: center;
font-weight: bold;
}
/* Submitting the flag */ /* Submitting the flag */
#Submit_Flag { #Submit_Flag {
background-color: white; background-color: white;
@ -155,3 +139,26 @@ textarea {
margin: 10px; margin: 10px;
font-size: 200%; font-size: 200%;
} }
.CorrectSub {
background-color: lawngreen;
}
/* for profile in top right */
a {
color: black;
text-decoration: none;
text-align: center;
font-size: 175%;
font-weight: bold;
padding: 3%;
display: inline;
}
a:visited {
text-decoration: none;
}
a:hover {
background-color: white;
color: black;
}

@ -12,13 +12,13 @@
<!-- Bar at top for moving tabs, this is for the practice contest --> <!-- Bar at top for moving tabs, this is for the practice contest -->
<ng-container *ngIf="isPractice"> <ng-container *ngIf="isPractice">
<a href="#" (click)="confirmSelection(1); $event.preventDefault()">Leave Practice</a> <a href="#" (click)="confirmSelection(1); $event.preventDefault()">Leave Practice</a>
</ng-container> </ng-container>
<!-- Show if NOT Admin and NOT in Practice --> <!-- Show if NOT Admin and NOT in Practice -->
<ng-container id="Taskbar" *ngIf="!isPractice && !isAdmin"> <ng-container id="Taskbar" *ngIf="!isPractice && !isAdmin">
<a id="Current_Page" href="#" (click)="navtoPageUM(); $event.preventDefault()">Contest</a>
<a href="#" (click)="confirmSelection(2); $event.preventDefault()">Profile</a> <a href="#" (click)="confirmSelection(2); $event.preventDefault()">Profile</a>
</ng-container> </ng-container>
<!-- Contest name --> <!-- Contest name -->
<div id="Contest_Name"> <div id="Contest_Name">
<h1 id="ContHeader"></h1> <h1 id="ContHeader"></h1>

@ -104,19 +104,24 @@ label {
/* tooltips */ /* tooltips */
.tooltip { .tooltip {
font-weight: bold; font-weight: bold;
color: white; color: white;
display: inline; display: inline;
} }
.tooltip:hover .tooltipText { .tooltip:hover .tooltipText {
visibility: visible; visibility: visible;
} }
.tooltip .tooltipText { .tooltip .tooltipText {
visibility: hidden; visibility: hidden;
height: auto; height: auto;
background-color: gray; background-color: gray;
color: black; color: black;
text-align: center; text-align: center;
position: absolute; position: absolute;
padding: 5px; padding: 5px;
}
/* Correct submission */
.CorrectSub {
background-color: lawngreen;
} }

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
print('This is the flag: [FLAG]')

@ -1,7 +1,7 @@
import { Router } from "express"; import { Router } from "express";
import { getFlagHash } from "../server.js" import { getFlagHash } from "../server.js"
import { getUserID } from "../queries/userQueries.js"; import { getUserID } from "../queries/userQueries.js";
import { getSubmissions, insertSubmission, updateSubmissionAttempts } from "../queries/submissionQueries.js"; import { getSubmissions, insertSubmission, updateSubmissionAttempts, getAllSubs } from "../queries/submissionQueries.js";
import { updateUserFlags } from "../queries/userQueries.js"; import { updateUserFlags } from "../queries/userQueries.js";
const router = Router(); const router = Router();
@ -49,4 +49,10 @@ router.post('/checkPracSubmission', async (req, res) => {
return res.json({correct: false, message: 'Incorrect flag. Try Again'}); return res.json({correct: false, message: 'Incorrect flag. Try Again'});
}); });
// getting all submissions
router.post('/getSubs', async (req,res) => {
let subs = await getAllSubs();
res.json(subs);
});
export default router; export default router;
Loading…
Cancel
Save