diff --git a/devU-client/src/assets/global.scss b/devU-client/src/assets/global.scss index 8ffb1e5a..3ae2d520 100644 --- a/devU-client/src/assets/global.scss +++ b/devU-client/src/assets/global.scss @@ -23,6 +23,11 @@ text-align: center; } + hr{ + border: 1px solid #ddd; + margin: 0; + } + a { color: var(--link-blue); } @@ -36,6 +41,10 @@ font-weight: 700; font-size: 16px; transition: all 0.2s ease; + &:disabled{ + opacity: 60%; + cursor: not-allowed; + } } .no_items { @@ -243,6 +252,8 @@ --secondary: #3d3f3f; --secondary-darker: #1f2020; + --link-blue: #0b8cdb; + --list-item-background: #333333; --list-item-background-hover: #303030; --list-item-subtext: #e0e0e0; diff --git a/devU-client/src/assets/variables.scss b/devU-client/src/assets/variables.scss index cdc4cb9b..aa48e2ce 100644 --- a/devU-client/src/assets/variables.scss +++ b/devU-client/src/assets/variables.scss @@ -39,6 +39,7 @@ $grey: var(--grey); $blue-lighter: var(--blue-lighter); $blue: var(--blue); +$link-blue: var(--link-blue); $red-lighter: var(--red-lighter); $red: var(--red); diff --git a/devU-client/src/components/authenticatedRouter.tsx b/devU-client/src/components/authenticatedRouter.tsx index 8913409d..1a3de3fe 100644 --- a/devU-client/src/components/authenticatedRouter.tsx +++ b/devU-client/src/components/authenticatedRouter.tsx @@ -14,7 +14,7 @@ import NonContainerAutoGraderForm from './pages/forms/containers/nonContainerAut import GradebookStudentPage from './pages/gradebook/gradebookStudentPage' import GradebookInstructorPage from './pages/gradebook/gradebookInstructorPage' import SubmissionFeedbackPage from './pages/submissions/submissionFeedbackPage' -import ContainerAutoGraderForm from './pages/forms/containers/ContainerAutoGraderModal' +import ContainerAutoGraderForm from './pages/forms/containers/containerAutoGraderModal' import CoursePreviewPage from './pages/courses/coursePreviewPage' import CoursesListPage from "./pages/listPages/courses/coursesListPage"; import AssignmentProblemFormPage from './pages/forms/assignments/assignmentProblemFormPage' diff --git a/devU-client/src/components/listItems/assignmentProblemListItem.scss b/devU-client/src/components/listItems/assignmentProblemListItem.scss new file mode 100644 index 00000000..901655fc --- /dev/null +++ b/devU-client/src/components/listItems/assignmentProblemListItem.scss @@ -0,0 +1,79 @@ +@import 'variables'; + + +.problem_header{ + font-size:16px; + margin: 0 0 10px 0; +} + +.problem{ + gap: 10px; + padding: 10px 0; +} + + +.textField{ + font-family: $font-family; + font-size: 16px; + background: none; + border: 2px solid #ccc; + color: $text-color; + border-radius: 10px; + padding: 10px; + box-sizing: border-box; + width: 100%; +} + +.mcqLabel{ + display: block; + position: relative; + padding-left: 25px; + margin-bottom: 5px; + cursor: pointer; + width: fit-content; + input { + position: absolute; + opacity: 0; + height: 0; + width: 0; + } + + + .checkbox { + position: absolute; + transition: all .1s ease; + top: 3px; + left: 0; + height: 18px; + width: 18px; + background-color: $background; + border: 1px solid #999; + border-radius: 100px; + margin-left: 0; + } + + + .checkbox::after { + width: 12px; + height: 12px; + border-radius: 100%; + content: ""; + position: absolute; + display: none; + } + + + input:checked { + ~ .checkbox{ + background-color: $primary; + border: 1px solid $primary; + } + ~ .checkbox::after { + display: block; + border: 3px solid #fff; + } + } + &:last-of-type{ + margin-bottom: 0; + } +} \ No newline at end of file diff --git a/devU-client/src/components/listItems/assignmentProblemListItem.tsx b/devU-client/src/components/listItems/assignmentProblemListItem.tsx new file mode 100644 index 00000000..a2b811c8 --- /dev/null +++ b/devU-client/src/components/listItems/assignmentProblemListItem.tsx @@ -0,0 +1,88 @@ +import React, { useState, useEffect} from 'react' +import { useParams } from 'react-router-dom' +import RequestService from 'services/request.service' +import {AssignmentProblem, NonContainerAutoGrader} from 'devu-shared-modules' + +import styles from './assignmentProblemListItem.scss' + +type Props = { + problem: AssignmentProblem + handleChange?: (e : React.ChangeEvent) => void + disabled?: boolean +} + +const AssignmentProblemListItem = ({problem, handleChange, disabled}: Props) => { + const { courseId } = useParams<{ courseId: string }>() + const [ncags, setNcags] = useState([]) + + //const type = ncags.at(0)?.metadata + + const fetchNcags = async() => { + await RequestService.get(`/api/course/${courseId}/assignment/${problem.assignmentId}/non-container-auto-graders`).then((res) => setNcags(res)) + } + + const getMeta = () => { + if (ncags && ncags.length > 0){ + const ncag = ncags.find(ncag => ncag.question == problem.problemName) + if (!ncag || !ncag.metadata) { + return undefined + } + return JSON.parse(ncag.metadata) + } + } + + + useEffect(() => { + fetchNcags() + }, []) + + const meta = getMeta() + if (!meta || !meta.type){ + return ( +
+
) + } + + const type = meta.type + if (type == "Text") { + return ( +
+

{problem.problemName}

+ +
+ )} + else if(type == "MCQ") { + const options = meta.options + if (!options){ + return
+ } + return ( +
+

{problem.problemName}

+ {Object.keys(options).map((key : string) => ( + ))} +
) + } + else { + return( +
Unknown type, something is wrong on the backend!
) + } +} + + +export default AssignmentProblemListItem \ No newline at end of file diff --git a/devU-client/src/components/listItems/simpleAssignmentListItem.tsx b/devU-client/src/components/listItems/simpleAssignmentListItem.tsx index a1dd63ef..137d4489 100644 --- a/devU-client/src/components/listItems/simpleAssignmentListItem.tsx +++ b/devU-client/src/components/listItems/simpleAssignmentListItem.tsx @@ -14,7 +14,8 @@ const SimpleAssignmentListItem = ({assignment}: Props) => ( className={styles.title} tagStyle={styles.tag} containerStyle={styles.container}>
{assignment.name}
- Due: {wordPrintDate(assignment.dueDate)} |   + Due: {wordPrintDate(assignment.dueDate)} +  |  End: {wordPrintDate(assignment.endDate)}
diff --git a/devU-client/src/components/misc/footer.scss b/devU-client/src/components/misc/footer.scss index 7cd48741..4b288854 100644 --- a/devU-client/src/components/misc/footer.scss +++ b/devU-client/src/components/misc/footer.scss @@ -31,3 +31,8 @@ } } } +@media (max-width: $extreme){ + .footer{ + padding: 10px $phonePadding; + } +} diff --git a/devU-client/src/components/misc/globalToolbar.scss b/devU-client/src/components/misc/globalToolbar.scss index bee326f1..eee6a4f2 100644 --- a/devU-client/src/components/misc/globalToolbar.scss +++ b/devU-client/src/components/misc/globalToolbar.scss @@ -34,7 +34,7 @@ $font-size: 16px; } .bar { - height: $bar-height; + min-height: $bar-height; background-color: $primary; font-size: 40px; color: #D9D9D9; diff --git a/devU-client/src/components/pages/assignments/assignmentDetailPage.scss b/devU-client/src/components/pages/assignments/assignmentDetailPage.scss index e7658399..dfe21f0d 100644 --- a/devU-client/src/components/pages/assignments/assignmentDetailPage.scss +++ b/devU-client/src/components/pages/assignments/assignmentDetailPage.scss @@ -12,7 +12,6 @@ .details{ display: grid; grid-template-columns: 1fr 1fr; - width: 100%; gap: 10px; margin-top: 10px; } @@ -21,6 +20,7 @@ width: 100%; text-align: left; flex-direction: column; + overflow-wrap: anywhere; display: flex; align-items: flex-start; } @@ -29,10 +29,12 @@ display: flex; flex-direction: column; gap: 10px; - width: 95%; + margin-left: auto; padding: 20px; + width: 100%; + box-sizing: border-box; font-size: 16px; - background-color: $secondary-lighter; + background-color: $list-item-background-hover; border-radius: 20px } @@ -61,28 +63,20 @@ flex-direction: row; align-items: center; gap:10px; + flex-wrap: wrap; justify-content: flex-end; } .problems_list{ width: 50%; + gap: 10px; } -.problem_header{ - font-size:16px; - margin: 0 0 10px 0; -} .no_problems{ font-style: italic; text-align: center; margin-top: 10px; } -.textField{ - align-items: center; - margin-bottom: 0; - background: none; - border: 2px solid #ccc; -} .submit_container{ display: flex; @@ -93,13 +87,20 @@ .affirmation{ display: flex; align-items: center; + margin-top: 10px; align-self: flex-start; gap: 10px; } + .affirmText{ color: $text-color; } +.handinHistory{ + text-decoration: underline; + cursor: pointer +} + .line { border: none; @@ -249,7 +250,7 @@ padding: 10px; } -@media (max-width: 768px) { +@media (max-width: $extreme) { .wrap { flex-direction: column; align-items: center; @@ -284,6 +285,9 @@ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); margin: 20px; } + .problems_list{ + width: 100%; + } } @media (max-width: 370px) { diff --git a/devU-client/src/components/pages/assignments/assignmentDetailPage.tsx b/devU-client/src/components/pages/assignments/assignmentDetailPage.tsx index 62c5dae0..2866b4bd 100644 --- a/devU-client/src/components/pages/assignments/assignmentDetailPage.tsx +++ b/devU-client/src/components/pages/assignments/assignmentDetailPage.tsx @@ -1,8 +1,8 @@ import React, {useEffect, useState} from 'react' import {useHistory, useParams} from 'react-router-dom' import PageWrapper from 'components/shared/layouts/pageWrapper' -import TextField from 'components/shared/inputs/textField' -import {Assignment, AssignmentProblem, Course, Submission, /*SubmissionScore NonContainerAutoGrader, /*ContainerAutoGrader*/} from 'devu-shared-modules' +import AssignmentProblemListItem from 'components/listItems/assignmentProblemListItem' +import {Assignment, AssignmentProblem, Course, Submission, NonContainerAutoGrader /*SubmissionScore, /*ContainerAutoGrader*/} from 'devu-shared-modules' import RequestService from 'services/request.service' import ErrorPage from '../errorPage/errorPage' import LoadingOverlay from 'components/shared/loaders/loadingOverlay' @@ -27,16 +27,13 @@ const AssignmentDetailPage = () => { const { assignmentId, courseId } = useParams<{assignmentId: string, courseId: string}>() const userId = useAppSelector((store) => store.user.id) const role = useAppSelector((store) => store.roleMode) - role; const [error, setError] = useState(null) const [loading, setLoading] = useState(true) - const [formData, setFormData] = useState({}) + const [formData, setFormData] = useState<{ [key: string]: string }>({}) const [file, setFile] = useState() const [assignmentProblems, setAssignmentProblems] = useState(new Array()) const [submissions, setSubmissions] = useState(new Array()) - //const [submissionScores, setSubmissionScores] = useState(new Array()) - // const [submissionProblemScores, setSubmissionProblemScores] = useState(new Array()) const [assignment, setAssignment] = useState() const [course, setCourse] = useState() const [notClickable, setClickable] = useState(true); @@ -45,10 +42,9 @@ const AssignmentDetailPage = () => { // const [containerAutograder, setContainerAutograder] = useState() // const contaierAutograder = false; //TODO: Use the above commented out code to get the container autograder - // const [ setNonContainerAutograders] = useState(new Array ()) + const [nonContainerAutograders, setNonContainerAutograders] = useState(new Array ()) const [showScoreboard, setShowScoreboard] = useState(false); setShowScoreboard; - assignmentProblems; const location = useLocation(); useEffect(() => { @@ -86,9 +82,9 @@ const AssignmentDetailPage = () => { // const containerAutograder = (await RequestService.get(`/api/course/${courseId}/assignment/${assignmentId}/container-auto-graders`)).pop() ?? null // setContainerAutograder(containerAutograder) - // const nonContainers = await RequestService.get(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders`) - // setNonContainerAutograders(nonContainers) - + const nonContainers = await RequestService.get(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders`) + setNonContainerAutograders(nonContainers) + nonContainerAutograders } catch (err:any) { setError(err) @@ -101,13 +97,37 @@ const AssignmentDetailPage = () => { if (loading) return if (error) return - - const handleChange = (value: string, e : React.ChangeEvent) => { - console.log(e) - console.log(value) - const key = e.target.id - setFormData(prevState => ({...prevState,[key] : e.target.value})) - } + + const handleChange = (e: React.ChangeEvent) => { + const type = e.target.type; + const value = e.target.value; + const key = e.target.id; + + if (type === 'checkbox') { // behavior for multiple choic questions + const newState = e.target.checked; + + setFormData(prevState => { + const currentValue = prevState[key] || ""; + let res = ''; + if (newState) { + res = currentValue + value + } else { + res = currentValue.replace(value, "") + } + res = res.split('').sort().join('') // makes selecting answers in any order correct + return { + ...prevState, + [key]: res + }; + }); + + } else { + setFormData(prevState => ({ + ...prevState, + [key]: value + })); + } + }; const handleFileChange = (e : React.ChangeEvent) => { @@ -122,7 +142,7 @@ const AssignmentDetailPage = () => { let response; const contentField = { filepaths : [], - form : formData, + form : formData } const submission = { userId : userId, @@ -131,6 +151,8 @@ const AssignmentDetailPage = () => { content : JSON.stringify(contentField), } + console.log(contentField) + setLoading(true) try { @@ -172,7 +194,6 @@ const AssignmentDetailPage = () => { }; isSubmissionDisabled; handleFileChange; - handleSubmit; return( @@ -199,7 +220,7 @@ const AssignmentDetailPage = () => { history.push(`/course/${courseId}/assignment/${assignmentId}/submissions`)} - style={{color:'#075D92', textDecoration: 'underline', cursor: 'pointer'}}>View Handin History + className={styles.handinHistory}>View Handin History @@ -223,22 +244,18 @@ const AssignmentDetailPage = () => {
-

Problems

+

Problems

{assignmentProblems.length != 0 ? (assignmentProblems.map((problem) => ( -
-

{problem.problemName}

- -
+ <> + +
+ ))) :
No problems yet...
} - {!(isSubmissionDisabled()) &&assignmentProblems && assignmentProblems.length > 0 ? ( + {!(isSubmissionDisabled()) && assignmentProblems && assignmentProblems.length > 0 ? (
- I affirm that I have complied with this course’s academic integrity policy as defined in the syllabus. + I affirm that I have complied with this course's academic integrity policy as defined in the syllabus.
+
@@ -343,21 +354,20 @@ const AssignmentUpdatePage = () => { {(files.length != 0) ? (
Files: - {files.slice(0,-1).map((file, index) => ( + {files.slice(0,-1).map((file, index) => ( // For some reason the most recent file appears twice, so I did this as a quick fix, should be fixed in future
 {`${file.name},`}
))}
 {`${files[files.length-1].name}`}
-
) :
No files attached
} @@ -366,9 +376,9 @@ const AssignmentUpdatePage = () => {

Add Problems

- + - +

Add Graders

@@ -388,24 +398,22 @@ const AssignmentUpdatePage = () => { Code Grader
))} {nonContainerAutograders.length == 0 && containerAutograders.length == 0 &&
No graders yet
}

Problems

- - {assignmentProblems.length != 0 ? (assignmentProblems.map((problem) => ( -
-

{problem.problemName}

- -
- | - +
+ {assignmentProblems.length != 0 ? (assignmentProblems.map((problem) => ( +
+ +
+ | + +
+
-
- ))) :
No problems yet
} - + ))) :
No problems yet
} +
- +
diff --git a/devU-client/src/components/pages/forms/assignments/AddProblemModal.tsx b/devU-client/src/components/pages/forms/assignments/codeProblemModal.tsx similarity index 73% rename from devU-client/src/components/pages/forms/assignments/AddProblemModal.tsx rename to devU-client/src/components/pages/forms/assignments/codeProblemModal.tsx index 28e46c75..f26e5463 100644 --- a/devU-client/src/components/pages/forms/assignments/AddProblemModal.tsx +++ b/devU-client/src/components/pages/forms/assignments/codeProblemModal.tsx @@ -5,14 +5,13 @@ import { SET_ALERT } from 'redux/types/active.types'; import { useActionless } from 'redux/hooks'; import RequestService from 'services/request.service'; import Modal from 'components/shared/layouts/modal'; -import styles from './modal.module.scss'; interface Props { open: boolean; onClose: () => void; } -const AddProblemModal = ({ open, onClose }: Props) => { +const CodeProblemModal = ({ open, onClose }: Props) => { const [setAlert] = useActionless(SET_ALERT); const { assignmentId } = useParams<{ assignmentId: string }>(); const { courseId } = useParams<{ courseId: string }>(); @@ -22,8 +21,13 @@ const AddProblemModal = ({ open, onClose }: Props) => { maxScore: '', }); + const submittable = () => { + if (!formData.title || !formData.maxScore) {return false} + else {return true} + } + const handleSubmit = () => { - if (!formData.title || !formData.maxScore) return; + if (!submittable) return; const problemFormData = { assignmentId: parseInt(assignmentId), @@ -50,31 +54,29 @@ const AddProblemModal = ({ open, onClose }: Props) => { }; return ( - -
- + +
+ - - +
+ +
+ - -
); }; -export default AddProblemModal; +export default CodeProblemModal; diff --git a/devU-client/src/components/pages/forms/assignments/multipleChoiceModal.tsx b/devU-client/src/components/pages/forms/assignments/multipleChoiceModal.tsx new file mode 100644 index 00000000..25f8d841 --- /dev/null +++ b/devU-client/src/components/pages/forms/assignments/multipleChoiceModal.tsx @@ -0,0 +1,161 @@ +import React, { useState } from 'react' +import { useParams } from 'react-router-dom' +import { ExpressValidationError } from 'devu-shared-modules' +import { SET_ALERT } from 'redux/types/active.types' +import { useActionless } from 'redux/hooks' +import RequestService from 'services/request.service' +import Modal from 'components/shared/layouts/modal' + +interface Props { + open: boolean; + onClose: () => void; +} + +const MultipleChoiceModal = ({ open, onClose }: Props) => { + const [setAlert] = useActionless(SET_ALERT) + const { assignmentId } = useParams<{ assignmentId: string }>() + const { courseId } = useParams<{ courseId: string }>() + const [options, setOptions] = useState({}) + const [formData, setFormData] = useState({ + title: '', + maxScore: '', + correctAnswer: new Map(), + numCorrect: 0, + regex: false + }); + + const submittable = () => { + if (!formData.title || !formData.maxScore || formData.numCorrect == 0) { return false } + else { return true } + } + + const createCorrectString = () => { + var correctString = '' + formData.correctAnswer.forEach((val, key ) => { + if (val === true){ + correctString += key + } + }) + correctString = correctString.split('').sort().join('') // makes selecting answers in any order correct + return(correctString) + } + + const handleSubmit = () => { + // early return if form not fully filled out + if (!submittable) { return } + + const problemFormData = { + assignmentId: parseInt(assignmentId), + problemName: formData.title, + maxScore: parseInt(formData.maxScore), + }; + + const graderFormData = { + assignmentId: parseInt(assignmentId), + question: formData.title, + correctString: createCorrectString(), + score: Number(formData.maxScore), + isRegex: formData.regex, + metadata: {type: "MCQ", options: options} + } + + RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems`, problemFormData) + .then(() => { + console.log("PROBLEM CREATED") + setAlert({ autoDelete: true, type: 'success', message: 'Problem Added' }); + }) + .catch((err: ExpressValidationError[] | Error) => { + const message = Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message + setAlert({ autoDelete: false, type: 'error', message }) + }) + + RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders/`, graderFormData) + .then(() => { + console.log("GRADER CREATED") + }) + .catch((err: ExpressValidationError[] | Error) => { + const message = Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message + setAlert({ autoDelete: false, type: 'error', message }) + }) + + console.log(graderFormData) + + // close modal + onClose(); + } + + const handleChange = (e: React.ChangeEvent) => { + const key = e.target.id + const value = e.target.value + + setFormData(prevState => ({ ...prevState, [key]: value })) + } + + const handleQuestionTextChange = (e: React.ChangeEvent) => { + const key = e.target.id + const value = e.target.value + + setOptions(prevState => ({ ...prevState, [key]: value })) + } + + const handleCorrectAnswerChange = (e: React.ChangeEvent) => { + const value = e.target.id + const newState = e.target.checked + setFormData(prevState => { + const correctAnswers = new Map (prevState.correctAnswer) + correctAnswers.set(value, newState) + return { ...prevState, correctAnswer: correctAnswers, numCorrect: formData.numCorrect + (newState ? 1 : -1)} + }) + } + + return ( + +
+ + +
+
+ +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+ + +
+
+ ) +} + +export default MultipleChoiceModal; \ No newline at end of file diff --git a/devU-client/src/components/pages/forms/assignments/textProblemModal.tsx b/devU-client/src/components/pages/forms/assignments/textProblemModal.tsx index 55081a57..b8f6faf7 100644 --- a/devU-client/src/components/pages/forms/assignments/textProblemModal.tsx +++ b/devU-client/src/components/pages/forms/assignments/textProblemModal.tsx @@ -22,9 +22,14 @@ const TextProblemModal = ({ open, onClose }: Props) => { regex: false }); + const submittable = () => { + if (!formData.title || !formData.maxScore || !formData.correctAnswer) { return false } + else {return true} + } + const handleSubmit = () => { // early return if form not fully filled out - if (!formData.title || !formData.maxScore || !formData.correctAnswer) { return } + if (!submittable) { return } const problemFormData = { assignmentId: parseInt(assignmentId), @@ -38,11 +43,17 @@ const TextProblemModal = ({ open, onClose }: Props) => { correctString: formData.correctAnswer, score: Number(formData.maxScore), isRegex: formData.regex, + metadata: { + type: 'Text' + } + } RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems`, problemFormData) .then(() => { - console.log("PROBLEM CREATED") + console.log("PROBLEM CREATED"); + setAlert({ autoDelete: true, type: 'success', message: 'Problem Added' }); + }) .catch((err: ExpressValidationError[] | Error) => { const message = Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message @@ -70,7 +81,7 @@ const TextProblemModal = ({ open, onClose }: Props) => { } return ( - +
{
- +
) } diff --git a/devU-client/src/components/pages/forms/containers/ContainerAutoGraderModal.tsx b/devU-client/src/components/pages/forms/containers/containerAutoGraderModal.tsx similarity index 94% rename from devU-client/src/components/pages/forms/containers/ContainerAutoGraderModal.tsx rename to devU-client/src/components/pages/forms/containers/containerAutoGraderModal.tsx index 25550ca2..8d539f62 100644 --- a/devU-client/src/components/pages/forms/containers/ContainerAutoGraderModal.tsx +++ b/devU-client/src/components/pages/forms/containers/containerAutoGraderModal.tsx @@ -45,6 +45,11 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => { const handleMakefileChange = (e : React.ChangeEvent) => { setMakefile(e.target.files?.item(0)) } + const handleChange = (e: React.ChangeEvent) => { + const key = e.target.id; + const value = e.target.value; + setFormData(prevState => ({ ...prevState, [key]: value })); + }; @@ -89,7 +94,7 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
- +
diff --git a/devU-client/src/components/shared/inputs/button.tsx b/devU-client/src/components/shared/inputs/button.tsx index 5cc98dac..e3e6386b 100644 --- a/devU-client/src/components/shared/inputs/button.tsx +++ b/devU-client/src/components/shared/inputs/button.tsx @@ -10,7 +10,6 @@ type Props = { } const Button = ({ className = '', children, loading = false, onClick }: Props) => { - console.log(loading ? styles.isLoading : '') return (
{children} - + ) } diff --git a/devU-client/src/components/shared/layouts/pageWrapper.scss b/devU-client/src/components/shared/layouts/pageWrapper.scss index a021b3da..c33e9453 100644 --- a/devU-client/src/components/shared/layouts/pageWrapper.scss +++ b/devU-client/src/components/shared/layouts/pageWrapper.scss @@ -14,7 +14,7 @@ .content { flex-grow: 1; - padding: 0px 100px 50px 100px; + padding: 0px $pagePadding 70px $pagePadding; } @media (max-width: $extreme){ diff --git a/devU-client/src/components/utils/userOptionsDropdown.scss b/devU-client/src/components/utils/userOptionsDropdown.scss index fa742fb8..47564664 100644 --- a/devU-client/src/components/utils/userOptionsDropdown.scss +++ b/devU-client/src/components/utils/userOptionsDropdown.scss @@ -5,6 +5,9 @@ display: flex; flex-direction: column; position: relative; + //padding: 0 10px; + min-width: 100px; + outline: none; @@ -30,13 +33,15 @@ .trigger { @extend .button; - color: #D9D9D9; - border-radius: 20px; - margin:5px; - height: 40px; + color: #fff; + height: 60px; + margin: 0; + padding: 0 10px; + + transition: background-color 0.2s ease; &:hover { - opacity: 0.7; + background-color: var(--hover-darker); } } @@ -56,17 +61,19 @@ } .menu { - width: 100%; - + min-width: 97%; + width: inherit; position: absolute; - top: 50px; + top: 60px; display: flex; flex-direction: column; + border: 3px solid $primary; + border-top: none; - gap: 2px; + border-bottom-right-radius: 10px; + border-bottom-left-radius: 10px; - box-shadow: $box-shadow; visibility: hidden; opacity: 0; @@ -81,34 +88,38 @@ display: flex; align-items: center; - padding: 0 6px; + padding: 0 10px; - background-color: $primary; - color: $background; + background-color: $background; + color: $text-color; height: 50px; text-align: left; + border-bottom: 1px solid #ddd; text-decoration: none; + transition: background-color 0.2s ease; &:hover { - background: $purple-darker; + background-color: var(--hover-lighter); } + } -.dropCourse { - @extend .option; - background-color: $primary; /* Same as Account and Logout */ - color: $background; /* Matching the text color */ - border: none; - font-size: 16px; - height: 50px; - text-align: left; - text-decoration: none; - &:hover { - background: $purple-darker; - } -} +// .dropCourse { +// @extend .option; +// background-color: $primary; /* Same as Account and Logout */ +// color: $background; /* Matching the text color */ +// border: none; +// font-size: 16px; +// height: 50px; +// text-align: left; +// text-decoration: none; + +// &:hover { +// background: $purple-darker; +// } +// } @media (max-width: $small) { .name { diff --git a/devU-client/src/components/utils/userOptionsDropdown.tsx b/devU-client/src/components/utils/userOptionsDropdown.tsx index 2c4290ba..ee505f53 100644 --- a/devU-client/src/components/utils/userOptionsDropdown.tsx +++ b/devU-client/src/components/utils/userOptionsDropdown.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Link } from 'react-router-dom'; +//import { Link } from 'react-router-dom'; import FaIcon from 'components/shared/icons/faIcon'; import { useAppSelector } from 'redux/hooks'; import RequestService from 'services/request.service'; @@ -7,6 +7,8 @@ import styles from './userOptionsDropdown.scss'; import { useParams, useHistory } from 'react-router-dom' import { SET_ALERT } from 'redux/types/active.types'; import { useActionless } from 'redux/hooks'; +import { Link } from 'react-router-dom'; + const UserOptionsDropdown = () => { const name = useAppSelector((state) => state.user.preferredName || state.user.email); @@ -44,14 +46,16 @@ const UserOptionsDropdown = () => {
- + Account - -