Skip to content

Commit

Permalink
Merge pull request #613 from ubc-biztech/dataverse-isaac
Browse files Browse the repository at this point in the history
Implemented Base64 obfuscation, new dataset questions, and finalized final question + hints
  • Loading branch information
mchlcui authored Nov 29, 2024
2 parents b9e0093 + 48bc250 commit 87862c3
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 42 deletions.
6 changes: 4 additions & 2 deletions src/pages/public/Companion/components/dataverse/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {

const Dashboard = () => {
const startTime = new Date();
const endTime = new Date();
endTime.setHours(19, 50, 0, 0);
const endTimeAt3PM = new Date();
endTimeAt3PM.setHours(15, 0, 0, 0);
const endTimeIn50Minutes = new Date(startTime.getTime() + 50 * 60 * 1000);
const endTime = (endTimeIn50Minutes < endTimeAt3PM) ? endTimeIn50Minutes : endTimeAt3PM;
const location = useLocation();
const history = useHistory();
const {
Expand Down
11 changes: 5 additions & 6 deletions src/pages/public/Companion/components/dataverse/Progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import {

const CharacterInput = ({
onSubmit,
correctAnswer = "never gonna give you up",
promo = "stay tuned for blueprint",
disabled = true,
setAnswered,
userRegistration
}) => {
const numChars = correctAnswer.length;
const numChars = promo.length;
const [chars, setChars] = useState(Array(numChars).fill(""));
const [isTyping, setIsTyping] = useState(false);
const [letterColors, setLetterColors] = useState(Array(numChars).fill(""));
Expand Down Expand Up @@ -70,7 +70,7 @@ const CharacterInput = ({

// Mark green letters
for (let i = 0; i < numChars; i++) {
if (chars[i].toLowerCase() === correctAnswer[i].toLowerCase()) {
if (chars[i].toLowerCase() === promo[i].toLowerCase()) {
newColors[i] = "green";
correctLetters[i] = true;
}
Expand All @@ -81,7 +81,7 @@ const CharacterInput = ({
if (newColors[i] === "green") continue;

const letter = chars[i].toLowerCase();
const remainingCount = correctAnswer.toLowerCase().split(letter).length - 1;
const remainingCount = promo.toLowerCase().split(letter).length - 1;

// both green and yellow matches
let usedCount = 0;
Expand All @@ -104,7 +104,7 @@ const CharacterInput = ({
const input = chars.join("");
if (input.length === numChars) {
updateColors();
const isAnswerCorrect = input.toLowerCase() === correctAnswer.toLowerCase();
const isAnswerCorrect = input.toLowerCase() === promo.toLowerCase();
if (isAnswerCorrect) {
const toAddQuestion = [];
toAddQuestion.push("Final Question");
Expand All @@ -120,7 +120,6 @@ const CharacterInput = ({
false
);
setAnswered(true);
onSubmit(input);
}

setChars(Array(numChars).fill(""));
Expand Down
8 changes: 4 additions & 4 deletions src/pages/public/Companion/components/dataverse/Quiz.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ const QuizDashboard = ({
</div>
<Progress
teamScore={teamPoints}
maxScore={13}
maxScore={16}
setAnswered={setAnswered}
disabled={!(showScrambled1 && showScrambled2 && showScrambled3)}
userRegistration={userRegistration}
Expand All @@ -403,19 +403,19 @@ const QuizDashboard = ({
setSelectedRoom={setSelectedRoom}
completed={showScrambled1}
roomNumber={1}
letters={"ervne"}
letters={"yats"}
/>
<QuizCard
setSelectedRoom={setSelectedRoom}
completed={showScrambled2}
roomNumber={2}
letters={"uyo"}
letters={"dentu"}
/>
<QuizCard
setSelectedRoom={setSelectedRoom}
completed={showScrambled3}
roomNumber={3}
letters={"nngao"}
letters={"rof"}
/>
</div>
</div>
Expand Down
40 changes: 25 additions & 15 deletions src/pages/public/Companion/components/dataverse/QuizData.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ const quizData = {
"Which player had the most rebounds in a single game?",
"How many points did the players on ATL score in total?",
"Determine whether Field Goal Attempts, 3 Pointer Attempts, or Free Throw Attempts has the strongest positive correlation with Total Points Scored. Report the correlation coefficient of the variable with the strongest positive relationship (Round to two decimal places).",
"What is this SQL query trying to do? \n\nSELECT player \nFROM NBA \nWHERE team = 'NYK' AND total_points >= 20"
"What is this SQL query trying to do? \n\nSELECT player \nFROM NBA \nWHERE team = 'NYK' AND total_points >= 20",
"Based on historical outcomes, if the Boston Celtics and Charlotte Hornets play against each other, who would you predict would win?"
],
questionType: [
"text", // Free text question
"text", // Free text question
"text", // Free text question
"multiple-choice", // Free text question
"multiple-choice" // Free text question
],
correctAnswers: [
"Victor Wembanyama",
"703",
"0.89",
"Retrieve all players who play for the New York Knicks and scored at least 20 points in a game"
"VmljdG9yIFdlbWJhbnlhbWE=",
"NzAz",
"MC44OQ==",
"UmV0cmlldmUgYWxsIHBsYXllcnMgd2hvIHBsYXkgZm9yIHRoZSBOZXcgWW9yayBLbmlja3MgYW5kIHNjb3JlZCBhdCBsZWFzdCAyMCBwb2ludHMgaW4gYSBnYW1l",
"Qk9T"
],
options: [
[],
Expand All @@ -26,49 +29,56 @@ const quizData = {
"Retrieve all players who scored at least 20 points in a game",
"Retrieve the total points scored by New York Knicks players who scored more than 20 points in a game",
"Retrieve all players who play for the New York Knicks and scored at least 20 points in a game"
]
],
["BOS", "CHO"]
] // No multiple choice questions for this quiz
},
2: {
questions: [
"Which of the following graphs would best display the relationship between vid_duration and views?\n\na) Bar Chart\nb) Pie Chart\nc) Scatter Plot",
"What's the ID of the video with the highest net subscriber gain (subs gained - unsubs)?",
"What's the ID of the video with the highest ratio of likes to dislikes?",
"Youtube Ads were the channel's largest source of revenue in 2024. What percentage of 2024's total revenue came from these ads? (Round to the nearest percentage and do not include the \"%\" in your answer)"
"Youtube Ads were the channel's largest source of revenue in 2024. What percentage of 2024's total revenue came from these ads? (Round to the nearest percentage and do not include the \"%\" in your answer)",
"Videos published on which day of the week have the highest average number of views?"
],
questionType: [
"multiple-choice", // Multiple choice question
"text", // Free text question
"text", // Free text question
"text" // Free text question
"text", // Free text question
"multiple-choice"
],
correctAnswers: ["Scatter Plot", "188", "325", "63"],
correctAnswers: ["U2NhdHRlciBQbG90", "MTg4", "MzI1", "NjM=", "RnJpZGF5"],
options: [
["Bar Chart", "Pie Chart", "Scatter Plot"], // Multiple choice options for the first question
[], // No options for this text question
[], // No options for this text question
[] // No options for this text question
[],
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] // No options for this text question
]
},
3: {
questions: [
"How many hours per day on average does a student spend socializing? (Round to the nearest whole number)",
"How many hours per day does the student with the median GPA in this dataset spend studying and participating in extracurriculars?",
"What's the difference between the average GPA of a student who gets <= 6 hours of sleep per day vs a student who gets >= 9 hours of sleep per day? (Round to 3 decimal places)",
"What should be placed in the blank to complete the following SQL query, which retrieves the ID of the most physically active student? (type out the value of A before B, and separate them by a comma -> 'A, B')"
"What should be placed in the blank to complete the following SQL query, which retrieves the ID of the most physically active student? (type out the value of A before B, and separate them by a comma -> \"A, B\") \n\nSELECT id \nFROM students \nWHERE [A] = (SELECT [B](physical_hours_daily) FROM students)",
"Of all the students who are experiencing high stress (3), what's the ID of the one with the highest GPA?",
"What's the correlation between study hours and sleep hours? (Round to 2 decimal places)"
],
questionType: [
"text", // Free text question
"text", // Free text question
"text", // Free text question
"text" // Free text question
"text", // Free text question
"text"
],
correctAnswers: ["3", "9.9", "0.015", "physical_hours_daily, MAX"],
correctAnswers: ["Mw==", "MC4wMTU=", "cGh5c2ljYWxfaG91cnNfZGFpbHksIE1BWA==", "NTI=", "MC4wMw=="],
options: [
[], // No options for this text question
[], // No options for this text question
[], // No options for this text question
[] // No options for this text question
[], // No options for this text question
[]
]
}
};
Expand Down
52 changes: 37 additions & 15 deletions src/pages/public/Companion/components/dataverse/QuizRoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,25 @@ export default function QuizRoom({
quizData,
datasetLink
}) {
const [answers, setAnswers] = useState(Array(4).fill(""));
const [selectedOptions, setSelectedOptions] = useState(Array(4).fill(null));
const [answers, setAnswers] = useState(Array(5).fill(""));
const [selectedOptions, setSelectedOptions] = useState(Array(5).fill(null));
const [completedQuestions, setCompletedQuestions] = useState([]);
const [answerStatus, setAnswerStatus] = useState(Array(4).fill(null));
const [answerStatus, setAnswerStatus] = useState(Array(5).fill(null));
const [openPopup, setOpenPopup] = useState(false);
const [cooldown, setCooldown] = useState(0);

const popupContent = {
1: {
title: "🏆 Room 1 Complete!",
message: "Great job! Your string is: ervne"
message: "Great job! Your string is: yats"
},
2: {
title: "🎯 Room 2 Mastered!",
message: "Fantastic! Your string is: uyo"
message: "Fantastic! Your string is: dentu"
},
3: {
title: "🚀 Room 3 Achieved!",
message: "Outstanding! Your string is: nngao"
message: "Outstanding! Your string is: rof"
}
};

Expand Down Expand Up @@ -130,13 +130,15 @@ export default function QuizRoom({
setAnswers(newAnswers);
};

// Define the function outside useEffect to make it reusable
const checkAnswers = async () => {
if (cooldown > 0) return;

const {
correctAnswers, questions
} = quizData[roomNumber];
const newAnswerStatus = [...answerStatus];
let isMounted = true; // Local flag for cleanup

try {
let score = 0;
Expand All @@ -153,9 +155,9 @@ export default function QuizRoom({
}

const sanitizedAnswer = answer ? answer.trim().toLowerCase() : "";
const sanitizedCorrectAnswer = correctAnswers[index]
? correctAnswers[index].trim().toLowerCase()
: "";
const sanitizedCorrectAnswer = atob(correctAnswers[index])
.trim()
.toLowerCase();

const isCorrect = sanitizedAnswer === sanitizedCorrectAnswer;

Expand All @@ -168,7 +170,9 @@ export default function QuizRoom({
}
});

setAnswerStatus(newAnswerStatus);
if (isMounted) {
setAnswerStatus(newAnswerStatus);
}

if (score > 0) {
await fetchBackend(
Expand All @@ -195,7 +199,9 @@ export default function QuizRoom({
false
);

setCompletedQuestions((prev) => [...prev, ...newlyScannedQuestions]);
if (isMounted) {
setCompletedQuestions((prev) => [...prev, ...newlyScannedQuestions]);
}
}

const allGreen = questions.every(
Expand All @@ -204,17 +210,33 @@ export default function QuizRoom({
newAnswerStatus[index] === "correct"
);

if (allGreen) {
if (isMounted && allGreen) {
setOpenPopup(true);
}

setCooldown(10);
if (isMounted) {
setCooldown(10);
}
} catch (error) {
console.error("Error updating team points:", error);
alert("Failed to update team points. Please try again.");
if (isMounted) {
console.error("Error updating team points:", error);
alert("Failed to update team points. Please try again.");
}
}

// Cleanup when function completes
return () => {
isMounted = false;
};
};

// Attach cleanup logic in useEffect
useEffect(() => {
return () => {
// Cleanup any ongoing asynchronous tasks
};
}, []);

const formatTime = (seconds) => {
if (isNaN(seconds) || seconds < 0) {
return "0:00";
Expand Down

0 comments on commit 87862c3

Please sign in to comment.