diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringForm.module.scss b/app/(pages)/judges/_components/ScoringForm/ScoringForm.module.scss new file mode 100644 index 00000000..162524a3 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringForm.module.scss @@ -0,0 +1,4 @@ +.container { + display: flex; + flex-direction: column; +} \ No newline at end of file diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringForm.tsx b/app/(pages)/judges/_components/ScoringForm/ScoringForm.tsx new file mode 100644 index 00000000..4c139848 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringForm.tsx @@ -0,0 +1,53 @@ +'use client'; +import { useState } from 'react'; +import styles from './ScoringForm.module.scss'; +import TeamBlock from './ScoringSubComponents/TeamBlock'; +import ScoringInput from './ScoringSubComponents/ScoreInput'; +import Comments from './ScoringSubComponents/Comments'; + +export default function ScoringForm() { + const generalScoreNames = [ + 'Social Good', + 'Technical Complexity', + 'Design', + 'Creativity', + 'Presentation', + ]; + + /* retrieve these from backend */ + const trackScoreNames = [ + 'Best Social Hack', + 'Best Beginner Hack', + 'Best Design Hack', + 'Best Usage of MongoDB', + ]; + + // prefils the map with all the categories and sets the scores to -1 to + // assist in error handling + + const initialCategoryScores = new Map(); + [...generalScoreNames, ...trackScoreNames].forEach((category) => { + initialCategoryScores.set(category, -1); + }); + + const [categoryScores, setCategoryScores] = useState(initialCategoryScores); + + return ( +
+ + + + +
+ ); +} diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/Comments.module.scss b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/Comments.module.scss new file mode 100644 index 00000000..a4f72f4c --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/Comments.module.scss @@ -0,0 +1,84 @@ +.commentContainer { + display: flex; + flex-direction: column; + background-color: #CEE7F4; + align-items: center; + width: 100%; + .commentTitle { + width: 91%; + color: #000; + font-family: "Proxima Nova"; + font-size: 32px; + font-style: normal; + font-weight: 600; + line-height: normal; + margin-top: 64px; + margin-bottom: 7px; + } + + .commentDescription { + width: 91%; + color: #000; + font-family: "DM Sans"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + margin-bottom: 15.5px; + } + .commentBox { + width: 91%; + height: 170px; + margin-bottom: 48px; + padding: 15.5px; + resize: none; + border-radius: 7.748px; + background: #FFF; + } + .submitButton { + width: 91%; + height: 46px; + margin-bottom: 7px; + + color: #173A52; + font-family: "Proxima Nova"; + font-size: 18px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: 0.36px; + + border-radius: 15.497px; + border: 2px solid #FFC370; + background: #FFC53D; + } + .submitButtonDone { + width: 91%; + height: 46px; + margin-bottom: 7px; + + color: #173A52; + font-family: "Proxima Nova"; + font-size: 18px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: 0.36px; + + border-radius: 15.497px; + border: 2px solid #F6D995; + background: #F6D995; + } + .submitDescription { + width: 91%; + color: #000; + font-family: "DM Sans"; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-align: center; + margin-bottom: 64px; + + } +} \ No newline at end of file diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/Comments.tsx b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/Comments.tsx new file mode 100644 index 00000000..21a9f431 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/Comments.tsx @@ -0,0 +1,66 @@ +'use client'; +import styles from './Comments.module.scss'; +import { useState } from 'react'; + +interface CommentsProps { + categoryScores: Map; +} + +export default function Comments({ categoryScores }: CommentsProps) { + const [commentText, setCommentText] = useState(''); + const [commentSubmitted, setCommentSubmitted] = useState(false); + + const hasNegativeScores = (scoresMap: Map) => { + let hasNegativeScore = false; + scoresMap.forEach((score) => { + if (score === -1) { + hasNegativeScore = true; + } + }); + return hasNegativeScore; + }; + + const onCommentType = (e: any) => { + setCommentText(e.target.value); + }; + + const onSubmitComment = () => { + if (hasNegativeScores(categoryScores)) { + alert('Some categories are not scored. Please score all of them.'); + } else { + setCommentSubmitted(true); + + /* send scores to backend */ + console.log(categoryScores); + console.log(commentText); + } + }; + + return ( +
+

Comments

+

+ Comments help us for deciding tiebreakers. If there was an exceptional + project or one you’re suspicious of cheating, write it here! +

+ + +

+ Once submitted, results cannot be changed. +

+
+ ); +} diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoreInput.module.scss b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoreInput.module.scss new file mode 100644 index 00000000..3f605718 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoreInput.module.scss @@ -0,0 +1,18 @@ +.inputContainer { + display: flex; + flex-direction: column; + align-items: center; + background-color: #CEE7F4; + gap: 20px; + + .scoringTitle { + width: 91%; + color: #000; + font-family: "Proxima Nova"; + font-size: 32px; + font-style: normal; + font-weight: 600; + line-height: normal; + margin-top: 42px; + } +} \ No newline at end of file diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoreInput.tsx b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoreInput.tsx new file mode 100644 index 00000000..bc9ded03 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoreInput.tsx @@ -0,0 +1,32 @@ +import { Dispatch, SetStateAction } from 'react'; +import styles from './ScoreInput.module.scss'; +import ScoringCard from './ScoringCard/ScoringCard'; + +interface ScoringInputProps { + inputNameHeader: string; + inputScoreNames: string[]; + categoryScores: Map; + setCategoryScores: Dispatch>>; +} + +export default function ScoringInput({ + inputNameHeader, + inputScoreNames, + categoryScores, + setCategoryScores, +}: ScoringInputProps) { + return ( +
+

{inputNameHeader}

+ {inputScoreNames.map((category, index) => ( + + ))} +
+ ); +} diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoringCard/ScoringCard.module.scss b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoringCard/ScoringCard.module.scss new file mode 100644 index 00000000..8f043e95 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoringCard/ScoringCard.module.scss @@ -0,0 +1,54 @@ +@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap'); + +.scoringCard { + display: flex; + flex-direction: column; + background-color: #FFFFFF; + gap: 20px; + width: 92%; + border-radius: 4px; + padding: 10px; + padding-top: 20px; + padding-bottom: 24px; + + .categoryName { + color: #000; + font-family: "DM Sans"; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: normal; + align-self: flex-start; + margin-left: 10px; + } + .scoringCircleContainer { + display: flex; + gap: 10px; + justify-content: space-around; + + .scoringCircle { + display: flex; + justify-content: center; + align-items: center; + width: 40px; + height: 40px; + border-radius: 50%; /* Make the border radius half of the width/height to create a circle */ + border: 2px solid black; + } + .scoringCircleFilled { + display: flex; + justify-content: center; + align-items: center; + width: 40px; + height: 40px; + border-radius: 50%; /* Make the border radius half of the width/height to create a circle */ + border: 2px solid black; + color: white; + background-color: #005271; + font-family: 'DM Sans', sans-serif; + } + .scoringCircle:hover { + border: 3px solid #005271;; + } + } +} \ No newline at end of file diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoringCard/ScoringCard.tsx b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoringCard/ScoringCard.tsx new file mode 100644 index 00000000..58f7f36d --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/ScoringCard/ScoringCard.tsx @@ -0,0 +1,50 @@ +'use client'; +import { Dispatch, SetStateAction, useState } from 'react'; +import styles from './ScoringCard.module.scss'; + +interface ScoringCardProps { + categoryName: string; + index: number; + categoryScores: Map; + setCategoryScores: Dispatch>>; +} +export default function ScoringCard({ + categoryName, + index, + categoryScores, + setCategoryScores, +}: ScoringCardProps) { + const scores = [1, 2, 3, 4, 5]; + + const [pickedScore, setPickedScore] = useState(-1); + + const enterChoice = (index: number) => { + return () => { + setPickedScore(index); + + const updatedMap = new Map(categoryScores); + updatedMap.set(categoryName, index + 1); + setCategoryScores(updatedMap); + }; + }; + return ( +
+

{`${index}. ${categoryName}`}

+
+ {scores.map((score, index) => ( +
+ {score} +
+ ))} +
+
+ ); +} diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/TeamBlock.module.scss b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/TeamBlock.module.scss new file mode 100644 index 00000000..986da9bc --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/TeamBlock.module.scss @@ -0,0 +1,93 @@ +.teamBlock { + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; + background: #005271; + height: 325px; + box-shadow: 0px 4px 4px 0px rgba(0, 82, 113, 0.25); + + .topText { + display: flex; + justify-content: space-between; + padding-top: 64px; + width: 350px; + + .teamTable { + color: #FFF; + font-family: "Proxima Nova Medium"; + font-size: 1.5rem; + font-style: normal; + font-weight: 500; + line-height: normal; + } + + .mapContent { + display: flex; + justify-content: space-around; + gap: 10px; + + .mapText { + color: #FFF; + font-family: "Proxima Nova"; + font-size: 1rem; + font-style: normal; + font-weight: 600; + line-height: normal; + } + } + } + .teamName { + color: #FFF; + font-family: "Proxima Nova"; + font-size: 3rem; + font-style: normal; + font-weight: 700; + line-height: normal; + } + + .guideContent { + display: flex; + flex-direction: column; + justify-content: space-around; + padding: 16px 24px 16px; + width: 350px; + height: 118px; + background: #CDE1E1; + border-radius: 8px; + + .guideText { + width: 299px; + color: #000; + font-family: "Proxima Nova"; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: normal; + } + .guideButton { + display: flex; + align-self: flex-start; + align-items: center; + justify-content: center; + gap: 8px; + width: 144px; + height: 38px; + margin-top: 10px; + + border-radius: 24px; + border: 0.5px solid #005271; + background: #FFF; + box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.10); + + .guideButtonText { + color: #000; + font-family: "Proxima Nova"; + font-size: 14px; + font-style: normal; + font-weight: 600; + line-height: normal; + } + } + } +} \ No newline at end of file diff --git a/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/TeamBlock.tsx b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/TeamBlock.tsx new file mode 100644 index 00000000..5b9792a5 --- /dev/null +++ b/app/(pages)/judges/_components/ScoringForm/ScoringSubComponents/TeamBlock.tsx @@ -0,0 +1,72 @@ +import styles from './TeamBlock.module.scss'; +import Link from 'next/link'; + +const RightArrow = () => { + return ( + + + + ); +}; + +const NoteBook = () => { + return ( + + + + ); +}; + +export default function TeamBlock() { + /* retrieve these from backend */ + const tableNumber = 117; + const teamName = 'Haptic Hand'; + + return ( +
+
+

Table {tableNumber}

+ +
+

Find on Map

+ +
+
+ +

{teamName}

+
+

+ Please refer back to our judging guide for each track. Tracks are on a + scale from 1-10. +

+ +
+ +

Judging Guide

+
+ +
+
+ ); +} diff --git a/app/(pages)/judges/scoring/page.tsx b/app/(pages)/judges/scoring/page.tsx new file mode 100644 index 00000000..4e703841 --- /dev/null +++ b/app/(pages)/judges/scoring/page.tsx @@ -0,0 +1,5 @@ +'use client'; +import ScoringForm from '../_components/ScoringForm/ScoringForm'; +export default function Scoring() { + return ; +}