fix
This commit is contained in:
BIN
app/.DS_Store
vendored
BIN
app/.DS_Store
vendored
Binary file not shown.
@@ -4,35 +4,43 @@ const path = require("path");
|
||||
|
||||
const BASE_UPLOAD_DIR = `/www/wwwroot/upload/`;
|
||||
|
||||
// try {
|
||||
// if (!fs.existsSync(BASE_UPLOAD_DIR)) {
|
||||
// fs.mkdirSync(BASE_UPLOAD_DIR, {recursive: true});
|
||||
// console.log (`Created upload directory: ${BASE_UPLOAD_DIR}`);
|
||||
// }
|
||||
// } catch(err) {
|
||||
// console.error(`Error creating directory ${BASE_UPLOAD_DIR}`)
|
||||
// }
|
||||
try {
|
||||
if (!fs.existsSync(BASE_UPLOAD_DIR)) {
|
||||
fs.mkdirSync(BASE_UPLOAD_DIR, {recursive: true});
|
||||
console.log (`Created upload directory: ${BASE_UPLOAD_DIR}`);
|
||||
}
|
||||
} catch(err) {
|
||||
console.error(`Error creating base upload directory ${BASE_UPLOAD_DIR}:`, err.message);
|
||||
}
|
||||
|
||||
|
||||
const storage = multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
const { objectId, fileType, name, model } = req.query;
|
||||
if (!objectId || !name || !fileType || !model) {
|
||||
return res.status(400).send({message: 'Required fields missed'});
|
||||
try {
|
||||
const { objectId, fileType, name, model } = req.query;
|
||||
if (!objectId || !name || !fileType || !model) {
|
||||
return cb(new Error('Required fields missed'));
|
||||
}
|
||||
const uploadDir = `${BASE_UPLOAD_DIR}${model}/${objectId}/${fileType}/`;
|
||||
if (!fs.existsSync(uploadDir)) {
|
||||
fs.mkdirSync(uploadDir, {recursive: true});
|
||||
console.log (`Created upload directory: ${uploadDir}/`);
|
||||
}
|
||||
cb(null, uploadDir);
|
||||
} catch (err) {
|
||||
console.error('Error in upload destination:', err);
|
||||
cb(err);
|
||||
}
|
||||
const uploadDir = `${BASE_UPLOAD_DIR}${model}/${objectId}/${fileType}/`;
|
||||
if (!fs.existsSync(uploadDir)) {
|
||||
fs.mkdirSync(uploadDir, {recursive: true});
|
||||
console.log (`Created upload directory: ${uploadDir}/`);
|
||||
}
|
||||
cb(null, uploadDir);
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const { objectId, fileType, name, date} = req.query;
|
||||
const uniqueSuffix = date || Date.now();
|
||||
const payload = req.body;
|
||||
console.log('is the payload', payload);
|
||||
cb(null, `${name.replaceAll(' ', '_')}_${objectId}_${fileType}_${uniqueSuffix}${path.extname(file.originalname)}`)
|
||||
try {
|
||||
const { objectId, fileType, name, date} = req.query;
|
||||
const uniqueSuffix = date || Date.now();
|
||||
cb(null, `${(name || '').replaceAll(' ', '_')}_${objectId}_${fileType}_${uniqueSuffix}${path.extname(file.originalname)}`)
|
||||
} catch (err) {
|
||||
console.error('Error in upload filename:', err);
|
||||
cb(err);
|
||||
}
|
||||
}
|
||||
})
|
||||
const uploadPhysicalFile = multer({
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
const {uploadPhysicalFile} = require("../middlewares");
|
||||
|
||||
const handleUploadMiddleware = (req, res, next) => {
|
||||
uploadPhysicalFile(req, res, (err) => {
|
||||
if (err) {
|
||||
console.error('Multer upload error:', err);
|
||||
return res.status(500).send({ message: `Upload error: ${err.message}` });
|
||||
}
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = app => {
|
||||
const upload = require("../controllers/upload.controller.js");
|
||||
var router = require("express").Router();
|
||||
router.get("/:name", upload.getFile);
|
||||
router.post("/upload/:filename", upload.uploadFiles);
|
||||
router.post("/upload-physical", [uploadPhysicalFile], upload.uploadPhysicalFile);
|
||||
router.post("/upload-physical", handleUploadMiddleware, upload.uploadPhysicalFile);
|
||||
router.post("/delete", upload.deleteFile);
|
||||
router.get("/uploadedDocs/:model/:objectId/type/:fileType/name/:name", upload.getFilesByType);
|
||||
app.use('/api/files', router);
|
||||
|
||||
BIN
app/views/.DS_Store
vendored
BIN
app/views/.DS_Store
vendored
Binary file not shown.
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.3078ab9c.css",
|
||||
"main.js": "/static/js/main.d4629ce4.js",
|
||||
"main.js": "/static/js/main.3a673056.js",
|
||||
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
||||
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
||||
"index.html": "/index.html",
|
||||
"main.3078ab9c.css.map": "/static/css/main.3078ab9c.css.map",
|
||||
"main.d4629ce4.js.map": "/static/js/main.d4629ce4.js.map",
|
||||
"main.3a673056.js.map": "/static/js/main.3a673056.js.map",
|
||||
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.3078ab9c.css",
|
||||
"static/js/main.d4629ce4.js"
|
||||
"static/js/main.3a673056.js"
|
||||
]
|
||||
}
|
||||
@@ -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="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.d4629ce4.js"></script><link href="/static/css/main.3078ab9c.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="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.3a673056.js"></script><link href="/static/css/main.3078ab9c.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
client/.DS_Store
vendored
BIN
client/.DS_Store
vendored
Binary file not shown.
@@ -439,16 +439,16 @@ const CreateCustomer = () => {
|
||||
edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name || '',
|
||||
status: 'active',
|
||||
|
||||
// Form Submission flags
|
||||
hipaa_authorization_form: !!hipaaAuthorizationForm,
|
||||
medication_management_consent_form: !!medicationManagementConsentForm,
|
||||
freedom_of_choice_form: !!freedomOfChoiceForm,
|
||||
meal_benefit_application_form: !!mealBenefitApplicationForm,
|
||||
photo_video_release_form: !!photoVideoReleaseForm,
|
||||
security_deposit_agreement_form: !!securityDepositAgreementForm,
|
||||
recreational_program_contract_form: !!recreationalProgramContractForm,
|
||||
tb_form: !!tbForm,
|
||||
pre_screening_form: !!preScreeningForm,
|
||||
// Form Submission flags — only include when a file was selected
|
||||
...(hipaaAuthorizationForm ? { hipaa_authorization_form: 'true' } : {}),
|
||||
...(medicationManagementConsentForm ? { medication_management_consent_form: 'true' } : {}),
|
||||
...(freedomOfChoiceForm ? { freedom_of_choice_form: 'true' } : {}),
|
||||
...(mealBenefitApplicationForm ? { meal_benefit_application_form: 'true' } : {}),
|
||||
...(photoVideoReleaseForm ? { photo_video_release_form: 'true' } : {}),
|
||||
...(securityDepositAgreementForm ? { security_deposit_agreement_form: 'true' } : {}),
|
||||
...(recreationalProgramContractForm ? { recreational_program_contract_form: 'true' } : {}),
|
||||
...(tbForm ? { tb_form: 'true' } : {}),
|
||||
...(preScreeningForm ? { pre_screening_form: 'true' } : {}),
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
@@ -157,6 +157,8 @@ const UpdateCustomer = () => {
|
||||
const [selectedFile, setSelectedFile] = useState();
|
||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||
|
||||
const isFormUploaded = (fieldValue) => fieldValue === true || fieldValue === 'true';
|
||||
|
||||
const redirectTo = () => {
|
||||
navigate(`/customers/list`);
|
||||
}
|
||||
@@ -736,16 +738,18 @@ const UpdateCustomer = () => {
|
||||
edit_by: localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name || '',
|
||||
status: 'active',
|
||||
|
||||
// Form Submission flags
|
||||
hipaa_authorization_form: hipaaAuthorizationForm ? true : (currentCustomer?.hipaa_authorization_form || false),
|
||||
medication_management_consent_form: medicationManagementConsentForm ? true : (currentCustomer?.medication_management_consent_form || false),
|
||||
freedom_of_choice_form: freedomOfChoiceForm ? true : (currentCustomer?.freedom_of_choice_form || false),
|
||||
meal_benefit_application_form: mealBenefitApplicationForm ? true : (currentCustomer?.meal_benefit_application_form || false),
|
||||
photo_video_release_form: photoVideoReleaseForm ? true : (currentCustomer?.photo_video_release_form || false),
|
||||
security_deposit_agreement_form: securityDepositAgreementForm ? true : (currentCustomer?.security_deposit_agreement_form || false),
|
||||
recreational_program_contract_form: recreationalProgramContractForm ? true : (currentCustomer?.recreational_program_contract_form || false),
|
||||
tb_form: tbForm ? true : (currentCustomer?.tb_form || false),
|
||||
pre_screening_form: preScreeningForm ? true : (currentCustomer?.pre_screening_form || false),
|
||||
// Form Submission flags — only include when a new file was selected,
|
||||
// so we don't overwrite existing values with boolean false (which becomes
|
||||
// the truthy string "false" in a String schema field).
|
||||
...(hipaaAuthorizationForm ? { hipaa_authorization_form: 'true' } : {}),
|
||||
...(medicationManagementConsentForm ? { medication_management_consent_form: 'true' } : {}),
|
||||
...(freedomOfChoiceForm ? { freedom_of_choice_form: 'true' } : {}),
|
||||
...(mealBenefitApplicationForm ? { meal_benefit_application_form: 'true' } : {}),
|
||||
...(photoVideoReleaseForm ? { photo_video_release_form: 'true' } : {}),
|
||||
...(securityDepositAgreementForm ? { security_deposit_agreement_form: 'true' } : {}),
|
||||
...(recreationalProgramContractForm ? { recreational_program_contract_form: 'true' } : {}),
|
||||
...(tbForm ? { tb_form: 'true' } : {}),
|
||||
...(preScreeningForm ? { pre_screening_form: 'true' } : {}),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1585,27 +1589,27 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section base-line">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Maryland HIPAA Authorization</div>
|
||||
{currentCustomer?.hipaa_authorization_form && !hipaaAuthorizationForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.hipaa_authorization_form) && !hipaaAuthorizationForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.hipaa_authorization_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.hipaa_authorization_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setHipaaAuthorizationForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{hipaaAuthorizationForm?.name}</div>
|
||||
</div>
|
||||
<div className="me-4">
|
||||
<div className="field-label">Medication Management Consent Form</div>
|
||||
{currentCustomer?.medication_management_consent_form && !medicationManagementConsentForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.medication_management_consent_form) && !medicationManagementConsentForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.medication_management_consent_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.medication_management_consent_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setMedicationManagementConsentForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{medicationManagementConsentForm?.name}</div>
|
||||
</div>
|
||||
<div className="me-4">
|
||||
<div className="field-label">Freedom Of Choice (Medicaid only)</div>
|
||||
{currentCustomer?.freedom_of_choice_form && !freedomOfChoiceForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.freedom_of_choice_form) && !freedomOfChoiceForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.freedom_of_choice_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.freedom_of_choice_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setFreedomOfChoiceForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{freedomOfChoiceForm?.name}</div>
|
||||
@@ -1614,27 +1618,27 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section base-line">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Meal Benefit Application</div>
|
||||
{currentCustomer?.meal_benefit_application_form && !mealBenefitApplicationForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.meal_benefit_application_form) && !mealBenefitApplicationForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.meal_benefit_application_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.meal_benefit_application_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setMealBenefitApplicationForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{mealBenefitApplicationForm?.name}</div>
|
||||
</div>
|
||||
<div className="me-4">
|
||||
<div className="field-label">Photo-Video Release Waiver Form</div>
|
||||
{currentCustomer?.photo_video_release_form && !photoVideoReleaseForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.photo_video_release_form) && !photoVideoReleaseForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.photo_video_release_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.photo_video_release_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setPhotoVideoReleaseForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{photoVideoReleaseForm?.name}</div>
|
||||
</div>
|
||||
<div className="me-4">
|
||||
<div className="field-label">Security Deposit Payment Agreement (Self Pay only)</div>
|
||||
{currentCustomer?.security_deposit_agreement_form && !securityDepositAgreementForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.security_deposit_agreement_form) && !securityDepositAgreementForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.security_deposit_agreement_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.security_deposit_agreement_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setSecurityDepositAgreementForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{securityDepositAgreementForm?.name}</div>
|
||||
@@ -1643,9 +1647,9 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section base-line">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Recreational Program Contract (Senior Plus only)</div>
|
||||
{currentCustomer?.recreational_program_contract_form && !recreationalProgramContractForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.recreational_program_contract_form) && !recreationalProgramContractForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.recreational_program_contract_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.recreational_program_contract_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setRecreationalProgramContractForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{recreationalProgramContractForm?.name}</div>
|
||||
@@ -1657,18 +1661,18 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section base-line">
|
||||
<div className="me-4">
|
||||
<div className="field-label">TB Form</div>
|
||||
{currentCustomer?.tb_form && !tbForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.tb_form) && !tbForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.tb_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.tb_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setTbForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{tbForm?.name}</div>
|
||||
</div>
|
||||
<div className="me-4">
|
||||
<div className="field-label">Pre-Screening Form</div>
|
||||
{currentCustomer?.pre_screening_form && !preScreeningForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
{isFormUploaded(currentCustomer?.pre_screening_form) && !preScreeningForm && <div style={{color: '#28a745', fontSize: '12px', marginBottom: '4px'}}><CheckCircleFill size={12} className="me-1"/>Uploaded</div>}
|
||||
<label className="custom-file-upload">
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {currentCustomer?.pre_screening_form ? 'Replace' : 'Upload'}
|
||||
<Upload width={20} color={"#fff"} className="me-2"></Upload> {isFormUploaded(currentCustomer?.pre_screening_form) ? 'Replace' : 'Upload'}
|
||||
<input type="file" onChange={(e) => setPreScreeningForm(e.target.files[0])}/>
|
||||
</label>
|
||||
<div className="file-name">{preScreeningForm?.name}</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, {useState, useEffect} from "react";
|
||||
import { PencilSquare } from "react-bootstrap-icons";
|
||||
import { PencilSquare, Download } from "react-bootstrap-icons";
|
||||
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
||||
import { AuthService, CustomerService } from "../../services";
|
||||
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||
@@ -32,8 +32,11 @@ const ViewCustomer = () => {
|
||||
const [currentCustomer, setCurrentCustomer] = useState(undefined);
|
||||
const [currentAvatar, setCurrentAvatar] = useState(undefined);
|
||||
const [activeTab, setActiveTab] = useState(searchParams.get('tab') || 'personalInfo');
|
||||
const [formFiles, setFormFiles] = useState({});
|
||||
|
||||
|
||||
const isFormUploaded = (fieldValue) => fieldValue === true || fieldValue === 'true';
|
||||
|
||||
const redirectTo = () => {
|
||||
navigate(`/customers/list`)
|
||||
}
|
||||
@@ -68,6 +71,26 @@ const ViewCustomer = () => {
|
||||
CustomerService.getAvatar(currentCustomer?.id).then((data) => {
|
||||
setCurrentAvatar(data.data);
|
||||
})
|
||||
|
||||
const formTypes = [
|
||||
'hipaa_authorization_form', 'medication_management_consent_form', 'freedom_of_choice_form',
|
||||
'meal_benefit_application_form', 'photo_video_release_form', 'security_deposit_agreement_form',
|
||||
'recreational_program_contract_form', 'tb_form', 'pre_screening_form'
|
||||
];
|
||||
const uploadedTypes = formTypes.filter(ft => isFormUploaded(currentCustomer?.[ft]));
|
||||
if (uploadedTypes.length > 0) {
|
||||
Promise.all(
|
||||
uploadedTypes.map(ft =>
|
||||
CustomerService.getCustomerFormFiles(currentCustomer.id, currentCustomer.name || '', ft)
|
||||
.then(res => ({ fileType: ft, files: res.data?.data?.files || [] }))
|
||||
.catch(() => ({ fileType: ft, files: [] }))
|
||||
)
|
||||
).then(results => {
|
||||
const filesMap = {};
|
||||
results.forEach(r => { if (r.files.length > 0) filesMap[r.fileType] = r.files; });
|
||||
setFormFiles(filesMap);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [currentCustomer]);
|
||||
|
||||
@@ -80,6 +103,21 @@ const ViewCustomer = () => {
|
||||
}).join(', ');
|
||||
};
|
||||
|
||||
const renderFormStatus = (fieldValue, fileType) => {
|
||||
if (!isFormUploaded(fieldValue)) return 'Not Uploaded';
|
||||
const files = formFiles[fileType];
|
||||
if (files && files.length > 0) {
|
||||
const latestFile = files[files.length - 1];
|
||||
const downloadUrl = CustomerService.getFileDownloadUrl(latestFile.url);
|
||||
return (
|
||||
<a href={downloadUrl} target="_blank" rel="noopener noreferrer" style={{ color: '#28a745', textDecoration: 'none' }}>
|
||||
<Download size={12} className="me-1"/>Uploaded - Download
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return <span style={{ color: '#28a745' }}>Uploaded</span>;
|
||||
};
|
||||
|
||||
// Helper to format Yes/No values
|
||||
const formatYesNo = (value) => {
|
||||
if (value === 'yes' || value === true) return 'Yes';
|
||||
@@ -663,35 +701,35 @@ const ViewCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="field-body">
|
||||
<div className="field-label">Maryland HIPAA Authorization</div>
|
||||
<div className="field-value">{currentCustomer?.hipaa_authorization_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.hipaa_authorization_form, 'hipaa_authorization_form')}</div>
|
||||
</div>
|
||||
<div className="field-body">
|
||||
<div className="field-label">Medication Management Consent Form</div>
|
||||
<div className="field-value">{currentCustomer?.medication_management_consent_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.medication_management_consent_form, 'medication_management_consent_form')}</div>
|
||||
</div>
|
||||
<div className="field-body">
|
||||
<div className="field-label">Freedom Of Choice</div>
|
||||
<div className="field-value">{currentCustomer?.freedom_of_choice_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.freedom_of_choice_form, 'freedom_of_choice_form')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="field-body">
|
||||
<div className="field-label">Meal Benefit Application</div>
|
||||
<div className="field-value">{currentCustomer?.meal_benefit_application_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.meal_benefit_application_form, 'meal_benefit_application_form')}</div>
|
||||
</div>
|
||||
<div className="field-body">
|
||||
<div className="field-label">Photo-Video Release Waiver Form</div>
|
||||
<div className="field-value">{currentCustomer?.photo_video_release_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.photo_video_release_form, 'photo_video_release_form')}</div>
|
||||
</div>
|
||||
<div className="field-body">
|
||||
<div className="field-label">Security Deposit Payment Agreement</div>
|
||||
<div className="field-value">{currentCustomer?.security_deposit_agreement_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.security_deposit_agreement_form, 'security_deposit_agreement_form')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="field-body">
|
||||
<div className="field-label">Recreational Program Contract</div>
|
||||
<div className="field-value">{currentCustomer?.recreational_program_contract_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.recreational_program_contract_form, 'recreational_program_contract_form')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -700,11 +738,11 @@ const ViewCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="field-body">
|
||||
<div className="field-label">TB Form</div>
|
||||
<div className="field-value">{currentCustomer?.tb_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.tb_form, 'tb_form')}</div>
|
||||
</div>
|
||||
<div className="field-body">
|
||||
<div className="field-label">Pre-Screening Form</div>
|
||||
<div className="field-value">{currentCustomer?.pre_screening_form ? 'Uploaded' : 'Not Uploaded'}</div>
|
||||
<div className="field-value">{renderFormStatus(currentCustomer?.pre_screening_form, 'pre_screening_form')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
|
||||
@@ -363,7 +363,7 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
)
|
||||
)}
|
||||
{AuthService.canAddOrEditCustomers() && <PencilSquare size={16} className="clickable" onClick={() => goToView(customer?.id)} style={{ flexShrink: 0 }}></PencilSquare>}
|
||||
<span>{customer?.name}</span>
|
||||
<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>}
|
||||
|
||||
@@ -76,6 +76,14 @@ const getAllCustomerFiles = (customerId, name, fileType) => {
|
||||
return http.get(`/files/list?objectId=${customerId}&name=${name}&fileType=${fileType}&model=customer`);
|
||||
}
|
||||
|
||||
const getCustomerFormFiles = (customerId, customerName, fileType) => {
|
||||
return http.get(`/files/uploadedDocs/customer/${customerId}/type/${fileType}/name/${encodeURIComponent(customerName)}`);
|
||||
}
|
||||
|
||||
const getFileDownloadUrl = (fileUrl) => {
|
||||
const baseUrl = http.defaults.baseURL || '';
|
||||
return baseUrl.replace('/api', '') + fileUrl;
|
||||
}
|
||||
|
||||
export const CustomerService = {
|
||||
getAllActiveCustomers,
|
||||
@@ -95,5 +103,7 @@ export const CustomerService = {
|
||||
getClientsByNameOrEmail,
|
||||
getClient,
|
||||
uploadCustomerFile,
|
||||
getAllCustomerFiles
|
||||
getAllCustomerFiles,
|
||||
getCustomerFormFiles,
|
||||
getFileDownloadUrl
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user