diff --git a/components/publisher/PublisherShiftsModal.js b/components/publisher/PublisherShiftsModal.js new file mode 100644 index 0000000..c873d8b --- /dev/null +++ b/components/publisher/PublisherShiftsModal.js @@ -0,0 +1,189 @@ +import React, { useEffect } from 'react'; +import Link from 'next/link'; +import common from 'src/helpers/common'; +import axiosInstance from 'src/axiosSecure'; + +const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentChange }) => { + + const [shifts, setShifts] = React.useState([_shifts]); + //Refactor ToDo: show the whole month instead of just the current week by showing the shift start time in front of the rows, and show all shifts in the month from the first to the last week in the cell where we show one shift now + + const monthInfo = common.getMonthDatesInfo(new Date(date)); + const monthShifts = shifts.filter(shift => { + const shiftDate = new Date(shift.startTime); + return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastDay; + }); + const weekShifts = monthShifts.filter(shift => { + const shiftDate = new Date(shift.startTime); + return common.getStartOfWeek(date) <= shiftDate && shiftDate <= common.getEndOfWeek(date); + }); + const dayShifts = weekShifts.map(shift => { + const isAvailable = publisher?.availabilities?.some(avail => + avail.startTime <= shift.startTime && avail.endTime >= shift.endTime + ); + let color = isAvailable ? getColorForShift(shift) : 'bg-gray-300'; + if (shift.isFromPreviousMonth) { + color += ' border-l-4 border-orange-500 '; + } + if (shift.isFromPreviousAssignment) { + color += ' border-l-4 border-red-500 '; + } + return { ...shift, isAvailable, color }; + }).reduce((acc, shift) => { + const dayIndex = new Date(shift.startTime).getDay(); + acc[dayIndex] = acc[dayIndex] || []; + acc[dayIndex].push(shift); + return acc; + }, {}); + console.log("dayShifts:", dayShifts); + + const hasAssignment = (shiftId) => { + // return publisher.assignments.some(ass => ass.shift.id == shiftId); + return publisher.assignments?.some(ass => { + //console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`); + return ass.shift.id === shiftId; + }); + }; + + + useEffect(() => { + const handleKeyDown = (event) => { + if (event.key === 'Escape') { + console.log('ESC: closing modal.'); + onClose(); // Call the onClose function when ESC key is pressed + } + }; + + // Add event listener + window.addEventListener('keydown', handleKeyDown); + + // Remove event listener on cleanup + return () => { + window.removeEventListener('keydown', handleKeyDown); + }; + }, [onClose]); // Include onClose in the dependency array + + return ( +
+
+

График на + {publisher.firstName} {publisher.lastName} + {publisher.email} + тази седмица:

+ + {/* ... Display shifts in a calendar-like UI ... */} +
+ {Object.entries(dayShifts).map(([dayIndex, shiftsForDay]) => ( +
+ {/* Day header */} +
{new Date(shiftsForDay[0].startTime).getDate()}-ти
+ + {shiftsForDay.map((shift, index) => { + const assignmentExists = hasAssignment(shift.id); + const availability = publisher.availabilities.find(avail => + avail.startTime <= shift.startTime && avail.endTime >= shift.endTime + ); + const isFromPrevMonth = availability && availability.isFromPreviousMonth; + return ( +
+ {common.getTimeRange(shift.startTime, shift.endTime)} {shift.id} + + {!assignmentExists && shift.isAvailable && ( + + )} + {assignmentExists && ( + + )} +
+ ); + } + )} +
+ ))} +
+ + {/* Close button in the top right corner */} + + + {/* + + */} + {/* Edit button in the top right corner, next to the close button */} + + + + +
+
+ ); +} + +function getColorForShift(shift) { + const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property + switch (assignedCount) { + case 0: return 'bg-blue-300'; + case 1: return 'bg-green-300'; + case 2: return 'bg-yellow-300'; + case 3: return 'bg-orange-300'; + case 4: return 'bg-red-200'; + default: return 'bg-gray-300'; + } +} + +//ToDo: DRY - move to common +const addAssignment = async (publisher, shiftId) => { + try { + console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`); + const newAssignment = { + publisher: { connect: { id: publisher.id } }, + shift: { connect: { id: shiftId } }, + isConfirmed: true + }; + const { data } = await axiosInstance.post("/api/data/assignments", newAssignment); + + // Update the 'publisher' property of the returned data with the full publisher object + data.publisher = publisher; + data.shift = shifts.find(shift => shift.id === shiftId); + publisher.assignments = [...publisher.assignments, data]; + // handleAssignmentChange(publisher.id, 'add'); + if (onAssignmentChange) { onAssignmentChange(publisher.id, 'add'); } + } catch (error) { + console.error("Error adding assignment:", error); + } +}; +const removeAssignment = async (publisher, shiftId) => { + try { + const assignment = publisher.assignments.find(ass => ass.shift.id === shiftId); + console.log(`calendar.idx: remove assignment for shift ${shiftId}`); + const { data } = await axiosInstance.delete(`/api/data/assignments/${assignment.id}`); + //remove from local assignments: + publisher.assignments = publisher.assignments.filter(a => a.id !== assignment.id) + // + // handleAssignmentChange(publisher.id, 'remove') + if (onAssignmentChange) { + onAssignmentChange(publisher.id, 'remove') + } + } catch (error) { + console.error("Error removing assignment:", error); + } +} + + +export default PublisherShiftsModal; \ No newline at end of file diff --git a/pages/cart/calendar/index.tsx b/pages/cart/calendar/index.tsx index fd55e48..040c075 100644 --- a/pages/cart/calendar/index.tsx +++ b/pages/cart/calendar/index.tsx @@ -899,7 +899,15 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
{/* */}
- {isModalOpen && setIsModalOpen(false)} />} + {isModalOpen && ( + setIsModalOpen(false)} + date={value} + onAssignmentChange={handleAssignmentChange} + /> + )}