This commit is contained in:
@@ -1,97 +1,26 @@
|
||||
import React, {useState, useEffect} from "react";
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { AuthService, CustomerService } from "../../services";
|
||||
import { AuthService } from "../../services";
|
||||
import { Export } from "../../shared";
|
||||
import { Plus } from "react-bootstrap-icons";
|
||||
import DashboardCustomersList from "../dashboard/DashboardCustomersList";
|
||||
|
||||
const CustomersList = () => {
|
||||
const navigate = useNavigate();
|
||||
const [customers, setCustomers] = useState([]);
|
||||
const CUSTOMER_LIST_COLUMN_TAB_MAP = {
|
||||
name: 'personalInfo',
|
||||
chinese_name: 'personalInfo',
|
||||
email: 'personalInfo',
|
||||
type: 'careServices',
|
||||
pickup_status: 'careServices',
|
||||
birth_date: 'personalInfo',
|
||||
gender: 'personalInfo',
|
||||
language: 'personalInfo',
|
||||
medicare_number: 'medicalInsurance',
|
||||
medicaid_number: 'medicalInsurance',
|
||||
address: 'personalInfo',
|
||||
phone: 'personalInfo',
|
||||
emergency_contact: 'medicalInsurance',
|
||||
health_condition: 'medicalInsurance',
|
||||
payment_status: 'careServices',
|
||||
payment_due_date: 'careServices',
|
||||
service_requirement: 'careServices',
|
||||
tags: 'personalInfo'
|
||||
};
|
||||
const getVisibleColumnsByPermission = (columnList = []) => {
|
||||
return columnList.filter((column) => {
|
||||
if (column.key === 'name') return true;
|
||||
const mappedTab = CUSTOMER_LIST_COLUMN_TAB_MAP[column.key];
|
||||
if (!mappedTab) return true;
|
||||
return AuthService.canViewCustomerTab(mappedTab);
|
||||
});
|
||||
};
|
||||
const [columns] = useState(getVisibleColumnsByPermission([
|
||||
{ key: 'name', label:'Name', show: true },
|
||||
{ key: 'chinese_name', label: 'Preferred Name', show: true },
|
||||
{ key: 'email', label: 'Email', show: true },
|
||||
{ key: 'type', label: 'Type', show: true },
|
||||
{ key: 'pickup_status', label: 'Pickup Status', show: true },
|
||||
{ key: 'birth_date', label: 'Date of Birth', show: true },
|
||||
{ key: 'gender', label: 'Gender', show: true },
|
||||
{ key: 'language', label: 'Language', show: true },
|
||||
{ key: 'medicare_number', label: 'Medicare Number', show: true },
|
||||
{ key: 'medicaid_number', label: 'Medicaid Number', show: true },
|
||||
{ key: 'address', label: 'Address', show: true },
|
||||
{ key: 'phone', label: 'Phone', show: true },
|
||||
{ key: 'emergency_contact', label: 'Fasting', show: true },
|
||||
{ key: 'health_condition', label: 'Health Condition', show: true },
|
||||
{ key: 'payment_status', label: 'Payment Status', show: true },
|
||||
{ key: 'payment_due_date', label: 'Payment Due Date', show: true },
|
||||
{ key: 'service_requirement', label: 'Service Requirement', show: true },
|
||||
{ key: 'tags', label: 'Tags', show: true }
|
||||
]));
|
||||
|
||||
useEffect(() => {
|
||||
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.')
|
||||
AuthService.logout();
|
||||
navigate(`/login`);
|
||||
return;
|
||||
}
|
||||
CustomerService.getAllCustomers().then((data) => {
|
||||
const customerData = data.data.map((item) => {
|
||||
item.phone = item?.phone || item?.home_phone || item?.mobile_phone;
|
||||
item.address = item?.address1 || item?.address2 || item?.address3 || item?.address4 || item?.address5;
|
||||
return item;
|
||||
}).sort((a, b) => a.lastname > b.lastname ? 1 : -1);
|
||||
setCustomers(customerData);
|
||||
});
|
||||
}, [navigate]);
|
||||
|
||||
const goToCreateNew = () => {
|
||||
navigate(`/customers`);
|
||||
}
|
||||
|
||||
const additionalButtons = ({ showExportDropdown, onExportToggle }) => (
|
||||
const additionalButtons = ({ showExportDropdown, onExportToggle, exportColumns = [], exportData = [] }) => (
|
||||
<>
|
||||
{AuthService.canCreateCustomer() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}>
|
||||
<Plus size={16}></Plus>Add New Customer
|
||||
</button>}
|
||||
{AuthService.canExportCustomerReport() && (
|
||||
<Export
|
||||
columns={columns}
|
||||
data={customers.map((customer) => ({
|
||||
...customer,
|
||||
address: customer?.address1 || customer?.address2 || customer?.address3 || customer?.address4 || customer?.address5,
|
||||
phone: customer?.phone || customer?.home_phone || customer?.mobile_phone,
|
||||
tags: customer?.tags?.join(', ')
|
||||
}))}
|
||||
columns={exportColumns}
|
||||
data={exportData}
|
||||
filename="customers"
|
||||
show={showExportDropdown}
|
||||
onToggle={onExportToggle}
|
||||
|
||||
@@ -3,31 +3,151 @@ import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { customerSlice } from "./../../store";
|
||||
import { AuthService, CustomerService, EventsService } from "../../services";
|
||||
import { CUSTOMER_TYPE, CUSTOMER_TYPE_TEXT, PROGRAM_TYPE, PROGRAM_TYPE_TEXT, PAY_SOURCE, PAY_SOURCE_TEXT, YES_NO, YES_NO_TEXT, ManageTable } from "../../shared";
|
||||
import {
|
||||
CUSTOMER_TYPE,
|
||||
CUSTOMER_TYPE_TEXT,
|
||||
PROGRAM_TYPE,
|
||||
PROGRAM_TYPE_TEXT,
|
||||
PAY_SOURCE,
|
||||
PAY_SOURCE_TEXT,
|
||||
LEGAL_SEX_TEXT,
|
||||
MARITAL_STATUS_TEXT,
|
||||
IMMIGRATION_STATUS_TEXT,
|
||||
LANGUAGE_OPTIONS,
|
||||
DAYS_OF_WEEK_OPTIONS,
|
||||
REFERRAL_SOURCE_TEXT,
|
||||
CUSTOMER_DISCHARGE_REASON_TEXT,
|
||||
DIETARY_RESTRICTIONS_OPTIONS,
|
||||
DIET_TEXTURE_TEXT,
|
||||
TRANSPORTATION_TYPE_TEXT,
|
||||
PREFERRED_TEXT_LANGUAGE_TEXT,
|
||||
YES_NO,
|
||||
YES_NO_TEXT,
|
||||
ManageTable
|
||||
} from "../../shared";
|
||||
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab, Dropdown, Modal } from "react-bootstrap";
|
||||
import { Columns, Download, Filter, PencilSquare, PersonSquare, Plus } from "react-bootstrap-icons";
|
||||
|
||||
const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, title = null }) => {
|
||||
const HIDDEN_CUSTOMER_TYPE_FILTER_VALUES = [CUSTOMER_TYPE.TRANSFERRED, CUSTOMER_TYPE.DECEASED, CUSTOMER_TYPE.DISCHARGED];
|
||||
const DISCHARGE_ONLY_COLUMN_KEYS = new Set(['discharge_date', 'discharge_by', 'discharge_reason']);
|
||||
const CUSTOMER_COLUMNS = [
|
||||
{ key: 'customer_name', label: 'Customer Name', show: true },
|
||||
{ key: 'customer_type', label: 'Customer Type', show: true },
|
||||
{ key: 'program_type_display', label: 'Program Type', show: true },
|
||||
{ key: 'pay_source_display', label: 'Pay Source', show: true },
|
||||
{ key: 'date_of_birth', label: 'Date Of Birth', show: true },
|
||||
{ key: 'legal_sex_display', label: 'Legal Sex', show: true },
|
||||
{ key: 'marital_status_display', label: 'Marital Status', show: true },
|
||||
{ key: 'marriage_date', label: 'Marriage Date', show: true },
|
||||
{ key: 'immigration_status_display', label: 'Immigration Status', show: true },
|
||||
{ key: 'language_spoken_display', label: 'Language Spoken', show: true },
|
||||
{ key: 'phone_number', label: 'Phone Number', show: true },
|
||||
{ key: 'email', label: 'Email', show: true },
|
||||
{ key: 'address_display', label: 'Address', show: true },
|
||||
{ key: 'emergency_contact_display', label: 'Emergency Contact', show: true },
|
||||
{ key: 'admission_date', label: 'Admission Date', show: true },
|
||||
{ key: 'days_of_week_display', label: 'Days of Week', show: true },
|
||||
{ key: 'admission_date_duplicate', label: 'Admission Date', show: true },
|
||||
{ key: 'enrolled_date', label: 'Enrolled Date', show: true },
|
||||
{ key: 'created_by', label: 'Created By', show: true },
|
||||
{ key: 'referral_source_display', label: 'Referral Source', show: true },
|
||||
{ key: 'discharge_date', label: 'Discharge Date', show: true },
|
||||
{ key: 'discharge_by', label: 'Discharge By', show: true },
|
||||
{ key: 'discharge_reason', label: 'Discharge Reason', show: true },
|
||||
{ key: 'notes_and_attachments', label: 'Notes And Attachments', show: true },
|
||||
{ key: 'notes_for_driver', label: 'Notes for Driver', show: true },
|
||||
{ key: 'dietary_restrictions_display', label: 'Dietary Restrictions', show: true },
|
||||
{ key: 'diet_texture_display', label: 'Diet Texture', show: true },
|
||||
{ key: 'meal_type', label: 'Meal Type', show: true },
|
||||
{ key: 'table_number', label: 'Table Number', show: true },
|
||||
{ key: 'seat_number', label: 'Seat Number', show: true },
|
||||
{ key: 'transportation_type_display', label: 'Transportation Type', show: true },
|
||||
{ key: 'consent_to_text_messages_display', label: 'Consent To Text Messages', show: true },
|
||||
{ key: 'preferred_text_language_display', label: 'Preferred Text Language', show: true },
|
||||
{ key: 'consent_to_media_use_display', label: 'Consent to Media Use', show: true },
|
||||
{ key: 'primary_care_physician_display', label: 'Primary Care Physician', show: true },
|
||||
{ key: 'pharmacy_name', label: 'Pharmacy Name', show: true },
|
||||
{ key: 'pharmacy_id', label: 'Pharmacy ID', show: true },
|
||||
{ key: 'diabetes_mellitus_display', label: 'Diabetes Mellitus', show: true },
|
||||
{ key: 'eyes_on_display', label: 'Eyes-On', show: true },
|
||||
{ key: 'wheelchair_display', label: 'Wheelchair', show: true },
|
||||
{ key: 'molst', label: 'MOLST', show: true },
|
||||
{ key: 'provisions_for_advance_medical', label: 'Provisions for Advance Medical', show: true },
|
||||
{ key: 'hospice_display', label: 'Hospice', show: true },
|
||||
{ key: 'burial_arrangements', label: 'Burial Arrangements', show: true },
|
||||
{ key: 'power_of_attorney', label: 'Power of Attorney', show: true },
|
||||
{ key: 'requires_rounding_display', label: 'Requires Rounding', show: true },
|
||||
{ key: 'rounding_notes', label: 'Rounding Notes', show: true },
|
||||
{ key: 'adcaps_completed_date', label: 'Adcaps Completed Date', show: true },
|
||||
{ key: 'center_qualification_renew_date', label: 'Center Qualification Renew Date', show: true },
|
||||
{ key: 'medicaid_renew_date', label: 'Medicaid Renew Date', show: true },
|
||||
{ key: 'id_expiration_date', label: 'ID Expiration Date', show: true },
|
||||
{ key: 'medicare_number', label: 'Medicare Number', show: true },
|
||||
{ key: 'medicaid_number', label: 'Medicaid Number', show: true },
|
||||
{ key: 'social_security_number', label: 'Social Security Number', show: true },
|
||||
{ key: 'adcaps_id', label: 'Adcaps ID', show: true }
|
||||
];
|
||||
const CUSTOMER_LIST_COLUMN_TAB_MAP = {
|
||||
name: 'personalInfo',
|
||||
chinese_name: 'personalInfo',
|
||||
customer_name: 'personalInfo',
|
||||
customer_type: 'careServices',
|
||||
program_type_display: 'personalInfo',
|
||||
pay_source_display: 'personalInfo',
|
||||
date_of_birth: 'personalInfo',
|
||||
legal_sex_display: 'personalInfo',
|
||||
marital_status_display: 'personalInfo',
|
||||
marriage_date: 'personalInfo',
|
||||
immigration_status_display: 'personalInfo',
|
||||
language_spoken_display: 'personalInfo',
|
||||
phone_number: 'personalInfo',
|
||||
email: 'personalInfo',
|
||||
type: 'careServices',
|
||||
pickup_status: 'careServices',
|
||||
birth_date: 'personalInfo',
|
||||
gender: 'personalInfo',
|
||||
language: 'personalInfo',
|
||||
medicare_number: 'medicalInsurance',
|
||||
medicaid_number: 'medicalInsurance',
|
||||
address: 'personalInfo',
|
||||
phone: 'personalInfo',
|
||||
emergency_contact: 'medicalInsurance',
|
||||
tags: 'personalInfo'
|
||||
address_display: 'personalInfo',
|
||||
emergency_contact_display: 'personalInfo',
|
||||
admission_date: 'careServices',
|
||||
days_of_week_display: 'careServices',
|
||||
admission_date_duplicate: 'careServices',
|
||||
enrolled_date: 'careServices',
|
||||
created_by: 'careServices',
|
||||
referral_source_display: 'careServices',
|
||||
discharge_date: 'careServices',
|
||||
discharge_by: 'careServices',
|
||||
discharge_reason: 'careServices',
|
||||
notes_and_attachments: 'careServices',
|
||||
notes_for_driver: 'careServices',
|
||||
dietary_restrictions_display: 'careServices',
|
||||
diet_texture_display: 'careServices',
|
||||
meal_type: 'careServices',
|
||||
table_number: 'careServices',
|
||||
seat_number: 'careServices',
|
||||
transportation_type_display: 'careServices',
|
||||
consent_to_text_messages_display: 'careServices',
|
||||
preferred_text_language_display: 'careServices',
|
||||
consent_to_media_use_display: 'careServices',
|
||||
primary_care_physician_display: 'medicalInsurance',
|
||||
pharmacy_name: 'medicalInsurance',
|
||||
pharmacy_id: 'medicalInsurance',
|
||||
diabetes_mellitus_display: 'medicalInsurance',
|
||||
eyes_on_display: 'medicalInsurance',
|
||||
wheelchair_display: 'medicalInsurance',
|
||||
molst: 'medicalInsurance',
|
||||
provisions_for_advance_medical: 'medicalInsurance',
|
||||
hospice_display: 'medicalInsurance',
|
||||
burial_arrangements: 'medicalInsurance',
|
||||
power_of_attorney: 'medicalInsurance',
|
||||
requires_rounding_display: 'medicalInsurance',
|
||||
rounding_notes: 'medicalInsurance',
|
||||
adcaps_completed_date: 'confidentialDetails',
|
||||
center_qualification_renew_date: 'confidentialDetails',
|
||||
medicaid_renew_date: 'confidentialDetails',
|
||||
id_expiration_date: 'confidentialDetails',
|
||||
medicare_number: 'confidentialDetails',
|
||||
medicaid_number: 'confidentialDetails',
|
||||
social_security_number: 'confidentialDetails',
|
||||
adcaps_id: 'confidentialDetails'
|
||||
};
|
||||
const getVisibleColumnsByPermission = (columnList = []) => {
|
||||
return columnList.filter((column) => {
|
||||
if (column.key === 'name') return true;
|
||||
if (column.key === 'customer_name') return true;
|
||||
const mappedTab = CUSTOMER_LIST_COLUMN_TAB_MAP[column.key];
|
||||
if (!mappedTab) return true;
|
||||
return AuthService.canViewCustomerTab(mappedTab);
|
||||
@@ -74,82 +194,115 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
const [customerAvatars, setCustomerAvatars] = useState({});
|
||||
const isAllCustomersPage = title === 'All Customers';
|
||||
const customerTabOrder = ['personalInfo', 'careServices', 'medicalInsurance', 'confidentialDetails', 'formSubmission'];
|
||||
const [columns, setColumns] = useState(getVisibleColumnsByPermission([
|
||||
{
|
||||
key: 'name',
|
||||
label:'Name',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'chinese_name',
|
||||
label: 'Preferred Name',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'email',
|
||||
label: 'Email',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'type',
|
||||
label: 'Type',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'pickup_status',
|
||||
label: 'Pickup Status',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'birth_date',
|
||||
label: 'Date of Birth',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'gender',
|
||||
label: 'Gender',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'language',
|
||||
label: 'Language',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'medicare_number',
|
||||
label: 'Medicare Number',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'medicaid_number',
|
||||
label: 'Medicaid Number',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'address',
|
||||
label: 'Address',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'phone',
|
||||
label: 'Phone',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'emergency_contact',
|
||||
label: 'Fasting',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'tags',
|
||||
label: 'Tags',
|
||||
show: true
|
||||
}
|
||||
]));
|
||||
const [columns, setColumns] = useState(getVisibleColumnsByPermission(CUSTOMER_COLUMNS));
|
||||
useEffect(() => {
|
||||
setColumns((prevColumns) => getVisibleColumnsByPermission(prevColumns));
|
||||
}, []);
|
||||
|
||||
const toDisplayText = (value) => {
|
||||
if (value === undefined || value === null) return '';
|
||||
const normalized = `${value}`.trim();
|
||||
if (!normalized) return '';
|
||||
const lowered = normalized.toLowerCase();
|
||||
if (lowered === 'yes') return 'Yes';
|
||||
if (lowered === 'no') return 'No';
|
||||
return normalized;
|
||||
};
|
||||
|
||||
const getOptionLabel = (options = [], value = '') => {
|
||||
const normalizedValue = `${value || ''}`.trim().toLowerCase();
|
||||
const option = options.find((item) => `${item?.value || ''}`.trim().toLowerCase() === normalizedValue);
|
||||
return option?.label || `${value || ''}`;
|
||||
};
|
||||
|
||||
const formatAddress = (customer) => {
|
||||
const modernAddress = [
|
||||
customer?.address_line_1,
|
||||
customer?.address_line_2,
|
||||
customer?.city,
|
||||
customer?.state,
|
||||
customer?.zip_code
|
||||
].filter(Boolean).join(', ');
|
||||
return modernAddress || customer?.address1 || customer?.address2 || customer?.address3 || customer?.address4 || customer?.address5 || '';
|
||||
};
|
||||
|
||||
const formatEmergencyContact = (customer) => {
|
||||
const modernContact = [customer?.emergency_contact_name, customer?.emergency_contact_phone].filter(Boolean).join(' - ');
|
||||
return modernContact || customer?.emergency_contact || customer?.emergency_contact2 || '';
|
||||
};
|
||||
|
||||
const formatCustomerRecord = (customer) => {
|
||||
const paySource = customer?.pay_source || '';
|
||||
const paySourceLabel = PAY_SOURCE_TEXT[paySource] || paySource;
|
||||
const paySourceDisplay = paySource === 'other' && customer?.pay_source_other
|
||||
? `${paySourceLabel} (${customer.pay_source_other})`
|
||||
: paySourceLabel;
|
||||
|
||||
const immigrationStatus = customer?.immigration_status || '';
|
||||
const immigrationStatusLabel = IMMIGRATION_STATUS_TEXT[immigrationStatus] || immigrationStatus;
|
||||
const immigrationStatusDisplay = immigrationStatus === 'other' && customer?.immigration_status_other
|
||||
? `${immigrationStatusLabel} (${customer.immigration_status_other})`
|
||||
: immigrationStatusLabel;
|
||||
|
||||
const referralSource = customer?.referral_source || '';
|
||||
const referralSourceLabel = REFERRAL_SOURCE_TEXT[referralSource] || referralSource;
|
||||
const referralSourceDisplay = referralSource === 'other' && customer?.referral_source_other
|
||||
? `${referralSourceLabel} (${customer.referral_source_other})`
|
||||
: referralSourceLabel;
|
||||
|
||||
const dischargeReason = customer?.discharge_reason || '';
|
||||
const dischargeReasonLabel = CUSTOMER_DISCHARGE_REASON_TEXT[dischargeReason] || dischargeReason;
|
||||
const dischargeReasonDisplay = dischargeReason === 'other' && customer?.discharge_reason_other
|
||||
? `${dischargeReasonLabel} (${customer.discharge_reason_other})`
|
||||
: dischargeReasonLabel;
|
||||
|
||||
return {
|
||||
...customer,
|
||||
customer_name: customer?.name || '',
|
||||
customer_type: CUSTOMER_TYPE_TEXT[customer?.type] || customer?.type || '',
|
||||
program_type_display: PROGRAM_TYPE_TEXT[customer?.program_type || customer?.program] || customer?.program_type || customer?.program || '',
|
||||
pay_source_display: paySourceDisplay,
|
||||
date_of_birth: customer?.birth_date || '',
|
||||
legal_sex_display: LEGAL_SEX_TEXT[customer?.legal_sex] || customer?.legal_sex || customer?.gender || '',
|
||||
marital_status_display: MARITAL_STATUS_TEXT[customer?.marital_status] || customer?.marital_status || '',
|
||||
marriage_date: customer?.marriage_date || '',
|
||||
immigration_status_display: immigrationStatusDisplay,
|
||||
language_spoken_display: Array.isArray(customer?.language_spoken) && customer.language_spoken.length > 0
|
||||
? customer.language_spoken.map((lang) => getOptionLabel(LANGUAGE_OPTIONS, lang)).join(', ')
|
||||
: (customer?.language || ''),
|
||||
phone_number: customer?.phone || customer?.home_phone || customer?.mobile_phone || '',
|
||||
address_display: formatAddress(customer),
|
||||
emergency_contact_display: formatEmergencyContact(customer),
|
||||
admission_date: customer?.admission_date || '',
|
||||
days_of_week_display: Array.isArray(customer?.days_of_week) ? customer.days_of_week.map((day) => getOptionLabel(DAYS_OF_WEEK_OPTIONS, day)).join(', ') : '',
|
||||
admission_date_duplicate: customer?.admission_date || '',
|
||||
enrolled_date: customer?.enrolled_date || '',
|
||||
created_by: customer?.create_by || '',
|
||||
referral_source_display: referralSourceDisplay,
|
||||
discharge_reason: dischargeReasonDisplay,
|
||||
notes_and_attachments: customer?.note || '',
|
||||
notes_for_driver: customer?.notes_for_driver || '',
|
||||
dietary_restrictions_display: Array.isArray(customer?.dietary_restrictions)
|
||||
? customer.dietary_restrictions.map((item) => getOptionLabel(DIETARY_RESTRICTIONS_OPTIONS, item)).join(', ')
|
||||
: '',
|
||||
diet_texture_display: DIET_TEXTURE_TEXT[customer?.diet_texture] || customer?.diet_texture || '',
|
||||
meal_type: customer?.meal_requirement || '',
|
||||
table_number: customer?.table_id || '',
|
||||
seat_number: customer?.seat_number || '',
|
||||
transportation_type_display: TRANSPORTATION_TYPE_TEXT[customer?.transportation_type] || customer?.transportation_type || '',
|
||||
consent_to_text_messages_display: YES_NO_TEXT[`${customer?.consent_to_text_messages || ''}`.toLowerCase()] || toDisplayText(customer?.consent_to_text_messages || ''),
|
||||
preferred_text_language_display: PREFERRED_TEXT_LANGUAGE_TEXT[customer?.preferred_text_language] || customer?.preferred_text_language || '',
|
||||
consent_to_media_use_display: YES_NO_TEXT[`${customer?.consent_to_media_use || ''}`.toLowerCase()] || toDisplayText(customer?.consent_to_media_use || ''),
|
||||
primary_care_physician_display: customer?.primary_care_physician || customer?.care_provider || '',
|
||||
pharmacy_name: customer?.pharmacy || '',
|
||||
diabetes_mellitus_display: toDisplayText(customer?.diabetes_mellitus || ''),
|
||||
eyes_on_display: YES_NO_TEXT[`${customer?.eyes_on || (customer?.disability ? YES_NO.YES : '')}`.toLowerCase()] || toDisplayText(customer?.eyes_on || (customer?.disability ? YES_NO.YES : '')),
|
||||
wheelchair_display: toDisplayText(customer?.wheelchair || ''),
|
||||
hospice_display: toDisplayText(customer?.hospice || ''),
|
||||
requires_rounding_display: YES_NO_TEXT[`${customer?.requires_rounding || ''}`.toLowerCase()] || toDisplayText(customer?.requires_rounding || '')
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!AuthService.canViewCustomers()) {
|
||||
@@ -159,12 +312,11 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
}
|
||||
setShowSpinner(true);
|
||||
CustomerService.getAllCustomers().then((data) => {
|
||||
setCustomers(data.data.map((item) =>{
|
||||
item.phone = item?.phone || item?.home_phone || item?.mobile_phone;
|
||||
item.address = item?.address1 || item?.address2 || item?.address3 || item?.address4|| item?.address5;
|
||||
|
||||
return item;
|
||||
}).sort((a, b) => a.lastname > b.lastname ? 1: -1));
|
||||
setCustomers(
|
||||
data.data
|
||||
.map((item) => formatCustomerRecord(item))
|
||||
.sort((a, b) => a.lastname > b.lastname ? 1 : -1)
|
||||
);
|
||||
}).finally(() => {
|
||||
setShowSpinner(false);
|
||||
});
|
||||
@@ -214,7 +366,7 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
}
|
||||
|
||||
if (programTypeFilter && visibleProgramTypeFilter) {
|
||||
filtered = filtered.filter((item) => (item?.program || '') === programTypeFilter);
|
||||
filtered = filtered.filter((item) => (item?.program_type || item?.program || '') === programTypeFilter);
|
||||
}
|
||||
|
||||
if (paySourceFilter && visiblePaySourceFilter) {
|
||||
@@ -351,6 +503,10 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
setAvatarCustomerName('');
|
||||
}
|
||||
|
||||
const visibleTableColumns = columns.filter((column) => (
|
||||
column.show && (showInactive || !DISCHARGE_ONLY_COLUMN_KEYS.has(column.key))
|
||||
));
|
||||
|
||||
const table = <div className="list row mb-4">
|
||||
<div
|
||||
className="col-md-12"
|
||||
@@ -365,7 +521,7 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
<tr>
|
||||
<th className="th-index">No.</th>
|
||||
{
|
||||
columns.filter(col => col.show).map((column, index) => <th className="sortable-header" key={index}>
|
||||
visibleTableColumns.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>)
|
||||
}
|
||||
@@ -375,49 +531,40 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
{
|
||||
filteredCustomers.map((customer, index) => <tr key={customer.id}>
|
||||
<td className="td-index">{index + 1}</td>
|
||||
{columns.find(col => col.key === 'name')?.show && <td style={{ verticalAlign: 'middle' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
{AuthService.canViewCustomers() && (
|
||||
customerAvatars[customer.id] && customerAvatars[customer.id] !== false ? (
|
||||
<img
|
||||
src={`data:image/png;base64, ${customerAvatars[customer.id]}`}
|
||||
alt={customer?.name}
|
||||
onClick={() => showProfilePicture(customer)}
|
||||
style={{
|
||||
width: '64px',
|
||||
height: '64px',
|
||||
borderRadius: '8px',
|
||||
objectFit: 'cover',
|
||||
cursor: 'pointer',
|
||||
flexShrink: 0
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<PersonSquare
|
||||
onClick={() => showProfilePicture(customer)}
|
||||
size={64}
|
||||
className="clickable"
|
||||
style={{ flexShrink: 0, color: '#ccc' }}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{AuthService.canEditAnyCustomerTab() && <PencilSquare size={16} className="clickable" onClick={() => goToEdit(customer?.id)} style={{ flexShrink: 0 }}></PencilSquare>}
|
||||
<span className="clickable" style={{ color: '#0066B1', textDecoration: 'underline', cursor: 'pointer' }} onClick={() => goToView(customer?.id)}>{customer?.name}</span>
|
||||
</div>
|
||||
</td>}
|
||||
{columns.find(col => col.key === 'chinese_name')?.show && <td>{customer?.name_cn}</td>}
|
||||
{columns.find(col => col.key === 'email')?.show && <td>{customer?.email}</td>}
|
||||
{columns.find(col => col.key === 'type')?.show && <td>{customer?.type}</td>}
|
||||
{columns.find(col => col.key === 'pickup_status')?.show && <td>{customer?.pickup_status}</td>}
|
||||
{columns.find(col => col.key === 'birth_date')?.show && <td>{customer?.birth_date}</td>}
|
||||
{columns.find(col => col.key === 'gender')?.show && <td>{customer?.gender}</td>}
|
||||
{columns.find(col => col.key === 'language')?.show && <td>{customer?.language}</td>}
|
||||
{columns.find(col => col.key === 'medicare_number')?.show && <td>{customer?.medicare_number}</td>}
|
||||
{columns.find(col => col.key === 'medicaid_number')?.show && <td>{customer?.medicaid_number}</td>}
|
||||
{columns.find(col => col.key === 'address')?.show && <td>{customer?.address1 || customer?.address2 || customer?.address3 || customer?.address4 || customer?.address5}</td>}
|
||||
{columns.find(col => col.key === 'phone')?.show && <td>{customer?.phone || customer?.home_phone || customer?.mobile_phone}</td>}
|
||||
{columns.find(col => col.key === 'emergency_contact')?.show && <td>{customer?.emergency_contact}</td>}
|
||||
{columns.find(col => col.key === 'tags')?.show && <td>{customer?.tags?.join(', ')}</td>}
|
||||
{visibleTableColumns.map((column) => (
|
||||
column.key === 'customer_name' ? (
|
||||
<td key={column.key} style={{ verticalAlign: 'middle' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
{AuthService.canViewCustomers() && (
|
||||
customerAvatars[customer.id] && customerAvatars[customer.id] !== false ? (
|
||||
<img
|
||||
src={`data:image/png;base64, ${customerAvatars[customer.id]}`}
|
||||
alt={customer?.name}
|
||||
onClick={() => showProfilePicture(customer)}
|
||||
style={{
|
||||
width: '64px',
|
||||
height: '64px',
|
||||
borderRadius: '8px',
|
||||
objectFit: 'cover',
|
||||
cursor: 'pointer',
|
||||
flexShrink: 0
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<PersonSquare
|
||||
onClick={() => showProfilePicture(customer)}
|
||||
size={64}
|
||||
className="clickable"
|
||||
style={{ flexShrink: 0, color: '#ccc' }}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{AuthService.canEditAnyCustomerTab() && <PencilSquare size={16} className="clickable" onClick={() => goToEdit(customer?.id)} style={{ flexShrink: 0 }}></PencilSquare>}
|
||||
<span className="clickable" style={{ color: '#0066B1', textDecoration: 'underline', cursor: 'pointer' }} onClick={() => goToView(customer?.id)}>{customer?.customer_name}</span>
|
||||
</div>
|
||||
</td>
|
||||
) : <td key={column.key}>{customer?.[column.key] || ''}</td>
|
||||
))}
|
||||
</tr>)
|
||||
}
|
||||
</tbody>
|
||||
@@ -540,7 +687,7 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
<Dropdown.Menu as={customFilterMenu}/>
|
||||
</Dropdown>}
|
||||
<ManageTable
|
||||
columns={isAllCustomersPage ? columns.filter((column) => column.key !== 'pickup_status') : columns}
|
||||
columns={showInactive ? columns : columns.filter((column) => !DISCHARGE_ONLY_COLUMN_KEYS.has(column.key))}
|
||||
onColumnsChange={handleColumnsChange}
|
||||
show={showManageTableDropdown}
|
||||
onToggle={(isOpen) => {
|
||||
@@ -554,6 +701,14 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
{typeof additionalButtons === 'function'
|
||||
? additionalButtons({
|
||||
showExportDropdown,
|
||||
exportColumns: visibleTableColumns,
|
||||
exportData: filteredCustomers.map((customer) => {
|
||||
const exportRecord = {};
|
||||
visibleTableColumns.forEach((column) => {
|
||||
exportRecord[column.key] = customer?.[column.key] || '';
|
||||
});
|
||||
return exportRecord;
|
||||
}),
|
||||
onExportToggle: (isOpen) => {
|
||||
if (isOpen) {
|
||||
setShowFilterDropdown(false);
|
||||
|
||||
@@ -21,11 +21,6 @@ const EventRequestList = () => {
|
||||
label:'Customer Name',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'resource_display',
|
||||
label: 'Doctor',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'source',
|
||||
label: 'Request By',
|
||||
@@ -101,10 +96,26 @@ const EventRequestList = () => {
|
||||
}, [sorting]);
|
||||
|
||||
const filterRequestsFun = (item, statusParam, keywordParam) => {
|
||||
|
||||
return (item?.customer_display?.toLowerCase()?.includes(keywordParam?.toLowerCase()) || item?.source?.toLowerCase()?.includes(keywordParam?.toLowerCase()) ||
|
||||
item?.resource_display?.toLowerCase()?.includes(keywordParam?.toLowerCase())) && item?.status === statusParam
|
||||
|
||||
const normalizedKeyword = `${keywordParam || ''}`.toLowerCase().trim();
|
||||
const statusLabel = getStatusLabel(item?.status || '');
|
||||
const completeBy = item?.edit_history?.[item?.edit_history?.length - 1]?.employee || '';
|
||||
if (!normalizedKeyword) {
|
||||
return item?.status === statusParam;
|
||||
}
|
||||
return (
|
||||
item?.status === statusParam &&
|
||||
(
|
||||
item?.customer_display?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
item?.source?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
item?.type?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
item?.transportation?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
item?.symptom?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
item?.np?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
item?.upload?.toLowerCase()?.includes(normalizedKeyword) ||
|
||||
statusLabel.toLowerCase().includes(normalizedKeyword) ||
|
||||
completeBy.toLowerCase().includes(normalizedKeyword)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const redirectToAdmin = () => {
|
||||
@@ -254,6 +265,16 @@ const EventRequestList = () => {
|
||||
}
|
||||
|
||||
const getStatusLabel = (status) => status === 'active' ? 'In Progress' : (status==='done' ? 'Done' : 'Deleted')
|
||||
const activeTabStatus = showDone ? 'done' : 'active';
|
||||
const filteredEventRequests = eventRequests.filter((item) => filterRequestsFun(item, activeTabStatus, keyword));
|
||||
const exportColumns = showDone ? [...columns, { key: 'complete_by', label: 'Complete By', show: true }] : columns;
|
||||
const exportData = filteredEventRequests.map((eventRequest) => ({
|
||||
...eventRequest,
|
||||
create_date: eventRequest?.create_date ? new Date(eventRequest.create_date).toLocaleDateString() : '',
|
||||
status: getStatusLabel(eventRequest?.status),
|
||||
source: EventRequestsService.sourceList.find((item) => item?.value === eventRequest?.source)?.label || eventRequest?.source,
|
||||
complete_by: eventRequest?.edit_history && eventRequest?.edit_history[eventRequest?.edit_history?.length - 1]?.employee || ''
|
||||
}));
|
||||
|
||||
const table = (statusParam, keywordParam) => <div className="list row mb-4">
|
||||
<div className="col-md-12">
|
||||
@@ -267,7 +288,7 @@ const EventRequestList = () => {
|
||||
{column.label} <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span>
|
||||
</th>)
|
||||
}
|
||||
<th>Completed By</th>
|
||||
{statusParam === 'done' && <th>Complete By</th>}
|
||||
<th>Comments</th>
|
||||
<th>Comment on the record</th>
|
||||
<th></th>
|
||||
@@ -280,7 +301,6 @@ const EventRequestList = () => {
|
||||
<td className="td-checkbox"><input type="checkbox" checked={selectedItems.includes(eventRequest?.id)} onClick={()=>toggleItem(eventRequest?.id)}/></td>
|
||||
<td className="td-index">{index + 1}</td>
|
||||
{columns.find(col => col.key === 'customer_display')?.show && <td>{eventRequest?.customer_display}</td>}
|
||||
{columns.find(col => col.key === 'resource_display')?.show && <td>{eventRequest?.resource_display}</td>}
|
||||
{columns.find(col => col.key === 'source')?.show && <td>{EventRequestsService.sourceList.find((item) => item?.value === eventRequest?.source)?.label || eventRequest?.source}</td>}
|
||||
{columns.find(col => col.key === 'type')?.show && <td>{eventRequest?.type}</td>}
|
||||
{columns.find(col => col.key === 'transportation')?.show && <td>{eventRequest?.transportation || '-'}</td>}
|
||||
@@ -289,7 +309,7 @@ const EventRequestList = () => {
|
||||
{columns.find(col => col.key === 'upload')?.show && <td>{eventRequest?.upload}</td>}
|
||||
{columns.find(col => col.key === 'status')?.show && <td>{getStatusLabel(eventRequest?.status)}</td>}
|
||||
{columns.find(col => col.key === 'create_date')?.show && <td>{new Date(eventRequest?.create_date).toLocaleDateString()}</td>}
|
||||
<td>{ eventRequest.status === 'done' && eventRequest?.edit_history && eventRequest?.edit_history[eventRequest?.edit_history?.length - 1]?.employee || ''}</td>
|
||||
{statusParam === 'done' && <td>{eventRequest?.edit_history && eventRequest?.edit_history[eventRequest?.edit_history?.length - 1]?.employee || ''}</td>}
|
||||
<td>{eventRequest?.notes?.map((note) => {
|
||||
return <p>{`${note?.author}: ${note?.content}`}</p>
|
||||
})}</td>
|
||||
@@ -340,8 +360,8 @@ const EventRequestList = () => {
|
||||
<ManageTable columns={columns} onColumnsChange={setColumns} />
|
||||
{AuthService.canEditAppointmentRequests() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Appointment Request</button>}
|
||||
<Export
|
||||
columns={columns}
|
||||
data={eventRequests.filter((item) => filterRequestsFun(item, showDone ? 'done': 'active', keyword))}
|
||||
columns={exportColumns}
|
||||
data={exportData}
|
||||
filename="event-requests"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -485,6 +485,14 @@ const EventsList = () => {
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
const exportColumns = columns.filter((column) => column.show);
|
||||
const exportData = events
|
||||
.filter(event => event.status === (showDeletedItems ? 'inactive' : 'active'))
|
||||
.map((event) => ({
|
||||
...event,
|
||||
customer: `${event?.customer || ''}${event?.chinese_name ? ` (${event.chinese_name})` : ''}`
|
||||
}));
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -531,8 +539,8 @@ const EventsList = () => {
|
||||
{AuthService.canEditMedicalEvents() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Medical Appointment</button>}
|
||||
{AuthService.canEditDriverAssignment() && (
|
||||
<Export
|
||||
columns={columns}
|
||||
data={events.filter(event => event.status === (showDeletedItems ? 'inactive' : 'active'))}
|
||||
columns={exportColumns}
|
||||
data={exportData}
|
||||
filename="events"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -6,6 +6,7 @@ import Select from 'react-select';
|
||||
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab, Button, Modal, DropdownButton, Dropdown } from "react-bootstrap";
|
||||
import { Columns, Download, Filter, PencilSquare, PersonSquare, Plus } from "react-bootstrap-icons";
|
||||
import { ManageTable, Export } from "../../shared/components";
|
||||
import { CUSTOMER_TYPE_TEXT, PROGRAM_TYPE_TEXT, PAY_SOURCE_TEXT } from "../../shared/constants/customer.constant";
|
||||
|
||||
|
||||
const EventsMultipleList = () => {
|
||||
@@ -24,72 +25,138 @@ const EventsMultipleList = () => {
|
||||
const [showFilterDropdown, setShowFilterDropdown] = useState(false);
|
||||
const [columns, setColumns] = useState([
|
||||
{
|
||||
key: 'customer',
|
||||
label:'Customer',
|
||||
key: 'customer_name',
|
||||
label:'Customer Name (Full Name + Preferred Name)',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'chinese_name',
|
||||
label: 'Preferred Name',
|
||||
key: 'customer_type',
|
||||
label: 'Customer Type',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'member_type',
|
||||
label: 'Member Type',
|
||||
key: 'program_type',
|
||||
label: 'Program Type',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'eyes_on',
|
||||
label: 'Eyes-on',
|
||||
key: 'pay_source',
|
||||
label: 'Pay Source',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'doctor',
|
||||
label: 'Doctor',
|
||||
key: 'dob',
|
||||
label: 'Date Of Birth',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'phone',
|
||||
label: 'Phone',
|
||||
key: 'language_support',
|
||||
label: 'Language Support',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'address',
|
||||
label: 'Address',
|
||||
key: 'transportation_support',
|
||||
label: 'Transportation Support',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'translation',
|
||||
label: 'Translation',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'newPatient',
|
||||
label: 'New Patient',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'needId',
|
||||
label: 'Need ID',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'startTime',
|
||||
label: 'Start Time',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'transportation',
|
||||
key: 'driver',
|
||||
label: 'Driver',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'fasting',
|
||||
label: 'Fasting',
|
||||
key: 'appointment_time',
|
||||
label: 'Appointment Time',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'eyes_on',
|
||||
label: 'Eyes-On',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'new_patient',
|
||||
label: 'New Patient',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'doctor_order',
|
||||
label: "Doctor's Order",
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'fasting_required',
|
||||
label: 'Fasting Required',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'id_needed',
|
||||
label: 'ID Needed',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'need_medication_list',
|
||||
label: 'Need Medication List',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'provider',
|
||||
label: 'Provider',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'provider_phone_number',
|
||||
label: 'Provider Phone Number',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'provider_address',
|
||||
label: 'Provider Address',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'notes',
|
||||
label: 'Notes',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'reason',
|
||||
label: 'Reason',
|
||||
show: true
|
||||
},
|
||||
{
|
||||
key: 'requirement',
|
||||
label: 'Requirement',
|
||||
show: true
|
||||
}
|
||||
]);
|
||||
|
||||
const toDisplayText = (value) => {
|
||||
if (value === undefined || value === null) return '';
|
||||
const normalized = `${value}`.trim();
|
||||
if (!normalized) return '';
|
||||
const lowered = normalized.toLowerCase();
|
||||
if (lowered === 'yes') return 'Yes';
|
||||
if (lowered === 'no') return 'No';
|
||||
return normalized;
|
||||
};
|
||||
|
||||
const getOptionLabel = (options = [], value = '') => {
|
||||
const normalizedValue = `${value || ''}`.trim().toLowerCase();
|
||||
const option = options.find((item) => `${item?.value || ''}`.trim().toLowerCase() === normalizedValue);
|
||||
return option?.label || `${value || ''}`;
|
||||
};
|
||||
|
||||
const getCustomerPaySource = (customer) => {
|
||||
if (!customer) return '';
|
||||
const paySource = customer?.pay_source || '';
|
||||
const paySourceLabel = PAY_SOURCE_TEXT[paySource] || paySource;
|
||||
if (paySource === 'other' && customer?.pay_source_other) {
|
||||
return `${paySourceLabel} (${customer.pay_source_other})`;
|
||||
}
|
||||
return paySourceLabel;
|
||||
};
|
||||
|
||||
const checkDisability = (customers, event) => {
|
||||
const currentCustomer = customers?.find(c => c?.id === event?.data?.customer || c?.name === event?.data?.client_name || c?.name === event?.target_name);
|
||||
return currentCustomer?.disability || event?.data?.disability?.toLowerCase() === 'yes' || false;
|
||||
@@ -113,6 +180,31 @@ const EventsMultipleList = () => {
|
||||
if (fromDate && toDate && customers?.length > 0 && resources?.length > 0) {
|
||||
EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => {
|
||||
setEvents(data.data.filter((item) => {
|
||||
const currentCustomer = customers.find(c => c.id === item?.data?.customer) || customers?.find(c => c?.name === item?.data?.client_name || c?.name === item?.target_name);
|
||||
const currentResource = resources.find(r => r.id === item?.data?.resource);
|
||||
const customerName = item?.data?.customer ? (currentCustomer?.name || item?.data?.client_name || '') : (item?.data?.client_name || '');
|
||||
const preferredName = item?.data?.customer ? (currentCustomer?.name_cn || '') : (currentCustomer?.name_cn || '');
|
||||
item.customer_name = preferredName ? `${customerName} (${preferredName})` : customerName;
|
||||
item.customer_type = CUSTOMER_TYPE_TEXT[currentCustomer?.type] || currentCustomer?.type || '';
|
||||
item.program_type = PROGRAM_TYPE_TEXT[currentCustomer?.program_type] || currentCustomer?.program_type || '';
|
||||
item.pay_source = getCustomerPaySource(currentCustomer);
|
||||
item.dob = item?.data?.customer ? (currentCustomer?.birth_date || '') : (item?.data?.client_birth_date || '');
|
||||
item.language_support = getOptionLabel(EventsService.interpreterLevelOptions, item?.data?.interpreter || '');
|
||||
item.transportation_support = getOptionLabel(EventsService.transportationTypeOptions, item?.data?.trans_method || '');
|
||||
item.driver = item?.link_event_name || '';
|
||||
item.appointment_time = item?.start_time? `${EventsService.formatDate(new Date(item?.start_time))} ${new Date(item?.start_time).toLocaleTimeString('en-US', { hour: '2-digit', minute: 'numeric', hour12: true })}` : '' ;
|
||||
item.eyes_on = checkDisability(customers, item) ? 'Yes' : 'No';
|
||||
item.new_patient = toDisplayText(item?.data?.new_patient || '');
|
||||
item.doctor_order = toDisplayText(item?.data?.doc_order || '');
|
||||
item.fasting_required = item?.data?.fasting || '';
|
||||
item.id_needed = toDisplayText(item?.data?.need_id || '');
|
||||
item.need_medication_list = toDisplayText(item?.data?.need_med_list || '');
|
||||
item.provider = item?.data?.resource ? (currentResource?.name || item?.data?.resource_name || '') : (item?.data?.resource_name || '');
|
||||
item.provider_phone_number = item?.data?.resource ? (currentResource?.phone || item?.data?.resource_phone || '') : (item?.data?.resource_phone || '');
|
||||
item.provider_address = item?.data?.resource ? (currentResource?.address || item?.data?.resource_address || '') : (item?.data?.resource_address || '');
|
||||
item.notes = item?.data?.notes || '';
|
||||
item.reason = item?.data?.reason || '';
|
||||
item.requirement = item?.data?.other || '';
|
||||
item.customer = (item?.data?.customer ? (customers.find(c=>c.id === item?.data?.customer)?.name || item?.data?.client_name || '') : (item?.data?.client_name || ''));
|
||||
item.doctor = item?.data?.resource ? (resources.find(r=> r.id === item?.data?.resource)?.name || item?.data?.resource_name || '') : (item?.data?.resource_name || '');
|
||||
item.phone = item?.data?.resource ? (resources.find(r=> r.id === item?.data?.resource)?.phone || item?.data?.resource_phone || '') : (item?.data?.resource_phone || '');
|
||||
@@ -139,8 +231,8 @@ const EventsMultipleList = () => {
|
||||
useEffect(() => {
|
||||
setFilteredEvents(events?.filter((event) => {
|
||||
if (selectedResource && selectedResource.label !== '' && selectedResource.value !== '') {
|
||||
if (selectedResource?.label?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', '').includes(event.doctor?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', ''))
|
||||
|| event.doctor?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', '').includes(selectedResource?.label?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', ''))) {
|
||||
if (selectedResource?.label?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', '').includes(event.provider?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', ''))
|
||||
|| event.provider?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', '').includes(selectedResource?.label?.replaceAll(' ', '').replaceAll('*', '').replaceAll('*', ''))) {
|
||||
return event;
|
||||
}
|
||||
} else {
|
||||
@@ -148,7 +240,7 @@ const EventsMultipleList = () => {
|
||||
}
|
||||
}).filter((event => {
|
||||
if (selectedCustomer && selectedCustomer !== '' && selectedCustomer.value !== '') {
|
||||
if (selectedCustomer?.label?.replaceAll(' ', '').replaceAll('(Eyes-on)', '').replaceAll('(discharged)', '').replaceAll('*', '').replaceAll('*', '') === (event.customer?.replaceAll(' ', '').replaceAll('(discharged)', '').replaceAll('(Eyes-on)', '').replaceAll('*', '').replaceAll('*', ''))) {
|
||||
if ((event.customer_name || '').toLowerCase().includes((selectedCustomer?.label || '').toLowerCase())) {
|
||||
return event;
|
||||
}
|
||||
} else {
|
||||
@@ -174,6 +266,31 @@ const EventsMultipleList = () => {
|
||||
EventsService.updateEvent(id, {confirmed: true}).then(() => {
|
||||
EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => {
|
||||
setEvents(data.data.filter((item) => {
|
||||
const currentCustomer = customers.find(c => c.id === item?.data?.customer) || customers?.find(c => c?.name === item?.data?.client_name || c?.name === item?.target_name);
|
||||
const currentResource = resources.find(r => r.id === item?.data?.resource);
|
||||
const customerName = item?.data?.customer ? (currentCustomer?.name || item?.data?.client_name || '') : (item?.data?.client_name || '');
|
||||
const preferredName = item?.data?.customer ? (currentCustomer?.name_cn || '') : (currentCustomer?.name_cn || '');
|
||||
item.customer_name = preferredName ? `${customerName} (${preferredName})` : customerName;
|
||||
item.customer_type = CUSTOMER_TYPE_TEXT[currentCustomer?.type] || currentCustomer?.type || '';
|
||||
item.program_type = PROGRAM_TYPE_TEXT[currentCustomer?.program_type] || currentCustomer?.program_type || '';
|
||||
item.pay_source = getCustomerPaySource(currentCustomer);
|
||||
item.dob = item?.data?.customer ? (currentCustomer?.birth_date || '') : (item?.data?.client_birth_date || '');
|
||||
item.language_support = getOptionLabel(EventsService.interpreterLevelOptions, item?.data?.interpreter || '');
|
||||
item.transportation_support = getOptionLabel(EventsService.transportationTypeOptions, item?.data?.trans_method || '');
|
||||
item.driver = item?.link_event_name || '';
|
||||
item.appointment_time = item?.start_time? `${EventsService.formatDate(new Date(item?.start_time))} ${new Date(item?.start_time).toLocaleTimeString('en-US', { hour: '2-digit', minute: 'numeric', hour12: true })}` : '' ;
|
||||
item.eyes_on = checkDisability(customers, item) ? 'Yes' : 'No';
|
||||
item.new_patient = toDisplayText(item?.data?.new_patient || '');
|
||||
item.doctor_order = toDisplayText(item?.data?.doc_order || '');
|
||||
item.fasting_required = item?.data?.fasting || '';
|
||||
item.id_needed = toDisplayText(item?.data?.need_id || '');
|
||||
item.need_medication_list = toDisplayText(item?.data?.need_med_list || '');
|
||||
item.provider = item?.data?.resource ? (currentResource?.name || item?.data?.resource_name || '') : (item?.data?.resource_name || '');
|
||||
item.provider_phone_number = item?.data?.resource ? (currentResource?.phone || item?.data?.resource_phone || '') : (item?.data?.resource_phone || '');
|
||||
item.provider_address = item?.data?.resource ? (currentResource?.address || item?.data?.resource_address || '') : (item?.data?.resource_address || '');
|
||||
item.notes = item?.data?.notes || '';
|
||||
item.reason = item?.data?.reason || '';
|
||||
item.requirement = item?.data?.other || '';
|
||||
item.customer = (item?.data?.customer ? (customers.find(c=>c.id === item?.data?.customer)?.name || item?.data?.client_name || '') : (item?.data?.client_name || ''));
|
||||
item.doctor = item?.data?.resource ? (resources.find(r=> r.id === item?.data?.resource)?.name || item?.data?.resource_name || '') : (item?.data?.resource_name || '');
|
||||
item.phone = item?.data?.resource ? (resources.find(r=> r.id === item?.data?.resource)?.phone || item?.data?.resource_phone || '') : (item?.data?.resource_phone || '');
|
||||
@@ -314,8 +431,6 @@ const EventsMultipleList = () => {
|
||||
{column.label} <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span>
|
||||
</th>)
|
||||
}
|
||||
<th>Customer Date of Birth</th>
|
||||
<th>Transportation</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
@@ -325,21 +440,27 @@ const EventsMultipleList = () => {
|
||||
filteredEvents && filteredEvents.filter(event => event.status === statusParam).map((medicalEvent, index) => <tr key={medicalEvent.id}>
|
||||
<td className="td-checkbox"><input type="checkbox" checked={selectedItems.includes(medicalEvent.id)} onClick={()=>toggleItem(medicalEvent?.id)}/></td>
|
||||
<td className="td-index">{index + 1}</td>
|
||||
{columns.find(col => col.key === 'customer')?.show && <td>{medicalEvent?.customer}</td>}
|
||||
{columns.find(col => col.key === 'chinese_name')?.show && <td>{medicalEvent?.chinese_name}</td>}
|
||||
{columns.find(col => col.key === 'member_type')?.show && <td>{medicalEvent?.member_type}</td>}
|
||||
{columns.find(col => col.key === 'customer_name')?.show && <td>{medicalEvent?.customer_name}</td>}
|
||||
{columns.find(col => col.key === 'customer_type')?.show && <td>{medicalEvent?.customer_type}</td>}
|
||||
{columns.find(col => col.key === 'program_type')?.show && <td>{medicalEvent?.program_type}</td>}
|
||||
{columns.find(col => col.key === 'pay_source')?.show && <td>{medicalEvent?.pay_source}</td>}
|
||||
{columns.find(col => col.key === 'dob')?.show && <td>{medicalEvent?.dob}</td>}
|
||||
{columns.find(col => col.key === 'language_support')?.show && <td>{medicalEvent?.language_support}</td>}
|
||||
{columns.find(col => col.key === 'transportation_support')?.show && <td>{medicalEvent?.transportation_support}</td>}
|
||||
{columns.find(col => col.key === 'driver')?.show && <td>{medicalEvent?.driver}</td>}
|
||||
{columns.find(col => col.key === 'appointment_time')?.show && <td>{medicalEvent?.appointment_time}</td>}
|
||||
{columns.find(col => col.key === 'eyes_on')?.show && <td>{medicalEvent?.eyes_on}</td>}
|
||||
{columns.find(col => col.key === 'doctor')?.show && <td>{medicalEvent?.doctor}</td>}
|
||||
{columns.find(col => col.key === 'phone')?.show && <td>{medicalEvent?.phone}</td>}
|
||||
{columns.find(col => col.key === 'address')?.show && <td>{medicalEvent?.address}</td>}
|
||||
{columns.find(col => col.key === 'translation')?.show && <td>{medicalEvent?.translation}</td>}
|
||||
{columns.find(col => col.key === 'newPatient')?.show && <td>{medicalEvent?.newPatient}</td>}
|
||||
{columns.find(col => col.key === 'needId')?.show && <td>{medicalEvent?.needId}</td>}
|
||||
{columns.find(col => col.key === 'startTime')?.show && <td>{medicalEvent?.startTime}</td>}
|
||||
{columns.find(col => col.key === 'transportation')?.show && <td>{medicalEvent?.transportation}</td>}
|
||||
{columns.find(col => col.key === 'fasting')?.show && <td>{medicalEvent?.fasting}</td>}
|
||||
<td>{medicalEvent?.dob}</td>
|
||||
<td>{medicalEvent?.transMethod}</td>
|
||||
{columns.find(col => col.key === 'new_patient')?.show && <td>{medicalEvent?.new_patient}</td>}
|
||||
{columns.find(col => col.key === 'doctor_order')?.show && <td>{medicalEvent?.doctor_order}</td>}
|
||||
{columns.find(col => col.key === 'fasting_required')?.show && <td>{medicalEvent?.fasting_required}</td>}
|
||||
{columns.find(col => col.key === 'id_needed')?.show && <td>{medicalEvent?.id_needed}</td>}
|
||||
{columns.find(col => col.key === 'need_medication_list')?.show && <td>{medicalEvent?.need_medication_list}</td>}
|
||||
{columns.find(col => col.key === 'provider')?.show && <td>{medicalEvent?.provider}</td>}
|
||||
{columns.find(col => col.key === 'provider_phone_number')?.show && <td>{medicalEvent?.provider_phone_number}</td>}
|
||||
{columns.find(col => col.key === 'provider_address')?.show && <td>{medicalEvent?.provider_address}</td>}
|
||||
{columns.find(col => col.key === 'notes')?.show && <td>{medicalEvent?.notes}</td>}
|
||||
{columns.find(col => col.key === 'reason')?.show && <td>{medicalEvent?.reason}</td>}
|
||||
{columns.find(col => col.key === 'requirement')?.show && <td>{medicalEvent?.requirement}</td>}
|
||||
<td>{medicalEvent?.confirmed ? 'Confirmed' : (AuthService.canEditMedicalEvents() ? <button className="btn btn-primary btn-sm me-2 ms-2" onClick={() => confirmEvent(medicalEvent?.id)}>Confirm</button> : 'Pending')}</td>
|
||||
</tr>)
|
||||
}
|
||||
@@ -358,6 +479,17 @@ const EventsMultipleList = () => {
|
||||
setShowFilterDropdown(false);
|
||||
}
|
||||
|
||||
const exportColumns = columns.filter((column) => column.show);
|
||||
const exportData = filteredEvents
|
||||
.filter(event => event.status === (showDeletedItems ? 'inactive' : 'active'))
|
||||
.map((event) => {
|
||||
const row = {};
|
||||
exportColumns.forEach((column) => {
|
||||
row[column.key] = event?.[column.key] || '';
|
||||
});
|
||||
return row;
|
||||
});
|
||||
|
||||
|
||||
const customMenu = React.forwardRef(
|
||||
({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
|
||||
@@ -415,7 +547,7 @@ const EventsMultipleList = () => {
|
||||
</div>
|
||||
<div className="app-main-content-fields-section margin-sm">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Resource</div>
|
||||
<div className="field-label">Provider</div>
|
||||
<Select styles={{
|
||||
control: (baseStyles, state) => ({
|
||||
...baseStyles,
|
||||
@@ -534,8 +666,8 @@ const EventsMultipleList = () => {
|
||||
<ManageTable columns={columns} onColumnsChange={setColumns} />
|
||||
{AuthService.canEditMedicalEvents() && <button className="btn btn-primary me-2" onClick={() => goToCreateNew()}><Plus size={16}></Plus>Add New Medical Appointment</button>}
|
||||
<Export
|
||||
columns={columns}
|
||||
data={filteredEvents.filter(event => event.status === (showDeletedItems ? 'inactive' : 'active'))}
|
||||
columns={exportColumns}
|
||||
data={exportData}
|
||||
filename="events-multiple"
|
||||
customActions={[
|
||||
{ label: 'Medical Notifications Doc', onClick: generateMedicalNotificationDocs },
|
||||
|
||||
Reference in New Issue
Block a user