All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 36s
326 lines
13 KiB
JavaScript
326 lines
13 KiB
JavaScript
import React, {useState, useEffect} from "react";
|
|
import { useNavigate, useParams } from "react-router-dom";
|
|
import { AuthService, ResourceService } from "../../services";
|
|
import { Archive } from "react-bootstrap-icons";
|
|
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab, Modal, Button } from "react-bootstrap";
|
|
import { RESOURCE_TYPE_OPTIONS, RESOURCE_SPECIALTY_OPTIONS } from "../../shared/constants";
|
|
|
|
const UpdateResource = () => {
|
|
const navigate = useNavigate();
|
|
const urlParams = useParams();
|
|
const [currentResource, setCurrentResource] = useState(undefined);
|
|
|
|
// Basic Information
|
|
const [name, setName] = useState(''); // Provider name
|
|
const [officeName, setOfficeName] = useState('');
|
|
const [specialty, setSpecialty] = useState('');
|
|
const [type, setType] = useState('');
|
|
const [typeOther, setTypeOther] = useState('');
|
|
|
|
// Contact Information
|
|
const [phone, setPhone] = useState(''); // Office Phone Number
|
|
const [contact, setContact] = useState(''); // Secondary Phone Number
|
|
const [fax, setFax] = useState(''); // Fax Number
|
|
const [email, setEmail] = useState('');
|
|
|
|
// Address (split fields)
|
|
const [addressLine1, setAddressLine1] = useState('');
|
|
const [addressLine2, setAddressLine2] = useState('');
|
|
const [city, setCity] = useState('');
|
|
const [state, setState] = useState('');
|
|
const [zipcode, setZipcode] = useState('');
|
|
|
|
// Additional Information
|
|
const [note, setNote] = useState('');
|
|
|
|
// Modal
|
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
|
|
|
const redirectTo = () => {
|
|
navigate(`/medical/resources/list`);
|
|
}
|
|
|
|
const redirectToView = () => {
|
|
navigate(`/medical/resources/${urlParams.id}`);
|
|
}
|
|
|
|
const validateResource = () => {
|
|
const errors = [];
|
|
|
|
// Required fields validation
|
|
if (!name || name.trim() === '') {
|
|
errors.push('Provider');
|
|
}
|
|
if (!phone || phone.trim() === '') {
|
|
errors.push('Office Phone Number');
|
|
}
|
|
if (type === 'other' && (!typeOther || typeOther.trim() === '')) {
|
|
errors.push('Other-please specify');
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
window.alert(`Please fill in the following required fields:\n${errors.join('\n')}`);
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
const saveResource = () => {
|
|
if (!validateResource()) {
|
|
return;
|
|
}
|
|
|
|
const combinedAddress = `${addressLine1}${addressLine2 ? ', ' + addressLine2 : ''}, ${city}, ${state} ${zipcode}`.trim();
|
|
|
|
const updatedResource = {
|
|
...currentResource,
|
|
data: currentResource?.data || {},
|
|
|
|
// Basic Information
|
|
name, // Provider
|
|
office_name: officeName,
|
|
name_original: officeName, // Legacy field
|
|
specialty,
|
|
type,
|
|
type_other: type === 'other' ? typeOther : '',
|
|
|
|
// Contact Information
|
|
phone, // Office Phone Number
|
|
contact, // Secondary Phone Number
|
|
fax, // Fax Number
|
|
email,
|
|
|
|
// Address (split fields)
|
|
address_line_1: addressLine1,
|
|
address_line_2: addressLine2,
|
|
city,
|
|
state,
|
|
zipcode,
|
|
address: combinedAddress, // Legacy field
|
|
|
|
// Additional Information
|
|
note,
|
|
|
|
// System fields
|
|
edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
|
edit_date: new Date(),
|
|
edit_history: currentResource?.edit_history
|
|
? [...currentResource.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() }]
|
|
};
|
|
|
|
ResourceService.updateResource(urlParams.id, updatedResource).then(() => redirectToView());
|
|
};
|
|
|
|
const triggerShowDeleteModal = () => {
|
|
setShowDeleteModal(true);
|
|
}
|
|
|
|
const closeDeleteModal = () => {
|
|
setShowDeleteModal(false);
|
|
}
|
|
|
|
const deactivateResource = () => {
|
|
ResourceService.disableResource(urlParams.id, {
|
|
status: 'inactive',
|
|
edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
|
|
edit_date: new Date()
|
|
}).then(() => {
|
|
setShowDeleteModal(false);
|
|
redirectTo();
|
|
});
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!AuthService.canViewMedicalSection()) {
|
|
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`);
|
|
}
|
|
ResourceService.getResource(urlParams.id).then(resourceData => {
|
|
setCurrentResource(resourceData.data);
|
|
});
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (currentResource) {
|
|
// Basic Information
|
|
setName(currentResource?.name || '');
|
|
setOfficeName(currentResource?.office_name || currentResource?.name_original || '');
|
|
setSpecialty(currentResource?.specialty || '');
|
|
setType(currentResource?.type || '');
|
|
setTypeOther(currentResource?.type_other || '');
|
|
|
|
// Contact Information
|
|
setPhone(currentResource?.phone || '');
|
|
setContact(currentResource?.contact || '');
|
|
setFax(currentResource?.fax || '');
|
|
setEmail(currentResource?.email || '');
|
|
|
|
// Address - try new fields first, then fall back to legacy
|
|
setAddressLine1(currentResource?.address_line_1 || currentResource?.address || '');
|
|
setAddressLine2(currentResource?.address_line_2 || '');
|
|
setCity(currentResource?.city || '');
|
|
setState(currentResource?.state || '');
|
|
setZipcode(currentResource?.zipcode || '');
|
|
|
|
// Additional Information - merge description into note if note is empty
|
|
setNote(currentResource?.note || currentResource?.description || '');
|
|
}
|
|
}, [currentResource]);
|
|
|
|
return (
|
|
<>
|
|
<div className="list row mb-4">
|
|
<Breadcrumb>
|
|
<Breadcrumb.Item href="/medical/index">Medical</Breadcrumb.Item>
|
|
<Breadcrumb.Item href="/medical/resources/list">
|
|
Provider Information
|
|
</Breadcrumb.Item>
|
|
<Breadcrumb.Item active>
|
|
Update Provider Information
|
|
</Breadcrumb.Item>
|
|
</Breadcrumb>
|
|
<div className="col-md-12 text-primary">
|
|
<h4>Update Provider Information <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
|
|
</div>
|
|
</div>
|
|
<div className="app-main-content-list-container">
|
|
<div className="app-main-content-list-func-container">
|
|
<Tabs defaultActiveKey="providerInfo" id="providers-tab">
|
|
<Tab eventKey="providerInfo" title="Provider Information">
|
|
<h6 className="text-primary">Basic Information</h6>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Provider <span className="required">*</span></div>
|
|
<input placeholder="e.g., Dr. Cao Qing" type="text" value={name} onChange={e => setName(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Office Name</div>
|
|
<input type="text" placeholder="e.g., Silver Spring Family Medicine Clinic" value={officeName} onChange={e => setOfficeName(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Type</div>
|
|
<select value={type} onChange={e => {
|
|
const nextType = e.target.value;
|
|
setType(nextType);
|
|
if (nextType !== 'other') {
|
|
setTypeOther('');
|
|
}
|
|
}}>
|
|
<option value="">Select...</option>
|
|
{RESOURCE_TYPE_OPTIONS.map((item, index) => (
|
|
<option key={index} value={item.value}>{item.label}</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
{type === 'other' && <div className="me-4">
|
|
<div className="field-label">Other-please specify</div>
|
|
<input type="text" value={typeOther} onChange={e => setTypeOther(e.target.value)} />
|
|
</div>}
|
|
<div className="me-4">
|
|
<div className="field-label">Specialty</div>
|
|
<select value={specialty} onChange={e => setSpecialty(e.target.value)}>
|
|
<option value="">Select...</option>
|
|
{RESOURCE_SPECIALTY_OPTIONS.map((item, index) => (
|
|
<option key={index} value={item.value}>{item.label}</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<h6 className="text-primary">Contact Information</h6>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Office Phone Number <span className="required">*</span></div>
|
|
<input placeholder="e.g., 240-463-1098" type="text" value={phone} onChange={e => setPhone(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Secondary Phone Number</div>
|
|
<input type="text" placeholder="e.g., 240-463-1698" value={contact} onChange={e => setContact(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Fax Number</div>
|
|
<input type="text" placeholder="e.g., 240-463-1698" value={fax} onChange={e => setFax(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Email</div>
|
|
<input type="email" placeholder="e.g., example@gmail.com" value={email} onChange={e => setEmail(e.target.value)}/>
|
|
</div>
|
|
</div>
|
|
|
|
<h6 className="text-primary">Provider Address</h6>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Address Line 1 <span className="required">*</span></div>
|
|
<input type="text" placeholder="e.g., 555 Cloverly Forest Dr" value={addressLine1} onChange={e => setAddressLine1(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Address Line 2</div>
|
|
<input type="text" placeholder="e.g., Suite 200" value={addressLine2} onChange={e => setAddressLine2(e.target.value)}/>
|
|
</div>
|
|
</div>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">City <span className="required">*</span></div>
|
|
<input type="text" placeholder="e.g., Rockville" value={city} onChange={e => setCity(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">State <span className="required">*</span></div>
|
|
<input type="text" placeholder="e.g., MD" value={state} onChange={e => setState(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Zip Code <span className="required">*</span></div>
|
|
<input type="text" placeholder="e.g., 20850" value={zipcode} onChange={e => setZipcode(e.target.value)}/>
|
|
</div>
|
|
</div>
|
|
|
|
<h6 className="text-primary">Additional Information</h6>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Note</div>
|
|
<textarea
|
|
placeholder="e.g., Preferred provider for cardiology referrals"
|
|
value={note}
|
|
onChange={e => setNote(e.target.value)}
|
|
rows={4}
|
|
style={{width: '400px'}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="list row mb-5">
|
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectTo()}> Cancel </button>
|
|
<button className="btn btn-primary btn-sm float-right" onClick={() => saveResource()}> Save </button>
|
|
</div>
|
|
</div>
|
|
</Tab>
|
|
</Tabs>
|
|
<div className="list-func-panel">
|
|
<button className="btn btn-primary" onClick={() => deactivateResource()}><Archive size={16} className="me-2"></Archive>Archive</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Modal show={showDeleteModal} onHide={() => closeDeleteModal()}>
|
|
<Modal.Header closeButton>
|
|
<Modal.Title>Delete Provider</Modal.Title>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<div>Are you sure you want to delete this provider?</div>
|
|
</Modal.Body>
|
|
<Modal.Footer>
|
|
<Button variant="secondary" onClick={() => closeDeleteModal()}>
|
|
No
|
|
</Button>
|
|
<Button variant="primary" onClick={() => deactivateResource()}>
|
|
Yes
|
|
</Button>
|
|
</Modal.Footer>
|
|
</Modal>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default UpdateResource;
|