Files
worldshine-redesign/client/src/components/resources/UpdateResource.js
Lixian Zhou 5489dbf327
All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 36s
patch
2026-03-11 11:43:27 -04:00

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;