diff --git a/client/src/App.jsx b/client/src/App.jsx
index 3efe80918..a774de9d2 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -6,6 +6,7 @@ import BlocklyPage from './views/BlocklyPage/BlocklyPage';
import BugReport from './views/BugReport/BugReport';
import ContentCreator from './views/ContentCreator/ContentCreator';
import Home from './views/Home/Home';
+import ChallengeCreation from './views/Mentor/Challenges/ChallengeCreation';
import Classroom from './views/Mentor/Classroom/Classroom';
import Dashboard from './views/Mentor/Dashboard/Dashboard';
import NotFound from './views/NotFound';
@@ -20,6 +21,7 @@ import ForgetPassword from './views/TeacherLogin/ForgetPassword';
import ResetPassword from './views/TeacherLogin/ResetPassword';
import TeacherLogin from './views/TeacherLogin/TeacherLogin';
+// FIXME: Challenge creation later has to become a private route
const App = () => {
return (
@@ -32,6 +34,7 @@ const App = () => {
} />
} />
} />
+ } />
{
+const BlocklyCanvasPanel = ({ activity, isSandbox, setActivity, isChallengeActivity }) => {
const [value] = useGlobalState('currUser');
const userRole = value.role;
@@ -21,6 +21,7 @@ const BlocklyCanvasPanel = ({ activity, isSandbox, setActivity }) => {
setActivity={setActivity}
isSandbox={isSandbox}
isMentorActivity={!activity.selectedToolbox && !isSandbox}
+ isChallengeActivity={isChallengeActivity}
/>;
case 'ContentCreator':
return (
diff --git a/client/src/components/ActivityPanels/BlocklyCanvasPanel/canvas/MentorCanvas.jsx b/client/src/components/ActivityPanels/BlocklyCanvasPanel/canvas/MentorCanvas.jsx
index 7d99ef2be..eda5c198a 100644
--- a/client/src/components/ActivityPanels/BlocklyCanvasPanel/canvas/MentorCanvas.jsx
+++ b/client/src/components/ActivityPanels/BlocklyCanvasPanel/canvas/MentorCanvas.jsx
@@ -21,7 +21,7 @@ import PlotterLogo from '../Icons/PlotterLogo';
let plotId = 1;
-export default function MentorCanvas({ activity, isSandbox, setActivity, isMentorActivity }) {
+export default function MentorCanvas({ activity, isSandbox, setActivity, isMentorActivity, isChallengeActivity }) {
const [hoverUndo, setHoverUndo] = useState(false);
const [hoverRedo, setHoverRedo] = useState(false);
const [hoverCompile, setHoverCompile] = useState(false);
@@ -261,6 +261,12 @@ export default function MentorCanvas({ activity, isSandbox, setActivity, isMent
}
}
};
+
+ const handleCreatorChallengeSave = async () => {
+ // FIXME: Handle saving a challenge to the database or updating it if it already exists
+ console.log("Saving a challenge to the database not yet implemented");
+ }
+
const menu = (
);
- const menuSave = (
-
- );
+ const menuSave = (isChallengeActivity) => {
+ console.log(`Menu save sees that challenge activity is: ${isChallengeActivity}`);
+ if (isChallengeActivity) {
+ return (
+
+ );
+ } else {
+ return (
+
+ );
+ }
+ }
return (
@@ -332,7 +352,7 @@ export default function MentorCanvas({ activity, isSandbox, setActivity, isMent
className='flex flex-row'
id='save-dropdown-container'
>
-
+ menuSave(isChallengeActivity)}>
diff --git a/client/src/views/BlocklyPage/BlocklyPage.jsx b/client/src/views/BlocklyPage/BlocklyPage.jsx
index 584766bd6..bb5aa957b 100644
--- a/client/src/views/BlocklyPage/BlocklyPage.jsx
+++ b/client/src/views/BlocklyPage/BlocklyPage.jsx
@@ -11,11 +11,13 @@ import {
import { useGlobalState } from "../../Utils/userState"
export default function BlocklyPage({ isSandbox }) {
+ const [isChallengeActivity, setIsChallengeActivity] = useState(false);
const [value] = useGlobalState("currUser")
const [activity, setActivity] = useState({})
const navigate = useNavigate()
useEffect(() => {
+ setIsChallengeActivity(false);
const setup = async () => {
// if we are in sandbox mode show all toolbox
const sandboxActivity = JSON.parse(localStorage.getItem("sandbox-activity"))
@@ -48,8 +50,13 @@ export default function BlocklyPage({ isSandbox }) {
// else show toolbox based on the activity we are viewing
else {
const localActivity = JSON.parse(localStorage.getItem("my-activity"))
+ // FIXME: Remove this debugging console log
+ console.log(`the following was found for local activity: ${localActivity}`);
if (localActivity) {
+ setIsChallengeActivity(localActivity?.is_challenge == true);
+ // FIXME: Remove this debugging console log
+ console.log(`Set is challenge activity to: ${isChallengeActivity}`);
if (localActivity.toolbox) {
setActivity(localActivity)
} else {
@@ -59,6 +66,7 @@ export default function BlocklyPage({ isSandbox }) {
localStorage.setItem("my-activity", JSON.stringify(loadedActivity))
setActivity(loadedActivity)
+ setIsChallengeActivity(localActivity?.is_challenge == true);
} else {
message.error(res.err)
}
@@ -76,7 +84,7 @@ export default function BlocklyPage({ isSandbox }) {
-
+
)
diff --git a/client/src/views/Mentor/Challenges/BadgeSelection.jsx b/client/src/views/Mentor/Challenges/BadgeSelection.jsx
new file mode 100644
index 000000000..4799aa2e2
--- /dev/null
+++ b/client/src/views/Mentor/Challenges/BadgeSelection.jsx
@@ -0,0 +1,119 @@
+//Import stuff
+import React, { useEffect, useRef, useState, useReducer } from 'react';
+import Badge1 from "../../../Images/Badge1.jpg";
+import Badge2 from "../../../Images/Badge2.jpg";
+
+//Function component to select/view badges
+function BadgeSelection ({onBadgeSelect})
+{
+ //State variable to keep track of current badge using ID
+ const [currentBadgeID, setBadgeID] = useState(0);
+ //Array of badge images - will add more later as I draw them
+ const badgeImages = [Badge1, Badge2];
+
+ //Style for the badge carousel
+ const sliderStyles = {
+ height: "300px",
+ position: "relative",
+ }
+
+ //Style to display each badge
+ const badgeStyles = {
+ width: "300px",
+ height: "300px",
+ borderRadius: "10px",
+ backgroundPosition: "center",
+ backgroundSize: "cover",
+ //Set badge image based on the current badge ID
+ backgroundImage: `url(${badgeImages[currentBadgeID]})`,
+ zIndex: 10,
+
+ }
+
+ //Left arrow style to navigate from each badge
+ const leftArrowStyles = {
+ position: "absolute",
+ top: "50%",
+ transform: "translate(-50%, -50%)",
+ left: "16px",
+ fontSize: '45px',
+ color: "black",
+ zIndex: 1000,
+ cursor: "pointer",
+
+ }
+
+ //Right arrow style to navigate from each badge
+ const rightArrowStyles = {
+ position: "absolute",
+ top: "50%",
+ transform: "translate(-50%, -50%)",
+ right: "32px",
+ fontSize: '45px',
+ color: 'black',
+ zIndex: 1000,
+ cursor: "pointer",
+
+ }
+
+ //Function to navigate to previous badge
+ const goToPrevious = () => {
+ const isFirstBadge = currentBadgeID === 0;
+ const newIndex = isFirstBadge ? badgeImages.length - 1 : currentBadgeID - 1;
+ setBadgeID(newIndex);
+ }
+
+ //Function to navigate to next badge
+ const goToNext = () => {
+ const isLastBadge = currentBadgeID === badgeImages.length - 1;
+ const newIndex = isLastBadge ? 0 : currentBadgeID + 1;
+ setBadgeID(newIndex);
+ }
+
+ //Function to select current badge, and pass to parent component, to use
+ const selectBadge = () => {
+ //Console log to show button is working
+ console.log("Button pressed");
+ onBadgeSelect(currentBadgeID);
+ }
+
+ //Make button appear over other things
+ const buttonStyle = {
+ zIndex: 2000,
+
+
+ }
+ //Fixing sonarcloud bug
+ const keyboardListener = (event) => {
+ //Left and right arrows
+ if (event.key === 'leftArrow')
+ {
+ goToPrevious();
+ }
+ else if (event.key === 'rightArrow')
+ {
+ goToNext();
+ }
+ }
+
+ //Render the badge selection on page
+ //*Needed to change the way of displaying arrows, use unicode
+ return (
+
+
◀
+
+
+
+
▶
+
+
+
+
+
+
+ )
+
+}
+
+export default BadgeSelection;
+
diff --git a/client/src/views/Mentor/Challenges/ChallengeCreation.jsx b/client/src/views/Mentor/Challenges/ChallengeCreation.jsx
new file mode 100644
index 000000000..c7bb9e39b
--- /dev/null
+++ b/client/src/views/Mentor/Challenges/ChallengeCreation.jsx
@@ -0,0 +1,119 @@
+import React, { useState } from 'react';
+import { Form, Input } from "antd"
+import './ChallengeCreation.less';
+import NavBar from '../../../components/NavBar/NavBar';
+import { useGlobalState } from '../../../Utils/userState';
+import { useNavigate } from 'react-router-dom';
+import {
+ getActivityToolboxAll,
+} from "../../../Utils/requests"
+import BadgeSelection from '../../../views/Mentor/Challenges/BadgeSelection.jsx'
+
+export default function ChallengeCreation() {
+ const defaultChallengeData = {
+ name: '',
+ badge: 0,
+ description: '',
+ };
+
+ const [challengeData, setChallengeData] = useState(defaultChallengeData);
+ const [value] = useGlobalState('currUser');
+ const navigate = useNavigate();
+ const [selectedBadge, setSelectedBadge] = useState(null);
+
+ const handleViewActivityTemplate = async () => {
+ // FIXME: Navigate with specific SELECTED information
+ console.log("Navigating to activity template page not yet implemented");
+
+ const allToolBoxRes = await getActivityToolboxAll();
+ const selectedToolBoxRes = await getActivityToolboxAll();
+ let activity = {
+ selectedToolbox: selectedToolBoxRes.data.toolbox,
+ toolbox: allToolBoxRes.data.toolbox,
+ lesson_module_name: challengeData.name,
+ is_challenge: true,
+ }
+ localStorage.setItem("my-activity", JSON.stringify(activity));
+ navigate("/activity");
+ }
+
+ const handleSave = () => {
+ // FIXME: Save information to database
+ console.log("Saving challenge to database not yet implemented")
+ }
+
+ const navigateToAssignChallenge = () => {
+ // FIXME: Navigate to assign challenge page
+ console.log("Navigating to assign challenge page not yet implemented")
+ }
+
+ return (
+