diff --git a/client/src/components/center-calendar/CenterCalendar.js b/client/src/components/center-calendar/CenterCalendar.js index 2832b69..d3c3f97 100644 --- a/client/src/components/center-calendar/CenterCalendar.js +++ b/client/src/components/center-calendar/CenterCalendar.js @@ -607,7 +607,11 @@ const EventsCalendar = () => { } const disableEvent = (id) => { - if (!AuthService.canEditCalendarTab(currentTab)) return; + if (currentTab === 'medicalCalendar') { + if (!AuthService.canEditMedicalEvents()) return; + } else { + if (!AuthService.canEditCalendarTab(currentTab)) return; + } // Handle recurring event instances const isRecurInstance = typeof id === 'string' && id.startsWith('recur-'); if (isRecurInstance) { @@ -921,7 +925,7 @@ const EventsCalendar = () => { style={{ cursor: 'pointer' }} title="Edit" />} - {currentTab !== 'medicalCalendar' && AuthService.canEditCalendarTab(currentTab) && { setDeleteTargetId(calendarEvent?.id); setShowDeleteConfirm(true); }} style={{ cursor: 'pointer' }} diff --git a/client/src/components/events/EventsCalendar.js b/client/src/components/events/EventsCalendar.js index 2d68230..1c89745 100644 --- a/client/src/components/events/EventsCalendar.js +++ b/client/src/components/events/EventsCalendar.js @@ -13,7 +13,7 @@ import { import { createEventsServicePlugin } from '@schedule-x/events-service'; import { createEventModalPlugin} from '@schedule-x/event-modal'; import '@schedule-x/theme-default/dist/calendar.css'; -import { Filter } from "react-bootstrap-icons"; +import { Archive, Filter, PencilSquare } from "react-bootstrap-icons"; import DatePicker from "react-datepicker"; @@ -40,6 +40,8 @@ const EventsCalendar = () => { const [currentRangeStart, setCurrentRangeStart] = useState(null); const [currentRangeEnd, setCurrentRangeEnd] = useState(null); const [showCreationModal, setShowCreationModal] = useState(false); + const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); + const [deleteTargetId, setDeleteTargetId] = useState(null); const [newEventStartDateTime, setNewEventStartDateTime] = useState(new Date()); const [newEventEndDateTime, setNewEventEndDateTime] = useState(new Date()); const [newEventColor, setNewEventColor] = useState(''); @@ -270,6 +272,28 @@ const EventsCalendar = () => { navigate(`/medical/events/${id}`) } + const goToEdit = (id) => { + if (!AuthService.canEditMedicalEvents()) return; + navigate(`/medical/events/edit/${id}?from=calendar`) + } + + const disableEvent = (id) => { + if (!AuthService.canEditMedicalEvents()) return; + const currentEvent = events.find(item => item.id === id); + EventsService.disableEvent(id, { + status: 'inactive', + edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, + edit_date: new Date(), + edit_history: currentEvent?.edit_history + ? [...currentEvent.edit_history, { employee: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, date: new Date() }] + : [{ employee: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, date: new Date() }] + }).then(() => { + EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => { + setAllEvents(data?.data); + }) + }); + } + const toggleColorFilter = (colorValue) => { setSelectedColorFilters(prev => prev.includes(colorValue) @@ -294,6 +318,20 @@ const EventsCalendar = () => {
{calendarEvent?.customer}
{calendarEvent?.doctor &&
{`${calendarEvent?.doctor}`}
}
{`${calendarEvent?.start}`}
+ {AuthService.canEditMedicalEvents() &&
+ goToEdit(calendarEvent?.id)} + style={{ cursor: 'pointer' }} + title="Edit" + /> + { setDeleteTargetId(calendarEvent?.id); setShowDeleteConfirm(true); }} + style={{ cursor: 'pointer' }} + title="Delete" + /> +
} } }; @@ -412,6 +450,20 @@ const EventsCalendar = () => { {moment(eventItem?.start_time).format('HH:mm')} - {moment(eventItem?.stop_time || eventItem?.start_time).format('HH:mm')}
Provider: {eventItem?.doctor || '-'}
+ {AuthService.canEditMedicalEvents() &&
e.stopPropagation()}> + goToEdit(eventItem?.id)} + style={{ cursor: 'pointer' }} + title="Edit" + /> + { setDeleteTargetId(eventItem?.id); setShowDeleteConfirm(true); }} + style={{ cursor: 'pointer' }} + title="Delete" + /> +
} ) } @@ -592,6 +644,22 @@ const handleSave = () => { + { setShowDeleteConfirm(false); setDeleteTargetId(null); }} size="sm" centered> + + Confirm Delete + + + Are you sure you want to delete this event? + + + + + + diff --git a/client/src/components/events/EventsList.js b/client/src/components/events/EventsList.js index b2ffc5e..d9bc9f8 100644 --- a/client/src/components/events/EventsList.js +++ b/client/src/components/events/EventsList.js @@ -97,6 +97,11 @@ const EventsList = () => { const currentCustomer = customers?.find(c => c?.id === event?.data?.customer || c?.name === event?.data?.client_name || c?.name === event?.target_name); return currentCustomer?.disability || event?.data?.disability?.toLowerCase() === 'yes' || false; }; + const isEligibleDriverOption = (employee) => { + const roles = Array.isArray(employee?.roles) ? employee.roles.map((role) => `${role || ''}`.toLowerCase()) : []; + const permissions = Array.isArray(employee?.permissions) ? employee.permissions.map((permission) => `${permission || ''}`.toLowerCase()) : []; + return roles.includes('driver') || permissions.includes('isdriver'); + }; // Default sort: 1) driver name ascending, 2) start time early to late, 3) address ascending, 4) language (empty first) const applyDefaultSort = (eventsArray) => { @@ -141,8 +146,11 @@ const EventsList = () => { setCustomers(data.data); }) DriverService.getAllActiveDrivers().then((data) => { - console.log('drivers', data.data); - setDriverOptions(data.data); + const filteredDrivers = (data?.data || []) + .filter((employee) => employee?.status === 'active') + .filter(isEligibleDriverOption) + .sort((a, b) => `${a?.name || ''}`.localeCompare(`${b?.name || ''}`)); + setDriverOptions(filteredDrivers); }) ResourceService.getAll().then(data => { setResources(data.data); diff --git a/client/src/components/trans-routes/RouteEdit.js b/client/src/components/trans-routes/RouteEdit.js index bf51ecc..2a29bfa 100644 --- a/client/src/components/trans-routes/RouteEdit.js +++ b/client/src/components/trans-routes/RouteEdit.js @@ -179,9 +179,10 @@ const RouteEdit = () => { if (!validateRoute()) { return; } - // Do not persist scheduled-absence entries into route_customer_list. + // Keep scheduled-absence customers in route assignment payload; only skip transient + // attendance-derived placeholder rows if any are ever injected into this list. const filteredCustomerList = (newCustomerList || []).filter( - (customer) => customer?.customer_route_status !== PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT + (customer) => customer?._attendance_based !== true ); const existingRouteCustomers = currentRoute?.route_customer_list || []; const existingByCustomerId = new Map(existingRouteCustomers.map((c) => [c?.customer_id, c])); @@ -677,12 +678,7 @@ const RouteEdit = () => { const mergedAbsentIds = Array.from(new Set([].concat(existingScheduledAbsentIds, attendanceBasedAbsentIds))); return ( customer?.customer_route_status !== PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT - ) || [] - } : undefined} + currentRoute={currentRoute} setNewCustomerList={setNewCustomerList} onAddCustomer={(addFn) => setAddCustomerToRoute(() => addFn)} scheduledAbsentCustomerIds={mergedAbsentIds}