From 53d6e927d8ddc702511613e33d40fbf786a22b6d Mon Sep 17 00:00:00 2001 From: Diego Cabiya Date: Mon, 10 Mar 2025 19:27:06 -0400 Subject: [PATCH 01/97] styling changes to list items, new courses load on creation --- .../listItems/simpleAssignmentListItem.scss | 11 +- .../listItems/simpleAssignmentListItem.tsx | 20 ++-- .../listItems/userCourseListItem.scss | 3 +- .../assignments/assignmentUpdatePage.tsx | 12 +-- .../gradebook/gradebookInstructorPage.scss | 2 +- .../gradebook/gradebookInstructorPage.tsx | 12 ++- .../components/pages/homePage/homePage.tsx | 1 + .../src/components/shared/inputs/button.tsx | 2 +- .../shared/inputs/textDropDown.scss | 7 ++ .../components/shared/inputs/textDropDown.tsx | 100 ++++++++++++++++++ .../components/shared/inputs/textField.scss | 3 +- 11 files changed, 140 insertions(+), 33 deletions(-) create mode 100644 devU-client/src/components/shared/inputs/textDropDown.scss create mode 100644 devU-client/src/components/shared/inputs/textDropDown.tsx diff --git a/devU-client/src/components/listItems/simpleAssignmentListItem.scss b/devU-client/src/components/listItems/simpleAssignmentListItem.scss index 7716d36b..345ccbf2 100644 --- a/devU-client/src/components/listItems/simpleAssignmentListItem.scss +++ b/devU-client/src/components/listItems/simpleAssignmentListItem.scss @@ -49,14 +49,13 @@ flex-direction: column; - border-radius: 0.6rem; - transition: background-color 0.2s linear; + transition: all 0.2s ease; // color: $primary; color: $text-color; - // &:hover, - // &:focus { - // background: $list-simple-item-background-hover; - // } + &:hover, + &:focus { + background-color: $list-item-background-hover; + } } \ 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..1cc2308f 100644 --- a/devU-client/src/components/listItems/simpleAssignmentListItem.tsx +++ b/devU-client/src/components/listItems/simpleAssignmentListItem.tsx @@ -10,16 +10,16 @@ type Props = { } const SimpleAssignmentListItem = ({assignment}: Props) => ( - -
{assignment.name}
-
- Due: {wordPrintDate(assignment.dueDate)} |   - End: {wordPrintDate(assignment.endDate)} -
- - -
+
(e.stopPropagation())}> + +
{assignment.name}
+
+ Due: {wordPrintDate(assignment.dueDate)} |   + End: {wordPrintDate(assignment.endDate)} +
+
+
) diff --git a/devU-client/src/components/listItems/userCourseListItem.scss b/devU-client/src/components/listItems/userCourseListItem.scss index 6e709717..9782d2c7 100644 --- a/devU-client/src/components/listItems/userCourseListItem.scss +++ b/devU-client/src/components/listItems/userCourseListItem.scss @@ -6,7 +6,6 @@ font-weight: 600; margin: 0; padding: 15px; - /* Add padding to the text inside the name block */ background: $primary; width: 100%; text-align: center; @@ -33,12 +32,12 @@ text-overflow: ellipsis; overflow-wrap: break-word; border-bottom: 1px solid #ddd; - } .Buttons { display: flex; justify-content: center; + cursor: default; margin-top: auto; padding: 15px; gap: 20px; diff --git a/devU-client/src/components/pages/forms/assignments/assignmentUpdatePage.tsx b/devU-client/src/components/pages/forms/assignments/assignmentUpdatePage.tsx index 436d265d..09bebfb2 100644 --- a/devU-client/src/components/pages/forms/assignments/assignmentUpdatePage.tsx +++ b/devU-client/src/components/pages/forms/assignments/assignmentUpdatePage.tsx @@ -109,19 +109,15 @@ const AssignmentUpdatePage = () => { } } - const fetchAssignmentProblems = () => { - RequestService.get(`/api/course/${courseId}/assignment/${currentAssignmentId}/assignment-problems`) + const fetchAssignmentProblems = async () => { + await RequestService.get(`/api/course/${courseId}/assignment/${currentAssignmentId}/assignment-problems`) .then((res) => { setAssignmentProblems(res) }) } - - useEffect(() => {RequestService.get(`/api/course/${courseId}/assignments/${assignmentId}`).then((res) => { setFormData(res) })}, []) useEffect(() => {RequestService.get(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems`).then((res) => { setAssignmentProblems(res) })}, []) useEffect(() => {RequestService.get(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders`).then((res) => { setNonContainerAutograders(res) })}, []) useEffect(() => {RequestService.get(`/api/course/${courseId}/assignment/${assignmentId}/container-auto-graders`).then((res) => { setContainerAutograders(res) })}, []) - - /*useEffect(() => {RequestService.get(`/api/course/${courseId}/categories/`).then((res) => { setCategories(res) }).finally(convertToOptions)}, []) const convertToOptions = () => { setAllCategoryOptions(categories.map((category) => ({label: category.name, value: category}))) @@ -209,7 +205,9 @@ const AssignmentUpdatePage = () => { // problemName: '', // maxScore: 0, // }) - const handleCloseTextModal = () => {setTextModal(false)} + const handleCloseTextModal = () => { + setTextModal(false) + } // const handleAddProblemChange = (value: String, e: React.ChangeEvent) => { // const key = e.target.id diff --git a/devU-client/src/components/pages/gradebook/gradebookInstructorPage.scss b/devU-client/src/components/pages/gradebook/gradebookInstructorPage.scss index ded1403d..8793090a 100644 --- a/devU-client/src/components/pages/gradebook/gradebookInstructorPage.scss +++ b/devU-client/src/components/pages/gradebook/gradebookInstructorPage.scss @@ -67,10 +67,10 @@ width: 300px; border-radius: 20px; margin: 0; + border: 2px solid #ccc; } .dropdown{ width: 300px; - border-radius: 20px; margin: 0; } .key{ diff --git a/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx b/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx index 6c07518d..f7816324 100644 --- a/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx +++ b/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx @@ -21,12 +21,11 @@ import { Option } from 'components/shared/inputs/dropdown' const customStyles: Partial>> = { menu: (provided) => ({ ...provided, backgroundColor: 'var(--background)', - border: '2px solid #ddd', borderRadius: '10px' }), input: (provided) => ({ ...provided, - backgroundColor: 'var(--input-field-background)', + backgroundColor: 'var(--background)', borderRadius: '20px', color: 'var(--text-color)', }), @@ -37,9 +36,12 @@ const customStyles: Partial>> = { margin: '0' }), control: (provided) => ({ ...provided, - backgroundColor: 'var(--input-field-background)', cursor: 'pointer', - borderRadius: '20px', padding: '10px', - border: 'none'}), + backgroundColor: 'var(--background)', + cursor: 'pointer', + border: '2px solid #ccc', + borderRadius: '20px', + padding: '10px', + }), singleValue: (provided) => ({ ...provided, color: 'var(--text-color)', diff --git a/devU-client/src/components/pages/homePage/homePage.tsx b/devU-client/src/components/pages/homePage/homePage.tsx index c4074bd6..545a70a7 100644 --- a/devU-client/src/components/pages/homePage/homePage.tsx +++ b/devU-client/src/components/pages/homePage/homePage.tsx @@ -29,6 +29,7 @@ const HomePage = () => { const handleCloseModal = () => { setOpenModal(false); + fetchData() }; const fetchData = async () => { diff --git a/devU-client/src/components/shared/inputs/button.tsx b/devU-client/src/components/shared/inputs/button.tsx index 5cc98dac..72fb2904 100644 --- a/devU-client/src/components/shared/inputs/button.tsx +++ b/devU-client/src/components/shared/inputs/button.tsx @@ -10,7 +10,7 @@ type Props = { } const Button = ({ className = '', children, loading = false, onClick }: Props) => { - console.log(loading ? styles.isLoading : '') + // console.log(loading ? styles.isLoading : '') return ( - + @@ -263,12 +263,12 @@ const AssignmentUpdatePage = () => {
Assignment Category:
- +
Assignment Name:
@@ -307,7 +307,7 @@ const AssignmentUpdatePage = () => { sx={{width: '100%', marginLeft : 1/10}}/>
-
Max File Size:
+
Max File Size (kb):
{ regex: false }); - const handleSubmit = () => { + const handleSubmit = async () => { // early return if form not fully filled out if (!formData.title || !formData.maxScore || !formData.correctAnswer) { return } @@ -40,7 +40,7 @@ const TextProblemModal = ({ open, onClose }: Props) => { isRegex: formData.regex, } - RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems`, problemFormData) + await RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems`, problemFormData) .then(() => { console.log("PROBLEM CREATED") }) @@ -49,7 +49,7 @@ const TextProblemModal = ({ open, onClose }: Props) => { setAlert({ autoDelete: false, type: 'error', message }) }) - RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders/`, graderFormData) + await RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders/`, graderFormData) .then(() => { console.log("GRADER CREATED") }) diff --git a/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx b/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx index f7816324..37f34a9e 100644 --- a/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx +++ b/devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx @@ -170,7 +170,6 @@ const GradebookInstructorPage = () => { setAllCategoryOptions(options); } - , [assignments]) const fetchData = async () => { @@ -216,7 +215,7 @@ const GradebookInstructorPage = () => { }; - const handleCategoryChange = (value:Option) => { + const handleCategoryChange = (value:Option) => { if(!value){ setDisplayedAssignments(assignments) return; diff --git a/devU-client/src/components/shared/inputs/textDropDown.tsx b/devU-client/src/components/shared/inputs/textDropDown.tsx index 4b5cff24..89828255 100644 --- a/devU-client/src/components/shared/inputs/textDropDown.tsx +++ b/devU-client/src/components/shared/inputs/textDropDown.tsx @@ -1,7 +1,8 @@ -import React from 'react' -import CreatableSelect, { Styles, GroupTypeBase } from 'react-select' +import React, { useState, useEffect } from 'react' +import CreatableSelect from 'react-select/creatable' +import { Styles, GroupTypeBase } from 'react-select' +import { getCssVariables } from 'utils/theme.utils' -//import { getCssVariables } from 'utils/theme.utils' import styles from './dropdown.scss' @@ -12,6 +13,7 @@ type Props = { onChange: (value: any) => void onCreate: (value: string) => void defaultOption?: Option + value?: Option placeholder?: string disabled?: boolean search?: boolean @@ -26,28 +28,47 @@ const TextDropdown = ({ onCreate, placeholder, disabled, - search = false, + search = true, defaultOption, className = '', label, + value, custom, }: Props) => { - const handleChange = (option: Option) => onChange(option) + const handleChange = (option: Option) => onChange(option) const handleCreate = (input: string) => onCreate(input) + const [theme, setTheme] = useState(getCssVariables()) + useEffect(() => { + const observer = new MutationObserver(() => setTheme(getCssVariables())) + + observer.observe(document.body, { attributes: true }) + + return () => observer.disconnect() + }) + + + const { textColor, background } = theme + - // Styling into this component isn't really possible with raw css alone due to its implementation - // Because of this we're going to use their style apis const customStyles: Partial>> = { + ...custom, menu: (provided) => ({ ...provided, backgroundColor: 'var(--background)', - borderRadius: '10px' }), + + container: (provided) => ({ ...provided, + width: '100%' + }), + input: (provided) => ({ ...provided, - backgroundColor: 'var(--background)', - borderRadius: '10px', - color: 'var(--text-color)', + backgroundColor: background, + color: textColor, + fontWeight: '500', + "input":{ + fontFamily: 'inherit' + } }), placeholder: (provided) => ({ ...provided, @@ -55,25 +76,30 @@ const TextDropdown = ({ color: '#9c9c9c', margin: '0' }), + control: (provided) => ({ ...provided, - backgroundColor: 'var(--background)', cursor: 'pointer', - borderRadius: '10px', padding: '10px', + backgroundColor: background, + cursor: 'pointer', + borderRadius: '10px', + padding: '8px 2px', border: '2px solid #ccc'}), singleValue: (provided) => ({ ...provided, - color: 'var(--text-color)', + color: textColor, }), - + option: (provided, state) => ({ ...provided, cursor: 'pointer', color: 'var(--color)', borderBottom: '1px solid #ccc', - backgroundColor: state.isFocused ? 'var(--list-item-background-hover)' : 'var(--background)', + backgroundColor: state.isFocused ? 'var(--list-item-background-hover)' : background, "&:last-of-type":{ borderBottom: 'none' } }), + + } return ( @@ -81,19 +107,22 @@ const TextDropdown = ({ {!!label && } null }} /> + {console.log(value)}
+ ) } From 29d92d983bc1629eb2e6a7d5690e75d1c87df44e Mon Sep 17 00:00:00 2001 From: RA341 Date: Tue, 11 Mar 2025 20:12:33 -0400 Subject: [PATCH 03/97] added --build to command --- devU-api/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devU-api/package.json b/devU-api/package.json index f308058c..90773536 100644 --- a/devU-api/package.json +++ b/devU-api/package.json @@ -17,7 +17,7 @@ "pre-commit": "lint-staged", "populate-db": "ts-node-dev ./scripts/populate-db.ts", "tango": "ts-node-dev ./src/tango/tests/tango.endpoint.test.ts", - "api-services": "docker compose -f ../docker-compose.yml --profile dev-api up", + "api-services": "docker compose -f ../docker-compose.yml --profile dev-api up --build", "api-services-stop": "docker compose -f ../docker-compose.yml --profile dev-api stop" }, "lint-staged": { @@ -67,6 +67,7 @@ "cors": "^2.8.5", "devu-shared-modules": "./devu-shared-modules", "express": "^4.17.1", + "express-list-endpoints": "^7.1.1", "express-validator": "^6.14.2", "helmet": "^4.6.0", "jsonwebtoken": "^9.0.2", From 8e6413f630200ae489e78b023b04aca9c509459e Mon Sep 17 00:00:00 2001 From: Diego Cabiya Date: Tue, 11 Mar 2025 20:12:44 -0400 Subject: [PATCH 04/97] finished, dropdown is now on both pages --- .../listItems/simpleAssignmentListItem.tsx | 2 +- .../forms/assignments/assignmentFormPage.scss | 6 +- .../forms/assignments/assignmentFormPage.tsx | 55 +++++++++++--- .../assignments/assignmentUpdatePage.scss | 3 +- .../assignments/assignmentUpdatePage.tsx | 8 +-- .../gradebook/gradebookInstructorPage.tsx | 54 ++------------ .../src/components/shared/inputs/dropdown.tsx | 72 ++++++++++++++++--- .../components/shared/inputs/textDropDown.tsx | 34 +++++++-- .../src/components/shared/layouts/modal.tsx | 2 +- 9 files changed, 152 insertions(+), 84 deletions(-) diff --git a/devU-client/src/components/listItems/simpleAssignmentListItem.tsx b/devU-client/src/components/listItems/simpleAssignmentListItem.tsx index 1cc2308f..ad73dd09 100644 --- a/devU-client/src/components/listItems/simpleAssignmentListItem.tsx +++ b/devU-client/src/components/listItems/simpleAssignmentListItem.tsx @@ -10,7 +10,7 @@ type Props = { } const SimpleAssignmentListItem = ({assignment}: Props) => ( -
(e.stopPropagation())}> +
(e.stopPropagation())}> {/*Wrapped in div so that clicking this item does not propogate to course cards onClick and take you to course detail page */}
{assignment.name}
diff --git a/devU-client/src/components/pages/forms/assignments/assignmentFormPage.scss b/devU-client/src/components/pages/forms/assignments/assignmentFormPage.scss index b815473f..e6a81367 100644 --- a/devU-client/src/components/pages/forms/assignments/assignmentFormPage.scss +++ b/devU-client/src/components/pages/forms/assignments/assignmentFormPage.scss @@ -1,8 +1,6 @@ @import 'variables'; - - h2 { text-align: center; } @@ -16,6 +14,10 @@ p { padding: 0 100px; } +.input { + font-size: 14px; +} + .flex { display: flex; justify-content: space-between; diff --git a/devU-client/src/components/pages/forms/assignments/assignmentFormPage.tsx b/devU-client/src/components/pages/forms/assignments/assignmentFormPage.tsx index 849d375b..449b8931 100644 --- a/devU-client/src/components/pages/forms/assignments/assignmentFormPage.tsx +++ b/devU-client/src/components/pages/forms/assignments/assignmentFormPage.tsx @@ -1,6 +1,6 @@ -import React, { useState } from 'react' +import React, { useState, useEffect } from 'react' // import { useHistory } from 'react-router-dom' -import { ExpressValidationError } from 'devu-shared-modules' +import { ExpressValidationError, Assignment } from 'devu-shared-modules' import 'react-datepicker/dist/react-datepicker.css' // import PageWrapper from 'components/shared/layouts/pageWrapper' @@ -9,6 +9,8 @@ import { useActionless } from 'redux/hooks' // import TextField from 'components/shared/inputs/textField' // import Button from '../../../shared/inputs/button' // import DragDropFile from 'components/utils/dragDropFile' +import { Option } from 'components/shared/inputs/dropdown' + import { SET_ALERT } from 'redux/types/active.types' @@ -17,6 +19,7 @@ import { useParams } from 'react-router-dom' import formStyles from './assignmentFormPage.scss' import Modal from 'components/shared/layouts/modal' +import TextDropdown from 'components/shared/inputs/textDropDown' interface Props { open: boolean; @@ -29,6 +32,8 @@ const AddAssignmentModal = ({ open, onClose }: Props) => { const [endDate, setEndDate] = useState('') const [dueDate, setDueDate] = useState('') const [startDate, setStartDate] = useState('') + const [categoryOptions, setAllCategoryOptions] = useState[]>([]) + const [assignments, setAssignments] = useState([]) const [formData, setFormData] = useState({ courseId: courseId, @@ -47,6 +52,20 @@ const AddAssignmentModal = ({ open, onClose }: Props) => { setFormData(prevState => ({ ...prevState, [key]: value })) } + const handleCategoryChange = (value: Option) => { + setFormData(prevState => ({ ...prevState, categoryName: value.label })) + }; + + const handleCategoryCreate = (value: string) => { + const newOption : Option = {value: value, label: value} + setAllCategoryOptions(prevState => { + const newArr: Option[] = (prevState); + newArr.push(newOption); + return newArr; + }) + setFormData(prevState => ({ ...prevState, categoryName: value })) + }; + const handleStartDateChange = (e: React.ChangeEvent) => { setStartDate(e.target.value) } const handleEndDateChange = (e: React.ChangeEvent) => { setEndDate(e.target.value) } const handleDueDateChange = (e: React.ChangeEvent) => { setDueDate(e.target.value) } @@ -99,36 +118,54 @@ const AddAssignmentModal = ({ open, onClose }: Props) => { .finally(() => { }) - } + useEffect(() => {RequestService.get(`/api/course/${courseId}/assignments`).then((res) => { setAssignments(res) })}, [formData]) + + + useEffect(() => { + const categories = [...new Set(assignments.map(a => a.categoryName))]; + const options = categories.map((category) => ({ + value: category, + label: category + })); + + setAllCategoryOptions(options); + }, [assignments]) return (
- + ({border:'none', padding:'3px 0'}), + placeholder: () => ({color: '#555555'}), + input: () => ({fontSize: '14px'}), + singleValue: () => ({fontSize: '14px'})}} + value={formData.categoryName ? {value: formData.categoryName, label: formData.categoryName} : undefined}/>
-
-