fix
All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 52s

This commit is contained in:
2026-03-11 13:35:05 -04:00
parent 5489dbf327
commit 39e00c7765
28 changed files with 353 additions and 206 deletions

View File

@@ -23,13 +23,17 @@ import Select from 'react-select';
const EventsCalendar = () => {
const navigate = useNavigate();
const calendarTabOrder = ['medicalCalendar', 'activitiesCalendar', 'incidentsCalendar', 'mealPlanCalendar', 'reminderDatesCalendar'];
const getFirstVisibleCalendarTab = () => {
return calendarTabOrder.find((tabKey) => AuthService.canViewCalendarTab(tabKey) || AuthService.canEditCalendarTab(tabKey)) || 'medicalCalendar';
};
const [events, setEvents] = useState([]);
const calendarColumnRef = useRef(null);
const [listHeight, setListHeight] = useState(null);
const [allEvents, setAllEvents] = useState([]);
const [targetedEventType, setTargetedEventType] = useState('medical');
const [currentTab, setCurrentTab] = useState('medicalCalendar');
const currentTabRef = useRef('medicalCalendar');
const [currentTab, setCurrentTab] = useState(getFirstVisibleCalendarTab());
const currentTabRef = useRef(getFirstVisibleCalendarTab());
const [customers, setCustomers] = useState([]);
const [resources, setResources] = useState([]);
const [fromDate, setFromDate] = useState(new Date(new Date().getFullYear(), new Date().getMonth(), 1));
@@ -126,6 +130,8 @@ const EventsCalendar = () => {
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const [deleteTargetId, setDeleteTargetId] = useState(null);
const [showSpinner, setShowSpinner] = useState(false);
const visibleCalendarTabs = calendarTabOrder.filter((tabKey) => AuthService.canViewCalendarTab(tabKey) || AuthService.canEditCalendarTab(tabKey));
const canEditCurrentTab = () => AuthService.canEditCalendarTab(currentTab);
// Helper function to format name from "lastname, firstname" to "firstname lastname"
const formatFullName = (name) => {
@@ -245,7 +251,7 @@ const EventsCalendar = () => {
setToDate(new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0));
},
onClickDate(date) {
if (currentTabRef.current === 'medicalCalendar') return;
if (currentTabRef.current === 'medicalCalendar' || !AuthService.canEditCalendarTab(currentTabRef.current)) return;
// Parse as local date to avoid UTC timezone offset shifting the day
const [y, m, d] = date.split('-').map(Number);
const localDate = new Date(y, m - 1, d);
@@ -258,7 +264,7 @@ const EventsCalendar = () => {
setShowCreationModal(true);
},
onClickDateTime(dateTime) {
if (currentTabRef.current === 'medicalCalendar') return;
if (currentTabRef.current === 'medicalCalendar' || !AuthService.canEditCalendarTab(currentTabRef.current)) return;
setNewEventStartDateTime(new Date(dateTime.replace(' ', 'T')));
setNewEventEndDateTime(new Date(dateTime.replace(' ', 'T')));
setShowCreationModal(true);
@@ -343,6 +349,14 @@ const EventsCalendar = () => {
});
}, []);
useEffect(() => {
if (!visibleCalendarTabs.includes(currentTab)) {
const nextTab = getFirstVisibleCalendarTab();
setCurrentTab(nextTab);
currentTabRef.current = nextTab;
}
}, [currentTab]);
useEffect(() => {
EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then(data => setAllEvents(data?.data));
EventsService.getAllEventRecurrences().then(data => setAllEventRecurrences(data?.data || []));
@@ -509,10 +523,12 @@ const EventsCalendar = () => {
}
const goToEdit = (id) => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events/edit/${id}?from=calendar`)
}
const goToCreateNew = () => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events`)
}
@@ -530,6 +546,7 @@ const EventsCalendar = () => {
}
const disableEvent = (id) => {
if (!AuthService.canEditCalendarTab(currentTab)) return;
// Handle recurring event instances
const isRecurInstance = typeof id === 'string' && id.startsWith('recur-');
if (isRecurInstance) {
@@ -596,6 +613,7 @@ const EventsCalendar = () => {
// Edit modal functions (for non-medical tabs)
const openEditModal = (calendarEvent) => {
if (!AuthService.canEditCalendarTab(currentTab)) return;
// Check if this is a recurring event instance (ID starts with 'recur-')
const isRecurInstance = typeof calendarEvent.id === 'string' && calendarEvent.id.startsWith('recur-');
let eventData;
@@ -676,6 +694,7 @@ const EventsCalendar = () => {
};
const handleEditSave = () => {
if (!AuthService.canEditCalendarTab(currentTab)) return;
const userName = localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name;
let data = {
@@ -813,6 +832,7 @@ const EventsCalendar = () => {
}
const goToTab = (value) => {
if (!value || !visibleCalendarTabs.includes(value)) return;
setTargetedEventType(eventTypeMap[value]);
setCurrentTab(value);
currentTabRef.current = value;
@@ -834,13 +854,13 @@ const EventsCalendar = () => {
{calendarEvent?.doctor && <div className="sx__event-modal__time">{`${calendarEvent?.doctor}`}</div>}
<div className="sx__event-modal__time">{`${calendarEvent?.start}`}</div>
<div className="sx__event-modal__time" style={{ display: 'flex', gap: '12px', marginTop: '8px' }}>
<PencilSquare
{((currentTab === 'medicalCalendar' && AuthService.canEditMedicalEvents()) || (currentTab !== 'medicalCalendar' && AuthService.canEditCalendarTab(currentTab))) && <PencilSquare
size={16}
onClick={() => currentTab === 'medicalCalendar' ? goToEdit(calendarEvent?.id) : openEditModal(calendarEvent)}
style={{ cursor: 'pointer' }}
title="Edit"
/>
{currentTab !== 'medicalCalendar' && <Archive
/>}
{currentTab !== 'medicalCalendar' && AuthService.canEditCalendarTab(currentTab) && <Archive
size={16}
onClick={() => { setDeleteTargetId(calendarEvent?.id); setShowDeleteConfirm(true); }}
style={{ cursor: 'pointer' }}
@@ -1130,6 +1150,7 @@ const handleClose = () => {
setNewReminderAssociatedEntity(null);
}
const handleSave = () => {
if ((currentTab === 'medicalCalendar' && !AuthService.canEditMedicalEvents()) || (currentTab !== 'medicalCalendar' && !AuthService.canEditCalendarTab(currentTab))) return;
const userName = localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name;
let data = {
@@ -1302,26 +1323,26 @@ const getReminderTitleLabel = (value) => {
<div className="app-main-content-list-container" style={{"min-width": "1500px"}}>
<div className="app-main-content-list-func-container">
<Tabs defaultActiveKey="medicalCalendar" id="medical-calendar-tab" onSelect={(k) => goToTab(k)}>
<Tab eventKey="medicalCalendar" title="Medical Appointments">
<Tabs activeKey={currentTab} id="medical-calendar-tab" onSelect={(k) => goToTab(k)}>
{visibleCalendarTabs.includes('medicalCalendar') && <Tab eventKey="medicalCalendar" title="Medical Appointments">
</Tab>
<Tab eventKey="activitiesCalendar" title="Activities">
</Tab>}
{visibleCalendarTabs.includes('activitiesCalendar') && <Tab eventKey="activitiesCalendar" title="Activities">
</Tab>
<Tab eventKey="incidentsCalendar" title="Attendance">
</Tab>}
{visibleCalendarTabs.includes('incidentsCalendar') && <Tab eventKey="incidentsCalendar" title="Attendance">
</Tab>
<Tab eventKey="mealPlanCalendar" title="Meal Plan">
</Tab>}
{visibleCalendarTabs.includes('mealPlanCalendar') && <Tab eventKey="mealPlanCalendar" title="Meal Plan">
</Tab>
<Tab eventKey="reminderDatesCalendar" title="Important Dates">
</Tab>}
{visibleCalendarTabs.includes('reminderDatesCalendar') && <Tab eventKey="reminderDatesCalendar" title="Important Dates">
</Tab>
</Tab>}
</Tabs>
{ calendarView}
<div className="list-func-panel">
{currentTab !== 'medicalCalendar' && (
{currentTab !== 'medicalCalendar' && canEditCurrentTab() && (
<button className="btn btn-primary me-2" onClick={() => {
setNewEventStartDateTime(new Date());
setNewEventEndDateTime(new Date());
@@ -1757,6 +1778,8 @@ const getReminderTitleLabel = (value) => {
Cancel
</Button>
<Button variant="primary" size="sm" onClick={handleSave} disabled={
(currentTab === 'medicalCalendar' && !AuthService.canEditMedicalEvents()) ||
(currentTab !== 'medicalCalendar' && !AuthService.canEditCalendarTab(currentTab)) ||
(currentTab === 'medicalCalendar' && (!newEventCustomer || !newEventResource || !newEventStartDateTime)) ||
(currentTab === 'activitiesCalendar' && (!newEventTitle || !newActivityCategory)) ||
(currentTab === 'incidentsCalendar' && (!newAttendanceCustomer || !newEventStartDateTime)) ||
@@ -2112,6 +2135,7 @@ const getReminderTitleLabel = (value) => {
Cancel
</Button>
<Button variant="primary" size="sm" onClick={handleEditSave} disabled={
!AuthService.canEditCalendarTab(currentTab) ||
(currentTab === 'activitiesCalendar' && (!editEventTitle || !editActivityCategory)) ||
(currentTab === 'incidentsCalendar' && (!editAttendanceCustomer || !editEventStartDateTime)) ||
(currentTab === 'mealPlanCalendar' && (!editEventTitle || !editMealType)) ||

View File

@@ -52,9 +52,9 @@ const CustomersList = () => {
const additionalButtons = ({ showExportDropdown, onExportToggle }) => (
<>
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}>
{AuthService.canCreateCustomer() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}>
<Plus size={16}></Plus>Add New Customer
</button>
</button>}
<Export
columns={columns}
data={customers.map((customer) => ({

View File

@@ -42,6 +42,9 @@ const UpdateCustomer = () => {
const normalizedInitialTab = ['additionalInfo', 'complianceDeadlines'].includes(initialTab) ? 'personalInfo' : initialTab;
const showDischargeButton = searchParams.get('fromEdit') === '1';
const [activeTab, setActiveTab] = useState(normalizedInitialTab || 'personalInfo');
const customerTabOrder = ['personalInfo', 'careServices', 'medicalInsurance', 'confidentialDetails', 'formSubmission'];
const editableTabs = customerTabOrder.filter((tabKey) => AuthService.canEditCustomerTab(tabKey));
const firstEditableTab = editableTabs[0] || 'personalInfo';
const [currentCustomer, setCurrentCustomer] = useState(undefined);
// Basic Info
@@ -191,7 +194,13 @@ const UpdateCustomer = () => {
};
useEffect(() => {
if (!AuthService.canAddOrEditCustomers()) {
if (!editableTabs.includes(activeTab)) {
setActiveTab(firstEditableTab);
}
}, [activeTab]);
useEffect(() => {
if (!AuthService.canEditAnyCustomerTab()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -944,7 +953,7 @@ const UpdateCustomer = () => {
<div className="app-main-content-list-container form-page">
<div className="app-main-content-list-func-container">
<Tabs activeKey={activeTab} onSelect={(k) => setActiveTab(k)} id="customers-tab">
<Tab eventKey="personalInfo" title="Personal Information">
{AuthService.canEditCustomerTab('personalInfo') && <Tab eventKey="personalInfo" title="Personal Information">
{/* Basic Info Section */}
<h6 className="text-primary">Basic Info</h6>
<div className="app-main-content-fields-section" style={{ flexWrap: 'wrap' }}>
@@ -1311,7 +1320,7 @@ const UpdateCustomer = () => {
)}
</div>
)}
{!isCustomerActive() && (
{!isCustomerActive() && AuthService.canReactivateCustomer() && (
<div style={{ marginTop: '16px' }}>
<button className="btn btn-warning btn-sm" onClick={handleReactivate} disabled={isReactivating}>
<BoxArrowRight className="me-2" size={16}></BoxArrowRight>{isReactivating ? 'Reactivating...' : 'Reactivate Customer'}
@@ -1358,9 +1367,9 @@ const UpdateCustomer = () => {
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="careServices" title="Care & Services">
{AuthService.canEditCustomerTab('careServices') && <Tab eventKey="careServices" title="Care & Services">
{/* Care & Services Section */}
<h6 className="text-primary">Care & Services</h6>
<div className="app-main-content-fields-section">
@@ -1442,9 +1451,9 @@ const UpdateCustomer = () => {
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="medicalInsurance" title="Medical & Insurance">
{AuthService.canEditCustomerTab('medicalInsurance') && <Tab eventKey="medicalInsurance" title="Medical & Insurance">
{/* Providers Section */}
<h6 className="text-primary">Providers</h6>
<div className="app-main-content-fields-section">
@@ -1623,9 +1632,9 @@ const UpdateCustomer = () => {
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="confidentialDetails" title="Confidential Details">
{AuthService.canEditCustomerTab('confidentialDetails') && <Tab eventKey="confidentialDetails" title="Confidential Details">
<h6 className="text-primary">Confidential Details</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
@@ -1653,10 +1662,10 @@ const UpdateCustomer = () => {
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="formSubmission" title="Form Submission">
{AuthService.canEditCustomerTab('formSubmission') && <Tab eventKey="formSubmission" title="Form Submission">
{/* Admission Forms Section */}
<h6 className="text-primary">Admission Forms</h6>
<div className="app-main-content-fields-section base-line">
@@ -1759,10 +1768,10 @@ const UpdateCustomer = () => {
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</Tab>}
</Tabs>
{isCustomerActive() && showDischargeButton && (
{isCustomerActive() && showDischargeButton && AuthService.canDischargeCustomer() && (
<div className="list-func-panel">
<button className="btn btn-warning btn-sm" onClick={openDischargeConfirmModal}>
<BoxArrowRight className="me-2" size={16}></BoxArrowRight>Discharge Customer

View File

@@ -35,6 +35,9 @@ const ViewCustomer = () => {
const normalizedInitialTab = ['additionalInfo', 'complianceDeadlines'].includes(initialTab) ? 'personalInfo' : initialTab;
const [activeTab, setActiveTab] = useState(normalizedInitialTab || 'personalInfo');
const [formFiles, setFormFiles] = useState({});
const customerTabOrder = ['personalInfo', 'careServices', 'medicalInsurance', 'confidentialDetails', 'formSubmission'];
const visibleTabs = customerTabOrder.filter((tabKey) => AuthService.canViewCustomerTab(tabKey));
const firstVisibleTab = visibleTabs[0] || 'personalInfo';
const isFormUploaded = (fieldValue) => fieldValue === true || fieldValue === 'true';
@@ -44,7 +47,11 @@ const ViewCustomer = () => {
}
const goToEdit = (id) => {
navigate(`/customers/edit/${id}?tab=${activeTab}&fromEdit=1`)
const editableTab = AuthService.canEditCustomerTab(activeTab)
? activeTab
: customerTabOrder.find((tabKey) => AuthService.canEditCustomerTab(tabKey));
if (!editableTab) return;
navigate(`/customers/edit/${id}?tab=${editableTab}&fromEdit=1`)
}
// Check if customer is active
@@ -56,7 +63,13 @@ const ViewCustomer = () => {
};
useEffect(() => {
if (!AuthService.canViewCustomers()) {
if (!visibleTabs.includes(activeTab)) {
setActiveTab(firstVisibleTab);
}
}, [activeTab]);
useEffect(() => {
if (!AuthService.canViewAnyCustomerTab()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -146,7 +159,7 @@ const ViewCustomer = () => {
<div className="app-main-content-list-container form-page">
<div className="app-main-content-list-func-container">
<Tabs activeKey={activeTab} onSelect={(k) => setActiveTab(k)} id="customers-tab">
<Tab eventKey="personalInfo" title="Personal Information">
{AuthService.canViewCustomerTab('personalInfo') && <Tab eventKey="personalInfo" title="Personal Information">
{/* Basic Info Section */}
<h6 className="text-primary">Basic Info</h6>
<div className="app-main-content-fields-section">
@@ -546,9 +559,9 @@ const ViewCustomer = () => {
<div className="field-value">{currentCustomer?.notes_for_driver}</div>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="careServices" title="Care & Services">
{AuthService.canViewCustomerTab('careServices') && <Tab eventKey="careServices" title="Care & Services">
<h6 className="text-primary">Care & Services</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
@@ -591,9 +604,9 @@ const ViewCustomer = () => {
<div className="field-value">{formatYesNo(currentCustomer?.consent_to_media_use)}</div>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="medicalInsurance" title="Medical & Insurance">
{AuthService.canViewCustomerTab('medicalInsurance') && <Tab eventKey="medicalInsurance" title="Medical & Insurance">
{/* Providers Section */}
<h6 className="text-primary">Providers</h6>
<div className="app-main-content-fields-section">
@@ -687,9 +700,9 @@ const ViewCustomer = () => {
<div className="field-value">{currentCustomer?.id_expiration_date}</div>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="confidentialDetails" title="Confidential Details">
{AuthService.canViewCustomerTab('confidentialDetails') && <Tab eventKey="confidentialDetails" title="Confidential Details">
<h6 className="text-primary">Confidential Details</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
@@ -709,10 +722,10 @@ const ViewCustomer = () => {
<div className="field-value">{currentCustomer?.adcaps_id}</div>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="formSubmission" title="Form Submission">
{AuthService.canViewCustomerTab('formSubmission') && <Tab eventKey="formSubmission" title="Form Submission">
{/* Admission Forms Section */}
<h6 className="text-primary">Admission Forms</h6>
<div className="app-main-content-fields-section">
@@ -762,11 +775,11 @@ const ViewCustomer = () => {
<div className="field-value">{renderFormStatus(currentCustomer?.pre_screening_form, 'pre_screening_form')}</div>
</div>
</div>
</Tab>
</Tab>}
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary me-2" onClick={() => goToEdit(currentCustomer?.id)}><PencilSquare className="me-2" size={16}></PencilSquare>Edit</button>
{AuthService.canEditAnyCustomerTab() && <button className="btn btn-primary me-2" onClick={() => goToEdit(currentCustomer?.id)}><PencilSquare className="me-2" size={16}></PencilSquare>Edit</button>}
</div>
</div>
</div>

View File

@@ -348,7 +348,7 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
/>
)
)}
{AuthService.canAddOrEditCustomers() && <PencilSquare size={16} className="clickable" onClick={() => isAllCustomersPage ? goToEdit(customer?.id) : goToView(customer?.id)} style={{ flexShrink: 0 }}></PencilSquare>}
{AuthService.canEditAnyCustomerTab() && <PencilSquare size={16} className="clickable" onClick={() => isAllCustomersPage ? goToEdit(customer?.id) : goToView(customer?.id)} style={{ flexShrink: 0 }}></PencilSquare>}
<span className="clickable" style={{ color: '#0066B1', textDecoration: 'underline', cursor: 'pointer' }} onClick={() => goToView(customer?.id)}>{customer?.name}</span>
</div>
</td>}

View File

@@ -83,7 +83,7 @@ const CreateEventRequest = () => {
useEffect(() => {
if (!AuthService.canViewMedicalSection()) {
if (!AuthService.canEditAppointmentRequests()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);

View File

@@ -69,7 +69,7 @@ const EventRequestList = () => {
]);
useEffect(() => {
if (!AuthService.canViewMedicalSection()) {
if (!AuthService.canViewAppointmentRequests()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -293,10 +293,10 @@ const EventRequestList = () => {
<td>{eventRequest?.notes?.map((note) => {
return <p>{`${note?.author}: ${note?.content}`}</p>
})}</td>
<td align="center"><textarea id={eventRequest?.id} name={eventRequest?.id} onChange={setCommentsValue} className="comments-text"/> <button className="btn btn-primary btn-sm me-2 mt-2" onClick={() => saveComments(eventRequest?.id)}>Submit</button></td>
<td align="center"><textarea id={eventRequest?.id} name={eventRequest?.id} onChange={setCommentsValue} className="comments-text" disabled={!AuthService.canEditAppointmentRequests()}/> {AuthService.canEditAppointmentRequests() && <button className="btn btn-primary btn-sm me-2 mt-2" onClick={() => saveComments(eventRequest?.id)}>Submit</button>}</td>
<td className={eventRequest.status === 'active' ? 'table-button-container': ''}>
{eventRequest.status !== 'done' && <button className="btn btn-primary btn-sm me-2" onClick={() => createNewEvent(eventRequest)}> New Appointment </button>}
{eventRequest.status !== 'done' && <button className="btn btn-secondary btn-sm me-2" onClick={() => confirmEventRequest(eventRequest)}> Completed</button>}
{eventRequest.status !== 'done' && AuthService.canEditAppointmentRequests() && <button className="btn btn-primary btn-sm me-2" onClick={() => createNewEvent(eventRequest)}> New Appointment </button>}
{eventRequest.status !== 'done' && AuthService.canEditAppointmentRequests() && <button className="btn btn-secondary btn-sm me-2" onClick={() => confirmEventRequest(eventRequest)}> Completed</button>}
{/* <button className="btn btn-danger btn-sm" onClick={() => deleteItem(eventRequest?.id)}> Delete </button> */}
</td>
</tr>)
@@ -338,7 +338,7 @@ const EventRequestList = () => {
<input className="me-2 with-search-icon" type="text" placeholder="Search" value={keyword} onChange={(e) => setKeyword(e.currentTarget.value)} />
<button className="btn btn-primary me-2"><Filter size={16} className="me-2"></Filter>Filter</button>
<ManageTable columns={columns} onColumnsChange={setColumns} />
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Appointment Request</button>
{AuthService.canEditAppointmentRequests() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Appointment Request</button>}
<Export
columns={columns}
data={eventRequests.filter((item) => filterRequestsFun(item, showDone ? 'done': 'active', keyword))}

View File

@@ -438,6 +438,7 @@ const handleClose = () => {
}
const handleSave = () => {
if (!AuthService.canEditMedicalEvents()) return;
const userName = localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name;
const selectedCustomer = customers.find(c => c.id === newEventCustomer);
const selectedResource = resources.find(r => r.id === newEventResource);
@@ -585,7 +586,7 @@ const handleSave = () => {
Cancel
</Button>
<Button variant="primary" size="sm" onClick={handleSave} disabled={
!newEventCustomer || !newEventResource || !newEventStartDateTime
!AuthService.canEditMedicalEvents() || !newEventCustomer || !newEventResource || !newEventStartDateTime
}>
Save
</Button>

View File

@@ -228,10 +228,12 @@ const EventsList = () => {
}
const goToEdit = (id) => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events/edit/${id}`)
}
const goToCreateNew = () => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events`)
}
@@ -519,7 +521,7 @@ const EventsList = () => {
<Button className="me-2" variant="outline-primary" size="sm" onClick={() => goToPreviousDay()} > {'<'} </Button>
<DatePicker className="me-2" selected={selectedDate} onChange={(v) => setSelectedDate(v)} />
<Button className="me-2 ms-2" variant="outline-primary" size="sm" onClick={() => goToNextDay()}> {'>'} </Button>
<Button className="me-2" variant="primary" size="sm" disabled={selectedItems.length === 0} onClick={() => { setTransportSelected('create_new'); setShowTransportationModal(true); }}> + Show Assign Transportation Panel</Button>
{AuthService.canEditMedicalEvents() && <Button className="me-2" variant="primary" size="sm" disabled={selectedItems.length === 0} onClick={() => { setTransportSelected('create_new'); setShowTransportationModal(true); }}> + Show Assign Transportation Panel</Button>}
</div>
{table('active')}
</Tab>
@@ -536,7 +538,7 @@ const EventsList = () => {
{/* <input className="me-2 with-search-icon" type="text" placeholder="Search" value={keyword} onChange={(e) => setKeyword(e.currentTarget.value)} /> */}
{/* <button className="btn btn-primary me-2"><Filter size={16} className="me-2"></Filter>Filter</button> */}
<ManageTable columns={columns} onColumnsChange={setColumns} />
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Medical Appointment</button>
{AuthService.canEditMedicalEvents() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Medical Appointment</button>}
<Export
columns={columns}
data={events.filter(event => event.status === (showDeletedItems ? 'inactive' : 'active'))}

View File

@@ -170,6 +170,7 @@ const EventsMultipleList = () => {
}, [sorting]);
const confirmEvent = (id) => {
if (!AuthService.canEditMedicalEvents()) return;
EventsService.updateEvent(id, {confirmed: true}).then(() => {
EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => {
setEvents(data.data.filter((item) => {
@@ -202,10 +203,12 @@ const EventsMultipleList = () => {
}
const goToEdit = (id) => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events/edit/${id}`)
}
const goToCreateNew = () => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events`)
}
@@ -337,7 +340,7 @@ const EventsMultipleList = () => {
{columns.find(col => col.key === 'fasting')?.show && <td>{medicalEvent?.fasting}</td>}
<td>{medicalEvent?.dob}</td>
<td>{medicalEvent?.transMethod}</td>
<td>{medicalEvent?.confirmed ? 'Confirmed' : <button className="btn btn-primary btn-sm me-2 ms-2" onClick={() => confirmEvent(medicalEvent?.id)}>Confirm</button>}</td>
<td>{medicalEvent?.confirmed ? 'Confirmed' : (AuthService.canEditMedicalEvents() ? <button className="btn btn-primary btn-sm me-2 ms-2" onClick={() => confirmEvent(medicalEvent?.id)}>Confirm</button> : 'Pending')}</td>
</tr>)
}
</tbody>
@@ -529,7 +532,7 @@ const EventsMultipleList = () => {
<Dropdown.Menu as={customMenu}/>
</Dropdown>
<ManageTable columns={columns} onColumnsChange={setColumns} />
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Medical Appointment</button>
{AuthService.canEditMedicalEvents() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Medical Appointment</button>}
<Export
columns={columns}
data={filteredEvents.filter(event => event.status === (showDeletedItems ? 'inactive' : 'active'))}

View File

@@ -23,6 +23,7 @@ const ViewEvent = () => {
}
const goToEdit = (id) => {
if (!AuthService.canEditMedicalEvents()) return;
navigate(`/medical/events/edit/${id}?tab=${activeTab}`);
}
@@ -196,9 +197,9 @@ const ViewEvent = () => {
</Tab>
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary" onClick={() => goToEdit(currentEvent?.id)}>
{AuthService.canEditMedicalEvents() && <button className="btn btn-primary" onClick={() => goToEdit(currentEvent?.id)}>
<PencilSquare className="me-2" size={16}></PencilSquare>Edit
</button>
</button>}
</div>
</div>
</div>

View File

@@ -110,7 +110,7 @@ const CreateResource = () => {
};
useEffect(() => {
if (!AuthService.canViewMedicalSection()) {
if (!AuthService.canEditProviderInfo()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);

View File

@@ -62,7 +62,7 @@ const ResourcesList = () => {
}
]);
useEffect(() => {
if (!AuthService.canViewMedicalSection()) {
if (!AuthService.canViewProviderInfo()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -275,7 +275,7 @@ const ResourcesList = () => {
currentItems?.map((resource, index) => <tr key={resource?.id}>
<td className="td-checkbox"><input type="checkbox" checked={selectedItems.includes(resource.id)} onClick={()=>toggleItem(resource?.id)}/></td>
<td className="td-index">{itemOffset + index + 1}</td>
{columns.find(col => col.key === 'name')?.show && <td> {AuthService.canAccessLegacySystem() && <PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(resource?.id)}></PencilSquare>} {AuthService.canAccessLegacySystem() ? <button className="btn btn-link btn-sm" onClick={() => goToView(resource?.id)}>{resource?.name || '-'}</button> : (resource?.name || '-') } </td>}
{columns.find(col => col.key === 'name')?.show && <td> {AuthService.canEditProviderInfo() && <PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(resource?.id)}></PencilSquare>} {AuthService.canViewProviderInfo() ? <button className="btn btn-link btn-sm" onClick={() => goToView(resource?.id)}>{resource?.name || '-'}</button> : (resource?.name || '-') } </td>}
{columns.find(col => col.key === 'office_name')?.show && <td>{resource?.office_name || '-'}</td>}
{columns.find(col => col.key === 'type')?.show && <td>{resource?.type || '-'}</td>}
{columns.find(col => col.key === 'specialty')?.show && <td>{resource?.specialty || '-'}</td>}
@@ -367,7 +367,7 @@ const ResourcesList = () => {
</Dropdown.Toggle>
<Dropdown.Menu as={customFilterMenu}/>
</Dropdown>
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Providers</button>
{AuthService.canEditProviderInfo() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Providers</button>}
<Export
columns={columns}
data={currentItems || []}

View File

@@ -132,7 +132,7 @@ const UpdateResource = () => {
}
useEffect(() => {
if (!AuthService.canViewMedicalSection()) {
if (!AuthService.canEditProviderInfo()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -298,7 +298,7 @@ const UpdateResource = () => {
</Tab>
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary" onClick={() => deactivateResource()}><Archive size={16} className="me-2"></Archive>Archive</button>
{AuthService.canEditProviderInfo() && <button className="btn btn-primary" onClick={() => deactivateResource()}><Archive size={16} className="me-2"></Archive>Archive</button>}
</div>
</div>
</div>

View File

@@ -15,10 +15,12 @@ const ViewResource = () => {
}
const goToEdit = (id) => {
if (!AuthService.canEditProviderInfo()) return;
navigate(`/medical/resources/edit/${id}`);
}
const deactivateResource = (id) => {
if (!AuthService.canEditProviderInfo()) return;
const data = {
status: 'inactive',
edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
@@ -49,7 +51,7 @@ const ViewResource = () => {
}
useEffect(() => {
if (!AuthService.canViewMedicalSection()) {
if (!AuthService.canViewProviderInfo()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -156,8 +158,8 @@ const ViewResource = () => {
</Tab>
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary me-2" onClick={() => goToEdit(currentResource?.id)}><Pencil size={16} className="me-2"></Pencil>Edit</button>
<button className="btn btn-primary me-2" onClick={() => deactivateResource(currentResource?.id)}><Archive size={16} className="me-2"></Archive>Archive</button>
{AuthService.canEditProviderInfo() && <button className="btn btn-primary me-2" onClick={() => goToEdit(currentResource?.id)}><Pencil size={16} className="me-2"></Pencil>Edit</button>}
{AuthService.canEditProviderInfo() && <button className="btn btn-primary me-2" onClick={() => deactivateResource(currentResource?.id)}><Archive size={16} className="me-2"></Archive>Archive</button>}
</div>
</div>
</div>

View File

@@ -27,7 +27,7 @@ const CreateTemplateRoute = () => {
const currentVehicle = vehicles.find((vehicle) => vehicle.id === newVehicle);
useEffect(() => {
if (!AuthService.canAddOrEditRoutes()) {
if (!AuthService.canEditRouteTemplates()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);

View File

@@ -55,7 +55,7 @@ const DailyTemplatesList = () => {
];
useEffect(() => {
if (!AuthService.canViewRoutes()) {
if (!AuthService.canViewRouteTemplates() && !AuthService.canEditRouteTemplates()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -392,7 +392,7 @@ const DailyTemplatesList = () => {
</Tabs>
<div className="list-func-panel">
<input className="me-2 with-search-icon" type="text" placeholder="Search" value={keyword} onChange={(e) => setKeyword(e.currentTarget.value)} />
<Dropdown
{AuthService.canEditRouteTemplates() && <Dropdown
key={'create-template-from-date'}
id="create-template-from-date"
className="me-2"
@@ -404,7 +404,7 @@ const DailyTemplatesList = () => {
Create template from date
</Dropdown.Toggle>
<Dropdown.Menu as={customMenuCreateFromDate}/>
</Dropdown>
</Dropdown>}
</div>
</div>
</div>

View File

@@ -3,6 +3,7 @@ import { useSelector,useDispatch } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import { transRouteTemplatesSlice, selectAllRouteTemplates, selectAllActiveDrivers, selectAllActiveVehicles } from "./../../store";
import RouteCustomerEditor from "./RouteCustomerEditor";
import { AuthService } from "../../services";
const RouteTemplateEdit = () => {
const urlParams = new URLSearchParams(window.location.search);
@@ -38,6 +39,12 @@ const RouteTemplateEdit = () => {
}
useEffect(() => {
if (!AuthService.canEditRouteTemplates()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.');
AuthService.logout();
navigate('/login');
return;
}
if (currentTemplate) {
setRouteName(currentTemplate.name);
setNewDriver(currentTemplate.driver);

View File

@@ -1,7 +1,8 @@
import React, {useState} from "react";
import React, {useState, useEffect} from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { selectAllRouteTemplates, selectAllActiveDrivers, selectAllActiveVehicles } from "./../../store";
import { AuthService } from "../../services";
const RouteTemplatesList = () => {
const params = new URLSearchParams(window.location.search);
@@ -11,6 +12,14 @@ const RouteTemplatesList = () => {
const navigate = useNavigate();
const [nameFilter, setNameFilter] = useState('');
useEffect(() => {
if (!AuthService.canViewRouteTemplates() && !AuthService.canEditRouteTemplates()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.');
AuthService.logout();
navigate('/login');
}
}, []);
const redirectToCreateRoute = () => {
navigate(`/trans-routes/create${params.get('type')?`?type=${params.get('type')}`: ''}${params.get('date')? `&date=${params.get('date')}` : ''}`);
}
@@ -53,7 +62,7 @@ const RouteTemplatesList = () => {
<td>{drivers.find((d) => d.id === driver)?.name}</td>
<td>{vehicles.find((v) => v.id === vehicle)?.vehicle_number}</td>
<td>{status}</td>
<td><button className="btn btn-primary btn-sm" onClick={() => goToEdit(id)}>Edit</button></td>
<td>{AuthService.canEditRouteTemplates() ? <button className="btn btn-primary btn-sm" onClick={() => goToEdit(id)}>Edit</button> : '-'}</td>
</tr>)
})
}

View File

@@ -1835,41 +1835,14 @@ const RoutesDashboard = () => {
View and Update Daily Route Templates
</button> */}
</div>
) : (
<div style={{display: 'flex', alignItems: 'center', gap: '10px'}}>
<select
className="form-select"
style={{width: 'auto', display: 'inline-block'}}
value={selectedTemplateId}
onChange={(e) => setSelectedTemplateId(e.target.value)}
disabled={applyingTemplate}
>
<option value="">Choose a daily template to apply to this day</option>
{templates.map(template => (
<option key={template.id} value={template.id}>
{template.name} - {template.template_date}
</option>
))}
</select>
<button
className="btn btn-primary btn-sm"
onClick={applyTemplate}
disabled={!selectedTemplateId || applyingTemplate}
>
{applyingTemplate ? <><Spinner size="sm" className="me-1" />Applying...</> : 'Submit'}
</button>
{/* <button className="btn btn-secondary btn-sm" onClick={() => navigate('/trans-routes/daily-templates/list')}>
View and Update Daily Route Templates
</button> */}
</div>
)}
) : null}
</div>
<div className="col-md-12 mb-4">
<RoutesSection transRoutes={tmrInboundRoutes} copyList={tmrOutboundRoutes} addText="Add New Route" copyText="Import Outbound Routes" canAddNew={true} drivers={drivers} vehicles={vehicles} redirect={goToCreateRoute} routeType="inbound" sectionName="Inbound Routes" showCheckedInText={false} showRouteHeaderButtons={true} clearAllRoutesAction={() => triggerShowDeleteModal('inbound')}/>
<RoutesSection transRoutes={tmrInboundRoutes} copyList={tmrOutboundRoutes} addText="Add New Route" copyText={AuthService.canAddOrEditRoutes() ? "Import Outbound Routes" : null} canAddNew={AuthService.canAddOrEditRoutes()} drivers={drivers} vehicles={vehicles} redirect={goToCreateRoute} routeType="inbound" sectionName="Inbound Routes" showCheckedInText={false} showRouteHeaderButtons={true} clearAllRoutesAction={AuthService.canAddOrEditRoutes() ? () => triggerShowDeleteModal('inbound') : null}/>
</div>
<hr />
<div className="col-md-12 mb-4">
<RoutesSection transRoutes={tmrOutboundRoutes} copyList={tmrInboundRoutes} addText="Add New Route" copyText="Import Inbound Routes" canAddNew={true} drivers={drivers} vehicles={vehicles} redirect={goToCreateRoute} routeType="outbound" sectionName="Outbound Routes" showRouteHeaderButtons={true} clearAllRoutesAction={() => triggerShowDeleteModal('outbound')}/>
<RoutesSection transRoutes={tmrOutboundRoutes} copyList={tmrInboundRoutes} addText="Add New Route" copyText={AuthService.canAddOrEditRoutes() ? "Import Inbound Routes" : null} canAddNew={AuthService.canAddOrEditRoutes()} drivers={drivers} vehicles={vehicles} redirect={goToCreateRoute} routeType="outbound" sectionName="Outbound Routes" showRouteHeaderButtons={true} clearAllRoutesAction={AuthService.canAddOrEditRoutes() ? () => triggerShowDeleteModal('outbound') : null}/>
</div>
<hr />
</>}

View File

@@ -16,7 +16,12 @@ const TransRoutes = () => {
navigate('/admin');
}
useEffect(() => {
if (!AuthService.canAddOrEditRoutes() && !AuthService.canViewRoutes()) {
if (
!AuthService.canAddOrEditRoutes() &&
!AuthService.canViewRoutes() &&
!AuthService.canViewRouteTemplates() &&
!AuthService.canEditRouteTemplates()
) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change a dispatcher or admin account to login.')
AuthService.logout();
navigate(`/login`);

View File

@@ -29,7 +29,7 @@ const AddRepairRecord = () => {
const [nextReminder, setNextReminder] = useState('');
useEffect(() => {
if (!AuthService.canAddOrEditVechiles()) {
if (!AuthService.canEditVehicleRepairs()) {
window.alert('You haven\'t login yet OR this user does not have access to this page.');
AuthService.logout();
navigate('/login');

View File

@@ -18,7 +18,7 @@ const AddVehicleInspection = () => {
const [existingFiles, setExistingFiles] = useState([]);
useEffect(() => {
if (!AuthService.canAddOrEditVechiles()) {
if (!AuthService.canEditVehicleDocuments()) {
window.alert('You haven\'t login yet OR this user does not have access to this page.');
AuthService.logout();
navigate('/login');

View File

@@ -27,7 +27,7 @@ const EditRepairRecord = () => {
const [nextReminder, setNextReminder] = useState('');
useEffect(() => {
if (!AuthService.canAddOrEditVechiles()) {
if (!AuthService.canEditVehicleRepairs()) {
window.alert('You haven\'t login yet OR this user does not have access to this page.');
AuthService.logout();
navigate('/login');

View File

@@ -20,7 +20,7 @@ const EditVehicleInspection = () => {
const [currentFileName, setCurrentFileName] = useState('');
useEffect(() => {
if (!AuthService.canAddOrEditVechiles()) {
if (!AuthService.canEditVehicleDocuments()) {
window.alert('You haven\'t login yet OR this user does not have access to this page.');
AuthService.logout();
navigate('/login');

View File

@@ -96,7 +96,7 @@ const VehicleList = () => {
]);
useEffect(() => {
if (!AuthService.canAddOrEditVechiles()) {
if (!AuthService.canViewVechiles()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -383,7 +383,7 @@ const VehicleList = () => {
</Dropdown.Toggle>
<Dropdown.Menu as={customFilterMenu}/>
</Dropdown>
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Vehicle</button>
{AuthService.canAddVehicle() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Vehicle</button>}
<Export
columns={columns}
data={filteredVehicles}

View File

@@ -34,13 +34,20 @@ const ViewVehicle = () => {
const { updateVehicle, deleteVehicle, fetchAllVehicles } = vehicleSlice.actions;
const [currentTab, setCurrentTab] = useState(searchParams.get('tab') || 'basicInfo');
const [currentVehicle, setCurrentVehicle] = useState(undefined);
const vehicleTabsOrder = ['basicInfo', 'complianceDeadlines', 'documents'];
const visibleVehicleTabs = vehicleTabsOrder.filter((tabKey) => {
if (tabKey === 'documents') return AuthService.canViewVehicleDocuments() || AuthService.canViewVehicleRepairs();
return AuthService.canViewVehicleBasic();
});
const firstVisibleVehicleTab = visibleVehicleTabs[0] || 'basicInfo';
const redirectTo = () => {
navigate(`/vehicles/list`);
}
const goToEdit = (id) => {
navigate(`/vehicles/edit/${id}?redirect=list&tab=${currentTab}`);
const nextTab = currentTab === 'documents' && !AuthService.canEditVehicleDocuments() && AuthService.canEditVehicleBasic() ? 'basicInfo' : currentTab;
navigate(`/vehicles/edit/${id}?redirect=list&tab=${nextTab}`);
}
const download = () => {
@@ -116,7 +123,7 @@ const ViewVehicle = () => {
const v_repairs = (await VehicleRepairService.getAll(vid)).data;
setRepairs(v_repairs);
}
if (!AuthService.canViewVechiles()) {
if (!AuthService.canViewVehicleAny()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
@@ -133,6 +140,12 @@ const ViewVehicle = () => {
}
}, []);
useEffect(() => {
if (!visibleVehicleTabs.includes(currentTab)) {
setCurrentTab(firstVisibleVehicleTab);
}
}, [currentTab]);
useEffect(() => {
setFilteredMonthlyDocs(monthlyDocs?.filter(item => item?.name?.toLowerCase().includes(keyword.toLowerCase()) || item?.inspectionDate?.includes(keyword.toLowerCase())));
setFilteredYearlyDocs(yearlyDocs?.filter(item => item?.name?.toLowerCase().includes(keyword.toLowerCase()) || item?.inspectionDate?.includes(keyword.toLowerCase())));
@@ -340,8 +353,8 @@ const ViewVehicle = () => {
<tr key={doc.url}>
<td className="td-index">{index + 1}</td>
<td>
<PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/monthly/edit?fileName=${encodeURIComponent(doc?.name)}&date=${encodeURIComponent(doc?.inspectionDate || '')}`)} />
<Trash size={14} className="clickable me-2 text-danger" onClick={() => deleteInspectionFile('monthlyInspection', doc?.name)} />
{AuthService.canEditVehicleDocuments() && <PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/monthly/edit?fileName=${encodeURIComponent(doc?.name)}&date=${encodeURIComponent(doc?.inspectionDate || '')}`)} />}
{AuthService.canEditVehicleDocuments() && <Trash size={14} className="clickable me-2 text-danger" onClick={() => deleteInspectionFile('monthlyInspection', doc?.name)} />}
<a className="btn btn-link btn-sm" href={doc?.url} target="_blank">{doc?.name}</a>
</td>
<td>{doc?.inspectionDate}</td>
@@ -373,8 +386,8 @@ const ViewVehicle = () => {
<tr key={doc.url}>
<td className="td-index">{index + 1}</td>
<td>
<PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/yearly/edit?fileName=${encodeURIComponent(doc?.name)}&date=${encodeURIComponent(doc?.inspectionDate || '')}`)} />
<Trash size={14} className="clickable me-2 text-danger" onClick={() => deleteInspectionFile('yearlyInspection', doc?.name)} />
{AuthService.canEditVehicleDocuments() && <PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/yearly/edit?fileName=${encodeURIComponent(doc?.name)}&date=${encodeURIComponent(doc?.inspectionDate || '')}`)} />}
{AuthService.canEditVehicleDocuments() && <Trash size={14} className="clickable me-2 text-danger" onClick={() => deleteInspectionFile('yearlyInspection', doc?.name)} />}
<a className="btn btn-link btn-sm" href={doc?.url} target="_blank">{doc?.name}</a>
</td>
<td>{doc?.inspectionDate}</td>
@@ -406,7 +419,7 @@ const ViewVehicle = () => {
<tr key={repair.id}>
<td className="td-index">{index + 1}</td>
<td>
<PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/repairs/edit/${repair?.id}`)} />
{AuthService.canEditVehicleRepairs() && <PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/repairs/edit/${repair?.id}`)} />}
{repair?.part_name === 'other'
? (repair?.part_name_other || REPAIR_PART_NAME_TEXT[repair?.part_name] || repair?.repair_description)
: (REPAIR_PART_NAME_TEXT[repair?.part_name] || repair?.part_name || repair?.repair_description)}
@@ -445,7 +458,7 @@ const ViewVehicle = () => {
<div className="app-main-content-list-container form-page">
<div className="app-main-content-list-func-container">
<Tabs activeKey={currentTab} id="vehicles-tab" onSelect={k => changeTab(k)}>
<Tab eventKey="basicInfo" title="Basic Information">
{AuthService.canViewVehicleBasic() && <Tab eventKey="basicInfo" title="Basic Information">
<h6 className="text-primary">Basic Information</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
@@ -529,9 +542,9 @@ const ViewVehicle = () => {
<div className="field-value">{currentVehicle?.note}</div>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="complianceDeadlines" title="Compliance & Deadlines">
{AuthService.canViewVehicleBasic() && <Tab eventKey="complianceDeadlines" title="Compliance & Deadlines">
<h6 className="text-primary">Compliance & Deadlines</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
@@ -543,25 +556,25 @@ const ViewVehicle = () => {
<div className="field-value">{currentVehicle?.vehicle_registration_date || currentVehicle?.title_registration_on}</div>
</div>
</div>
</Tab>
</Tab>}
<Tab eventKey="documents" title="Documents & Records">
{(AuthService.canViewVehicleDocuments() || AuthService.canViewVehicleRepairs()) && <Tab eventKey="documents" title="Documents & Records">
<div className="d-flex justify-content-between align-items-center mb-3">
<h6 className="text-primary mb-0">Yearly Inspection</h6>
<button className="btn btn-primary btn-sm" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/yearly/add`)}>+ Add Yearly Inspection</button>
{AuthService.canEditVehicleDocuments() && <button className="btn btn-primary btn-sm" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/yearly/add`)}>+ Add Yearly Inspection</button>}
</div>
{tableYearly}
<div className="d-flex justify-content-between align-items-center mb-3 mt-4">
<h6 className="text-primary mb-0">Monthly Inspection</h6>
<button className="btn btn-primary btn-sm" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/monthly/add`)}>+ Add Monthly Inspection</button>
{AuthService.canEditVehicleDocuments() && <button className="btn btn-primary btn-sm" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/inspections/monthly/add`)}>+ Add Monthly Inspection</button>}
</div>
{tableMonthly}
<div className="d-flex justify-content-between align-items-center mb-3 mt-4">
<h6 className="text-primary mb-0">Repair & Maintenance Record</h6>
<button className="btn btn-primary btn-sm" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/repairs/add`)}>+ Add Repair Record</button>
{AuthService.canEditVehicleRepairs() && <button className="btn btn-primary btn-sm" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/repairs/add`)}>+ Add Repair Record</button>}
</div>
{tableRepair}
</Tab>
</Tab>}
</Tabs>
<div className="list-func-panel">
{currentTab === 'documents' && (
@@ -574,7 +587,7 @@ const ViewVehicle = () => {
/>
</>
)}
{currentTab !== 'documents' && (
{currentTab !== 'documents' && AuthService.canEditVehicleBasic() && (
<button className="btn btn-primary ms-2" onClick={() => goToEdit(currentVehicle?.id)}><PencilSquare className="me-2" size={16}></PencilSquare>Edit</button>
)}
</div>

View File

@@ -37,6 +37,100 @@ const hasAnyPermission = (permissionKeys = []) => {
return permissionKeys.some((permissionKey) => permissionSet.has(permissionKey));
};
const CUSTOMER_VIEW_TAB_PERMISSION_MAP = {
personalInfo: 'View_Customer Info _Personal Info',
careServices: 'View_Customer Info _Care & Services',
medicalInsurance: 'View_Customer Info _Medical & Insurance',
confidentialDetails: 'View_Customer Info _Confidential Details',
formSubmission: 'View_Customer Info _Form Submission'
};
const CUSTOMER_EDIT_TAB_PERMISSION_MAP = {
personalInfo: 'Edit_Customer Info _ Personal Info',
careServices: 'Edit_Customer Info _ Care & Services',
medicalInsurance: 'Edit_Customer Info _ Medical & Insurance',
confidentialDetails: 'Edit_Customer Info _ Confidential Details',
formSubmission: 'Edit_Customer Info _ Form Submission'
};
const CALENDAR_VIEW_PERMISSION_BY_TAB = {
medicalCalendar: 'View _Calendar _Medical Appointment',
activitiesCalendar: 'View _Calendar _Activities',
incidentsCalendar: 'View _Calendar _Attendance Notes',
mealPlanCalendar: 'View _Calendar _Meal Plan',
reminderDatesCalendar: 'View _Calendar _Important Dates'
};
const CALENDAR_EDIT_PERMISSION_BY_TAB = {
medicalCalendar: 'Edit&Create _Calendar _Medical Appointment',
activitiesCalendar: 'Edit&Create _Calendar _Activities',
incidentsCalendar: 'Edit&Create _Calendar _Attendance Notes',
mealPlanCalendar: 'Edit&Create _Calendar _Meal Plan',
reminderDatesCalendar: 'Edit&Create _Calendar _Important Dates'
};
const canViewCustomerTab = (tabKey) => {
const permissionKey = CUSTOMER_VIEW_TAB_PERMISSION_MAP?.[tabKey];
return permissionKey ? hasPermission(permissionKey) : false;
}
const canEditCustomerTab = (tabKey) => {
const permissionKey = CUSTOMER_EDIT_TAB_PERMISSION_MAP?.[tabKey];
return permissionKey ? hasPermission(permissionKey) : false;
}
const canViewAnyCustomerTab = () => {
return Object.keys(CUSTOMER_VIEW_TAB_PERMISSION_MAP).some(canViewCustomerTab);
}
const canEditAnyCustomerTab = () => {
return Object.keys(CUSTOMER_EDIT_TAB_PERMISSION_MAP).some(canEditCustomerTab);
}
const canCreateCustomer = () => hasPermission('Create_Customer');
const canDischargeCustomer = () => hasPermission('Discharge_Customer');
const canReactivateCustomer = () => hasPermission('Reactivate_Customer');
const canExportCustomerReport = () => hasPermission('Export_Customer Report');
const canViewCalendarTab = (tabKey) => {
const permissionKey = CALENDAR_VIEW_PERMISSION_BY_TAB?.[tabKey];
return permissionKey ? hasPermission(permissionKey) : false;
}
const canEditCalendarTab = (tabKey) => {
const permissionKey = CALENDAR_EDIT_PERMISSION_BY_TAB?.[tabKey];
return permissionKey ? hasPermission(permissionKey) : false;
}
const canViewAnyCalendarTab = () => {
return Object.keys(CALENDAR_VIEW_PERMISSION_BY_TAB).some(canViewCalendarTab);
}
const canEditAnyCalendarTab = () => {
return Object.keys(CALENDAR_EDIT_PERMISSION_BY_TAB).some(canEditCalendarTab);
}
const canViewTransportationOverview = () => hasPermission('View_Transportation Schedule_Route Overview');
const canEditTransportationSchedule = () => hasPermission('Create&Edit_Transportation Schedule');
const canExportTransportationScheduleReport = () => hasPermission('Export_Transportation Schedule Report');
const canViewRouteTemplates = () => hasPermission('View_Route Template');
const canEditRouteTemplates = () => hasPermission('Create&Edit_Route Template');
const canViewDriverAssignment = () => hasPermission('View_Driver Assignment for Appointment');
const canEditDriverAssignment = () => hasPermission('Edit_Driver Assignment for Appointment');
const canViewVehicleBasic = () => hasAnyPermission(['View_Vehicle info_Basic Info', 'Edit_Vehicle info_Basic Info']);
const canEditVehicleBasic = () => hasPermission('Edit_Vehicle info_Basic Info');
const canViewVehicleDocuments = () => hasAnyPermission(['View_Vehicle info_Documents', 'Edit_Vehicle info_Documents']);
const canEditVehicleDocuments = () => hasPermission('Edit_Vehicle info_Documents');
const canViewVehicleRepairs = () => hasAnyPermission(['View_Vehicle info_Repair Records', 'Edit_Vehicle info_Repair Records']);
const canEditVehicleRepairs = () => hasPermission('Edit_Vehicle info_Repair Records');
const canAddVehicle = () => hasPermission('Add_New Vehicle');
const canArchiveVehicle = () => hasPermission('Archive_Vehicle');
const canDeleteVehicle = () => hasPermission('Delete_Vehicle');
const canExportVehicleReport = () => hasPermission('Export_Vehicle Report');
const canViewVehicleAny = () => canViewVehicleBasic() || canViewVehicleDocuments() || canViewVehicleRepairs() || canEditVehicleBasic() || canEditVehicleDocuments() || canEditVehicleRepairs() || canAddVehicle() || canArchiveVehicle() || canDeleteVehicle() || canExportVehicleReport();
const canEditVehicleAny = () => canEditVehicleBasic() || canEditVehicleDocuments() || canEditVehicleRepairs() || canAddVehicle() || canArchiveVehicle() || canDeleteVehicle();
const canViewDashboard = () => {
return hasAnyPermission([
'Dashboard',
@@ -54,18 +148,7 @@ const canViewInfoScreen = () => {
}
const canViewCalendar = () => {
return hasAnyPermission([
'View _Calendar _Medical Appointment',
'View _Calendar _Activities',
'View _Calendar _Attendance Notes',
'View _Calendar _Meal Plan',
'View _Calendar _Important Dates',
'Edit&Create _Calendar _Medical Appointment',
'Edit&Create _Calendar _Activities',
'Edit&Create _Calendar _Attendance Notes',
'Edit&Create _Calendar _Meal Plan',
'Edit&Create _Calendar _Important Dates'
]);
return canViewAnyCalendarTab() || canEditAnyCalendarTab();
}
const canViewMessaging = () => {
@@ -89,6 +172,28 @@ const canViewMedicalSection = () => {
]);
}
const canViewProviderInfo = () => {
return hasAnyPermission([
'View_Provider Info',
'Create & Edit _Provider Info'
]);
}
const canEditProviderInfo = () => {
return hasPermission('Create & Edit _Provider Info');
}
const canViewAppointmentRequests = () => {
return hasAnyPermission([
'View_Appointment Request',
'Edit & Create_Appointment Request'
]);
}
const canEditAppointmentRequests = () => {
return hasPermission('Edit & Create_Appointment Request');
}
const canViewMedicalEvents = () => {
return hasAnyPermission([
'View _Calendar _Medical Appointment',
@@ -133,17 +238,11 @@ const isAdmin = () => {
// }
const canCreateOrEditDrivers = () => {
return hasAnyPermission([
'Edit_Driver Assignment for Appointment',
'Create&Edit_Transportation Schedule'
]);
return canEditDriverAssignment() || canEditTransportationSchedule();
}
const canViewDrivers = () => {
return hasAnyPermission([
'View_Driver Assignment for Appointment',
'Edit_Driver Assignment for Appointment'
]);
return canViewDriverAssignment() || canEditDriverAssignment();
}
const canViewEmployees = () => {
@@ -158,73 +257,27 @@ const canAddOrEditEmployees = () => {
}
const canAddOrEditRoutes = () => {
return hasPermission('Create&Edit_Transportation Schedule');
return canEditTransportationSchedule();
}
const canViewRoutes = () => {
return hasAnyPermission([
'View_Transportation Schedule_Route Overview',
'Create&Edit_Transportation Schedule',
'Export_Transportation Schedule Report'
]);
return canViewTransportationOverview() || canEditTransportationSchedule() || canExportTransportationScheduleReport();
}
const canViewVechiles = () => {
return hasAnyPermission([
'View_Vehicle info_Basic Info',
'View_Vehicle info_Documents',
'View_Vehicle info_Repair Records',
'Edit_Vehicle info_Basic Info',
'Edit_Vehicle info_Documents',
'Edit_Vehicle info_Repair Records',
'Add_New Vehicle',
'Archive_Vehicle',
'Delete_Vehicle',
'Export_Vehicle Report'
]);
return canViewVehicleAny();
}
const canAddOrEditVechiles = () => {
return hasAnyPermission([
'Edit_Vehicle info_Basic Info',
'Edit_Vehicle info_Documents',
'Edit_Vehicle info_Repair Records',
'Add_New Vehicle',
'Archive_Vehicle',
'Delete_Vehicle'
]);
return canEditVehicleAny();
}
const canViewCustomers = () => {
return hasAnyPermission([
'View_Customer Info _Personal Info',
'View_Customer Info _Care & Services',
'View_Customer Info _Medical & Insurance',
'View_Customer Info _Confidential Details',
'View_Customer Info _Form Submission',
'Edit_Customer Info _ Personal Info',
'Edit_Customer Info _ Care & Services',
'Edit_Customer Info _ Medical & Insurance',
'Edit_Customer Info _ Confidential Details',
'Edit_Customer Info _ Form Submission',
'Create_Customer',
'Discharge_Customer',
'Reactivate_Customer',
'Export_Customer Report'
]);
return canViewAnyCustomerTab() || canEditAnyCustomerTab() || canCreateCustomer() || canDischargeCustomer() || canReactivateCustomer() || canExportCustomerReport();
}
const canAddOrEditCustomers = () => {
return hasAnyPermission([
'Edit_Customer Info _ Personal Info',
'Edit_Customer Info _ Care & Services',
'Edit_Customer Info _ Medical & Insurance',
'Edit_Customer Info _ Confidential Details',
'Edit_Customer Info _ Form Submission',
'Create_Customer',
'Discharge_Customer',
'Reactivate_Customer'
]);
return canEditAnyCustomerTab() || canCreateCustomer() || canDischargeCustomer() || canReactivateCustomer();
}
const canViewAttendance = () => {
@@ -260,10 +313,7 @@ const canAddOrEditMedicalSchedule = () => {
}
const canAddOrEditResources = () => {
return hasAnyPermission([
'View_Provider Info',
'Create & Edit _Provider Info'
]);
return canEditProviderInfo();
}
const canAccessLegacySystem = () => {
@@ -304,9 +354,17 @@ export const AuthService = {
hasPermission,
canViewDashboard,
canViewInfoScreen,
canViewCalendarTab,
canEditCalendarTab,
canViewAnyCalendarTab,
canEditAnyCalendarTab,
canViewCalendar,
canViewMessaging,
canViewMedicalSection,
canViewProviderInfo,
canEditProviderInfo,
canViewAppointmentRequests,
canEditAppointmentRequests,
canViewMedicalEvents,
canEditMedicalEvents,
canViewMealStatus,
@@ -316,12 +374,39 @@ export const AuthService = {
canCreateOrEditDrivers,
getLocalAccessToken,
canViewDrivers,
canViewTransportationOverview,
canEditTransportationSchedule,
canExportTransportationScheduleReport,
canViewRouteTemplates,
canEditRouteTemplates,
canViewDriverAssignment,
canEditDriverAssignment,
canViewEmployees,
canAddOrEditEmployees,
canAddOrEditRoutes,
canViewRoutes,
canViewVechiles,
canAddOrEditVechiles,
canViewVehicleBasic,
canEditVehicleBasic,
canViewVehicleDocuments,
canEditVehicleDocuments,
canViewVehicleRepairs,
canEditVehicleRepairs,
canAddVehicle,
canArchiveVehicle,
canDeleteVehicle,
canExportVehicleReport,
canViewVehicleAny,
canEditVehicleAny,
canViewCustomerTab,
canEditCustomerTab,
canViewAnyCustomerTab,
canEditAnyCustomerTab,
canCreateCustomer,
canDischargeCustomer,
canReactivateCustomer,
canExportCustomerReport,
canViewCustomers,
canAddOrEditCustomers,
canAddOrEditAttendance,