diff --git a/src/components/Auth/apiClient.tsx b/src/components/Auth/apiClient.tsx index 83cc88a..297e764 100644 --- a/src/components/Auth/apiClient.tsx +++ b/src/components/Auth/apiClient.tsx @@ -93,8 +93,9 @@ export class ApiClient { UserID: "abc", FirstName: "john", LastName: "doe", - Type: "Admin", - Picture: "https://imgs.search.brave.com/DZmzoTAPlNT9HUb2ISfyTd_sPZab1hG4VcyupoK2gwE/rs:fit:860:0:0/g:ce/aHR0cHM6Ly90My5m/dGNkbi5uZXQvanBn/LzAwLzYxLzU0LzA4/LzM2MF9GXzYxNTQw/ODU1X3lFYmIwTlRr/d3ZJVzdaZG1KeThM/aHU1WHJPMXlweURl/LmpwZw", + Type: "Supervisor", + // Type: "Associate", + Picture: "https://www.google.com/koala.png", }; } diff --git a/src/components/TimeCardPage/CellTypes/CommentCell.tsx b/src/components/TimeCardPage/CellTypes/CommentCell.tsx index 59eb993..6e2a96a 100644 --- a/src/components/TimeCardPage/CellTypes/CommentCell.tsx +++ b/src/components/TimeCardPage/CellTypes/CommentCell.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useContext } from "react"; -import { Stack } from "@chakra-ui/react"; +import {IconButton, Stack} from "@chakra-ui/react"; import { UserContext } from "../UserContext"; import { CommentSchema, ReportSchema } from "../../../schemas/RowSchema"; @@ -8,6 +8,7 @@ import { getAllActiveCommentsOfType } from "../utils"; import ShowCommentModal from "./CommentModals/ShowCommentModal"; import ShowReportModal from "./CommentModals/ShowReportModal"; +import {AddIcon, WarningIcon} from "@chakra-ui/icons"; interface CommentProps { comments: CommentSchema[] | undefined; @@ -36,6 +37,7 @@ export function CommentCell({ } }, [user?.Type]); + return ( + - + {employee?.FirstName + " " + employee?.LastName} @@ -93,7 +90,16 @@ function SearchEmployeeTimesheet({employees, setSelected}) { const handleChange = (selectedOption) => { setSelected(selectedOption); } + const handleChange = (selectedOption) => { + setSelected(selectedOption); + } + const customStyles = { + control: (base) => ({ + ...base, + flexDirection: 'row-reverse', + }), + } const customStyles = { control: (base) => ({ ...base, @@ -104,7 +110,7 @@ function SearchEmployeeTimesheet({employees, setSelected}) { const DropdownIndicator = (props) => { return ( - + ); }; @@ -120,9 +126,9 @@ function SearchEmployeeTimesheet({employees, setSelected}) { size="lg" options={employees} onChange={handleChange} - components={{DropdownIndicator}} + components={{ DropdownIndicator }} getOptionLabel={option => `${option.FirstName + " " + option.LastName}`} - getOptionValue={option => `${option.FirstName + " " + option.LastName}`}/> + getOptionValue={option => `${option.FirstName + " " + option.LastName}`} /> ) } @@ -137,6 +143,9 @@ function WeeklyCommentSection({ weeklyComments, weeklyReports }: WeeklyCommentSectionProps) { + weeklyComments, + weeklyReports + }: WeeklyCommentSectionProps) { // row of Comments // row of Reports @@ -180,7 +189,16 @@ function WeeklyCommentSection({ export default function Page() { //const today = moment(); const [selectedDate, setSelectedDate] = useState(moment().startOf('week').day(0)); + //const today = moment(); + const [selectedDate, setSelectedDate] = useState(moment().startOf('week').day(0)); + // fetch the information of the user whos timesheet is being displayed + // if user is an employee selected and user would be the same + // if user is a supervisor/admin then selected would contain the information of the user + // whos timesheet is being looked at and user would contain the supervisor/admins information + // by default the first user is selected + const [selectedUser, setSelectedUser] = useState(); + const [user, setUser] = useState(); // fetch the information of the user whos timesheet is being displayed // if user is an employee selected and user would be the same // if user is a supervisor/admin then selected would contain the information of the user @@ -189,18 +207,43 @@ export default function Page() { const [selectedUser, setSelectedUser] = useState(); const [user, setUser] = useState(); + // associates is only used by supervisor/admin for the list of all associates they have access to + const [associates, setAssociates] = useState([]); // associates is only used by supervisor/admin for the list of all associates they have access to const [associates, setAssociates] = useState([]); + // A list of the timesheet objects + // TODO: add types + const [userTimesheets, setUserTimesheets] = useState([]); + const [currentTimesheets, setCurrentTimesheets] = useState([]); + const [selectedTimesheet, setTimesheet] = useState(undefined); // A list of the timesheet objects // TODO: add types const [userTimesheets, setUserTimesheets] = useState([]); const [currentTimesheets, setCurrentTimesheets] = useState([]); const [selectedTimesheet, setTimesheet] = useState(undefined); + const [weeklyComments, setWeeklyComments] = useState([]); + const [weeklyReports, setWeeklyReports] = useState([]); const [weeklyComments, setWeeklyComments] = useState([]); const [weeklyReports, setWeeklyReports] = useState([]); + // this hook should always run first + useEffect(() => { + apiClient.getUser().then(userInfo => { + setUser(userInfo); + if (userInfo.Type === "Supervisor" || userInfo.Type === "Admin") { + apiClient.getAllUsers().then(users => { + setAssociates(users); + setSelectedUser(users[0]); + }) + } + setSelectedUser(userInfo) + }) + // if employee setSelectedUSer to be userinfo + // if supervisor/admin get all users + // set selected user + }, []) // this hook should always run first useEffect(() => { apiClient.getUser().then(userInfo => { @@ -218,6 +261,14 @@ export default function Page() { // set selected user }, []) + // Pulls user timesheets, marking first returned as the active one + useEffect(() => { + apiClient.getUserTimesheets(selectedUser?.UserID).then(timesheets => { + setUserTimesheets(timesheets); + //By Default just render / select the first timesheet for now + setCurrentTimesheetsToDisplay(timesheets, selectedDate); + }); + }, [selectedUser]) // Pulls user timesheets, marking first returned as the active one useEffect(() => { apiClient.getUserTimesheets(selectedUser?.UserID).then(timesheets => { @@ -227,6 +278,18 @@ export default function Page() { }); }, [selectedUser]) + const processTimesheetChange = (updated_sheet) => { + // Updating the rows of the selected timesheets from our list of timesheets + const modifiedTimesheets = userTimesheets.map((entry) => { + if (entry.TimesheetID === selectedTimesheet.TimesheetID) { + return { + ...entry, + TableData: updated_sheet.TableData + } + } + return entry + }); + setUserTimesheets(modifiedTimesheets); const processTimesheetChange = (updated_sheet) => { // Updating the rows of the selected timesheets from our list of timesheets const modifiedTimesheets = userTimesheets.map((entry) => { @@ -252,8 +315,25 @@ export default function Page() { return entry } )); + //Also need to update our list of currently selected - TODO come up with a way to not need these duplicated lists + setCurrentTimesheets(currentTimesheets.map( + (entry) => { + if (entry.TimesheetID === selectedTimesheet.TimesheetID) { + return { + ...entry, + TableData: updated_sheet.TableData + } + } + return entry + } + )); } + const updateDateRange = (date: Moment) => { + setSelectedDate(date); + //TODO - Refactor this to use the constant in merge with contants branch + setCurrentTimesheetsToDisplay(userTimesheets, date); + } const updateDateRange = (date: Moment) => { setSelectedDate(date); //TODO - Refactor this to use the constant in merge with contants branch @@ -265,8 +345,15 @@ export default function Page() { setWeeklyComments(getAllActiveCommentsOfType(CommentType.Comment, sheet.WeekNotes)) setWeeklyReports(getAllActiveCommentsOfType(CommentType.Report, sheet.WeekNotes)) } + const changeTimesheet = (sheet) => { + setTimesheet(sheet) + setWeeklyComments(getAllActiveCommentsOfType(CommentType.Comment, sheet.WeekNotes)) + setWeeklyReports(getAllActiveCommentsOfType(CommentType.Report, sheet.WeekNotes)) + } + const setCurrentTimesheetsToDisplay = (timesheets, currentStartDate: Moment) => { + const newCurrentTimesheets = timesheets.filter(sheet => moment.unix(sheet.StartDate).isSame(currentStartDate, 'day')); const setCurrentTimesheetsToDisplay = (timesheets, currentStartDate: Moment) => { const newCurrentTimesheets = timesheets.filter(sheet => moment.unix(sheet.StartDate).isSame(currentStartDate, 'day')); @@ -274,31 +361,118 @@ export default function Page() { if (newCurrentTimesheets.length > 0) { changeTimesheet(newCurrentTimesheets[0]) } + setCurrentTimesheets(newCurrentTimesheets); + if (newCurrentTimesheets.length > 0) { + changeTimesheet(newCurrentTimesheets[0]) + } } const renderWarning = () => { - const currentDate = moment(); + const currentDate = moment().tz(TIMEZONE); const dateToCheck = moment(selectedDate); dateToCheck.add(TIMESHEET_DURATION, 'days'); if (currentDate.isAfter(dateToCheck, 'days')) { return - + Your timesheet is late! Please submit this as soon as possible } else { const dueDuration = dateToCheck.diff(currentDate, 'days'); return - + Your timesheet is due in {dueDuration} days! Remember to press the submit button! } } - // use this to control whether the timesheet is disabled or not - const disabled = false + // use this to control whether the timesheet is disabled or not + const disabled = false + const [isOpenCommentForm, setIsOpenCommentForm] = useState(false); + const [selectedOption,setSelectedOption] = useState(''); + const [otherText,setOtherText] = useState(''); + const [commentList, setCommentList] = useState([]); + const [selectedComment, setSelectedComment] = useState(null); + + const openCommentForm =(comment: CommentSchema) =>{ + setSelectedComment(comment); + setIsOpenCommentForm(true); + } + + const openEvaluationForm =() =>{ + setIsOpenCommentForm(true); + } + + const closeCommentForm =() =>{ + setIsOpenCommentForm(false); + } + + const handleInputOption = (event: React.ChangeEvent) => { + setOtherText(event.target.value); + } + + const handleOptionChange =(value:string) => { + setSelectedOption(value); + } + + + const handleSubmit =()=>{ + closeCommentForm(); + let selectedOptionContent = ""; + + + + if (selectedOption !== ""){ + if (selectedOption =="option5"){ + selectedOptionContent = otherText; + }else{ + selectedOptionContent = options.find(opt=>opt.value ===selectedOption)?.content; + } + const newComment = createNewComment(user, CommentType.Comment, selectedOptionContent); + if (selectedComment){ + const updatedComments = commentList.map(comment => { + if (comment == selectedComment){ + return{ + ...comment, + Content: selectedOptionContent, + }; + } + return comment; + }); + setCommentList(updatedComments); + setSelectedComment(null); + }else{ + setCommentList([...commentList, newComment]); + } + + //setSelectedComment(selectedOptionContent); + } + } + const handleDelete = () => { + if (selectedComment) { + const updatedComments = commentList.filter(comment => comment !== selectedComment); + setCommentList(updatedComments); + setSelectedComment(null); // Clear the selected comment after deletion + closeCommentForm(); + } + }; + + const cancelForm =()=>{ + setIsOpenCommentForm(false); + } + + + + + const options = [ + {value:'option1', content:'This associate was a total rock star this week!'}, + {value:'option2', content:'This associate did just okay this week'}, + {value:'option3', content:'Lack of professionalism and/or poor behavior'}, + {value:'option4', content:'N/A'}, + {value:'option5', content:otherText}, + ] return ( @@ -307,35 +481,112 @@ export default function Page() { {(user?.Type === "Supervisor" || user?.Type === "Admin") ? <> - - }/> - }/> + + + + + + + + Weekly Performance Evaluation + + +
+ How would you describe this associate's overall work performance this week? + + + This associate was a total rock star this week! + This associate did just okay this week + Lack of professionalism and/or poor behavior + N/A + Other + {selectedOption === "option5" && ( + + + )} + + + + +
+ + {/**/} + + + + +
+
+
+ + + } /> + } /> : <>} - - + + {useMemo(() => renderWarning(), [selectedDate])} -
- - - {currentTimesheets.map( - (sheet) => ( - changeTimesheet(sheet)}>{sheet.CompanyID} - ) +
+ + + {currentTimesheets.map( + (sheet) => ( + changeTimesheet(sheet)}>{sheet.CompanyID} + ) + )} + + +
+ {selectedTimesheet?.CompanyID === "Total" ? + () + : ( + + )} +
+ +
+ + {commentList.length > 0 && ( +
+

Weekly Comments

+ {commentList.map((comment,index)=>( + + ))} +
)} - - -
- {selectedTimesheet?.CompanyID === "Total" ? - () - : ( - - )} -
- -
+ + + +
+ + +
) } \ No newline at end of file