Vechile & Providers

This commit is contained in:
Yang Li 2025-05-02 14:13:33 -04:00
parent fb3bd27a15
commit 176af8407b
28 changed files with 2023 additions and 819 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
app/.DS_Store vendored

Binary file not shown.

View File

@ -30,6 +30,7 @@ exports.createResource = (req, res) => {
description: req.body.description, description: req.body.description,
contact: req.body.contact, contact: req.body.contact,
fax: req.body.fax, fax: req.body.fax,
email: req.body.email,
note: req.body.note, note: req.body.note,
data: req.body.data, data: req.body.data,
edit_by: req.body.edit_by, edit_by: req.body.edit_by,

View File

@ -25,6 +25,7 @@ module.exports = mongoose => {
description: String, description: String,
contact: String, contact: String,
fax: String, fax: String,
email: String,
note: String, note: String,
data: Object, data: Object,
edit_by: String, edit_by: String,

View File

@ -1,16 +1,16 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.3602a440.css", "main.css": "/static/css/main.38d76725.css",
"main.js": "/static/js/main.d36451b8.js", "main.js": "/static/js/main.6292bf56.js",
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js", "static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png", "static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
"index.html": "/index.html", "index.html": "/index.html",
"main.3602a440.css.map": "/static/css/main.3602a440.css.map", "main.38d76725.css.map": "/static/css/main.38d76725.css.map",
"main.d36451b8.js.map": "/static/js/main.d36451b8.js.map", "main.6292bf56.js.map": "/static/js/main.6292bf56.js.map",
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map" "787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.3602a440.css", "static/css/main.38d76725.css",
"static/js/main.d36451b8.js" "static/js/main.6292bf56.js"
] ]
} }

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.d36451b8.js"></script><link href="/static/css/main.3602a440.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.6292bf56.js"></script><link href="/static/css/main.38d76725.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

BIN
client/.DS_Store vendored

Binary file not shown.

View File

@ -1,16 +1,16 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.3602a440.css", "main.css": "/static/css/main.38d76725.css",
"main.js": "/static/js/main.d36451b8.js", "main.js": "/static/js/main.6292bf56.js",
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js", "static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png", "static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
"index.html": "/index.html", "index.html": "/index.html",
"main.3602a440.css.map": "/static/css/main.3602a440.css.map", "main.38d76725.css.map": "/static/css/main.38d76725.css.map",
"main.d36451b8.js.map": "/static/js/main.d36451b8.js.map", "main.6292bf56.js.map": "/static/js/main.6292bf56.js.map",
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map" "787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.3602a440.css", "static/css/main.38d76725.css",
"static/js/main.d36451b8.js" "static/js/main.6292bf56.js"
] ]
} }

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.d36451b8.js"></script><link href="/static/css/main.3602a440.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.6292bf56.js"></script><link href="/static/css/main.38d76725.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

View File

@ -174,6 +174,7 @@ input {
padding: 40px; padding: 40px;
height: 100vh; height: 100vh;
overflow: auto; overflow: auto;
position: relative;
} }
.app-side-bar-logo img { .app-side-bar-logo img {
@ -369,7 +370,12 @@ table tr td {
width: 30px !important; width: 30px !important;
padding-left: 8px !important; padding-left: 8px !important;
min-width: 5px !important; min-width: 5px !important;
border-right: none; }
.td-index, .th-index {
width: 30px !important;
padding-left: 8px !important;
min-width: 5px !important;
} }
.float-right { .float-right {
@ -388,6 +394,112 @@ table .group td {
font-style: italic; font-style: italic;
} }
.app-main-content-fields-section {
display: flex;
align-items: baseline;
margin-top: 24px;
margin-bottom: 40px;
}
.app-main-content-fields-section.column {
flex-direction: column;
}
.app-main-content-fields-section li {
list-style: decimal;
margin-top: 4px;
margin-bottom: 4px;
}
/* .app-main-content-fields-section.base-line {
align-items: baseline !important;
} */
.app-main-content-fields-section .field-label {
font-size: 13px;
color: black;
font-weight: 500;
line-height: 2;
}
.app-main-content-fields-section .field-value {
font-size: 12px;
color: #555;
}
.app-main-content-fields-section .field-body {
margin-right: 100px;
}
.app-main-content-fields-section input[type=text] {
width: 350px;
height: 45px;
}
.app-main-content-fields-section input[type=text].shorter {
width: 50px;
height: 45px;
}
.app-main-content-fields-section input[type=text].short {
width: 150px;
height: 45px;
}
.app-main-content-fields-section input[type=text].long {
width: 450px;
height: 45px;
}
.app-main-content-fields-section .file-name {
color: #aaa;
margin-top: 4px;
font-size: 13px;
}
.app-main-content-fields-section input[type=email] {
width: 350px;
height: 45px;
}
.app-main-content-fields-section input[type=number] {
width: 350px;
height: 45px;
}
.app-main-content-fields-section input[type=file] {
display: none;
}
.custom-file-upload {
background:#0066B1;
display: inline-block;
cursor: pointer;
color: white;
height: 45px;
width: 150px;
padding: 12px;
font-size: 13px;
font-weight: 500;
border-radius: 6px;
}
.app-main-content-fields-section select {
width: 350px;
height: 45px;
border-radius: 8px;
margin-left: 0 !important;
border-color: #ccc !important;
}
.app-main-content-fields-section .field-blurb {
color: #aaa;
}
.app-main-content-fields-section .required {
color:#0066B1;
}
select { select {
margin-left: 5px; margin-left: 5px;
min-width: 200px; min-width: 200px;
@ -449,20 +561,6 @@ input[type="checkbox"] {
cursor: pointer; cursor: pointer;
} }
table.medical th {
font-size: 16px;
color: #000;
}
table.medical td {
font-size: 14px;
color: #000;
}
table.medical, table tr, table.medical tr td, table.medical tr th {
border-color: #000;
}
.personnel-info-table .red { .personnel-info-table .red {
background: #dc3545; background: #dc3545;
color: rgb(25, 23, 23); color: rgb(25, 23, 23);
@ -755,11 +853,63 @@ table.medical, table tr, table.medical tr td, table.medical tr th {
height: 50px; height: 50px;
} }
.pagination-container {
display: flex;
justify-content: right;
margin-top: 20px;
}
.page-prev-item, .page-next-item {
font-size: 12px;
padding: 4px 0;
border: 1px solid #777;
border-radius: 10px;
margin-right: 4px;
color: #777;
}
.page-prev-item.disabled, .page-next-item.disabled {
color: #aaa;
border-color: #aaa;
}
.per-page, .page-picker {
width: 55px !important;
height: 30px;
border-radius: 10px;
border-color: #777;
color: #777;
font-size: 12px;
min-width: 20px;
margin-right: 2px;
}
.per-page option {
width: 30px;
}
.page-item {
display:none;
}
.per-page-label {
font-size: 12px;
}
.select-page-container {
font-size: 12px;
display: flex;
align-items: baseline;
margin-right: 4px;
margin-left: 4px;
}
.customers-pagination { .customers-pagination {
margin-bottom: 2rem; margin-bottom: 2rem;
margin-right: 4px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: right;
list-style-type: none; list-style-type: none;
padding: 0; padding: 0;
flex-wrap: wrap; flex-wrap: wrap;
@ -774,9 +924,9 @@ table.medical, table tr, table.medical tr td, table.medical tr th {
color: #777; color: #777;
} }
.customers-pagination li { /* .customers-pagination li {
border: none; border: none;
} } */
.customers-pagination li a { .customers-pagination li a {
border: none; border: none;

View File

@ -5,6 +5,8 @@ import { customerSlice } from "../../store";
import { AuthService, CustomerService, ResourceService } from "../../services"; import { AuthService, CustomerService, ResourceService } from "../../services";
import Select from 'react-select'; import Select from 'react-select';
import { CUSTOMER_TYPE, PICKUP_STATUS, PICKUP_STATUS_TEXT , CUSTOMER_TYPE_TEXT} from "../../shared"; import { CUSTOMER_TYPE, PICKUP_STATUS, PICKUP_STATUS_TEXT , CUSTOMER_TYPE_TEXT} from "../../shared";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
import { Upload } from "react-bootstrap-icons";
const CreateCustomer = () => { const CreateCustomer = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -13,6 +15,8 @@ const CreateCustomer = () => {
const [username, setUsername] = useState(''); const [username, setUsername] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [firstname, setFirstname] = useState(''); const [firstname, setFirstname] = useState('');
const [middlename, setMiddlename] = useState('');
const [nameOnId, setNameOnId] = useState('')
const [lastname, setLastname] = useState(''); const [lastname, setLastname] = useState('');
const [nameCN, setNameCN] = useState(''); const [nameCN, setNameCN] = useState('');
const [birthDate, setBirthDate] = useState(''); const [birthDate, setBirthDate] = useState('');
@ -60,7 +64,7 @@ const CreateCustomer = () => {
const [textMsgEnabled, setTextMsgEnabled] = useState(false); const [textMsgEnabled, setTextMsgEnabled] = useState(false);
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const redirectTo = () => { const redirectTo = () => {
navigate('/admin'); navigate('/customers/list');
} }
useEffect(() => { useEffect(() => {
@ -185,49 +189,249 @@ const CreateCustomer = () => {
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item>General</Breadcrumb.Item>
<Breadcrumb.Item active>
Customer Information
</Breadcrumb.Item>
<Breadcrumb.Item active>
Create New Customer
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary"> <div className="col-md-12 text-primary">
<h5>Create New Customer <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5> <h4>Create New Customer <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
</div> </div>
</div> </div>
<div className="list row mb-4">
<div className="col-md-4 mb-4"> <div className="app-main-content-list-container">
<div>First Name:(*)</div> <input type="text" value={firstname || ''} onChange={e => setFirstname(e.target.value)}/> <div className="app-main-content-list-func-container">
</div> <Tabs defaultActiveKey="basicInfo" id="customers-tab">
<div className="col-md-4 mb-4"> <Tab eventKey="basicInfo" title="Basic Information">
<div>Last Name:(*)</div> <input type="text" value={lastname || ''} onChange={e => setLastname(e.target.value)}/> <h6 className="text-primary">Personal Details</h6>
</div> <div className="app-main-content-fields-section">
<div className="col-md-4 mb-4"> <div className="me-4"><div className="field-label">First Name <span className="required">*</span></div> <input type="text" placeholder="e.g.,John" value={firstname || ''} onChange={e => setFirstname(e.target.value)}/></div>
<div>Preferred Name (中文姓名):</div> <input type="text" value={nameCN || ''} onChange={e => setNameCN(e.target.value)}/> {/* <div><div className="field-label">Middle Name</div> <input type="text" value={middlename || ''} onChange={e => setMiddlename(e.target.value)}/></div> */}
</div> <div className="me-4"><div className="field-label">Last Name <span className="required">*</span></div> <input type="text" placeholder="e.g.,Johnson" value={lastname || ''} onChange={e => setLastname(e.target.value)}/></div>
<div className="col-md-4 mb-4"> <div className="me-4"><div className="field-label">Preferred Name/Chinese Name</div> <input type="text" placeholder="e.g.,李华" value={nameCN || ''} onChange={e => setNameCN(e.target.value)}/></div>
<div>Nick Name:</div> <input type="text" value={nickname || ''} onChange={e => setNickname(e.target.value)}/> <div className="me-4"><div className="field-label">Nick Name</div> <input placeholder="e.g.,Johnson" type="text" value={nickname || ''} onChange={e => setNickname(e.target.value)}/></div>
</div> </div>
<div className="col-md-4 mb-4"> <div className="app-main-content-fields-section">
<div>Email:(*)</div> <input type="email" value={email || ''} onChange={e => setEmail(e.target.value)}/> <div className="me-4">
</div> <div className="field-label">Admission Date</div>
<div className="col-md-4 mb-4"> <input type="text" placeholder="e.g.,01/15/2025" value={admissionDate || ''} onChange={e => setAdmissionDate(e.target.value)}/>
<div>Care Provider:</div> <input type="text" value={careProvider || ''} onChange={e => setCareProvider(e.target.value)}/> </div>
</div> <div className="me-4">
<div className="field-label">Discharge Date</div>
<input type="text" placeholder="e.g.,01/15/2025" value={dischargeDate || ''} onChange={e => setDischargeDate(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Birth Date</div>
<input type="text" placeholder="e.g.,01/15/2025" value={birthDate || ''} onChange={e => setBirthDate(e.target.value)}/>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Customer Type</div>
<select value={customerType} onChange={e => setCustomerType(e.target.value)}>
<option value=""></option>
{
Object.keys(CUSTOMER_TYPE).map(key => <option key={key} value={CUSTOMER_TYPE[key]}> {CUSTOMER_TYPE_TEXT[CUSTOMER_TYPE[key]]}</option>)
}
</select>
</div>
<div className="me-4">
<div className="field-label">Gender</div>
<select value={gender} onChange={e => setGender(e.target.value)}>
<option value=""></option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</div>
<div className="me-4">
<div className="field-label">Language Spoken</div>
<input type="text" placeholder="e.g.,Chinese,English" value={language || ''} onChange={e => setLanguage(e.target.value)}/>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Height</div>
<input type="text" className="shorter me-2" value={heightFeet || ''} onChange={e => setHeightFeet(e.target.value)}/> Ft
<input type="text" className="shorter me-2 ms-4" value={heightInch || ''} onChange={e => setHeightInch(e.target.value)}/> In
</div>
<div className="me-4">
<div className="field-label">Weight</div>
<input type="text" className="short me-2" value={weight || ''} onChange={e => setWeight(e.target.value)}/> lb
</div>
</div>
<h6 className="text-primary">Contact Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Primary Phone Number <span className="required">*</span> <span className="field-blurb float-right">Text Message Available</span></div>
<input type="text" placeholder="e.g.,240-463-1698" className="long" 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" className="long" value={homePhone || ''} onChange={e => setHomePhone(e.target.value)}/>
</div>
{/* <div className="me-4">
<div className="field-label">Other Phone Number</div>
<input type="text" value={mobilePhone || ''} onChange={e => setMobilePhone(e.target.value)}/>
</div> */}
<div className="me-4">
<div className="field-label">Personal Email</div>
<input type="email" placeholder="e.g.,example@gmail.com" className="long" value={email || ''} onChange={e => setEmail(e.target.value)}/>
</div>
</div>
{/* We will do Address and Emergency later */}
<h6 className="text-primary">Service Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Text Message Enabled</div>
<select value={textMsgEnabled} onChange={e => setTextMsgEnabled(e.target.value)}>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div className="me-4">
<div className="field-label">Table Id</div>
<input type="text" placeholder="e.g.,T1-A" value={tableId || ''} onChange={e => setTableId(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Seating</div>
<input type="text" placeholder="e.g.,10" value={seating || ''} onChange={e => setSeating(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Pickup Status</div>
<select value={pickupStatus} onChange={e => setPickupStatus(e.target.value)}>
<option value=""></option>
{
Object.keys(PICKUP_STATUS).map(key => <option key={key} value={PICKUP_STATUS[key]}> {PICKUP_STATUS_TEXT[PICKUP_STATUS[key]]}</option>)
}
</select>
</div>
</div>
<h6 className="text-primary">General Health Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Eyes-on</div>
<select value={disability} onChange={e => setDisability(e.target.value)}>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div className="me-4">
<div className="field-label">Special Needs</div>
<input type="text" placeholder="e.g.,Special Needs" value={specialNeeds || ''} onChange={e => setSpecialNeeds(e.target.value)}/>
</div>
</div>
<h6 className="text-primary">Additional Information</h6>
<div className="app-main-content-fields-section base-line">
<div className="me-4">
<div className="field-label">Profile Picture</div>
<label className="custom-file-upload">
<Upload width={20} color={"#fff"} className="me-2"></Upload> Upload Files
<input
type="file"
onChange={(e) => setSelectedFile(e.target.files[0])}
/>
</label>
<div className="file-name">{ selectedFile && selectedFile?.name }</div>
</div>
<div className="me-4">
<div className="field-label">Note</div>
<input type="text" placeholder="Any Extra Details" value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
{/* <div className="me-4">
<div className="field-label">Private Note</div>
<input type="text" placeholder="Any Extra Details" value={privateNote || ''} onChange={e => setPrivateNote(e.target.value)}/>
</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={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
<Tab eventKey="healthCareInfo" title="Health Care Information">
<h6 className="text-primary">Personal Details</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Primary Care Provider</div>
<input placeholder="e.g.,John" type="text" value={careProvider || ''} onChange={e => setCareProvider(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Medicare Number</div>
<input placeholder="e.g.,8XE1-EQ4-WU37" type="text" value={medicareNumber || ''} onChange={e => setMedicareNumber(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Medicaid Number</div>
<input placeholder="e.g.,49103822700" type="text" value={medicaidNumber || ''} onChange={e => setMedicaidNumber(e.target.value)}/>
</div>
<div className="me-4">
{/* <div>Pharmacy:</div> <input type="text" value={pharmacy || ''} onChange={e => setPharmacy(e.target.value)}/> */}
<div className="field-label">Pharmacy</div>
<Select placeholder="e.g.,John" styles={{
control: (baseStyles, state) => ({
...baseStyles,
width: '350px',
height: '45px',
'padding-top': 0,
'padding-bottom': 0,
'margin-top': 0,
'margin-bottom': 0
}),
indicatorSeparator: (baseStyles, state) => ({
...baseStyles,
width: 0
}),
indicatorsContainer: (baseStyles) => ({
...baseStyles,
'margin-top': '-10px'
}),
placeholder: (baseStyles) => ({
...baseStyles,
'margin-top': '-10px',
'font-size': '13px'
}),
singleValue: (baseStyles, state) => ({
...baseStyles,
'margin-top': '-10px',
'font-size': '13px'
})
}} value={pharmacy || ''} onChange={selectedData => onPharmacyChange(selectedData)} options={[{value: '', label: ''}, ...resources.map(resource => ({
value: resource?.id || '',
label: resource?.name || '',
}))]}></Select>
</div>
<div className="me-4">
<div className="field-label">Pharmacy ID</div>
<input placeholder="e.g.,66cc94816bc80d114380629f" type="text" value={pharmacyId || ''} onChange={e => setPharmacyId(e.target.value)}/>
</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={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</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)} />
<button className="btn btn-primary me-2"><Filter size={16} className="me-2"></Filter>Filter</button>
<button className="btn btn-primary me-2"><Columns size={16} className="me-2"></Columns>Manage Table</button>
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Customer</button>
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button> */}
</div>
</div>
</div>
{/* <div className="list row mb-4">
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Emergency Contact:</div> <input type="text" value={emergencyContact || ''} onChange={e => setEmergencyContact(e.target.value)}/> <div>Emergency Contact:</div> <input type="text" value={emergencyContact || ''} onChange={e => setEmergencyContact(e.target.value)}/>
</div> </div>
<div className="col-md-4 mb-4">
<div>Medicare Number:</div> <input type="text" value={medicareNumber || ''} onChange={e => setMedicareNumber(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Medicaid Number:</div> <input type="text" value={medicaidNumber || ''} onChange={e => setMedicaidNumber(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
{/* <div>Pharmacy:</div> <input type="text" value={pharmacy || ''} onChange={e => setPharmacy(e.target.value)}/> */}
<div>Pharmacy</div>
<Select value={pharmacy || ''} onChange={selectedData => onPharmacyChange(selectedData)} options={[{value: '', label: ''}, ...resources.map(resource => ({
value: resource?.id || '',
label: resource?.name || '',
}))]}></Select>
</div>
<div className="col-md-4 mb-4">
<div>Pharmacy ID:</div> <input type="text" value={pharmacyId || ''} onChange={e => setPharmacyId(e.target.value)}/>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Address 1:</div> <input type="text" value={address1 || ''} onChange={e => setAddress1(e.target.value)}/> <div>Address 1:</div> <input type="text" value={address1 || ''} onChange={e => setAddress1(e.target.value)}/>
</div> </div>
@ -246,74 +450,15 @@ const CreateCustomer = () => {
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Apartment:</div> <input type="text" value={apartment || ''} onChange={e => setApartment(e.target.value)}/> <div>Apartment:</div> <input type="text" value={apartment || ''} onChange={e => setApartment(e.target.value)}/>
</div> </div>
<div className="col-md-4 mb-4">
<div>Table Id:</div> <input type="text" value={tableId || ''} onChange={e => setTableId(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Customer Type:</div> <select value={customerType} onChange={e => setCustomerType(e.target.value)}>
<option value=""></option>
{
Object.keys(CUSTOMER_TYPE).map(key => <option key={key} value={CUSTOMER_TYPE[key]}> {CUSTOMER_TYPE_TEXT[CUSTOMER_TYPE[key]]}</option>)
}
</select>
</div>
<div className="col-md-4 mb-4">
<div>Pickup Status:</div> <select value={pickupStatus} onChange={e => setPickupStatus(e.target.value)}>
<option value=""></option>
{
Object.keys(PICKUP_STATUS).map(key => <option key={key} value={PICKUP_STATUS[key]}> {PICKUP_STATUS_TEXT[PICKUP_STATUS[key]]}</option>)
}
</select>
</div>
<div className="col-md-4 mb-4">
<div>Upload Avatar (Image size should be less than 500 KB):</div>
<input
type="file"
onChange={(e) => setSelectedFile(e.target.files[0])}
className="form-control-file border"
/>
</div>
<div className="col-md-4 mb-4">
<div>Birth Date (Type in as: MM/DD/YYYY):</div> <input type="text" value={birthDate || ''} onChange={e => setBirthDate(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Phone :</div> <input type="text" value={phone || ''} onChange={e => setPhone(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Mobile Phone:</div> <input type="text" value={mobilePhone || ''} onChange={e => setMobilePhone(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Home Phone:</div> <input type="text" value={homePhone || ''} onChange={e => setHomePhone(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Special Needs:</div> <input type="text" value={specialNeeds || ''} onChange={e => setSpecialNeeds(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Language(Please use ',' between each language):</div> <input type="text" value={language || ''} onChange={e => setLanguage(e.target.value)}/>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Username (not required):</div> <input type="text" value={username || ''} onChange={e => setUsername(e.target.value)}/> <div>Username (not required):</div> <input type="text" value={username || ''} onChange={e => setUsername(e.target.value)}/>
</div> </div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Password (not required):</div> <input type="text" value={password || ''} onChange={e => setPassword(e.target.value)}/> <div>Password (not required):</div> <input type="text" value={password || ''} onChange={e => setPassword(e.target.value)}/>
</div> </div>
<div className="col-md-4 mb-4">
<div>Note:</div> <input type="text" value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Admission Date(Type in as 'MM/DD/YYYY'):</div> <input type="text" value={admissionDate || ''} onChange={e => setAdmissionDate(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Discharge Date(Type in as 'MM/DD/YYYY'):</div> <input type="text" value={dischargeDate || ''} onChange={e => setDischargeDate(e.target.value)}/>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Pin:</div> <input type="text" value={pin || ''} onChange={e => setPin(e.target.value)}/> <div>Pin:</div> <input type="text" value={pin || ''} onChange={e => setPin(e.target.value)}/>
</div> </div>
<div className="col-md-4 mb-4">
<div>Seating:</div> <input type="text" value={seating || ''} onChange={e => setSeating(e.target.value)}/>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Vehicle No:</div> <input type="text" value={vehicleNo || ''} onChange={e => setVehicleNo(e.target.value)}/> <div>Vehicle No:</div> <input type="text" value={vehicleNo || ''} onChange={e => setVehicleNo(e.target.value)}/>
</div> </div>
@ -332,43 +477,7 @@ const CreateCustomer = () => {
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Roles(Please use ',' between each roles):</div> <input type="text" value={roles || ''} onChange={e => setRoles(e.target.value)}/> <div>Roles(Please use ',' between each roles):</div> <input type="text" value={roles || ''} onChange={e => setRoles(e.target.value)}/>
</div> </div>
<div className="col-md-4 mb-4"> </div> */}
<div>Private Note:</div> <input type="text" value={privateNote || ''} onChange={e => setPrivateNote(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Disability:</div> <select value={disability} onChange={e => setDisability(e.target.value)}>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div className="col-md-4 mb-4">
<div>Height:</div>
<input type="text" value={heightFeet || ''} onChange={e => setHeightFeet(e.target.value)}/> Ft
<input type="text" value={heightInch || ''} onChange={e => setHeightInch(e.target.value)}/> In
</div>
<div className="col-md-4 mb-4">
<div>Weight:</div> <input type="text" value={weight || ''} onChange={e => setWeight(e.target.value)}/> lb
</div>
<div className="col-md-4 mb-4">
<div>Gender:</div> <select value={gender} onChange={e => setGender(e.target.value)}>
<option value=""></option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</div>
<div className="col-md-4 mb-4">
<div>Enable Text Message:</div> <select value={textMsgEnabled} onChange={e => setTextMsgEnabled(e.target.value)}>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
</div>
<div className="list row mb-5">
<div className="col-md-6 col-sm-6 col-xs-12">
<button className="btn btn-primary btn-sm" onClick={() => saveCustomer()}> Save </button>
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button>
</div>
</div>
</> </>
); );
}; };

View File

@ -140,7 +140,7 @@ const CustomersList = () => {
const toggleSelectedAllItems = () => { const toggleSelectedAllItems = () => {
if (selectedItems.length !== filteredCustomers.length || selectedItems.length === 0) { if (selectedItems.length !== filteredCustomers.length || selectedItems.length === 0) {
const newSelectedItems = [...filteredCustomers].filter(ev=> ev.status === 'active').map((customer) => customer.id); const newSelectedItems = [...filteredCustomers].map((customer) => customer.id);
setSelectedItems(newSelectedItems); setSelectedItems(newSelectedItems);
} else { } else {
setSelectedItems([]); setSelectedItems([]);
@ -167,11 +167,7 @@ const CustomersList = () => {
} }
const checkSelectAll = () => { const checkSelectAll = () => {
return selectedItems.length === filteredCustomers.filter(ev=> ev.status === 'active').length && selectedItems.length > 0; return selectedItems.length === filteredCustomers.length && selectedItems.length > 0;
}
const redirectToAdmin = () => {
navigate(`/admin/customer-report`)
} }
const goToEdit = (id) => { const goToEdit = (id) => {
@ -290,6 +286,7 @@ const CustomersList = () => {
<thead> <thead>
<tr> <tr>
<th className="th-checkbox"><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th> <th className="th-checkbox"><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th>
<th className="th-index">No.</th>
{ {
columns.map((column, index) => <th className="sortable-header" key={index}> columns.map((column, index) => <th className="sortable-header" key={index}>
{column.label} <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span> {column.label} <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span>
@ -302,8 +299,9 @@ const CustomersList = () => {
</thead> </thead>
<tbody> <tbody>
{ {
filteredCustomers.map(customer => <tr key={customer.id}> filteredCustomers.map((customer, index) => <tr key={customer.id}>
<td className="td-checkbox"><input type="checkbox" checked={selectedItems.includes(customer.id)} onClick={()=>toggleItem(customer?.id)}/></td> <td className="td-checkbox"><input type="checkbox" checked={selectedItems.includes(customer.id)} onClick={()=>toggleItem(customer?.id)}/></td>
<td className="td-index">{index + 1}</td>
<td> {AuthService.canAddOrEditCustomers() && <PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(customer?.id)}></PencilSquare>} {AuthService.canViewCustomers() && <PersonSquare onClick={() => goToView(customer?.id)} size={16} className="clickable me-2" />} {customer?.name}</td> <td> {AuthService.canAddOrEditCustomers() && <PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(customer?.id)}></PencilSquare>} {AuthService.canViewCustomers() && <PersonSquare onClick={() => goToView(customer?.id)} size={16} className="clickable me-2" />} {customer?.name}</td>
<td>{customer?.name_cn}</td> <td>{customer?.name_cn}</td>
<td>{customer?.email}</td> <td>{customer?.email}</td>

View File

@ -4,8 +4,9 @@ import { useNavigate, useParams } from "react-router-dom";
import { customerSlice } from "./../../store"; import { customerSlice } from "./../../store";
import { AuthService, CustomerService, ResourceService } from "../../services"; import { AuthService, CustomerService, ResourceService } from "../../services";
import Select from 'react-select'; import Select from 'react-select';
import { Modal, Button } from "react-bootstrap"; import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab, Modal, Button } from "react-bootstrap";
import { CUSTOMER_TYPE, PICKUP_STATUS, PICKUP_STATUS_TEXT , CUSTOMER_TYPE_TEXT} from "../../shared"; import { CUSTOMER_TYPE, PICKUP_STATUS, PICKUP_STATUS_TEXT , CUSTOMER_TYPE_TEXT} from "../../shared";
import { Upload } from "react-bootstrap-icons";
const UpdateCustomer = () => { const UpdateCustomer = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -101,7 +102,7 @@ const UpdateCustomer = () => {
setRoles(currentCustomer.roles?.join(',')); setRoles(currentCustomer.roles?.join(','));
setEmail(currentCustomer.email); setEmail(currentCustomer.email);
setMobilePhone(currentCustomer.mobile_phone); setMobilePhone(currentCustomer.mobile_phone);
setPhone(currentCustomer.phone); setPhone(currentCustomer.phone || currentCustomer.mobile_phone);
setHomePhone(currentCustomer.home_phone); setHomePhone(currentCustomer.home_phone);
setLanguage(currentCustomer.language); setLanguage(currentCustomer.language);
setAddress1(currentCustomer.address1); setAddress1(currentCustomer.address1);
@ -109,7 +110,7 @@ const UpdateCustomer = () => {
setAddress3(currentCustomer.address3); setAddress3(currentCustomer.address3);
setAddress4(currentCustomer.address4); setAddress4(currentCustomer.address4);
setAddress5(currentCustomer.address5); setAddress5(currentCustomer.address5);
setNote(currentCustomer.note); setNote(currentCustomer.note || currentCustomer.private_note);
setTableId(currentCustomer.table_id); setTableId(currentCustomer.table_id);
setCustomerType(currentCustomer.type); setCustomerType(currentCustomer.type);
setCareProvider(currentCustomer.care_provider); setCareProvider(currentCustomer.care_provider);
@ -369,6 +370,240 @@ const UpdateCustomer = () => {
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item>General</Breadcrumb.Item>
<Breadcrumb.Item active>
Customer Information
</Breadcrumb.Item>
<Breadcrumb.Item active>
Create New Customer
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary">
<h4>Create New Customer <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="basicInfo" id="customers-tab">
<Tab eventKey="basicInfo" title="Basic Information">
<h6 className="text-primary">Personal Details</h6>
<div className="app-main-content-fields-section">
<div className="me-4"><div className="field-label">First Name <span className="required">*</span></div> <input type="text" placeholder="e.g.,John" value={firstname || ''} onChange={e => setFirstname(e.target.value)}/></div>
{/* <div><div className="field-label">Middle Name</div> <input type="text" value={middlename || ''} onChange={e => setMiddlename(e.target.value)}/></div> */}
<div className="me-4"><div className="field-label">Last Name <span className="required">*</span></div> <input type="text" placeholder="e.g.,Johnson" value={lastname || ''} onChange={e => setLastname(e.target.value)}/></div>
<div className="me-4"><div className="field-label">Preferred Name/Chinese Name</div> <input type="text" placeholder="e.g.,李华" value={nameCN || ''} onChange={e => setNameCN(e.target.value)}/></div>
<div className="me-4"><div className="field-label">Nick Name</div> <input placeholder="e.g.,Johnson" type="text" value={nickname || ''} onChange={e => setNickname(e.target.value)}/></div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Admission Date</div>
<input type="text" placeholder="e.g.,01/15/2025" value={admissionDate || ''} onChange={e => setAdmissionDate(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Discharge Date</div>
<input type="text" placeholder="e.g.,01/15/2025" value={dischargeDate || ''} onChange={e => setDischargeDate(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Birth Date</div>
<input type="text" placeholder="e.g.,01/15/2025" value={birthDate || ''} onChange={e => setBirthDate(e.target.value)}/>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Customer Type</div>
<select value={customerType} onChange={e => setCustomerType(e.target.value)}>
<option value=""></option>
{
Object.keys(CUSTOMER_TYPE).map(key => <option key={key} value={CUSTOMER_TYPE[key]}> {CUSTOMER_TYPE_TEXT[CUSTOMER_TYPE[key]]}</option>)
}
</select>
</div>
<div className="me-4">
<div className="field-label">Gender</div>
<select value={gender} onChange={e => setGender(e.target.value)}>
<option value=""></option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</div>
<div className="me-4">
<div className="field-label">Language Spoken</div>
<input type="text" placeholder="e.g.,Chinese,English" value={language || ''} onChange={e => setLanguage(e.target.value)}/>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Height</div>
<input type="text" className="shorter me-2" value={heightFeet || ''} onChange={e => setHeightFeet(e.target.value)}/> Ft
<input type="text" className="shorter me-2 ms-4" value={heightInch || ''} onChange={e => setHeightInch(e.target.value)}/> In
</div>
<div className="me-4">
<div className="field-label">Weight</div>
<input type="text" className="short me-2" value={weight || ''} onChange={e => setWeight(e.target.value)}/> lb
</div>
</div>
<h6 className="text-primary">Contact Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Primary Phone Number <span className="required">*</span> <span className="field-blurb float-right">Text Message Available</span></div>
<input type="text" placeholder="e.g.,240-463-1698" className="long" 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" className="long" value={homePhone || ''} onChange={e => setHomePhone(e.target.value)}/>
</div>
{/* <div className="me-4">
<div className="field-label">Other Phone Number</div>
<input type="text" value={mobilePhone || ''} onChange={e => setMobilePhone(e.target.value)}/>
</div> */}
<div className="me-4">
<div className="field-label">Personal Email</div>
<input type="email" placeholder="e.g.,example@gmail.com" className="long" value={email || ''} onChange={e => setEmail(e.target.value)}/>
</div>
</div>
{/* We will do Address and Emergency later */}
<h6 className="text-primary">Service Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Text Message Enabled</div>
<select value={textMsgEnabled} onChange={e => setTextMsgEnabled(e.target.value)}>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div className="me-4">
<div className="field-label">Table Id</div>
<input type="text" placeholder="e.g.,T1-A" value={tableId || ''} onChange={e => setTableId(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Seating</div>
<input type="text" placeholder="e.g.,10" value={seating || ''} onChange={e => setSeating(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Pickup Status</div>
<select value={pickupStatus} onChange={e => setPickupStatus(e.target.value)}>
<option value=""></option>
{
Object.keys(PICKUP_STATUS).map(key => <option key={key} value={PICKUP_STATUS[key]}> {PICKUP_STATUS_TEXT[PICKUP_STATUS[key]]}</option>)
}
</select>
</div>
</div>
<h6 className="text-primary">General Health Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Eyes-on</div>
<select value={disability} onChange={e => setDisability(e.target.value)}>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div className="me-4">
<div className="field-label">Special Needs</div>
<input type="text" placeholder="e.g.,Special Needs" value={specialNeeds || ''} onChange={e => setSpecialNeeds(e.target.value)}/>
</div>
</div>
<h6 className="text-primary">Additional Information</h6>
<div className="app-main-content-fields-section base-line">
<div className="me-4">
<div className="field-label">Profile Picture</div>
<label className="custom-file-upload">
<Upload width={20} color={"#fff"} className="me-2"></Upload> Upload Files
<input
type="file"
onChange={(e) => setSelectedFile(e.target.files[0])}
/>
</label>
<div className="file-name">{ selectedFile && selectedFile?.name }</div>
</div>
<div className="me-4">
<div className="field-label">Note</div>
<input type="text" placeholder="Any Extra Details" value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
{/* <div className="me-4">
<div className="field-label">Private Note</div>
<input type="text" placeholder="Any Extra Details" value={privateNote || ''} onChange={e => setPrivateNote(e.target.value)}/>
</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-danger btn-sm me-2 mb-2" onClick={() => triggerShowDeleteModal()}> Delete </button>
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
<Tab eventKey="healthCareInfo" title="Health Care Information">
<h6 className="text-primary">Personal Details</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Primary Care Provider</div>
<input placeholder="e.g.,John" type="text" value={careProvider || ''} onChange={e => setCareProvider(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Medicare Number</div>
<input placeholder="e.g.,8XE1-EQ4-WU37" type="text" value={medicareNumber || ''} onChange={e => setMedicareNumber(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Medicaid Number</div>
<input placeholder="e.g.,49103822700" type="text" value={medicaidNumber || ''} onChange={e => setMedicaidNumber(e.target.value)}/>
</div>
<div className="me-4">
{/* <div>Pharmacy:</div> <input type="text" value={pharmacy || ''} onChange={e => setPharmacy(e.target.value)}/> */}
<div className="field-label">Pharmacy</div>
<Select placeholder="e.g.,John" styles={{
control: (baseStyles, state) => ({
...baseStyles,
width: '350px',
height: '45px',
'padding-top': 0,
'padding-bottom': 0,
'margin-top': 0,
'margin-bottom': 0
}),
indicatorSeparator: (baseStyles, state) => ({
...baseStyles,
width: 0
}),
indicatorsContainer: (baseStyles) => ({
...baseStyles,
'margin-top': '-10px'
}),
placeholder: (baseStyles) => ({
...baseStyles,
'margin-top': '-10px',
'font-size': '13px'
}),
singleValue: (baseStyles, state) => ({
...baseStyles,
'margin-top': '-10px',
'font-size': '13px'
})
}} value={pharmacy || ''} onChange={selectedData => onPharmacyChange(selectedData)} options={[{value: '', label: ''}, ...resources.map(resource => ({
value: resource?.id || '',
label: resource?.name || '',
}))]}></Select>
</div>
<div className="me-4">
<div className="field-label">Pharmacy ID</div>
<input placeholder="e.g.,66cc94816bc80d114380629f" type="text" value={pharmacyId || ''} onChange={e => setPharmacyId(e.target.value)}/>
</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-danger btn-sm me-2 mb-2" onClick={() => triggerShowDeleteModal()}> Delete </button>
<button className="btn btn-primary btn-sm float-right" onClick={() => saveCustomer()}> Save </button>
</div>
</div>
</Tab>
</Tabs>
</div>
</div>
{/* <div className="list row mb-4">
<div className="col-md-12 text-primary"> <div className="col-md-12 text-primary">
<h5>Update Customer <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5> <h5>Update Customer <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
</div> </div>
@ -545,14 +780,14 @@ const UpdateCustomer = () => {
<option value="false">No</option> <option value="false">No</option>
</select> </select>
</div> </div>
</div> </div> */}
<div className="list row mb-5"> {/* <div className="list row mb-5">
<div className="col-md-6 col-sm-6 col-xs-12"> <div className="col-md-6 col-sm-6 col-xs-12">
<button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => saveCustomer()}> Save </button> <button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => saveCustomer()}> Save </button>
<button className="btn btn-danger btn-sm me-2 mb-2" onClick={() => triggerShowDeleteModal()}> Delete </button> <button className="btn btn-danger btn-sm me-2 mb-2" onClick={() => triggerShowDeleteModal()}> Delete </button>
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button> <button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button>
</div> </div>
</div> </div> */}
<Modal show={showDeleteModal} onHide={() => closeDeleteModal()}> <Modal show={showDeleteModal} onHide={() => closeDeleteModal()}>
<Modal.Header closeButton> <Modal.Header closeButton>
<Modal.Title>Delete Customer</Modal.Title> <Modal.Title>Delete Customer</Modal.Title>

View File

@ -1,6 +1,8 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import { PencilSquare } from "react-bootstrap-icons";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { AuthService, CustomerService } from "../../services"; import { AuthService, CustomerService } from "../../services";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
const ViewCustomer = () => { const ViewCustomer = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -13,6 +15,10 @@ const ViewCustomer = () => {
navigate(`/customers/list`) navigate(`/customers/list`)
} }
const goToEdit = (id) => {
navigate(`/customers/edit/${id}`)
}
useEffect(() => { useEffect(() => {
if (!AuthService.canViewCustomers()) { if (!AuthService.canViewCustomers()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.') window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
@ -37,74 +43,185 @@ const ViewCustomer = () => {
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item>General</Breadcrumb.Item>
<Breadcrumb.Item active>
Customer Information
</Breadcrumb.Item>
<Breadcrumb.Item active>
View Customer Details
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary"> <div className="col-md-12 text-primary">
<h5>{currentCustomer?.name} <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5> <h4>View Customer Information <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
</div> </div>
</div> </div>
<div className="list row mb-4"> <div className="app-main-content-list-container">
<div className="app-main-content-list-func-container">
<Tabs defaultActiveKey="basicInfo" id="customers-tab">
<Tab eventKey="basicInfo" title="Basic Information">
<h6 className="text-primary">Personal Details</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Name</div>
<div className="field-value">{currentCustomer?.name}</div>
</div>
<div className="field-body">
<div className="field-label">First Name</div>
<div className="field-value">{currentCustomer?.firstname}</div>
</div>
{/* <div><div className="field-label">Middle Name</div> <input type="text" value={middlename || ''} onChange={e => setMiddlename(e.target.value)}/></div> */}
<div className="field-body">
<div className="field-label">Last Name</div>
<div className="field-value">{currentCustomer?.lastname}</div>
</div>
<div className="field-body">
<div className="field-label">Preferred Name/Chinese Name</div>
<div className="field-value">{currentCustomer?.name_cn}</div>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Admission Date</div>
<div className="field-value">{currentCustomer?.admission_date}</div>
</div>
<div className="field-body">
<div className="field-label">Discharge Date</div>
<div className="field-value">{currentCustomer?.discharge_date}</div>
</div>
<div className="field-body">
<div className="field-label">Birth Date</div>
<div className="field-value">{currentCustomer?.birth_date}</div>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Customer Type</div>
<div className="field-value">{currentCustomer?.type}</div>
</div>
<div className="field-body">
<div className="field-label">Gender</div>
<div className="field-value">{currentCustomer?.gender}</div>
</div>
<div className="field-body">
<div className="field-label">Language Spoken</div>
<div className="field-value">{currentCustomer?.language}</div>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Height</div>
<div className="field-value">{currentCustomer?.height}</div>
</div>
<div className="field-body">
<div className="field-label">Weight</div>
<div className="field-value">{currentCustomer?.weight}</div>
</div>
</div>
<h6 className="text-primary">Contact Information</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Primary Phone Number</div>
<div className="field-value">{currentCustomer?.phone}</div>
</div>
<div className="field-body">
<div className="field-label">Secondary Phone Number</div>
<div className="field-value">{currentCustomer?.home_phone}</div>
</div>
{/* <div className="field-body">
<div className="field-label">Other Phone Number</div>
<input type="text" value={mobilePhone || ''} onChange={e => setMobilePhone(e.target.value)}/>
</div> */}
<div className="field-body">
<div className="field-label">Personal Email</div>
<div className="field-value">{currentCustomer?.email}</div>
</div>
</div>
{/* We will do Address and Emergency later */}
<h6 className="text-primary">Service Information</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Text Message Enabled</div>
<div className="field-value">{currentCustomer?.text_msg_enabled ? 'Yes': 'No'}</div>
</div>
<div className="field-body">
<div className="field-label">Table Id</div>
<div className="field-value">{currentCustomer?.table_id}</div>
</div>
<div className="field-body">
<div className="field-label">Seating</div>
<div className="field-value">{currentCustomer?.seating}</div>
</div>
<div className="field-body">
<div className="field-label">Pickup Status</div>
<div className="field-value">{currentCustomer?.pickup_status}</div>
</div>
</div>
<h6 className="text-primary">General Health Information</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Eyes-on</div>
<div className="field-value">{currentCustomer?.disability ? 'Yes' : 'No'}</div>
</div>
<div className="field-body">
<div className="field-label">Special Needs</div>
<div className="field-value">{currentCustomer?.special_needs}</div>
</div>
</div>
<h6 className="text-primary">Additional Information</h6>
<div className="app-main-content-fields-section base-line">
<div className="field-body">
<div className="field-label">Profile Picture</div>
{currentAvatar && <img height="100px" width="100px" src={`data:image/png;base64, ${currentAvatar}`}/>}
</div>
<div className="field-body">
<div className="field-label">Note</div>
<div className="field-value">{currentCustomer?.note || currentCustomer?.private_note}</div>
</div>
</div>
</Tab>
<Tab eventKey="healthCareInfo" title="Health Care Information">
<h6 className="text-primary">Personal Details</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Primary Care Provider</div>
<div className="field-value">{currentCustomer?.care_provider}</div>
</div>
<div className="field-body">
<div className="field-label">Medicare Number</div>
<div className="field-value">{currentCustomer?.medicare_number}</div>
</div>
<div className="field-body">
<div className="field-label">Medicaid Number</div>
<div className="field-value">{currentCustomer?.medicaid_number}</div>
</div>
<div className="field-body">
<div className="field-label">Pharmacy</div>
<div className="field-value">{currentCustomer?.pharmacy}</div>
</div>
<div className="field-body">
<div className="field-label">Pharmacy ID</div>
<div className="field-value">{currentCustomer?.pharmacy_id}</div>
</div>
</div>
</Tab>
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary" onClick={() => goToEdit(currentCustomer?.id)}><PencilSquare className="me-2" size={16}></PencilSquare>Edit</button>
</div>
</div>
</div>
{/*<div className="list row mb-4">
<div className="col-md-12 mb-4"> <div className="col-md-12 mb-4">
{currentAvatar && <img height="100px" width="100px" src={`data:image/png;base64, ${currentAvatar}`}/>} {currentAvatar && <img height="100px" width="100px" src={`data:image/png;base64, ${currentAvatar}`}/>}
</div> </div>
<div className="col-md-4 mb-4">
<div>Name: {currentCustomer?.name}</div>
</div>
<div className="col-md-4 mb-4">
<div>First Name: {currentCustomer?.firstname}</div>
</div>
<div className="col-md-4 mb-4">
<div>Last Name: {currentCustomer?.lastname}</div>
</div>
<div className="col-md-4 mb-4">
<div>Preferred Name (中文姓名): {currentCustomer?.name_cn}</div>
</div>
<div className="col-md-4 mb-4">
<div>Birth Date: {currentCustomer?.birth_date}</div>
</div>
<div className="col-md-4 mb-4">
<div>Table Id:{currentCustomer?.table_id}</div>
</div>
<div className="col-md-4 mb-4">
<div>Customer Type:{currentCustomer?.type}</div>
</div>
<div className="col-md-4 mb-4">
<div>Pickup Status:{currentCustomer?.pickup_status}</div>
</div>
<div className="col-md-4 mb-4">
<div>Email: {currentCustomer?.email}</div>
</div>
<div className="col-md-4 mb-4">
<div>Care Provider:{currentCustomer?.care_provider}</div>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Emergency Contact:{currentCustomer?.emergency_contact}</div> <div>Emergency Contact:{currentCustomer?.emergency_contact}</div>
</div> </div>
<div className="col-md-4 mb-4">
<div>Medicare Number:{currentCustomer?.medicare_number}</div>
</div>
<div className="col-md-4 mb-4">
<div>Medicaid Number:{currentCustomer?.medicaid_number}</div>
</div>
<div className="col-md-4 mb-4">
<div>Pharmacy:{currentCustomer?.pharmacy}</div>
</div>
<div className="col-md-4 mb-4">
<div>Pharmacy ID:{currentCustomer?.pharmacy_id}</div>
</div>
<div className="col-md-4 mb-4">
<div>Phone: {currentCustomer?.phone}</div>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Mobile Phone: {currentCustomer?.mobile_phone}</div> <div>Mobile Phone: {currentCustomer?.mobile_phone}</div>
</div> </div>
<div className="col-md-4 mb-4">
<div>Home Phone: {currentCustomer?.home_phone}</div>
</div>
<div className="col-md-4 mb-4">
<div>Special Needs:{currentCustomer?.special_needs}</div>
</div>
<div className="col-md-4 mb-4">
<div>Language: {currentCustomer?.language}</div>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Username: {currentCustomer?.username}</div> <div>Username: {currentCustomer?.username}</div>
</div> </div>
@ -126,21 +243,9 @@ const ViewCustomer = () => {
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Apartment: {currentCustomer?.apartment}</div> <div>Apartment: {currentCustomer?.apartment}</div>
</div> </div>
<div className="col-md-4 mb-4">
<div>Note: {currentCustomer?.note}</div>
</div>
<div className="col-md-4 mb-4">
<div>Admission Date: {currentCustomer?.admission_date}</div>
</div>
<div className="col-md-4 mb-4">
<div>Discharge Date: {currentCustomer?.discharge_date}</div>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Pin:{currentCustomer?.pin}</div> <div>Pin:{currentCustomer?.pin}</div>
</div> </div>
<div className="col-md-4 mb-4">
<div>Seating:{currentCustomer?.seating}</div>
</div>
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Vehicle No: {currentCustomer?.vehicle_no}</div> <div>Vehicle No: {currentCustomer?.vehicle_no}</div>
</div> </div>
@ -159,25 +264,7 @@ const ViewCustomer = () => {
<div className="col-md-4 mb-4"> <div className="col-md-4 mb-4">
<div>Roles:{currentCustomer?.roles?.join(', ')}</div> <div>Roles:{currentCustomer?.roles?.join(', ')}</div>
</div> </div>
<div className="col-md-4 mb-4"> </div> */}
<div>Private Note:{currentCustomer?.private_note}</div>
</div>
<div className="col-md-4 mb-4">
<div>Disability:{currentCustomer?.disability ? 'Yes' : 'No'}</div>
</div>
<div className="col-md-4 mb-4">
<div>Gender:{currentCustomer?.gender}</div>
</div>
<div className="col-md-4 mb-4">
<div>Height:{currentCustomer?.height}</div>
</div>
<div className="col-md-4 mb-4">
<div>Weight:{currentCustomer?.weight} lb</div>
</div>
<div className="col-md-4 mb-4">
<div>Text Message Enabled:{currentCustomer?.text_msg_enabled ? 'Yes': 'No'} </div>
</div>
</div>
</> </>
); );
}; };

View File

@ -253,7 +253,7 @@ const columns = [
</div> </div>
<div className="col-md-12"> <div className="col-md-12">
<table className="personnel-info-table medical"> <table className="personnel-info-table">
<thead> <thead>
<tr> <tr>
{ {

View File

@ -161,7 +161,6 @@ const EventsCalendar = () => {
<div className="col-md-12 col-sm-12 mb-4"> <div className="col-md-12 col-sm-12 mb-4">
<Scheduler <Scheduler
view="month" view="month"
height={5000}
events={showDeletedItems ? events : events.filter(event => event.status === 'active')} events={showDeletedItems ? events : events.filter(event => event.status === 'active')}
month = {{ month = {{
weekDays: [0, 1, 2, 3, 4, 5, 6], weekDays: [0, 1, 2, 3, 4, 5, 6],
@ -174,7 +173,7 @@ const EventsCalendar = () => {
day = {{ day = {{
startHour: 0, startHour: 0,
endHour: 24, endHour: 24,
step: 60, step:1440,
navigation: true navigation: true
}} }}
onSelectedDateChange = {(date) => {setFromDate(new Date(new Date(date).getFullYear(), new Date(date).getMonth(), 1)); setToDate(new Date(new Date(date).getFullYear(), new Date(date).getMonth() + 1, 0))}} onSelectedDateChange = {(date) => {setFromDate(new Date(new Date(date).getFullYear(), new Date(date).getMonth(), 1)); setToDate(new Date(new Date(date).getFullYear(), new Date(date).getMonth() + 1, 0))}}

View File

@ -370,7 +370,7 @@ const EventsList = () => {
Show Deleted Events: <input type="checkbox" value={showDeletedItems} checked={showDeletedItems === true} onClick={() => setShowDeletedItems(!showDeletedItems)} /> Show Deleted Events: <input type="checkbox" value={showDeletedItems} checked={showDeletedItems === true} onClick={() => setShowDeletedItems(!showDeletedItems)} />
</div> </div>
<div className="col-md-12"> <div className="col-md-12">
<table className="personnel-info-table medical"> <table className="personnel-info-table">
<thead> <thead>
<tr> <tr>
<th><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th> <th><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th>

View File

@ -501,7 +501,7 @@ const EventsMultipleList = () => {
</div> </div>
<div className="col-md-12"> <div className="col-md-12">
<table className="personnel-info-table medical"> <table className="personnel-info-table">
<thead> <thead>
<tr> <tr>
<th><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th> <th><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th>

View File

@ -4,157 +4,173 @@ import { ArrowBarLeft, ArrowBarRight, Grid1x2, Display, Person, BusFront, BagPlu
import { AuthService } from '../../services'; import { AuthService } from '../../services';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
const sideNavs = [
{
icon: <Grid1x2 color="#777" size={14}/>,
name: 'Dashboard',
link: '#',
roleFunc: undefined
},
{
icon: <Display color="#777" size={14}/>,
name: 'Info Screen',
link: '#',
roleFunc: undefined
},
{
icon: <Person color="#777" size={14}/>,
name: 'General',
collapsed: false,
subNavs: [
{
name: 'Customer Information',
//collapsed: true,
link: '/customers/list',
category: '/customers'
// subNavs: [
// {
// name: 'Customer List',
// link: '/customers/list'
// },
// {
// name: 'Create New Customer',
// link: '/customers'
// }
// ]
},
{
name: 'Calendar',
link: '#'
},
{
name: 'Messaging',
//collapsed: true,
link: '/messages/list',
category: '/messages'
// subNavs: [
// {
// name: 'Messages List',
// link: '/messages/list'
// },
// {
// name: 'Create New Message',
// link: '/messages'
// },
// {
// name: 'Send Message',
// link: '/messages/send-message'
// },
// {
// name: 'Sent Messages List',
// link: '/messages/sent-messages/list'
// }
// ]
},
// {
// name: 'Center Phones',
// //collapsed: true,
// link: '/center-phones/list'
// // subNavs: [
// // {
// // name: 'Center Phones List',
// // link: '/center-phones/list'
// // },
// // {
// // name: 'Create New Center Phone',
// // link: '/center-phones'
// // }
// // ]
// }
]
},
{
name: 'Transportation',
icon: <BusFront color="#777" size={14}/>,
collapsed: false,
subNavs: [
{
name: 'Vehicle Information',
link: '/vehicles/list',
category: '/vehicles'
// subNavs: [
// {
// name: 'Vehicles List',
// link: '/vehicles/list'
// },
// {
// name: 'Create New Vehicle',
// link: '/vehicles'
// }
// ]
},
{
name: 'Transportation Schedule',
link: '/trans-routes/schedule',
category: '/trans-routes'
},
{
name: 'Schedule Driver for Appointment',
link: '#'
}
]
},
{
name: 'Medical',
icon: <BagPlus color="#777" size={14}/>,
collapsed: false,
subNavs: [
{
name: 'Provider Information',
link: '/medical/resources/list',
category: '/resources'
},
{
name: 'Appointment Requests',
link: '/medical/event-request/list',
category: '/event-request'
},
{
name: 'Appointment Calendar',
link: '/medical/events/calendar',
category: '/events'
}
]
},
{
name: 'Lobby',
icon: <Tools color="#777" size={14}/>,
collapsed: false,
subNavs: [
{
name: 'Meal Status',
link: '#'
},
{
name: 'Seating Chart',
link: '#'
}
]
}
]
const SideMenu = () => { const SideMenu = () => {
const sideNavs = [
{
icon: <Grid1x2 color="#777" size={14}/>,
name: 'Dashboard',
link: '#',
roleFunc: () => true
},
{
icon: <Display color="#777" size={14}/>,
name: 'Info Screen',
link: '#',
roleFunc: () => true
},
{
icon: <Person color="#777" size={14}/>,
name: 'General',
collapsed: false,
roleFunc: () => true,
subNavs: [
{
name: 'Customer Information',
//collapsed: true,
link: '/customers/list',
category: '/customers',
roleFunc: AuthService.canViewCustomers
// subNavs: [
// {
// name: 'Customer List',
// link: '/customers/list'
// },
// {
// name: 'Create New Customer',
// link: '/customers'
// }
// ]
},
{
name: 'Calendar',
link: '#',
roleFunc: () => true
},
{
name: 'Messaging',
//collapsed: true,
link: '/messages/list',
category: '/messages',
roleFunc: () => true
// subNavs: [
// {
// name: 'Messages List',
// link: '/messages/list'
// },
// {
// name: 'Create New Message',
// link: '/messages'
// },
// {
// name: 'Send Message',
// link: '/messages/send-message'
// },
// {
// name: 'Sent Messages List',
// link: '/messages/sent-messages/list'
// }
// ]
},
// {
// name: 'Center Phones',
// //collapsed: true,
// link: '/center-phones/list'
// // subNavs: [
// // {
// // name: 'Center Phones List',
// // link: '/center-phones/list'
// // },
// // {
// // name: 'Create New Center Phone',
// // link: '/center-phones'
// // }
// // ]
// }
]
},
{
name: 'Transportation',
icon: <BusFront color="#777" size={14}/>,
collapsed: false,
roleFunc: AuthService.canAddOrEditVechiles,
subNavs: [
{
name: 'Vehicle Information',
link: '/vehicles/list',
category: '/vehicles',
roleFunc: AuthService.canAddOrEditVechiles
// subNavs: [
// {
// name: 'Vehicles List',
// link: '/vehicles/list'
// },
// {
// name: 'Create New Vehicle',
// link: '/vehicles'
// }
// ]
},
{
name: 'Transportation Schedule',
link: '/trans-routes/schedule',
category: '/trans-routes',
roleFunc: AuthService.canAddOrEditRoutes
},
{
name: 'Schedule Driver for Appointment',
link: '#',
roleFunc: AuthService.canAddOrEditRoutes
}
]
},
{
name: 'Medical',
icon: <BagPlus color="#777" size={14}/>,
collapsed: false,
roleFunc: AuthService.canAccessLegacySystem,
subNavs: [
{
name: 'Provider Information',
link: '/medical/resources/list',
category: '/resources',
roleFunc: AuthService.canAccessLegacySystem
},
{
name: 'Appointment Requests',
link: '/medical/event-request/list',
category: '/event-request',
roleFunc: AuthService.canAccessLegacySystem
},
{
name: 'Appointment Calendar',
link: '/medical/events/calendar',
category: '/events',
roleFunc: AuthService.canAccessLegacySystem
}
]
},
{
name: 'Lobby',
icon: <Tools color="#777" size={14}/>,
collapsed: false,
roleFunc: () => true,
subNavs: [
{
name: 'Meal Status',
link: '#',
roleFunc: () => true
},
{
name: 'Seating Chart',
link: '#',
roleFunc: () => true
}
]
}
];
const [collapse, setCollapse] = useState(false); const [collapse, setCollapse] = useState(false);
const [navs, setNavs] = useState(sideNavs) const [navs, setNavs] = useState(sideNavs)
const location = useLocation(); const location = useLocation();
@ -186,7 +202,7 @@ const SideMenu = () => {
</div> </div>
<div className="app-side-bar-menu-container"> <div className="app-side-bar-menu-container">
{ {
sideNavs.map((sideNav) => { sideNavs.filter(item => item.roleFunc()).map((sideNav) => {
return <div className={`app-side-bar-list-item-container${collapse ? ' collapsed' : ''}`}> return <div className={`app-side-bar-list-item-container${collapse ? ' collapsed' : ''}`}>
<div onClick={() => sideNav.link && goToLink(sideNav.link)} className={`app-side-bar-list-item main-nav-item${sideNav.category && location?.pathname?.includes(sideNav.category) ? ' app-side-bar-list-item-active' : '' }`}> <div onClick={() => sideNav.link && goToLink(sideNav.link)} className={`app-side-bar-list-item main-nav-item${sideNav.category && location?.pathname?.includes(sideNav.category) ? ' app-side-bar-list-item-active' : '' }`}>
{ sideNav?.icon ? <>{sideNav.icon}</> : <></>} { sideNav?.icon ? <>{sideNav.icon}</> : <></>}
@ -194,7 +210,7 @@ const SideMenu = () => {
{ !collapse && sideNav?.subNavs?.length > 0 && <span onClick={() => toggleMenu(sideNav)} className="float-icon">{sideNav?.collapsed ? <ChevronDown color="#777" size={12}/> : <ChevronUp color="#777" size={12}/>}</span> } { !collapse && sideNav?.subNavs?.length > 0 && <span onClick={() => toggleMenu(sideNav)} className="float-icon">{sideNav?.collapsed ? <ChevronDown color="#777" size={12}/> : <ChevronUp color="#777" size={12}/>}</span> }
</div> </div>
{ {
!collapse && !sideNav?.collapsed && sideNav?.subNavs?.map((subNav) => <div onClick={() => subNav.link && goToLink(subNav.link)} className={`app-side-bar-list-item sub-nav-item${subNav?.category && location?.pathname?.includes(subNav?.category) ? ' app-side-bar-list-item-active' : '' }`}> !collapse && !sideNav?.collapsed && sideNav?.subNavs?.filter(item=> item.roleFunc()).map((subNav) => <div onClick={() => subNav.link && goToLink(subNav.link)} className={`app-side-bar-list-item sub-nav-item${subNav?.category && location?.pathname?.includes(subNav?.category) ? ' app-side-bar-list-item-active' : '' }`}>
{ subNav?.icon ? <>{subNav.icon}</> : <></>} { subNav?.icon ? <>{subNav.icon}</> : <></>}
{ !collapse && <span className={`app-side-bar-list-item-name${subNav?.icon? ' with-icon' : ''}`}>{subNav.name}</span> } { !collapse && <span className={`app-side-bar-list-item-name${subNav?.icon? ' with-icon' : ''}`}>{subNav.name}</span> }
{ subNav?.subNavs?.length > 0 && <span onClick={() => toggleMenu(subNav)} className="float-icon">{sideNav?.collapsed ? <ChevronDown color="#777" size={12}/> : <ChevronUp color="#777" size={12}/>}</span> } { subNav?.subNavs?.length > 0 && <span onClick={() => toggleMenu(subNav)} className="float-icon">{sideNav?.collapsed ? <ChevronDown color="#777" size={12}/> : <ChevronUp color="#777" size={12}/>}</span> }

View File

@ -79,7 +79,7 @@ const Medical = () => {
}, []) }, [])
return ( return (
<> <>
<div className="list row"> {/* <div className="list row">
<div className="col-md-12 noprint"> <div className="col-md-12 noprint">
<div className="float-end"><button className="btn btn-link btn-sm" onClick={() => AuthService.logout()}>Log Out</button></div> <div className="float-end"><button className="btn btn-link btn-sm" onClick={() => AuthService.logout()}>Log Out</button></div>
<h4>Medical Center </h4> <h4>Medical Center </h4>
@ -87,7 +87,6 @@ const Medical = () => {
<div className="col-md-12 noprint"> <div className="col-md-12 noprint">
<Navbar bg="light" expand="lg" className="admin-nav mb-4"> <Navbar bg="light" expand="lg" className="admin-nav mb-4">
<Container> <Container>
{/* <Navbar.Brand>Customers Admin</Navbar.Brand> */}
<Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav"> <Navbar.Collapse id="basic-navbar-nav">
{(AuthService.canViewRoutes() || AuthService.canAddOrEditRoutes() || AuthService.canAccessLegacySystem()) && <Nav className="me-auto"> {(AuthService.canViewRoutes() || AuthService.canAddOrEditRoutes() || AuthService.canAccessLegacySystem()) && <Nav className="me-auto">
@ -141,11 +140,11 @@ const Medical = () => {
</Container> </Container>
</Navbar> </Navbar>
</div> </div>
</div> </div> */}
<div className="list row"> <div className="list row">
<div className="col-md-12"> <div className="col-md-12">
<Outlet /> <Outlet />
</div> </div>
</div> </div>
</> </>

View File

@ -1,6 +1,8 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { AuthService, ResourceService } from "../../services"; import { AuthService, ResourceService } from "../../services";
import { Archive } from "react-bootstrap-icons";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
const CreateResource = () => { const CreateResource = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -23,6 +25,7 @@ const CreateResource = () => {
const [note, setNote] = useState(''); const [note, setNote] = useState('');
const [fax, setFax] = useState(''); const [fax, setFax] = useState('');
const [status, setStatus] = useState('active'); const [status, setStatus] = useState('active');
const [email, setEmail] = useState('');
const redirectTo = (id) => { const redirectTo = (id) => {
@ -45,6 +48,7 @@ const CreateResource = () => {
name_branch: branchName, name_branch: branchName,
specialty, specialty,
type, type,
email,
category, category,
color, color,
address, address,
@ -79,94 +83,155 @@ const CreateResource = () => {
return ( return (
<> <>
<div className="list row">
<div className="col-md-12 text-primary">
<h5>Create New Resource <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
</div>
</div>
<div className="list row mb-4"> <div className="list row mb-4">
<div className="col-md-4 mb-4"> <Breadcrumb>
<div>Doctor Name:</div> <input type="text" value={name || ''} onChange={e => setName(e.target.value)}/> <Breadcrumb.Item>Medical</Breadcrumb.Item>
</div> <Breadcrumb.Item active>
<div className="col-md-4 mb-4"> Provider Information
<div>Office Name:</div> <input type="text" value={originalName || ''} onChange={e => setOriginalName(e.target.value)}/> </Breadcrumb.Item>
</div> <Breadcrumb.Item active>
<div className="col-md-4 mb-4"> Create New Provider
<div>Branch Name:</div> <input type="text" value={branchName || ''} onChange={e => setBranchName(e.target.value)}/> </Breadcrumb.Item>
</div> </Breadcrumb>
<div className="col-md-4 mb-4"> <div className="col-md-12 text-primary">
{/* <div>Specialty:</div> <input type="text" value={specialty || ''} onChange={e => setSpecialty(e.target.value)}/> */} <h4>Create New Provider <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
<div>Specialty:</div>
<select value={specialty} onChange={e => setSpecialty(e.target.value)}>
<option value=""></option>
{
ResourceService.resourceOptionList.map((item) => <option value={item}>{item}</option>)
}
</select>
</div>
<div className="col-md-4 mb-4">
<div>Type:</div>
<select value={type} onChange={e => setType(e.target.value)}>
<option value="doctor">Doctor</option>
<option value="pharmacy">Pharmacy</option>
<option value="hospital">Hospital</option>
<option value="surgical center">Surgical Center</option>
<option value="government agency">Government Agency</option>
<option value="other">Other</option>
</select>
</div>
{/* <div className="col-md-4 mb-4">
<div>Category:</div> <input type="text" value={category || ''} onChange={e => setCategory(e.target.value)}/>
</div> */}
<div className="col-md-4 mb-4">
<div>Description:</div> <input type="text" value={description || ''} onChange={e => setDescription(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Color:</div> <input type="text" value={color || ''} onChange={e => setColor(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Address:</div> <textarea value={address || ''} onChange={e => setAddress(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>City:</div> <input type="text" value={city || ''} onChange={e => setCity(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>State:</div> <input type="text" value={state || ''} onChange={e => setState(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Zipcode:</div> <input type="text" value={zipcode || ''} onChange={e => setZipcode(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Contact:</div> <textarea value={contact || ''} onChange={e => setContact(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Phone:</div> <input type="text" value={phone || ''} onChange={e => setPhone(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Fax:</div> <input type="text" value={fax || ''} onChange={e => setFax(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Note:</div> <textarea value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
{/* <div className="col-md-4 mb-4">
<div>Data (object/json):</div> <textarea value={dataObject || ''} onChange={e => setDataObject(e.target.value)}/>
</div> */}
<div className="col-md-4 mb-4">
<div>Status:</div>
<select value={status} onChange={e => setStatus(e.target.value)}>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div> </div>
</div> </div>
<div className="list row mb-5"> <div className="app-main-content-list-container">
<div className="col-md-6 col-sm-6 col-xs-12"> <div className="app-main-content-list-func-container">
<button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => saveResource()}> Save </button> <Tabs defaultActiveKey="providerInfo" id="providerss-tab">
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button> <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">Doctor Name
<span className="required">*</span>
</div>
<input placeholder="e.g.,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={originalName || ''} onChange={e => setOriginalName(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Branch Name
</div>
<input type="text" placeholder="e.g.,Silver Spring" value={branchName || ''} onChange={e => setBranchName(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=""></option>
{
ResourceService.resourceOptionList.map((item) => <option value={item}>{item}</option>)
}
</select>
</div>
<div className="me-4">
<div className="field-label">Type
</div>
<select value={type} onChange={e => setType(e.target.value)}>
<option value="doctor">Doctor</option>
<option value="pharmacy">Pharmacy</option>
<option value="hospital">Hospital</option>
<option value="surgical center">Surgical Center</option>
<option value="government agency">Government Agency</option>
<option value="other">Other</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">Contact
</div>
{/* <textarea value={contact || ''} onChange={e => setContact(e.target.value)}/> */}
<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" placement="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" placement="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" placement="e.g.,555 Cloverly Forest Dr" value={address || ''} onChange={e => setAddress(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">City
<span className="required">*</span>
</div>
<input type="text" placement="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 placement="e.g.,MD" type="text" 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" 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 value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Description
</div>
<input type="text" placeholder={'e.g.,Description'} value={description || ''} onChange={e => setDescription(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Color
</div>
<input type="text" placeholder={'e.g.,red'} value={color || ''} onChange={e => setColor(e.target.value)}/>
</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> </div>
</div> </div>
{/* <div className="col-md-4 mb-4">
<div>Status:</div>
<select value={status} onChange={e => setStatus(e.target.value)}>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div> */}
</> </>
); );
}; };

View File

@ -1,7 +1,8 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { AuthService, ResourceService } from "../../services"; import { AuthService, ResourceService } from "../../services";
import { Button } from "react-bootstrap"; import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
import { Columns, Download, Filter, PencilSquare, PersonSquare, Plus } from "react-bootstrap-icons";
import ReactPaginate from 'react-paginate'; import ReactPaginate from 'react-paginate';
const ResourcesList = () => { const ResourcesList = () => {
@ -10,13 +11,14 @@ const ResourcesList = () => {
const [keyword, setKeyword] = useState(''); const [keyword, setKeyword] = useState('');
const [currentItems, setCurrentItems] = useState(null); const [currentItems, setCurrentItems] = useState(null);
const [sorting, setSorting] = useState({key: '', order: ''}); const [sorting, setSorting] = useState({key: '', order: ''});
const [selectedItems, setSelectedItems] = useState([]);
// Here we use item offsets; we could also use page offsets // Here we use item offsets; we could also use page offsets
// following the API or data you're working with. // following the API or data you're working with.
const [itemOffset, setItemOffset] = useState(0); const [itemOffset, setItemOffset] = useState(0);
const [pageCount, setPageCount] = useState(0); const [pageCount, setPageCount] = useState(0);
const [itemsPerPage, setItemsPerPage] = useState(10); const [itemsPerPage, setItemsPerPage] = useState(10);
const [showDeletedItems, setShowDeletedItems] = useState(false); const [showDeletedItems, setShowDeletedItems] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
useEffect(() => { useEffect(() => {
if (!AuthService.canAccessLegacySystem()) { if (!AuthService.canAccessLegacySystem()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.') window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
@ -30,13 +32,13 @@ const ResourcesList = () => {
useEffect(() => { useEffect(() => {
const endOffset = itemOffset + parseInt(itemsPerPage); const endOffset = itemOffset + parseInt(itemsPerPage);
const newResources = showDeletedItems ? resources : resources.filter(item => item.status === 'active')?.filter(resource => (resource?.name?.toLowerCase().includes(keyword.toLowerCase()) || (resource?.specialty?.toLowerCase().includes(keyword.toLowerCase()) ) || (resource?.address?.toLowerCase().includes(keyword.toLowerCase()) ))); const newResources = (showDeletedItems ? resources.filter(item => item.status !== 'active') : resources.filter(item => item.status === 'active'))?.filter(resource => (resource?.name?.toLowerCase().includes(keyword.toLowerCase()) || (resource?.specialty?.toLowerCase().includes(keyword.toLowerCase()) ) || (resource?.address?.toLowerCase().includes(keyword.toLowerCase()) )));
//const newResources = (.slice(itemOffset, endOffset); //const newResources = (.slice(itemOffset, endOffset);
const sortedResources = sorting.key === '' ? newResources : newResources.sort((a, b) => { const sortedResources = sorting.key === '' ? newResources : newResources.sort((a, b) => {
return a[sorting.key]?.localeCompare(b[sorting.key]); return a[sorting.key]?.localeCompare(b[sorting.key]);
}); });
const results = sorting.order === 'asc' ? sortedResources : sortedResources.reverse(); const results = sorting.order === 'asc' ? sortedResources : sortedResources.reverse();
setCurrentItems(results.slice(itemOffset, endOffset)); setCurrentItems(results.slice(itemOffset, endOffset)?.map(item => Object.assign({}, item, { display_name: `${item?.name || ''}${item?.name ? '-': ''}${item?.name_original || ''}${item?.name_original ? '-': ''}${item?.name_branch || ''}`}, {display_contact: item?.contact || item?.phone})));
setPageCount(Math.ceil(((showDeletedItems ? resources : resources.filter(item => item.status === 'active') )?.filter(resource => (resource?.name?.toLowerCase().includes(keyword.toLowerCase()) || (resource?.specialty?.toLowerCase().includes(keyword.toLowerCase()) ) || (resource?.address?.toLowerCase().includes(keyword.toLowerCase()) )))).length / itemsPerPage)); setPageCount(Math.ceil(((showDeletedItems ? resources : resources.filter(item => item.status === 'active') )?.filter(resource => (resource?.name?.toLowerCase().includes(keyword.toLowerCase()) || (resource?.specialty?.toLowerCase().includes(keyword.toLowerCase()) ) || (resource?.address?.toLowerCase().includes(keyword.toLowerCase()) )))).length / itemsPerPage));
}, [resources, itemOffset, keyword, itemsPerPage, showDeletedItems, sorting]); }, [resources, itemOffset, keyword, itemsPerPage, showDeletedItems, sorting]);
@ -55,6 +57,15 @@ const ResourcesList = () => {
`User requested page number ${event.selected}, which is offset ${newOffset}` `User requested page number ${event.selected}, which is offset ${newOffset}`
); );
setItemOffset(newOffset); setItemOffset(newOffset);
setCurrentPage(event.selected + 1);
};
const handlePageSelect = (pageNo) => {
const newOffset = ((pageNo-1) * itemsPerPage) % (showDeletedItems ? resources : resources.filter(item => item.status === 'active') )?.filter(resource => (resource?.name?.toLowerCase().includes(keyword.toLowerCase()) || (resource?.specialty?.toLowerCase().includes(keyword.toLowerCase()) ) || (resource?.address?.toLowerCase().includes(keyword.toLowerCase()) ))).length;
console.log(
`User requested page number ${pageNo}, which is offset ${newOffset}`
);
setItemOffset(newOffset);
}; };
const getSortingImg = (key) => { const getSortingImg = (key) => {
@ -89,6 +100,38 @@ const ResourcesList = () => {
navigate(`/medical/resources/${id}`) navigate(`/medical/resources/${id}`)
} }
const toggleSelectedAllItems = () => {
if (selectedItems.length !== currentItems?.length || selectedItems?.length === 0) {
const newSelectedItems = [...currentItems].map((provider) => provider.id);
setSelectedItems(newSelectedItems);
} else {
setSelectedItems([]);
}
}
const toggleItem = (id) => {
if (selectedItems.includes(id)) {
const newSelectedItems = [...selectedItems].filter((item) => item !== id);
setSelectedItems(newSelectedItems);
} else {
const newSelectedItems = [...selectedItems, id];
setSelectedItems(newSelectedItems);
}
}
const showArchive = (value) => {
console.log('here', value);
setShowDeletedItems(value === 'archivedProviders');
// Recover all filters
setKeyword('');
setSorting({key: '', order: ''});
setSelectedItems([]);
}
const checkSelectAll = () => {
return selectedItems?.length === currentItems?.length && selectedItems?.length > 0;
}
const deleteResource = (id) => { const deleteResource = (id) => {
const currentResource = resources.find((item) => item.id === id); const currentResource = resources.find((item) => item.id === id);
ResourceService.disableResource(id, { status: 'inactive', edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, ResourceService.disableResource(id, { status: 'inactive', edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
@ -100,86 +143,136 @@ const ResourcesList = () => {
}); });
} }
return ( const columns = [
<> {
<div className="list row mb-4"> key: 'display_name',
<div className="col-md-12 text-primary"> label: 'Name'
<h5>Resources List <button className="btn btn-primary btn-sm" onClick={() => {goToCreateNew()}}>Create New Resource</button> <button className="btn btn-link btn-sm" onClick={() => {redirectToAdmin()}}>Back</button></h5> },
{
key: 'type',
label: 'Type'
},
{
key: 'specialty',
label: 'Specialty'
},
{
key: 'email',
label: 'Email'
},
{
key: 'address',
label: 'Address'
},
{
key: 'display_contact',
label: 'Contact'
}
]
const table = <div className="list row mb-4">
<div className="col-md-12">
<table className="personnel-info-table">
<thead>
<tr>
<th className="th-checkbox"><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th>
<th className="th-index">No.</th>
{
columns.map((column, index) => <th className="sortable-header" key={index}>
{column.label} <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span>
</th>)
}
</tr>
</thead>
<tbody>
{
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">{index + 1}</td>
<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?.display_name}</button> : resource?.display_name } </td>
<td>{resource?.type}</td>
<td>{resource?.specialty}</td>
<td>{resource?.email}</td>
<td>{resource?.address}</td>
<td>{resource?.display_contact}</td>
</tr>)
}
</tbody>
</table>
<div className="pagination-container">
<ReactPaginate
key={itemsPerPage}
className="customers-pagination"
breakLabel="..."
nextLabel="Next"
onPageChange={handlePageClick}
pageRangeDisplayed={5}
pageCount={pageCount}
previousLabel="Prev"
renderOnZeroPageCount={null}
containerClassName="pagination justify-content-center"
pageClassName="page-item"
pageLinkClassName="page-link"
previousClassName="page-prev-item"
previousLinkClassName="page-link"
nextClassName="page-next-item"
nextLinkClassName="page-link"
activeClassName="active"
breakClassName="page-item"
breakLinkClassName="page-link"
/>
<div className="select-page-container">
<input type="number" className="page-picker" max={pageCount} min={1} value={currentPage} onChange={(e) => {handlePageSelect(e.target.value); setCurrentPage(e.target.value)}}/>
<div className="per-page-label"> {` of ${pageCount}`}</div>
</div> </div>
</div>
<div className="list row mb-4"> <div className="select-page-container">
<div className="col-md-12 col-sm-12 mb-4"> <select className="per-page" value={itemsPerPage} onChange={e => setItemsPerPage(e.target.value)}>
Search By Keywords: <input type="text" value={keyword} onChange={e => setKeyword(e.target.value)} />
</div>
<div className="col-md-12 col-sm-12 mb-4">
Show Deleted Events: <input type="checkbox" value={showDeletedItems} checked={showDeletedItems === true} onClick={() => setShowDeletedItems(!showDeletedItems)} />
</div>
<div className="col-md-12 col-sm-12 mb-4">
Items Per Page: <select value={itemsPerPage} onChange={e => setItemsPerPage(e.target.value)}>
<option value="10">10</option> <option value="10">10</option>
<option value="25">25</option> <option value="25">25</option>
<option value="50">50</option> <option value="50">50</option>
<option value="100">100</option> <option value="100">100</option>
</select> </select> <span className="per-page-label"> /page</span>
</div> </div>
<div className="col-md-12"> </div>
<table className="personnel-info-table mb-4 medical">
<thead>
<tr className="sortable-header">
<th>Name <span onClick={() => sortTableWithField('name')}><img src={`/images/${getSortingImg('name')}.png`}></img></span></th>
<th>Specialty <span onClick={() => sortTableWithField('specialty')}><img src={`/images/${getSortingImg('specialty')}.png`}></img></span></th>
<th>Address</th>
<th>Contact</th>
{/* <th>Office Name</th>
<th>Branch Name</th>
<th>City</th>
<th>State</th>
<th>Zipcode</th> */}
<th></th>
</tr>
</thead> </div>
<tbody> </div>;
{
currentItems?.map(resource => <tr key={resource.id}>
<td>{`${resource?.name || ''}${resource?.name ? '-': ''}${resource?.name_original || ''}${resource?.name_original ? '-': ''}${resource?.name_branch || ''}`}</td>
<td>{resource?.specialty}</td>
<td>{resource?.address}</td>
<td>{resource?.contact || resource?.phone}</td>
{/* <td>{resource?.name_original}</td>
<td>{resource?.name_branch}</td>
<td>{resource?.city}</td>
<td>{resource?.state}</td>
<td>{resource?.zipcode}</td> */}
<td style={{'min-width': '220px'}}><Button variant="primary" className="me-2" size="sm" onClick={() => goToEdit(resource?.id)}>Edit</Button> <Button variant="secondary" size="sm" onClick={() => goToView(resource?.id)} className="me-2">View</Button> <Button size="sm" variant="danger" onClick={() => deleteResource(resource?.id)}>Delete</Button></td>
</tr>)
}
</tbody>
</table>
<ReactPaginate
key={itemsPerPage}
className="customers-pagination"
breakLabel="..."
nextLabel=">"
onPageChange={handlePageClick}
pageRangeDisplayed={5}
pageCount={pageCount}
previousLabel="<"
renderOnZeroPageCount={null}
containerClassName="pagination justify-content-center"
pageClassName="page-item"
pageLinkClassName="page-link"
previousClassName="page-item"
previousLinkClassName="page-link"
nextClassName="page-item"
nextLinkClassName="page-link"
activeClassName="active"
breakClassName="page-item"
breakLinkClassName="page-link"
/>
return (
<>
<div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item>Medical</Breadcrumb.Item>
<Breadcrumb.Item active>
Provider Information
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary">
<h4>
All Providers
</h4>
</div> </div>
</div> </div>
<div className="app-main-content-list-container">
<div className="app-main-content-list-func-container">
<Tabs defaultActiveKey="activeProviders" id="provider-tab" onSelect={(k) => showArchive(k)}>
<Tab eventKey="activeProviders" title="Active Providers">
{table}
</Tab>
<Tab eventKey="archivedProviders" title="Archived Providers">
{table}
</Tab>
</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)} />
<button className="btn btn-primary me-2"><Filter size={16} className="me-2"></Filter>Filter</button>
<button className="btn btn-primary me-2"><Columns size={16} className="me-2"></Columns>Manage Table</button>
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Providers</button>
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button>
</div>
</div>
</div>
</> </>
) )

View File

@ -1,6 +1,8 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { AuthService, ResourceService } from "../../services"; import { AuthService, ResourceService } from "../../services";
import { Archive } from "react-bootstrap-icons";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
const UpdateResource = () => { const UpdateResource = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -24,6 +26,7 @@ const UpdateResource = () => {
const [fax, setFax] = useState(''); const [fax, setFax] = useState('');
const [status, setStatus] = useState(''); const [status, setStatus] = useState('');
const [branchName, setBranchName] = useState(''); const [branchName, setBranchName] = useState('');
const [email, setEmail] = useState('');
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
@ -55,6 +58,7 @@ const UpdateResource = () => {
zipcode, zipcode,
contact, contact,
phone, phone,
email,
fax, fax,
status, status,
edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name, edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name,
@ -105,95 +109,159 @@ const UpdateResource = () => {
return ( return (
<> <>
<div className="list row">
<div className="col-md-12 text-primary">
<h5>Update Resource <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
</div>
</div>
<div className="list row mb-4"> <div className="list row mb-4">
<div className="col-md-4 mb-4"> <Breadcrumb>
<div>Doctor Name:</div> <input type="text" value={name || ''} onChange={e => setName(e.target.value)}/> <Breadcrumb.Item>Medical</Breadcrumb.Item>
</div> <Breadcrumb.Item active>
<div className="col-md-4 mb-4"> Provider Information
<div>Office Name:</div> <input type="text" value={originalName || ''} onChange={e => setOriginalName(e.target.value)}/> </Breadcrumb.Item>
</div> <Breadcrumb.Item active>
<div className="col-md-4 mb-4"> Update Provider Information
<div>Branch Name:</div> <input type="text" value={branchName || ''} onChange={e => setBranchName(e.target.value)}/> </Breadcrumb.Item>
</div> </Breadcrumb>
<div className="col-md-4 mb-4"> <div className="col-md-12 text-primary">
{/* <div>Specialty:</div> <input type="text" value={specialty || ''} onChange={e => setSpecialty(e.target.value)}/> */} <h4>Update Provider Information <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
<div>Specialty:</div>
<select value={specialty} onChange={e => setSpecialty(e.target.value)}>
<option value=""></option>
{
ResourceService.resourceOptionList.map((item) => <option value={item}>{item}</option>)
}
</select>
</div>
<div className="col-md-4 mb-4">
<div>Type:</div>
<select value={type} onChange={e => setType(e.target.value)}>
<option value="doctor">Doctor</option>
<option value="pharmacy">Pharmacy</option>
<option value="hospital">Hospital</option>
<option value="surgical center">Surgical Center</option>
<option value="government agency">Government Agency</option>
<option value="other">Other</option>
</select>
</div>
{/* <div className="col-md-4 mb-4">
<div>Category:</div> <input type="text" value={category || ''} onChange={e => setCategory(e.target.value)}/>
</div> */}
<div className="col-md-4 mb-4">
<div>Description:</div> <input type="text" value={description || ''} onChange={e => setDescription(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Color:</div> <input type="text" value={color || ''} onChange={e => setColor(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Address:</div> <textarea value={address || ''} onChange={e => setAddress(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>City:</div> <input type="text" value={city || ''} onChange={e => setCity(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>State:</div> <input type="text" value={state || ''} onChange={e => setState(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Zipcode:</div> <input type="text" value={zipcode || ''} onChange={e => setZipcode(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Contact:</div> <textarea value={contact || ''} onChange={e => setContact(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Phone:</div> <input type="text" value={phone || ''} onChange={e => setPhone(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Fax:</div> <input type="text" value={fax || ''} onChange={e => setFax(e.target.value)}/>
</div>
<div className="col-md-4 mb-4">
<div>Note:</div> <textarea value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
{/* <div className="col-md-4 mb-4">
<div>Data (object/json):</div> <textarea value={dataObject || ''} onChange={e => setDataObject(e.target.value)}/>
</div> */}
<div className="col-md-4 mb-4">
<div>Status:</div>
<select value={status} onChange={e => setStatus(e.target.value)}>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div> </div>
</div> </div>
<div className="list row mb-5"> <div className="app-main-content-list-container">
<div className="col-md-6 col-sm-6 col-xs-12"> <div className="app-main-content-list-func-container">
<button className="btn btn-primary btn-sm me-2 mb-2" onClick={() => saveResource()}> Save </button> <Tabs defaultActiveKey="providerInfo" id="providerss-tab">
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button> <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">Doctor Name
<span className="required">*</span>
</div>
<input placeholder="e.g.,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={originalName || ''} onChange={e => setOriginalName(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Branch Name
</div>
<input type="text" placeholder="e.g.,Silver Spring" value={branchName || ''} onChange={e => setBranchName(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=""></option>
{
ResourceService.resourceOptionList.map((item) => <option value={item}>{item}</option>)
}
</select>
</div>
<div className="me-4">
<div className="field-label">Type
</div>
<select value={type} onChange={e => setType(e.target.value)}>
<option value="doctor">Doctor</option>
<option value="pharmacy">Pharmacy</option>
<option value="hospital">Hospital</option>
<option value="surgical center">Surgical Center</option>
<option value="government agency">Government Agency</option>
<option value="other">Other</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">Contact
</div>
{/* <textarea value={contact || ''} onChange={e => setContact(e.target.value)}/> */}
<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" placement="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" placement="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" placement="e.g.,555 Cloverly Forest Dr" value={address || ''} onChange={e => setAddress(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">City
<span className="required">*</span>
</div>
<input type="text" placement="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 placement="e.g.,MD" type="text" 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" 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 value={note || ''} onChange={e => setNote(e.target.value)}/>
</div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Description
</div>
<input type="text" placeholder={'e.g.,Description'} value={description || ''} onChange={e => setDescription(e.target.value)}/>
</div>
<div className="me-4">
<div className="field-label">Color
</div>
<input type="text" placeholder={'e.g.,red'} value={color || ''} onChange={e => setColor(e.target.value)}/>
</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={() => { ResourceService.disableResource(urlParams?.id, {status: 'inactive'})}}><Archive size={16} className="me-2"></Archive>Archive</button>
</div>
</div> </div>
</div> </div>
</> {/* <div className="col-md-4 mb-4">
<div>Status:</div>
<select value={status} onChange={e => setStatus(e.target.value)}>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div> */}
</>
); );
}; };

View File

@ -3,6 +3,8 @@ import React, {useState, useEffect} from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
// import { customerSlice } from "./../../store"; // import { customerSlice } from "./../../store";
import { AuthService, ResourceService } from "../../services"; import { AuthService, ResourceService } from "../../services";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
import { Download, Pencil, Archive } from "react-bootstrap-icons";
const ViewResource = () => { const ViewResource = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -11,10 +13,23 @@ const ViewResource = () => {
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const redirectTo = (id) => { const redirectTo = () => {
navigate(`/medical/resources/list`); navigate(`/medical/resources/list`);
} }
const goToEdit = (id) => {
navigate(`/medical/resources/edit/${id}`)
}
const deactivateResource = (id) => {
const data = {
status: 'inactive'
};
ResourceService.disableResource(id, data).then(() => {
redirectTo();
})
}
useEffect(() => { useEffect(() => {
if (!AuthService.canAccessLegacySystem()) { if (!AuthService.canAccessLegacySystem()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.') window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
@ -28,66 +43,97 @@ const ViewResource = () => {
return ( return (
<> <>
<div className="list row"> <div className="list row mb-4">
<div className="col-md-12 col-xs-12"> <Breadcrumb>
<div className="list row mb-4"> <Breadcrumb.Item>Medical</Breadcrumb.Item>
<div className="col-md-12 text-primary"> <Breadcrumb.Item active>
<h5>View Resource Details<button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back To List</button></h5> Provider Information
</div> </Breadcrumb.Item>
</div> <Breadcrumb.Item active>
<div className="list row mb-4"> View Provider Details
<div className="col-md-4 mb-4"> </Breadcrumb.Item>
<div>Name:</div> {currentResource?.name} </Breadcrumb>
</div> <div className="col-md-12 text-primary">
<div className="col-md-4 mb-4"> <h4>View Provider Information <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
<div>Specialty:</div> </div>
{currentResource?.specialty} </div>
</div> <div className="app-main-content-list-container">
<div className="col-md-4 mb-4"> <div className="app-main-content-list-func-container">
<div>type:</div> <Tabs defaultActiveKey="providerInfo" id="providerss-tab">
{currentResource?.type} <Tab eventKey="providerInfo" title="Provider Information">
</div> <h6 className="text-primary">Basic Information</h6>
{/* <div className="col-md-4 mb-4"> <div className="app-main-content-fields-section">
<div>Category:</div> <div className="field-body">
{currentResource?.category} <div className="field-label">Name</div>
</div> */} <div className="field-value">{currentResource?.name}</div>
<div className="col-md-4 mb-4"> </div>
<div>Description:</div> <div className="field-body">
{currentResource?.description} <div className="field-label">Office Name</div>
</div> <div className="field-value">{currentResource?.name_original}</div>
<div className="col-md-4 mb-4"> </div>
<div>Color:</div> <div className="field-body">
{currentResource?.color} <div className="field-label">Branch Name</div>
</div> <div className="field-value">{currentResource?.name_branch}</div>
<div className="col-md-4 mb-4"> </div>
<div>Address: </div> <div className="field-body">
{currentResource?.address} <div className="field-label">Specialty</div>
</div> <div className="field-value">{currentResource?.specialty}</div>
<div className="col-md-4 mb-4"> </div>
<div>Contact: </div> <div className="field-body">
{currentResource?.contact} <div className="field-label">Type</div>
</div> <div className="field-value">{currentResource?.type}</div>
<div className="col-md-4 mb-4"> </div>
<div>Phone:</div> </div>
{currentResource?.phone} <h6 className="text-primary">Contact Information</h6>
</div> <div className="app-main-content-fields-section">
<div className="col-md-4 mb-4"> <div className="field-body">
<div>Fax:</div> <div className="field-label">Office Phone Number</div>
{currentResource?.fax} <div className="field-value">{currentResource?.phone}</div>
</div> </div>
<div className="col-md-4 mb-4"> <div className="field-body">
<div>Note:</div> <div className="field-label">Contact</div>
{currentResource?.note} <div className="field-value">{currentResource?.contact}</div>
</div> </div>
<div className="col-md-4 mb-4"> <div className="field-body">
<div>Status:</div> <div className="field-label">Fax Number</div>
{currentResource?.status} <div className="field-value">{currentResource?.fax}</div>
</div> </div>
</div> </div>
<h6 className="text-primary">Provider Address</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Address</div>
<div className="field-value">{`${currentResource?.address}, ${currentResource?.city}, ${currentResource?.state}, ${currentResource?.zipcode}`}</div>
</div>
</div>
<h6 className="text-primary">Additional Information</h6>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Note</div>
<div className="field-value">{currentResource?.note}</div>
</div>
<div className="field-body">
<div className="field-label">Description</div>
<div className="field-value">{currentResource?.description}</div>
</div>
<div className="field-body">
<div className="field-label">Color</div>
<div className="field-value">{currentResource?.color}</div>
</div>
<div className="field-body">
<div className="field-label">Status</div>
<div className="field-value">{currentResource?.status}</div>
</div>
</div>
</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()}><Archive size={16} className="me-2"></Archive>Archive</button>
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Download</button>
</div>
</div> </div>
</div> </div>
</> </>
); );
}; };

View File

@ -3,6 +3,7 @@ import { useSelector,useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { vehicleSlice, selectVehicleError } from "./../../store"; import { vehicleSlice, selectVehicleError } from "./../../store";
import { AuthService } from "../../services"; import { AuthService } from "../../services";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
const CreateVehicle = () => { const CreateVehicle = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -33,10 +34,15 @@ const CreateVehicle = () => {
if (redirect === 'schedule') { if (redirect === 'schedule') {
navigate(`/trans-routes/schedule`); navigate(`/trans-routes/schedule`);
} else { } else {
navigate(`/trans-routes/dashboard`); // navigate(`/trans-routes/dashboard`);
redirectToList();
} }
} }
const redirectToList = () => {
navigate('/vehicles/list')
}
const addItemToArray = () => { const addItemToArray = () => {
const arr = [...checklist, '']; const arr = [...checklist, ''];
setChecklist(arr); setChecklist(arr);
@ -63,55 +69,70 @@ const CreateVehicle = () => {
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<div className="col-md-12 text-primary"> <Breadcrumb>
<h5>Create New Vehicle <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5> <Breadcrumb.Item>Transportation</Breadcrumb.Item>
<Breadcrumb.Item active>
Vehicles Information
</Breadcrumb.Item>
<Breadcrumb.Item active>
Create New Vehicle
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary">
<h4>Create New Vechile <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
</div> </div>
</div> </div>
<div className="list row mb-4"> <div className="app-main-content-list-container">
<div className="col-md-4 mb-4"> <div className="app-main-content-list-func-container">
<div>Vehicle Number(*):</div> <input type="number" value={vehicleNumber || ''} onChange={e => setVehicleNumber(e.target.value)}/> <Tabs defaultActiveKey="basicInfo" id="customers-tab">
</div> <Tab eventKey="basicInfo" title="Basic Information">
<div className="col-md-4 mb-4"> <h6 className="text-primary">Vehicle Information</h6>
<div>Tag(*):</div> <input type="text" value={tag || ''} onChange={e => setTag(e.target.value)}/> <div className="app-main-content-fields-section">
</div> <div className="me-4">
<div className="col-md-4 mb-4"> <div className="field-label">Vehicle Number
<div>EZ Pass:</div> <input type="text" value={ezpass || ''} onChange={e => setEzpass(e.target.value)}/> <span className="required">*</span>
</div> </div>
<div className="col-md-4 mb-4"> <input type="number" placeholder="e.g.,1" value={vehicleNumber || ''} onChange={e => setVehicleNumber(e.target.value)}/>
<div>GPS:</div> <input type="text" value={gps || ''} onChange={e => setGps(e.target.value)}/> </div>
</div> <div className="me-4"><div className="field-label">Seating Capacity</div><input type="number" value={capacity || ''} placeholder="e.g.,12" onChange={e => setCapacity(e.target.value)}/></div>
<div className="col-md-4 mb-4"> <div className="me-4"><div className="field-label">Mileage</div><input type="number" value={mileage || ''} placeholder="e.g.,48000" onChange={e => setMileage(e.target.value)}/></div>
<div>Make:</div> <input type="text" value={make || ''} onChange={e => setMake(e.target.value)}/> <div className="me-4"><div className="field-label">Make</div><input type="text" value={make || ''} placeholder="e.g.,Ford" onChange={e => setMake(e.target.value)}/></div>
</div> <div className="me-4"><div className="field-label">Model</div><input type="text" value={vehicleModel || ''} placeholder="e.g.,T350" onChange={e => setVehicleModel(e.target.value)}/></div>
<div className="col-md-4 mb-4"> </div>
<div>Model:</div> <input type="text" value={vehicleModel || ''} onChange={e => setVehicleModel(e.target.value)}/> <div className="app-main-content-fields-section">
</div> <div className="me-4"><div className="field-label">Year</div><input type="text" value={year || ''} placeholder="e.g.,2016" onChange={e => setYear(e.target.value)}/></div>
<div className="col-md-4 mb-4"> <div className="me-4"><div className="field-label">Licence Plate</div><input type="text" value={tag || ''} placeholder="e.g.,91579HT" onChange={e => setTag(e.target.value)}/></div>
<div>Year:</div> <input type="text" value={year || ''} onChange={e => setYear(e.target.value)}/> <div className="me-4"><div className="field-label">GPS ID</div><input type="text" value={gps || ''} placeholder="e.g.,609671" onChange={e => setGps(e.target.value)}/></div>
</div> <div className="me-4"><div className="field-label">EZPass</div><input type="text" value={ezpass || ''} placeholder="e.g.,NY12345" onChange={e => setEzpass(e.target.value)}/></div>
<div className="col-md-4 mb-4"> {/* Lift Equipped & VIN Number would be added later */}
<div>Mileage(*):</div> <input type="number" value={mileage || ''} onChange={e => setMileage(e.target.value)}/> </div>
</div> {/* Vehicle Maintenance & Compliance would be added later */}
<div className="col-md-4 mb-4"> <h6 className="text-primary">Check List</h6>
<div>Capacity(*):</div> <input type="number" value={capacity || ''} onChange={e => setCapacity(e.target.value)}/> <div className="app-main-content-fields-section column">
</div> {checklist.map((item, index) => (<div className="mb-4" key={index}><input type="text" value={item} onChange={(e) => setChecklist([...checklist].map((a, index1) => {if (index1 === index) {return e.target.value;} return a;}))}/>
<div className="col-md-12 mb-4"> <button className="btn btn-link btn-sm" onClick={(e) => setChecklist([...checklist].filter((value, index1) => index1 != index))}>Remove</button>
<div>Checklist(*):</div> </div>))}
{checklist.map((item, index) => (<div className="mb-4" key={index}><input type="text" value={item} onChange={(e) => setChecklist([...checklist].map((a, index1) => {if (index1 === index) {return e.target.value;} return a;}))}/> <button className="btn btn-link" onClick={() => addItemToArray()}>+Add New Item</button>
<button className="btn btn-link btn-sm" onClick={(e) => setChecklist([...checklist].filter((value, index1) => index1 != index))}>Remove</button> {/* Note would be added later */}
</div>))} </div>
<button className="btn btn-link" onClick={() => addItemToArray()}>+Add New Item</button> {error && <div className="col-md-12 mb-4 alert alert-danger" role="alert">
{error}
</div>}
<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={() => saveVechile()}> Save </button>
</div>
</Tab>
<Tab eventKey="documents" title="Documents">
Coming soon...
</Tab>
<Tab eventKey="Repair Records" title="Repair Records">
Coming soon...
</Tab>
</Tabs>
</div> </div>
</div> </div>
<div className="list row mb-5">
{error && <div className="col-md-12 mb-4 alert alert-danger" role="alert">
{error}
</div>}
<div className="col-md-6 col-sm-6 col-xs-12">
<button className="btn btn-primary btn-sm" onClick={() => saveVechile()}> Save </button>
<button className="btn btn-default btn-sm" onClick={() => redirectTo()}> Cancel </button>
</div>
</div>
</> </>
); );
}; };

View File

@ -3,6 +3,8 @@ import { useSelector,useDispatch } from "react-redux";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { vehicleSlice, selectVehicleError } from "./../../store"; import { vehicleSlice, selectVehicleError } from "./../../store";
import { AuthService } from "../../services"; import { AuthService } from "../../services";
import { Archive } from "react-bootstrap-icons";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
const UpdateVehicle = () => { const UpdateVehicle = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -108,6 +110,74 @@ const UpdateVehicle = () => {
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item>Transportation</Breadcrumb.Item>
<Breadcrumb.Item active>
Vehicles Information
</Breadcrumb.Item>
<Breadcrumb.Item active>
Update Vehicle Information
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary">
<h4>Update Vehicle 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="basicInfo" id="customers-tab">
<Tab eventKey="basicInfo" title="Basic Information">
<h6 className="text-primary">Vehicle Information</h6>
<div className="app-main-content-fields-section">
<div className="me-4">
<div className="field-label">Vehicle Number
<span className="required">*</span>
</div>
<input type="number" placeholder="e.g.,1" value={vehicleNumber || ''} onChange={e => setVehicleNumber(e.target.value)}/>
</div>
<div className="me-4"><div className="field-label">Seating Capacity</div><input type="number" value={capacity || ''} placeholder="e.g.,12" onChange={e => setCapacity(e.target.value)}/></div>
<div className="me-4"><div className="field-label">Mileage</div><input type="number" value={mileage || ''} placeholder="e.g.,48000" onChange={e => setMileage(e.target.value)}/></div>
<div className="me-4"><div className="field-label">Make</div><input type="text" value={make || ''} placeholder="e.g.,Ford" onChange={e => setMake(e.target.value)}/></div>
<div className="me-4"><div className="field-label">Model</div><input type="text" value={vehicleModel || ''} placeholder="e.g.,T350" onChange={e => setVehicleModel(e.target.value)}/></div>
</div>
<div className="app-main-content-fields-section">
<div className="me-4"><div className="field-label">Year</div><input type="text" value={year || ''} placeholder="e.g.,2016" onChange={e => setYear(e.target.value)}/></div>
<div className="me-4"><div className="field-label">Licence Plate</div><input type="text" value={tag || ''} placeholder="e.g.,91579HT" onChange={e => setTag(e.target.value)}/></div>
<div className="me-4"><div className="field-label">GPS ID</div><input type="text" value={gps || ''} placeholder="e.g.,609671" onChange={e => setGps(e.target.value)}/></div>
<div className="me-4"><div className="field-label">EZPass</div><input type="text" value={ezpass || ''} placeholder="e.g.,NY12345" onChange={e => setEzpass(e.target.value)}/></div>
{/* Lift Equipped & VIN Number would be added later */}
</div>
{/* Vehicle Maintenance & Compliance would be added later */}
<h6 className="text-primary">Check List</h6>
<div className="app-main-content-fields-section column">
{checklist.map((item, index) => (<div className="mb-4" key={index}><input type="text" value={item} onChange={(e) => setChecklist([...checklist].map((a, index1) => {if (index1 === index) {return e.target.value;} return a;}))}/>
<button className="btn btn-link btn-sm" onClick={(e) => setChecklist([...checklist].filter((value, index1) => index1 != index))}>Remove</button>
</div>))}
<button className="btn btn-link" onClick={() => addItemToArray()}>+Add New Item</button>
{/* Note would be added later */}
</div>
{error && <div className="col-md-12 mb-4 alert alert-danger" role="alert">
{error}
</div>}
<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={() => saveVechile()}> Save </button>
</div>
</Tab>
<Tab eventKey="documents" title="Documents">
Coming soon...
</Tab>
<Tab eventKey="Repair Records" title="Repair Records">
Coming soon...
</Tab>
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary" onClick={() => deactivateVehicle()}><Archive size={16} className="me-2"></Archive>Archive</button>
</div>
</div>
</div>
{/* <div className="list row mb-4">
<div className="col-md-12 text-primary"> <div className="col-md-12 text-primary">
<h5>Update Vehicle <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5> <h5>Update Vehicle <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5>
</div> </div>
@ -157,7 +227,7 @@ const UpdateVehicle = () => {
<button className="btn btn-danger btn-sm me-2 mb-2" onClick={() => deactivateVehicle()}> Delete </button> <button className="btn btn-danger btn-sm me-2 mb-2" onClick={() => deactivateVehicle()}> Delete </button>
<button className="btn btn-default btn-sm mb-2" onClick={() => redirectTo()}> Cancel </button> <button className="btn btn-default btn-sm mb-2" onClick={() => redirectTo()}> Cancel </button>
</div> </div>
</div> </div> */}
</> </>
); );
}; };

View File

@ -2,12 +2,19 @@ import React, {useState, useEffect} from "react";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { AuthService, VehicleService } from "../../services"; import { AuthService, VehicleService } from "../../services";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
import { Columns, Download, Filter, PencilSquare, PersonSquare, Plus } from "react-bootstrap-icons";
const VehicleList = () => { const VehicleList = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [keyword, setKeyword] = useState('');
const [vehicles, setVehicles] = useState([]); const [vehicles, setVehicles] = useState([]);
const [tag, setTag] = useState(''); const [tag, setTag] = useState('');
const [sorting, setSorting] = useState({key: '', order: ''});
const [selectedItems, setSelectedItems] = useState([]);
const [filteredVehicles, setFilteredVehicles] = useState(vehicles);
const [showInactive, setShowInactive] = useState(false);
useEffect(() => { useEffect(() => {
if (!AuthService.canAddOrEditVechiles()) { if (!AuthService.canAddOrEditVechiles()) {
@ -20,9 +27,41 @@ const VehicleList = () => {
); );
}, []); }, []);
const redirectToAdmin = () => { useEffect(() => {
navigate(`/admin/customer-report`) if (showInactive) {
} setFilteredVehicles(vehicles && vehicles.filter(item =>
(item?.vehicle_number?.toString()?.includes(keyword.toLowerCase()) ||
item?.tag?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.ezpass?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.gps_tag?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.make?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.vehicle_model?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.year?.toLowerCase()?.includes(keyword.toLowerCase())) &&
item?.status?.toLowerCase() !== 'active'
))
} else {
setFilteredVehicles(vehicles && vehicles.filter(item =>
(item?.vehicle_number?.toString()?.includes(keyword.toLowerCase()) ||
item?.tag?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.ezpass?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.gps_tag?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.make?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.vehicle_model?.toLowerCase()?.includes(keyword.toLowerCase()) ||
item?.year?.toLowerCase()?.includes(keyword.toLowerCase())) &&
item?.status?.toLowerCase() === 'active'
))
}
}, [keyword, vehicles]);
useEffect(() => {
const newVehicles = [...vehicles];
const sortedVehicles = sorting.key === '' ? newVehicles : newVehicles.sort((a, b) => {
return a[sorting.key]?.localeCompare(b[sorting.key]);
});
setVehicles(
sorting.order === 'asc' ? sortedVehicles : sortedVehicles.reverse()
)
}, [sorting]);
const goToEdit = (id) => { const goToEdit = (id) => {
navigate(`/vehicles/edit/${id}?redirect=list`) navigate(`/vehicles/edit/${id}?redirect=list`)
@ -33,15 +72,161 @@ const VehicleList = () => {
navigate(`/vehicles/${id}`) navigate(`/vehicles/${id}`)
} }
const goToCreateNew = () => {
navigate(`/vehicles`)
}
const columns = [
{
key: 'vehicle_number',
label: 'Vehicle Number'
},
{
key: 'tag',
label: 'License Plate'
},
{
key: 'capacity',
label: 'Seating Capacity'
},
{
key: 'mileage',
label: 'Mileage'
},
{
key: 'make',
label: 'Make'
},
{
key: 'model',
label: 'Model'
},
{
key: 'year',
label: 'Year'
}
];
const getSortingImg = (key) => {
return sorting.key === key ? (sorting.order === 'asc' ? 'up_arrow' : 'down_arrow') : 'default';
}
const sortTableWithField = (key) => {
let newSorting = {
key,
order: 'asc',
}
if (sorting.key === key && sorting.order === 'asc') {
newSorting = {...newSorting, order: 'desc'};
}
setSorting(newSorting);
}
const toggleSelectedAllItems = () => {
if (selectedItems.length !== filteredVehicles.length || selectedItems.length === 0) {
const newSelectedItems = [...filteredVehicles].map((vehicle) => vehicle.id);
setSelectedItems(newSelectedItems);
} else {
setSelectedItems([]);
}
}
const toggleItem = (id) => {
if (selectedItems.includes(id)) {
const newSelectedItems = [...selectedItems].filter((item) => item !== id);
setSelectedItems(newSelectedItems);
} else {
const newSelectedItems = [...selectedItems, id];
setSelectedItems(newSelectedItems);
}
}
const showArchive = (value) => {
setShowInactive(value === 'archivedVehicles');
// Recover all filters
setKeyword('');
setTag('');
setSorting({key: '', order: ''});
setSelectedItems([]);
}
const checkSelectAll = () => {
return selectedItems.length === filteredVehicles.length && selectedItems.length > 0;
}
const table = <div className="list row mb-4">
<div className="col-md-12">
<table className="personnel-info-table">
<thead>
<tr>
<th className="th-checkbox"><input type="checkbox" checked={checkSelectAll()} onClick={() => toggleSelectedAllItems()}></input></th>
<th className="th-index">No.</th>
{
columns.map((column, index) => <th className="sortable-header" key={index}>
{column.label} <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span>
</th>)
}
</tr>
</thead>
<tbody>
{
filteredVehicles.map((vehicle, index) => <tr key={vehicle.id}>
<td className="td-checkbox"><input type="checkbox" checked={selectedItems.includes(vehicle.id)} onClick={()=>toggleItem(vehicle?.id)}/></td>
<td className="td-index">{index + 1}</td>
<td> {AuthService.canAddOrEditVechiles() && <PencilSquare size={16} className="clickable me-2" onClick={() => goToEdit(vehicle?.id)}></PencilSquare>} {AuthService.canViewVechiles() ? <button className="btn btn-link btn-sm" onClick={() => goToView(vehicle?.id)}>{vehicle?.vehicle_number}</button> : vehicle?.vehicle_number } </td>
<td>{vehicle?.tag}</td>
<td>{vehicle?.capacity}</td>
<td>{vehicle?.mileage}</td>
<td>{vehicle?.make}</td>
<td>{vehicle?.vehicle_model}</td>
<td>{vehicle?.year}</td>
</tr>)
}
</tbody>
</table>
</div>
</div>;
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item>Transportation</Breadcrumb.Item>
<Breadcrumb.Item active>
Vehicle Information
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary"> <div className="col-md-12 text-primary">
<h5>All Vehicles <button className="btn btn-link btn-sm" onClick={() => {redirectToAdmin()}}>Back</button></h5> <h4>
All Vehicles
</h4>
</div> </div>
</div> </div>
<div className="list row mb-4"> <div className="app-main-content-list-container">
<div className="app-main-content-list-func-container">
<Tabs defaultActiveKey="activeVehicles" id="vehicles-tab" onSelect={(k) => showArchive(k)}>
<Tab eventKey="activeVehicles" title="Active Vehicles">
{table}
</Tab>
<Tab eventKey="archivedVehicles" title="Archived Vehicles">
{table}
</Tab>
</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)} />
<button className="btn btn-primary me-2"><Filter size={16} className="me-2"></Filter>Filter</button>
<button className="btn btn-primary me-2"><Columns size={16} className="me-2"></Columns>Manage Table</button>
<button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Vehicle</button>
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button>
</div>
</div>
</div>
{/* <div className="list row mb-4">
<div className="col-md-12"> <div className="col-md-12">
<div className="mb-4">Filter By Tag: <input type="text" value={tag} onChange={(e) => setTag(e.currentTarget.value)}/></div> <div className="mb-4">Filter By Tag: <input type="text" value={tag} onChange={(e) => setTag(e.currentTarget.value)}/></div>
<table className="personnel-info-table"> <table className="personnel-info-table">
@ -51,7 +236,7 @@ const VehicleList = () => {
<th>Tag Number</th> <th>Tag Number</th>
<th>Mileage</th> <th>Mileage</th>
<th>Status</th> <th>Status</th>
<th>Capacity</th> <th>Seating Capacity</th>
<th></th> <th></th>
</tr> </tr>
@ -74,7 +259,7 @@ const VehicleList = () => {
</table> </table>
</div> </div>
</div> </div> */}
</> </>
) )
}; };

View File

@ -1,17 +1,35 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { useSelector,useDispatch } from "react-redux";
import { AuthService, VehicleService } from "../../services"; import { AuthService, VehicleService } from "../../services";
import { vehicleSlice, selectVehicleError } from "./../../store";
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
import { Download, Pencil, Archive } from "react-bootstrap-icons";
const ViewVehicle = () => { const ViewVehicle = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch();
const urlParams = useParams(); const urlParams = useParams();
const [currentVehicle, setCurrentVehicle] = useState(undefined); const [currentVehicle, setCurrentVehicle] = useState(undefined);
const { updateVehicle, deleteVehicle, fetchAllVehicles } = vehicleSlice.actions;
const redirectTo = () => { const redirectTo = () => {
navigate(`/vehicles/list`) navigate(`/vehicles/list`)
} }
const goToEdit = (id) => {
navigate(`/vehicles/edit/${id}?redirect=list`)
}
const deactivateVehicle = () => {
const data = {
status: 'inactive'
};
dispatch(deleteVehicle({id: urlParams.id, data}));
redirectTo();
}
useEffect(() => { useEffect(() => {
if (!AuthService.canViewVechiles()) { 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.') window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
@ -28,40 +46,83 @@ const ViewVehicle = () => {
return ( return (
<> <>
<div className="list row mb-4"> <div className="list row mb-4">
<div className="col-md-12 text-primary"> <Breadcrumb>
<h5>View Vechile {currentVehicle?.vehicle_number} <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h5> <Breadcrumb.Item>Transportation</Breadcrumb.Item>
</div> <Breadcrumb.Item active>
Vehicles Information
</Breadcrumb.Item>
<Breadcrumb.Item active>
View Vehicle Information
</Breadcrumb.Item>
</Breadcrumb>
</div> </div>
<div className="list row mb-4"> <div className="col-md-12 text-primary">
<div className="col-md-4 mb-4"> <h4>View Vechile Information <button className="btn btn-link btn-sm" onClick={() => {redirectTo()}}>Back</button></h4>
<div>Vehicle Number: {currentVehicle?.vehicle_number}</div> </div>
</div> <div className="app-main-content-list-container">
<div className="col-md-4 mb-4"> <div className="app-main-content-list-func-container">
<div>Tag: {currentVehicle?.tag}</div> <Tabs defaultActiveKey="basicInfo" id="customers-tab">
</div> <Tab eventKey="basicInfo" title="Basic Information">
<div className="col-md-4 mb-4"> <h6 className="text-primary">Vehicle Information</h6>
<div>GPS: {currentVehicle?.gps_tag}</div> <div className="app-main-content-fields-section">
</div> <div className="field-body">
<div className="col-md-4 mb-4"> <div className="field-label">Vehicle Number</div>
<div>EZPass: {currentVehicle?.ezpass}</div> <div className="field-value">{currentVehicle?.vehicle_number}</div>
</div> </div>
<div className="col-md-4 mb-4"> <div className="field-body">
<div>Capacity: {currentVehicle?.capacity}</div> <div className="field-label">Seating Capacity</div>
</div> <div className="field-value">{currentVehicle?.capacity}</div>
<div className="col-md-4 mb-4"> </div>
<div>Mileage: {currentVehicle?.mileage}</div> <div className="field-body">
</div> <div className="field-label">Mileage</div>
<div className="col-md-4 mb-4"> <div className="field-value">{currentVehicle?.mileage}</div>
<div>Make: {currentVehicle?.make}</div> </div>
</div> <div className="field-body">
<div className="col-md-4 mb-4"> <div className="field-label">Make</div>
<div>Model: {currentVehicle?.vehicle_model}</div> <div className="field-value">{currentVehicle?.make}</div>
</div> </div>
<div className="col-md-4 mb-4"> <div className="field-body">
<div>Year: {currentVehicle?.year}</div> <div className="field-label">Model</div>
</div> <div className="field-value">{currentVehicle?.vehicle_model}</div>
<div className="col-md-4 mb-4"> </div>
<div>Checklist: {currentVehicle?.checklist?.join(', ')}</div> </div>
<div className="app-main-content-fields-section">
<div className="field-body">
<div className="field-label">Year</div>
<div className="field-value">{currentVehicle?.year}</div>
</div>
<div className="field-body">
<div className="field-label">Licence Plate</div>
<div className="field-value">{currentVehicle?.tag}</div>
</div>
<div className="field-body">
<div className="field-label">GPS ID</div>
<div className="field-value">{currentVehicle?.gps}</div>
</div>
<div className="field-body">
<div className="field-label">EZPass</div>
<div className="field-value">{currentVehicle?.ezpass}</div>
</div>
</div>
<h6 className="text-primary">Check List</h6>
<div className="app-main-content-fields-section column">
<ul>
{currentVehicle?.checklist?.map((item) => <li>{item}</li>)}
</ul>
</div>
</Tab>
<Tab eventKey="documents" title="Documents">
Coming soon...
</Tab>
<Tab eventKey="Repair Records" title="Repair Records">
Coming soon...
</Tab>
</Tabs>
<div className="list-func-panel">
<button className="btn btn-primary me-2" onClick={() => goToEdit(currentVehicle?.id)}><Pencil size={16} className="me-2"></Pencil>Edit</button>
<button className="btn btn-primary me-2" onClick={() => deactivateVehicle()}><Archive size={16} className="me-2"></Archive>Archive</button>
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Download</button>
</div>
</div> </div>
</div> </div>
</> </>