From 84a97867d2e84559dd66964deac7b2610c6f54f0 Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:35:25 -0500 Subject: [PATCH 01/15] started working on task list --- .env.development | 4 +- .../RAView/components/TaskList/index.jsx | 38 +++++++++++++++++++ src/views/ResLife/components/RAView/index.jsx | 4 ++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/views/ResLife/components/RAView/components/TaskList/index.jsx diff --git a/.env.development b/.env.development index 31f0c9be3b..d2f195b210 100644 --- a/.env.development +++ b/.env.development @@ -4,8 +4,8 @@ # VITE_API_URL=https://360Api.gordon.edu/ # @TRAIN - VITE_API_URL=https://360Apisp.gordon.edu/ +# VITE_API_URL=https://360Apisp.gordon.edu/ # @LOCALHOST -# VITE_API_URL=http://localhost:51644/ + VITE_API_URL=http://localhost:51628/ diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx new file mode 100644 index 0000000000..a22464b257 --- /dev/null +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -0,0 +1,38 @@ +import { + Card, + CardContent, + CardHeader, + Checkbox, + Container, + FormControl, + FormControlLabel, + Grid, + Typography, +} from '@mui/material'; +import { React, useEffect, useState } from 'react'; +import { ListItemIcon, ListItemText, ListSubheader, List, ListItem, Link } from '@mui/material'; + +// const [checked, setChecked] = useState(0); + +// const handleTaskCheckOff = (value) => { +// setChecked(value); +// }; + +const TaskList = () => ( + + + + + + + + No tasks to see + + + + + + +); + +export default TaskList; diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 00d393c286..7e59dff729 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -19,6 +19,7 @@ import { } from '@mui/material'; import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import Links from './components/Links'; +import TaskList from './components/TaskList'; import MyHall from '../ResidentView/components/MyHall/index'; import { React, useCallback, useEffect, useState } from 'react'; import SimpleSnackbar from 'components/Snackbar'; @@ -400,6 +401,9 @@ const RAView = () => { + + + )} From 370180b54e41c57e2a5e3c833e2c2ccf25c60df9 Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sat, 25 Jan 2025 20:27:51 -0500 Subject: [PATCH 02/15] change name --- .../ResLife/components/RAView/components/TaskList/index.jsx | 2 +- src/views/ResLife/components/RAView/index.jsx | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index a22464b257..8d831399f8 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -21,7 +21,7 @@ import { ListItemIcon, ListItemText, ListSubheader, List, ListItem, Link } from const TaskList = () => ( - + diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 7e59dff729..75f5ddf25b 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -386,6 +386,9 @@ const RAView = () => { {checkInButton()} + + + )} {isMobile && ( From 3bcb44bdb3ac5da2062fae4d1ec7131bf7d4a77e Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sat, 25 Jan 2025 22:46:09 -0500 Subject: [PATCH 03/15] add API calls --- src/services/residentLife/Tasks.ts | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/services/residentLife/Tasks.ts diff --git a/src/services/residentLife/Tasks.ts b/src/services/residentLife/Tasks.ts new file mode 100644 index 0000000000..8bc7ffad98 --- /dev/null +++ b/src/services/residentLife/Tasks.ts @@ -0,0 +1,34 @@ +import http from '../http'; + +type Task = { + Name: string; + Description: string; + HallID: string; + IsRecurring: boolean; + Frequency: string; + Interval: number; + StartDate: Date; + EndDate?: Date; + CreatedDate: Date; + CompletedDate?: Date; + CompletedBy?: string; + OccurDate?: Date; +}; + +const createTask = (newTask: Task) => http.post('Housing/halls/task', newTask); + +const updateTask = (taskID: number, newTask: Task) => + http.patch(`Housing/halls/task/${taskID}`, newTask); + +const deleteTask = (taskID: number) => http.del(`Housing/halls/task/${taskID}`); + +const completeTask = (taskID: number, completedBy: string) => + http.patch(`Housing/halls/task/Complete/${taskID}`, completedBy); + +const getActiveTasksForHall = (hallID: string): Promise => + http.get(`Housing/Halls/${hallID}/ActiveTasks`); + +const getTasksForHall = (hallID: string): Promise => + http.get(`Housing/Halls/${hallID}/DailyTasks`); + +export { createTask, updateTask, deleteTask, completeTask, getActiveTasksForHall, getTasksForHall }; From 5f316774918f2e30cdc5ac353161cbc0da11b942 Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sun, 2 Feb 2025 17:20:48 -0500 Subject: [PATCH 04/15] more work --- .../components/RAView/components/TaskList/index.jsx | 7 +++++++ src/views/ResLife/components/RAView/index.jsx | 12 ++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 8d831399f8..c708f90b5e 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -11,6 +11,7 @@ import { } from '@mui/material'; import { React, useEffect, useState } from 'react'; import { ListItemIcon, ListItemText, ListSubheader, List, ListItem, Link } from '@mui/material'; +import { completeTask, getActiveTasksForHall, getTasksForHall } from 'services/residentLife/Tasks'; // const [checked, setChecked] = useState(0); @@ -18,6 +19,12 @@ import { ListItemIcon, ListItemText, ListSubheader, List, ListItem, Link } from // setChecked(value); // }; +// useEffect(() => { +// const fetchData = async () => {}; + +// fetchData(); +// }); + const TaskList = () => ( diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 75f5ddf25b..b37d851229 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -379,15 +379,15 @@ const RAView = () => { <> - + {isCheckedIn ? : null} {contactMethod()} - + {checkInButton()} - - + + )} @@ -402,10 +402,10 @@ const RAView = () => { {contactMethod()} - + {isCheckedIn ? : null} - + )} From 3a5d87ada2efc2902772f1cac168092ec7e917d6 Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sun, 2 Feb 2025 18:12:33 -0500 Subject: [PATCH 05/15] fix ui --- src/views/ResLife/components/RAView/index.jsx | 84 ++++++++++--------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index b37d851229..0de302cb24 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -334,43 +334,41 @@ const RAView = () => { ); const contactMethod = () => ( - - - - - - }> - Select Contact Method - - - - + + + + }> + Select Contact Method + + + + + } label="Teams" /> + } label="Phone" /> + - - - - - - *This is your preferred method to be contacted by your hall's residents. - - - - + Submit + + + + + + + *This is your preferred method to be contacted by your hall's residents. + + + ); return ( @@ -378,10 +376,14 @@ const RAView = () => { {!isMobile && ( <> - - {isCheckedIn ? : null} + {isCheckedIn ? ( + + + + ) : null} + + {contactMethod()} - {contactMethod()} @@ -400,7 +402,9 @@ const RAView = () => { - {contactMethod()} + + {contactMethod()} + {isCheckedIn ? : null} From 46ff077e7e3cb826afd6f6e19b44d5448ce00084 Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Tue, 4 Feb 2025 19:16:51 -0500 Subject: [PATCH 06/15] more work --- src/services/residentLife/Tasks.ts | 12 +- .../RAView/components/TaskList/index.jsx | 222 +++++++++++++++--- src/views/ResLife/components/RAView/index.jsx | 1 + 3 files changed, 202 insertions(+), 33 deletions(-) diff --git a/src/services/residentLife/Tasks.ts b/src/services/residentLife/Tasks.ts index 8bc7ffad98..bc7c3942a6 100644 --- a/src/services/residentLife/Tasks.ts +++ b/src/services/residentLife/Tasks.ts @@ -1,6 +1,6 @@ import http from '../http'; -type Task = { +export type Task = { Name: string; Description: string; HallID: string; @@ -15,6 +15,16 @@ type Task = { OccurDate?: Date; }; +export type DailyTask = { + TaskID: number; + Name: string; + Description: string; + HallID: string; + CompletedDate?: Date; + CompletedBy?: string; + OccurDate?: Date; +}; + const createTask = (newTask: Task) => http.post('Housing/halls/task', newTask); const updateTask = (taskID: number, newTask: Task) => diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index c708f90b5e..17d6f1e6e7 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -9,37 +9,195 @@ import { Grid, Typography, } from '@mui/material'; -import { React, useEffect, useState } from 'react'; -import { ListItemIcon, ListItemText, ListSubheader, List, ListItem, Link } from '@mui/material'; -import { completeTask, getActiveTasksForHall, getTasksForHall } from 'services/residentLife/Tasks'; - -// const [checked, setChecked] = useState(0); - -// const handleTaskCheckOff = (value) => { -// setChecked(value); -// }; - -// useEffect(() => { -// const fetchData = async () => {}; - -// fetchData(); -// }); - -const TaskList = () => ( - - - - - - - - No tasks to see - - - - - - -); +import { React, useCallback, useEffect, useState } from 'react'; +import { + IconButton, + ListItemIcon, + ListItemText, + ListItemButton, + ListSubheader, + List, + ListItem, + Link, +} from '@mui/material'; +import CommentIcon from '@mui/icons-material/Comment'; +import { completeTask, getTasksForHall } from 'services/residentLife/Tasks'; +import { useUser } from 'hooks'; +import GordonDialogBox from 'components/GordonDialogBox'; +import SimpleSnackbar from 'components/Snackbar'; + +const TaskList = () => { + //const [taskTEMPList, setTaskList] = useState([]); + const taskList = [ + { + TaskID: 0, + Name: 'Clean', + Description: 'please clean', + HallID: 'brom', + }, + { + TaskID: 1, + Name: 'more Clean', + Description: 'please more clean', + HallID: 'ferr', + }, + { + TaskID: 2, + Name: 'take out trash', + Description: 'trashcan full', + HallID: 'fult', + }, + { + TaskID: 3, + Name: 'posters put up', + Description: 'please please posters', + HallID: 'evan', + }, + ]; + //const { profile } = useUser(); + const [descriptionOpen, setDescriptionOpen] = useState(false); + const [taskCheckedOpen, setTaskCheckedOpen] = useState(false); + const [checkedList, setCheckedList] = useState([]); + const [disabledList, setDisabledList] = useState([]); + const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); + + const createSnackbar = useCallback((message, severity) => { + setSnackbar({ message, severity, open: true }); + }, []); + + // useEffect(() => { + // const fetchTaskList = async () => { + // try { + // // also needs hallID aka a new api + // const tasks = await getTasksForHall(); + // setTaskList(tasks); + // } catch {} + // }; + // fetchTaskList(); + // }); + + const testTaskList = [ + { + TaskID: 0, + Name: 'Clean', + Description: 'please clean', + HallID: 'brom', + }, + { + TaskID: 1, + Name: 'more Clean', + Description: 'please more clean', + HallID: 'ferr', + }, + { + TaskID: 2, + Name: 'take out trash', + Description: 'trashcan full', + HallID: 'fult', + }, + { + TaskID: 3, + Name: 'posters put up', + Description: 'please please posters', + HallID: 'evan', + }, + ]; + + const handleConfirm = async (index, taskID) => { + try { + //await completeTask(taskID, profile.ID); + setTaskCheckedOpen(false); + setCheckedList[index] = true; + setDisabledList[index] = true; + createSnackbar(`Completed task: ${setCheckedList[index].Name}`, 'success'); + } catch (error) { + console.error('Error completing task', error); + createSnackbar('Failed to complete task. Please try again.', 'error'); + } + }; + + const handleTaskChecked = (index, taskID) => { + return ( + setTaskCheckedOpen(false)} + title={'Complete Task'} + buttonName="Confirm" + buttonClicked={handleConfirm(index, taskID)} + cancelButtonName="CANCEL" + cancelButtonClicked={() => setTaskCheckedOpen(false)} + > + ); + }; + + const handleClickDescription = (taskIndex) => { + return ( + setDescriptionOpen(false)} + title={'Task Description'} + > + + {taskList[taskIndex].Description.length == 0 + ? 'No description provided' + : taskList[taskIndex].Description} + + + ); + }; + + // map through array of tasks + // component of list item name, checkbox, and description + // if description is not blank, return, otherwise "No description provided" + return ( + + + + + + + {taskList.length == 0 ? ( + + No tasks to see + + ) : ( + taskList.map((task, index) => { + + + + } + > + + + + + + + ; + }) + )} + + + + + + ); +}; export default TaskList; diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 0de302cb24..6e58b024f7 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -371,6 +371,7 @@ const RAView = () => { ); + // NOTE: return a task list for each hall return ( {!isMobile && ( From 4552b24d9da6818c41440268325bc51201738a6e Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Thu, 6 Feb 2025 18:30:36 -0500 Subject: [PATCH 07/15] some debugging (save me) --- .../RAView/components/TaskList/index.jsx | 117 +++++++++--------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 17d6f1e6e7..95f74d82b8 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -26,34 +26,37 @@ import { useUser } from 'hooks'; import GordonDialogBox from 'components/GordonDialogBox'; import SimpleSnackbar from 'components/Snackbar'; +const taskList = [ + { + TaskID: 0, + Name: 'Clean', + Description: 'please clean', + HallID: 'brom', + }, + { + TaskID: 1, + Name: 'more Clean', + Description: 'please more clean', + HallID: 'ferr', + }, + { + TaskID: 2, + Name: 'take out trash', + Description: 'trashcan full', + HallID: 'fult', + }, + { + TaskID: 3, + Name: 'posters put up', + Description: 'please please posters', + HallID: 'evan', + }, +]; + const TaskList = () => { //const [taskTEMPList, setTaskList] = useState([]); - const taskList = [ - { - TaskID: 0, - Name: 'Clean', - Description: 'please clean', - HallID: 'brom', - }, - { - TaskID: 1, - Name: 'more Clean', - Description: 'please more clean', - HallID: 'ferr', - }, - { - TaskID: 2, - Name: 'take out trash', - Description: 'trashcan full', - HallID: 'fult', - }, - { - TaskID: 3, - Name: 'posters put up', - Description: 'please please posters', - HallID: 'evan', - }, - ]; + + // console.log(taskList.length); //const { profile } = useUser(); const [descriptionOpen, setDescriptionOpen] = useState(false); const [taskCheckedOpen, setTaskCheckedOpen] = useState(false); @@ -61,9 +64,9 @@ const TaskList = () => { const [disabledList, setDisabledList] = useState([]); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); - const createSnackbar = useCallback((message, severity) => { - setSnackbar({ message, severity, open: true }); - }, []); + // const createSnackbar = useCallback((message, severity) => { + // setSnackbar({ message, severity, open: true }); + // }, []); // useEffect(() => { // const fetchTaskList = async () => { @@ -76,32 +79,32 @@ const TaskList = () => { // fetchTaskList(); // }); - const testTaskList = [ - { - TaskID: 0, - Name: 'Clean', - Description: 'please clean', - HallID: 'brom', - }, - { - TaskID: 1, - Name: 'more Clean', - Description: 'please more clean', - HallID: 'ferr', - }, - { - TaskID: 2, - Name: 'take out trash', - Description: 'trashcan full', - HallID: 'fult', - }, - { - TaskID: 3, - Name: 'posters put up', - Description: 'please please posters', - HallID: 'evan', - }, - ]; + // const testTaskList = [ + // { + // TaskID: 0, + // Name: 'Clean', + // Description: 'please clean', + // HallID: 'brom', + // }, + // { + // TaskID: 1, + // Name: 'more Clean', + // Description: 'please more clean', + // HallID: 'ferr', + // }, + // { + // TaskID: 2, + // Name: 'take out trash', + // Description: 'trashcan full', + // HallID: 'fult', + // }, + // { + // TaskID: 3, + // Name: 'posters put up', + // Description: 'please please posters', + // HallID: 'evan', + // }, + // ]; const handleConfirm = async (index, taskID) => { try { @@ -109,10 +112,10 @@ const TaskList = () => { setTaskCheckedOpen(false); setCheckedList[index] = true; setDisabledList[index] = true; - createSnackbar(`Completed task: ${setCheckedList[index].Name}`, 'success'); + //createSnackbar(`Completed task: ${setCheckedList[index].Name}`, 'success'); } catch (error) { console.error('Error completing task', error); - createSnackbar('Failed to complete task. Please try again.', 'error'); + //createSnackbar('Failed to complete task. Please try again.', 'error'); } }; From b28044ddcb90833290c0c02be907e80d391a96fb Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sat, 8 Feb 2025 16:46:08 -0500 Subject: [PATCH 08/15] more work --- src/services/residentLife/Tasks.ts | 13 +- .../RAView/components/TaskList/index.jsx | 172 ++++++++---------- src/views/ResLife/components/RAView/index.jsx | 6 +- src/views/ResLife/index.jsx | 17 +- 4 files changed, 108 insertions(+), 100 deletions(-) diff --git a/src/services/residentLife/Tasks.ts b/src/services/residentLife/Tasks.ts index bc7c3942a6..b16c6eccdf 100644 --- a/src/services/residentLife/Tasks.ts +++ b/src/services/residentLife/Tasks.ts @@ -41,4 +41,15 @@ const getActiveTasksForHall = (hallID: string): Promise => const getTasksForHall = (hallID: string): Promise => http.get(`Housing/Halls/${hallID}/DailyTasks`); -export { createTask, updateTask, deleteTask, completeTask, getActiveTasksForHall, getTasksForHall }; +const getRACurrentHalls = (userName: string): Promise => + http.get(`Housing/halls/on-calls/${userName}/locations`); + +export { + createTask, + updateTask, + deleteTask, + completeTask, + getActiveTasksForHall, + getTasksForHall, + getRACurrentHalls, +}; diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 95f74d82b8..f231d01532 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -21,7 +21,7 @@ import { Link, } from '@mui/material'; import CommentIcon from '@mui/icons-material/Comment'; -import { completeTask, getTasksForHall } from 'services/residentLife/Tasks'; +import { completeTask, getTasksForHall, getRACurrentHalls } from 'services/residentLife/Tasks'; import { useUser } from 'hooks'; import GordonDialogBox from 'components/GordonDialogBox'; import SimpleSnackbar from 'components/Snackbar'; @@ -54,68 +54,53 @@ const taskList = [ ]; const TaskList = () => { - //const [taskTEMPList, setTaskList] = useState([]); + const [taskList, setTaskList] = useState([]); // console.log(taskList.length); - //const { profile } = useUser(); + const { profile } = useUser(); const [descriptionOpen, setDescriptionOpen] = useState(false); const [taskCheckedOpen, setTaskCheckedOpen] = useState(false); const [checkedList, setCheckedList] = useState([]); const [disabledList, setDisabledList] = useState([]); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); + const [hallList, setHallList] = useState([]); - // const createSnackbar = useCallback((message, severity) => { - // setSnackbar({ message, severity, open: true }); - // }, []); + const createSnackbar = useCallback((message, severity) => { + setSnackbar({ message, severity, open: true }); + }, []); - // useEffect(() => { - // const fetchTaskList = async () => { - // try { - // // also needs hallID aka a new api - // const tasks = await getTasksForHall(); - // setTaskList(tasks); - // } catch {} - // }; - // fetchTaskList(); - // }); + useEffect(() => { + const fetchCheckedInHalls = async () => { + try { + const halls = await getRACurrentHalls(profile.AD_Username); + setHallList(halls); + } catch (error) { + console.log('Error fetching halls', error); + } + }; + fetchCheckedInHalls(); - // const testTaskList = [ - // { - // TaskID: 0, - // Name: 'Clean', - // Description: 'please clean', - // HallID: 'brom', - // }, - // { - // TaskID: 1, - // Name: 'more Clean', - // Description: 'please more clean', - // HallID: 'ferr', - // }, - // { - // TaskID: 2, - // Name: 'take out trash', - // Description: 'trashcan full', - // HallID: 'fult', - // }, - // { - // TaskID: 3, - // Name: 'posters put up', - // Description: 'please please posters', - // HallID: 'evan', - // }, - // ]; + const fetchTaskList = async () => { + try { + const tasks = await getTasksForHall(); + setTaskList(tasks); + } catch (error) { + console.log('Error fetching tasks', error); + } + }; + fetchTaskList(); + }, []); const handleConfirm = async (index, taskID) => { try { - //await completeTask(taskID, profile.ID); + await completeTask(taskID, profile.ID); setTaskCheckedOpen(false); setCheckedList[index] = true; setDisabledList[index] = true; - //createSnackbar(`Completed task: ${setCheckedList[index].Name}`, 'success'); + createSnackbar(`Completed task: ${setCheckedList[index].Name}`, 'success'); } catch (error) { console.error('Error completing task', error); - //createSnackbar('Failed to complete task. Please try again.', 'error'); + createSnackbar('Failed to complete task. Please try again.', 'error'); } }; @@ -149,56 +134,57 @@ const TaskList = () => { ); }; - // map through array of tasks - // component of list item name, checkbox, and description - // if description is not blank, return, otherwise "No description provided" return ( - - - - - - {taskList.length == 0 ? ( - - No tasks to see - - ) : ( - taskList.map((task, index) => { - - - - } - > - - - - - - - ; - }) - )} - - - - + {hallList.length === 0 + ? null + : hallList.map((hall, hallIndex) => { + + + + + + {taskList.length === 0 ? ( + + No tasks to see + + ) : ( + taskList.map((task, index) => { + + + + } + > + + + + + + + ; + }) + )} + + + + ; + })} ); }; diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 6e58b024f7..738b169c4f 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -198,16 +198,16 @@ const RAView = () => { const handleContactSubmit = async () => { if (!selectedContact) { - alert('Please select a contact method before submitting.'); + createSnackbar('Please select a contact method before submitting.', 'warning'); return; } try { await preferredContact(profile.ID, selectedContact); - alert('Preferred contact method successfully updated.'); + createSnackbar('Preferred contact method successfully updated.', 'success'); } catch (error) { console.error('Error updating preferred contact method:', error); - alert('Failed to update contact method. Please try again.'); + createSnackbar('Failed to update contact method. Please try again.', 'error'); } }; diff --git a/src/views/ResLife/index.jsx b/src/views/ResLife/index.jsx index 67f46d4d45..427c72ce52 100644 --- a/src/views/ResLife/index.jsx +++ b/src/views/ResLife/index.jsx @@ -16,6 +16,7 @@ const Housing = () => { const [loading, setLoading] = useState(true); const { profile } = useUser(); const isAuthenticated = useIsAuthenticated(); + const [selectedView, setSelectedView] = useState(null); const [isStudent, isRA, isResLifeStaff, isRD, isPolice, isHallInfoViewer, isHousingDeveloper] = useAuthGroups( AuthGroup.Student, @@ -42,14 +43,24 @@ const Housing = () => { fetchUserInfo(); }, [isAuthenticated, profile]); + useEffect(() => { + if (isHousingDeveloper && !selectedView) { + const selectPage = prompt('Enter the view you want to access (RD, RA, Res, Staff):'); + setSelectedView(selectPage?.toLowerCase() || ''); + } + }, [isHousingDeveloper, selectedView]); + + if (loading) { + return
Loading...
; + } + if (isHousingDeveloper) { - const selectPage = prompt('Enter the view you want to access (RD, RA, Resident, Staff):'); - switch (selectPage?.toLowerCase()) { + switch (selectedView) { case 'rd': return ; case 'ra': return ; - case 'resident': + case 'res': return ; case 'staff': return ; From fede609a25e8f989d3886d2dcbe3cf9c7af60f2d Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:32:14 -0500 Subject: [PATCH 09/15] debugging --- src/services/residentLife/RA_Checkin.ts | 9 +- src/services/residentLife/Tasks.ts | 13 +- .../RAView/components/TaskList/index.jsx | 122 ++++++++++-------- 3 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/services/residentLife/RA_Checkin.ts b/src/services/residentLife/RA_Checkin.ts index 3a47dd5b02..6f1ecfe08d 100644 --- a/src/services/residentLife/RA_Checkin.ts +++ b/src/services/residentLife/RA_Checkin.ts @@ -1,7 +1,8 @@ import http from '../http'; const checkIfCheckedIn = async (raId: string): Promise => { - const response = await http.get<{ IsOnCall: boolean }>(`Housing/ras/${raId}/is-on-call/`); + //const response = await http.get<{ IsOnCall: boolean }>(`Housing/ras/${raId}/is-on-call/`); + const response = await http.get<{ IsOnCall: boolean }>(`Housing/ras/${'50223925'}/is-on-call/`); return response.IsOnCall; }; @@ -9,4 +10,8 @@ const submitCheckIn = async (raId: string, hallIds: string[]): Promise => await http.post(`Housing/ras/${raId}/checkin`, hallIds); }; -export { checkIfCheckedIn, submitCheckIn }; +const getRACurrentHalls = (userName: string): Promise => + //http.get(`Housing/halls/on-calls/${userName}/locations`); + http.get(`Housing/halls/on-calls/${'Daniel.Fagerland'}/locations`); + +export { checkIfCheckedIn, submitCheckIn, getRACurrentHalls }; diff --git a/src/services/residentLife/Tasks.ts b/src/services/residentLife/Tasks.ts index b16c6eccdf..bc7c3942a6 100644 --- a/src/services/residentLife/Tasks.ts +++ b/src/services/residentLife/Tasks.ts @@ -41,15 +41,4 @@ const getActiveTasksForHall = (hallID: string): Promise => const getTasksForHall = (hallID: string): Promise => http.get(`Housing/Halls/${hallID}/DailyTasks`); -const getRACurrentHalls = (userName: string): Promise => - http.get(`Housing/halls/on-calls/${userName}/locations`); - -export { - createTask, - updateTask, - deleteTask, - completeTask, - getActiveTasksForHall, - getTasksForHall, - getRACurrentHalls, -}; +export { createTask, updateTask, deleteTask, completeTask, getActiveTasksForHall, getTasksForHall }; diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index f231d01532..45a9133602 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -21,12 +21,13 @@ import { Link, } from '@mui/material'; import CommentIcon from '@mui/icons-material/Comment'; -import { completeTask, getTasksForHall, getRACurrentHalls } from 'services/residentLife/Tasks'; +import { completeTask, getTasksForHall } from 'services/residentLife/Tasks'; +import { getRACurrentHalls } from 'services/residentLife/RA_Checkin'; import { useUser } from 'hooks'; import GordonDialogBox from 'components/GordonDialogBox'; import SimpleSnackbar from 'components/Snackbar'; -const taskList = [ +const taskListTest = [ { TaskID: 0, Name: 'Clean', @@ -74,22 +75,32 @@ const TaskList = () => { try { const halls = await getRACurrentHalls(profile.AD_Username); setHallList(halls); + console.log(halls); } catch (error) { console.log('Error fetching halls', error); } }; fetchCheckedInHalls(); + }, []); - const fetchTaskList = async () => { + useEffect(() => { + const fetchTaskList = async (hallID) => { try { - const tasks = await getTasksForHall(); - setTaskList(tasks); + const tasks = await getTasksForHall(hallID); + const updatedTasks = taskList; + updatedTasks.push({ hallID: tasks }); + console.log('hey' + updatedTasks); + setTaskList(updatedTasks); } catch (error) { console.log('Error fetching tasks', error); } }; - fetchTaskList(); - }, []); + hallList.map((hall, index) => { + fetchTaskList(hall); + }); + }, [hallList]); + + //console.log(taskList); const handleConfirm = async (index, taskID) => { try { @@ -101,7 +112,7 @@ const TaskList = () => { } catch (error) { console.error('Error completing task', error); createSnackbar('Failed to complete task. Please try again.', 'error'); - } + }, [] }; const handleTaskChecked = (index, taskID) => { @@ -133,58 +144,55 @@ const TaskList = () => { ); }; + //console.log('tasklist' + taskList.length); return ( - {hallList.length === 0 - ? null - : hallList.map((hall, hallIndex) => { - - - - - - {taskList.length === 0 ? ( - - No tasks to see - - ) : ( - taskList.map((task, index) => { - - - - } - > - - - - - - - ; - }) - )} - - - - ; - })} + + + + + + {taskList.length === 0 ? ( + + No tasks to see + + ) : ( + taskList.map((task, index) => { + + + + } + > + + + + + + + ; + }) + )} + + + + ); }; From ecb9d6675e72bd690758772c67bb24f21b32584e Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sat, 15 Feb 2025 23:48:01 -0500 Subject: [PATCH 10/15] more work --- src/services/residentLife/RA_Checkin.ts | 3 +- src/services/residentLife/Tasks.ts | 2 +- .../RAView/components/TaskList/index.jsx | 85 ++++++++++--------- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/services/residentLife/RA_Checkin.ts b/src/services/residentLife/RA_Checkin.ts index 6f1ecfe08d..b32c3e67c8 100644 --- a/src/services/residentLife/RA_Checkin.ts +++ b/src/services/residentLife/RA_Checkin.ts @@ -7,7 +7,8 @@ const checkIfCheckedIn = async (raId: string): Promise => { }; const submitCheckIn = async (raId: string, hallIds: string[]): Promise => { - await http.post(`Housing/ras/${raId}/checkin`, hallIds); + //await http.post(`Housing/ras/${raId}/checkin`, hallIds); + await http.post(`Housing/ras/${'50223925'}/checkin`, hallIds); }; const getRACurrentHalls = (userName: string): Promise => diff --git a/src/services/residentLife/Tasks.ts b/src/services/residentLife/Tasks.ts index bc7c3942a6..fd0458c4e5 100644 --- a/src/services/residentLife/Tasks.ts +++ b/src/services/residentLife/Tasks.ts @@ -16,7 +16,7 @@ export type Task = { }; export type DailyTask = { - TaskID: number; + Task_ID: number; Name: string; Description: string; HallID: string; diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 45a9133602..a87475d29e 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -57,7 +57,6 @@ const taskListTest = [ const TaskList = () => { const [taskList, setTaskList] = useState([]); - // console.log(taskList.length); const { profile } = useUser(); const [descriptionOpen, setDescriptionOpen] = useState(false); const [taskCheckedOpen, setTaskCheckedOpen] = useState(false); @@ -87,9 +86,9 @@ const TaskList = () => { const fetchTaskList = async (hallID) => { try { const tasks = await getTasksForHall(hallID); + console.log(tasks); const updatedTasks = taskList; - updatedTasks.push({ hallID: tasks }); - console.log('hey' + updatedTasks); + updatedTasks.push({ [`${hallID}`]: tasks }); setTaskList(updatedTasks); } catch (error) { console.log('Error fetching tasks', error); @@ -100,8 +99,6 @@ const TaskList = () => { }); }, [hallList]); - //console.log(taskList); - const handleConfirm = async (index, taskID) => { try { await completeTask(taskID, profile.ID); @@ -112,7 +109,7 @@ const TaskList = () => { } catch (error) { console.error('Error completing task', error); createSnackbar('Failed to complete task. Please try again.', 'error'); - }, [] + } }; const handleTaskChecked = (index, taskID) => { @@ -122,7 +119,7 @@ const TaskList = () => { onClose={() => setTaskCheckedOpen(false)} title={'Complete Task'} buttonName="Confirm" - buttonClicked={handleConfirm(index, taskID)} + buttonClicked={() => handleConfirm(index, taskID)} cancelButtonName="CANCEL" cancelButtonClicked={() => setTaskCheckedOpen(false)} > @@ -144,7 +141,7 @@ const TaskList = () => { ); }; - //console.log('tasklist' + taskList.length); + console.log(hallList[0]); return ( @@ -153,41 +150,49 @@ const TaskList = () => { - {taskList.length === 0 ? ( + {taskList.length > 0 ? ( + taskList.map((hallTasks, hallIndex) => { + hallTasks[hallList[hallIndex]].length > 0 ? ( + hallTasks[hallList[hallIndex]].map((task, index) => { + handleClickDescription} + > + + + } + > + handleTaskChecked(index, task.TaskID)} + dense + > + + + + + + ; + }) + ) : ( + + No tasks to see for {hallList[hallIndex]} + + ); + }) + ) : ( No tasks to see - ) : ( - taskList.map((task, index) => { - - - - } - > - - - - - - - ; - }) )} From 59a526fe88beb363e06f778de3df1c8dc272ca9f Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Sun, 16 Feb 2025 19:13:26 -0500 Subject: [PATCH 11/15] more debugging --- .../RAView/components/TaskList/index.jsx | 88 ++++++++++--------- src/views/ResLife/components/RAView/index.jsx | 1 - 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index a87475d29e..31d88b9927 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -86,10 +86,10 @@ const TaskList = () => { const fetchTaskList = async (hallID) => { try { const tasks = await getTasksForHall(hallID); - console.log(tasks); - const updatedTasks = taskList; - updatedTasks.push({ [`${hallID}`]: tasks }); - setTaskList(updatedTasks); + console.log(JSON.stringify(tasks)); + taskList === [] + ? setTaskList(tasks) + : setTaskList((prevTasks) => [...prevTasks, { [`${hallID}`]: tasks }]); } catch (error) { console.log('Error fetching tasks', error); } @@ -134,14 +134,13 @@ const TaskList = () => { title={'Task Description'} > - {taskList[taskIndex].Description.length == 0 + {taskList[taskIndex].Description.length === 0 ? 'No description provided' : taskList[taskIndex].Description} ); }; - console.log(hallList[0]); return ( @@ -150,43 +149,52 @@ const TaskList = () => { - {taskList.length > 0 ? ( + hey look + {taskList != undefined && taskList.length > 0 ? ( taskList.map((hallTasks, hallIndex) => { - hallTasks[hallList[hallIndex]].length > 0 ? ( - hallTasks[hallList[hallIndex]].map((task, index) => { - handleClickDescription} + const hallName = hallList[hallIndex]; + const taskArray = hallTasks[hallName]; + hallName in Object.keys(hallTasks) ? ( + Object.keys(taskArray).length > 0 ? ( + taskArray.map((task, index) => { + return ( + handleClickDescription} + > + + + } > - - - } - > - handleTaskChecked(index, task.TaskID)} - dense - > - - - - - - ; - }) + handleTaskChecked(index, task.TaskID)} + dense + > + + + + + + + ); + }) + ) : ( + + No tasks to see for {hallList[hallIndex]} + + ) ) : ( - - No tasks to see for {hallList[hallIndex]} - + console.log('still waiting...') ); }) ) : ( diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 738b169c4f..5962522c34 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -371,7 +371,6 @@ const RAView = () => { ); - // NOTE: return a task list for each hall return ( {!isMobile && ( From 44f6fd42b4e5b867de9cfedc874de3c4966edfda Mon Sep 17 00:00:00 2001 From: Ross Clark <78284383+RossClark01@users.noreply.github.com> Date: Sun, 16 Feb 2025 21:47:53 -0500 Subject: [PATCH 12/15] Debugged TaskList tasks and descriptions now displaying, task completion working This was debugged with the help of AI please take extra caution when reviewing. The snackbar confirmation when completing a task is not working UI needs work on some of the popup dialogs --- .env.development | 2 +- .../RAView/components/TaskList/index.jsx | 233 +++++++++--------- 2 files changed, 122 insertions(+), 113 deletions(-) diff --git a/.env.development b/.env.development index d2f195b210..ff1fb56dcc 100644 --- a/.env.development +++ b/.env.development @@ -7,5 +7,5 @@ # VITE_API_URL=https://360Apisp.gordon.edu/ # @LOCALHOST - VITE_API_URL=http://localhost:51628/ + VITE_API_URL=http://localhost:51660/ diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 31d88b9927..872c62868e 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -9,7 +9,7 @@ import { Grid, Typography, } from '@mui/material'; -import { React, useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { IconButton, ListItemIcon, @@ -27,33 +27,6 @@ import { useUser } from 'hooks'; import GordonDialogBox from 'components/GordonDialogBox'; import SimpleSnackbar from 'components/Snackbar'; -const taskListTest = [ - { - TaskID: 0, - Name: 'Clean', - Description: 'please clean', - HallID: 'brom', - }, - { - TaskID: 1, - Name: 'more Clean', - Description: 'please more clean', - HallID: 'ferr', - }, - { - TaskID: 2, - Name: 'take out trash', - Description: 'trashcan full', - HallID: 'fult', - }, - { - TaskID: 3, - Name: 'posters put up', - Description: 'please please posters', - HallID: 'evan', - }, -]; - const TaskList = () => { const [taskList, setTaskList] = useState([]); @@ -64,6 +37,8 @@ const TaskList = () => { const [disabledList, setDisabledList] = useState([]); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); const [hallList, setHallList] = useState([]); + const [confirmTask, setConfirmTask] = useState(null); + const [selectedDescription, setSelectedDescription] = useState(null); const createSnackbar = useCallback((message, severity) => { setSnackbar({ message, severity, open: true }); @@ -83,63 +58,82 @@ const TaskList = () => { }, []); useEffect(() => { - const fetchTaskList = async (hallID) => { + const fetchTaskList = async () => { try { - const tasks = await getTasksForHall(hallID); - console.log(JSON.stringify(tasks)); - taskList === [] - ? setTaskList(tasks) - : setTaskList((prevTasks) => [...prevTasks, { [`${hallID}`]: tasks }]); + const updatedTasks = []; + for (const hall of hallList) { + const tasks = await getTasksForHall(hall); + updatedTasks.push({ hallID: hall, tasks }); + } + setTaskList(updatedTasks); } catch (error) { console.log('Error fetching tasks', error); } }; - hallList.map((hall, index) => { - fetchTaskList(hall); - }); + + if (hallList.length > 0) { + fetchTaskList(); + } }, [hallList]); - const handleConfirm = async (index, taskID) => { + const handleConfirm = async () => { + if (!confirmTask) { + console.error('No task selected for confirmation.'); + return; + } + + const { hallIndex, taskIndex, taskID } = confirmTask; + try { await completeTask(taskID, profile.ID); + + setCheckedList((prev) => { + const newCheckedList = prev.map((hall, hIndex) => + hIndex === hallIndex + ? hall.map((checked, tIndex) => (tIndex === taskIndex ? true : checked)) + : hall, + ); + return newCheckedList; + }); + + setDisabledList((prev) => { + const newDisabledList = prev.map((hall, hIndex) => + hIndex === hallIndex + ? hall.map((disabled, tIndex) => (tIndex === taskIndex ? true : disabled)) + : hall, + ); + return newDisabledList; + }); + + createSnackbar(`Completed task: ${taskList[hallIndex].tasks[taskIndex].Name}`, 'success'); + setTaskCheckedOpen(false); - setCheckedList[index] = true; - setDisabledList[index] = true; - createSnackbar(`Completed task: ${setCheckedList[index].Name}`, 'success'); + setConfirmTask(null); } catch (error) { console.error('Error completing task', error); createSnackbar('Failed to complete task. Please try again.', 'error'); } }; - const handleTaskChecked = (index, taskID) => { - return ( - setTaskCheckedOpen(false)} - title={'Complete Task'} - buttonName="Confirm" - buttonClicked={() => handleConfirm(index, taskID)} - cancelButtonName="CANCEL" - cancelButtonClicked={() => setTaskCheckedOpen(false)} - > - ); + useEffect(() => { + if (taskList.length > 0) { + const newCheckedList = taskList.map((hall) => + hall.tasks.map((task) => task.CompletedDate !== null), + ); + setCheckedList(newCheckedList); + setDisabledList(newCheckedList); + } + }, [taskList]); + + const handleTaskChecked = (hallIndex, taskIndex, taskID) => { + setConfirmTask({ hallIndex, taskIndex, taskID }); + setTaskCheckedOpen(true); }; - const handleClickDescription = (taskIndex) => { - return ( - setDescriptionOpen(false)} - title={'Task Description'} - > - - {taskList[taskIndex].Description.length === 0 - ? 'No description provided' - : taskList[taskIndex].Description} - - - ); + const handleClickDescription = (hallIndex, taskIndex) => { + const selectedTask = taskList[hallIndex]?.tasks[taskIndex]; + setSelectedDescription(selectedTask?.Description || 'No description provided'); + setDescriptionOpen(true); }; return ( @@ -149,54 +143,51 @@ const TaskList = () => { - hey look - {taskList != undefined && taskList.length > 0 ? ( - taskList.map((hallTasks, hallIndex) => { - const hallName = hallList[hallIndex]; - const taskArray = hallTasks[hallName]; - hallName in Object.keys(hallTasks) ? ( - Object.keys(taskArray).length > 0 ? ( - taskArray.map((task, index) => { - return ( - handleClickDescription} - > - - - } - > - handleTaskChecked(index, task.TaskID)} - dense + {taskList.length > 0 ? ( + taskList.map((hallData, hallIndex) => ( + + {hallData.hallID} + {hallData.tasks.length > 0 ? ( + hallData.tasks.map((task, index) => ( + handleClickDescription(hallIndex, index)} > - - - - - - - ); - }) + + + } + > + handleTaskChecked(hallIndex, index, task.TaskID)} + dense + > + + + + + + + )) ) : ( - - No tasks to see for {hallList[hallIndex]} + + No tasks available for {hallData.hallID} - ) - ) : ( - console.log('still waiting...') - ); - }) + )} + + )) ) : ( No tasks to see @@ -204,6 +195,24 @@ const TaskList = () => { )} + setTaskCheckedOpen(false)} + title={'Complete Task'} + buttonName="Confirm" + buttonClicked={handleConfirm} + cancelButtonName="CANCEL" + cancelButtonClicked={() => setTaskCheckedOpen(false)} + /> + setDescriptionOpen(false)} + title="Task Description" + buttonName="Close" + buttonClicked={() => setDescriptionOpen(false)} + > + {selectedDescription} + From 27f77d143e24a145fd0cc2ab9fecbcf067307a51 Mon Sep 17 00:00:00 2001 From: dli505 <100231490+dli505@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:29:24 -0500 Subject: [PATCH 13/15] cleaning up the ui --- .../RAView/components/TaskList/index.jsx | 33 ++++++++----- src/views/ResLife/components/RAView/index.jsx | 48 ++++++++++--------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 872c62868e..1385c833d4 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -142,7 +142,7 @@ const TaskList = () => { - + {taskList.length > 0 ? ( taskList.map((hallData, hallIndex) => ( @@ -166,19 +166,24 @@ const TaskList = () => { dense > - } /> - )) ) : ( @@ -203,7 +208,10 @@ const TaskList = () => { buttonClicked={handleConfirm} cancelButtonName="CANCEL" cancelButtonClicked={() => setTaskCheckedOpen(false)} - /> + > +
+ Are you sure you have completed this task? + setDescriptionOpen(false)} @@ -211,7 +219,8 @@ const TaskList = () => { buttonName="Close" buttonClicked={() => setDescriptionOpen(false)} > - {selectedDescription} +
+ {selectedDescription}
diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index 18978d40a0..dcbb0f7416 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -415,23 +415,21 @@ const RAView = () => { if (!isCheckedIn) return null; return ( - - - - - RA/AC on Duty by Hall - + + + + RA/AC on Duty by Hall - } - className="gc360_header" - /> - - - - - +
+ } + className="gc360_header" + /> + + + + ); }; @@ -440,19 +438,21 @@ const RAView = () => { {!isMobile && ( <> - {isCheckedIn ? ( - - - - ) : null} + + + {contactMethod()} {checkInButton()} - + {isCheckedIn ? ( + + + + ) : null} )} {isMobile && ( @@ -473,7 +473,9 @@ const RAView = () => { - + + + )}
From f74c78099dcabde22b30de22d2075764654a46b3 Mon Sep 17 00:00:00 2001 From: Ross Clark <78284383+RossClark01@users.noreply.github.com> Date: Thu, 20 Feb 2025 13:30:47 -0500 Subject: [PATCH 14/15] Task Completion Updates Added option to mark a task as not complete. modified RA pref contact to not use accordion Snackbar confirmations now displaying --- src/services/residentLife/Tasks.ts | 12 +- .../RAView/components/TaskList/index.jsx | 105 ++++++++++++++---- src/views/ResLife/components/RAView/index.jsx | 52 ++++----- 3 files changed, 120 insertions(+), 49 deletions(-) diff --git a/src/services/residentLife/Tasks.ts b/src/services/residentLife/Tasks.ts index fd0458c4e5..f29def9458 100644 --- a/src/services/residentLife/Tasks.ts +++ b/src/services/residentLife/Tasks.ts @@ -35,10 +35,20 @@ const deleteTask = (taskID: number) => http.del(`Housing/halls/task/${taskID}`); const completeTask = (taskID: number, completedBy: string) => http.patch(`Housing/halls/task/Complete/${taskID}`, completedBy); +const incompleteTask = (taskID: number) => http.patch(`Housing/halls/task/Incomplete/${taskID}`); + const getActiveTasksForHall = (hallID: string): Promise => http.get(`Housing/Halls/${hallID}/ActiveTasks`); const getTasksForHall = (hallID: string): Promise => http.get(`Housing/Halls/${hallID}/DailyTasks`); -export { createTask, updateTask, deleteTask, completeTask, getActiveTasksForHall, getTasksForHall }; +export { + createTask, + updateTask, + deleteTask, + completeTask, + incompleteTask, + getActiveTasksForHall, + getTasksForHall, +}; diff --git a/src/views/ResLife/components/RAView/components/TaskList/index.jsx b/src/views/ResLife/components/RAView/components/TaskList/index.jsx index 1385c833d4..5bdd31c932 100644 --- a/src/views/ResLife/components/RAView/components/TaskList/index.jsx +++ b/src/views/ResLife/components/RAView/components/TaskList/index.jsx @@ -8,9 +8,6 @@ import { FormControlLabel, Grid, Typography, -} from '@mui/material'; -import React, { useCallback, useEffect, useState } from 'react'; -import { IconButton, ListItemIcon, ListItemText, @@ -20,8 +17,9 @@ import { ListItem, Link, } from '@mui/material'; +import React, { useCallback, useEffect, useState } from 'react'; import CommentIcon from '@mui/icons-material/Comment'; -import { completeTask, getTasksForHall } from 'services/residentLife/Tasks'; +import { completeTask, incompleteTask, getTasksForHall } from 'services/residentLife/Tasks'; import { getRACurrentHalls } from 'services/residentLife/RA_Checkin'; import { useUser } from 'hooks'; import GordonDialogBox from 'components/GordonDialogBox'; @@ -29,15 +27,16 @@ import SimpleSnackbar from 'components/Snackbar'; const TaskList = () => { const [taskList, setTaskList] = useState([]); - const { profile } = useUser(); const [descriptionOpen, setDescriptionOpen] = useState(false); const [taskCheckedOpen, setTaskCheckedOpen] = useState(false); + const [incompleteTaskDialogOpen, setIncompleteTaskDialogOpen] = useState(false); const [checkedList, setCheckedList] = useState([]); const [disabledList, setDisabledList] = useState([]); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); const [hallList, setHallList] = useState([]); const [confirmTask, setConfirmTask] = useState(null); + const [confirmIncompleteTask, setConfirmIncompleteTask] = useState(null); const [selectedDescription, setSelectedDescription] = useState(null); const createSnackbar = useCallback((message, severity) => { @@ -87,23 +86,21 @@ const TaskList = () => { try { await completeTask(taskID, profile.ID); - setCheckedList((prev) => { - const newCheckedList = prev.map((hall, hIndex) => + setCheckedList((prev) => + prev.map((hall, hIndex) => hIndex === hallIndex ? hall.map((checked, tIndex) => (tIndex === taskIndex ? true : checked)) : hall, - ); - return newCheckedList; - }); + ), + ); - setDisabledList((prev) => { - const newDisabledList = prev.map((hall, hIndex) => + setDisabledList((prev) => + prev.map((hall, hIndex) => hIndex === hallIndex ? hall.map((disabled, tIndex) => (tIndex === taskIndex ? true : disabled)) : hall, - ); - return newDisabledList; - }); + ), + ); createSnackbar(`Completed task: ${taskList[hallIndex].tasks[taskIndex].Name}`, 'success'); @@ -115,6 +112,46 @@ const TaskList = () => { } }; + const handleMarkIncompleteConfirm = async () => { + if (!confirmIncompleteTask) { + console.error('No task selected for incomplete confirmation.'); + return; + } + + const { hallIndex, taskIndex, taskID } = confirmIncompleteTask; + + try { + await incompleteTask(taskID, profile.ID); + + setCheckedList((prev) => + prev.map((hall, hIndex) => + hIndex === hallIndex + ? hall.map((checked, tIndex) => (tIndex === taskIndex ? false : checked)) + : hall, + ), + ); + + setDisabledList((prev) => + prev.map((hall, hIndex) => + hIndex === hallIndex + ? hall.map((disabled, tIndex) => (tIndex === taskIndex ? false : disabled)) + : hall, + ), + ); + + createSnackbar( + `Marked task as incomplete: ${taskList[hallIndex].tasks[taskIndex].Name}`, + 'success', + ); + + setIncompleteTaskDialogOpen(false); + setConfirmIncompleteTask(null); + } catch (error) { + console.error('Error marking task as incomplete', error); + createSnackbar('Failed to mark task as incomplete. Please try again.', 'error'); + } + }; + useEffect(() => { if (taskList.length > 0) { const newCheckedList = taskList.map((hall) => @@ -125,9 +162,14 @@ const TaskList = () => { } }, [taskList]); - const handleTaskChecked = (hallIndex, taskIndex, taskID) => { - setConfirmTask({ hallIndex, taskIndex, taskID }); - setTaskCheckedOpen(true); + const handleTaskChecked = (hallIndex, taskIndex, taskID, taskCompleted) => { + if (taskCompleted) { + setConfirmIncompleteTask({ hallIndex, taskIndex, taskID }); + setIncompleteTaskDialogOpen(true); + } else { + setConfirmTask({ hallIndex, taskIndex, taskID }); + setTaskCheckedOpen(true); + } }; const handleClickDescription = (hallIndex, taskIndex) => { @@ -162,7 +204,14 @@ const TaskList = () => { } > handleTaskChecked(hallIndex, index, task.TaskID)} + onClick={() => + handleTaskChecked( + hallIndex, + index, + task.TaskID, + checkedList[hallIndex]?.[index] || task.CompletedDate !== null, + ) + } dense > @@ -212,6 +261,18 @@ const TaskList = () => {
Are you sure you have completed this task? + setIncompleteTaskDialogOpen(false)} + title={'Mark Task as Incomplete'} + buttonName="Confirm" + buttonClicked={handleMarkIncompleteConfirm} + cancelButtonName="CANCEL" + cancelButtonClicked={() => setIncompleteTaskDialogOpen(false)} + > +
+ Are you sure you want to mark this task as incomplete? +
setDescriptionOpen(false)} @@ -222,6 +283,12 @@ const TaskList = () => {
{selectedDescription}
+ setSnackbar((s) => ({ ...s, open: false }))} + />
diff --git a/src/views/ResLife/components/RAView/index.jsx b/src/views/ResLife/components/RAView/index.jsx index dcbb0f7416..97fd17c1a4 100644 --- a/src/views/ResLife/components/RAView/index.jsx +++ b/src/views/ResLife/components/RAView/index.jsx @@ -374,36 +374,30 @@ const RAView = () => { ); const contactMethod = () => ( - + - - - }> - Select Contact Method - - - - - } label="Teams" /> - } label="Phone" /> - - - - - + + + Select Contact Method + + } label="Teams" /> + } label="Phone" /> + + + *This is your preferred method to be contacted by your hall's residents. From c0526cf098c4a3e92c4722a30c8d4aa9dae2f5b4 Mon Sep 17 00:00:00 2001 From: Mya Randolph <72843238+Mrand03@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:07:21 -0500 Subject: [PATCH 15/15] Update RA_Checkin.ts --- src/services/residentLife/RA_Checkin.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/services/residentLife/RA_Checkin.ts b/src/services/residentLife/RA_Checkin.ts index b32c3e67c8..9c5dd042be 100644 --- a/src/services/residentLife/RA_Checkin.ts +++ b/src/services/residentLife/RA_Checkin.ts @@ -1,18 +1,15 @@ import http from '../http'; const checkIfCheckedIn = async (raId: string): Promise => { - //const response = await http.get<{ IsOnCall: boolean }>(`Housing/ras/${raId}/is-on-call/`); - const response = await http.get<{ IsOnCall: boolean }>(`Housing/ras/${'50223925'}/is-on-call/`); + const response = await http.get<{ IsOnCall: boolean }>(`Housing/ras/${raId}/is-on-call/`); return response.IsOnCall; }; const submitCheckIn = async (raId: string, hallIds: string[]): Promise => { - //await http.post(`Housing/ras/${raId}/checkin`, hallIds); - await http.post(`Housing/ras/${'50223925'}/checkin`, hallIds); + await http.post(`Housing/ras/${raId}/checkin`, hallIds); }; const getRACurrentHalls = (userName: string): Promise => - //http.get(`Housing/halls/on-calls/${userName}/locations`); - http.get(`Housing/halls/on-calls/${'Daniel.Fagerland'}/locations`); + http.get(`Housing/halls/on-calls/${userName}/locations`); export { checkIfCheckedIn, submitCheckIn, getRACurrentHalls };