From 4e68cef2e22f043c8b6bf5fa9c73c3a39f2c8791 Mon Sep 17 00:00:00 2001 From: kelvinsuen Date: Tue, 17 Jun 2025 12:48:10 +0800 Subject: [PATCH 1/2] update client page --- .../client/ClientMaintainPage/ClientForm.js | 938 +++++++++--------- src/pages/client/ClientMaintainPage/index.js | 238 ++--- .../ClientSearchPage/ClientSearchForm.js | 1 - .../client/ClientSearchPage/ClientTable.js | 5 +- src/pages/client/ClientSearchPage/index.js | 4 +- src/utils/CommonFunction.js | 25 +- 6 files changed, 593 insertions(+), 618 deletions(-) diff --git a/src/pages/client/ClientMaintainPage/ClientForm.js b/src/pages/client/ClientMaintainPage/ClientForm.js index 0d83ffb..b2d9177 100644 --- a/src/pages/client/ClientMaintainPage/ClientForm.js +++ b/src/pages/client/ClientMaintainPage/ClientForm.js @@ -25,9 +25,9 @@ import axios from "axios"; import {apiPath} from "../../../auth/utils"; import { CHECK_EVENT_DUPLICATE, //GET_EVENT_NOTIFICATION_OVERTIME, - GET_EVENT_PATH, + GET_CLIENT_PATH, GET_SUB_DIVISION_COMBO_LIST, - POST_EVENT_PATH + POST_CLIENT_PATH } from "../../../utils/ApiPathConst"; import {LIONER_BUTTON_THEME, LIONER_LONG_BUTTON_THEME, GENERAL_RED_COLOR} from "../../../themes/colorConst"; import {eventFrequencyCombo, EVENT_REGION_COMBO, EVENT_TYPE_COMBO} from "../../../utils/ComboConst"; @@ -46,19 +46,8 @@ import {CARD_MAX_WIDTH} from "../../../themes/themeConst"; const ClientForm = ({ refClientDetail, isNewRecord, - refSubDivisionList, getClientDetail, - applicationList, - refReminderInterval, - refReminderBefore, - refReminderLimit, - refReminderLimitMax }) => { - const [overtimeWarning, setOvertimeWarning] = useState(""); - const [reminderInterval, setReminderInterval] = useState(null); - const [reminderBefore, setReminderBefore] = useState(null); - const [reminderLimit, setReminderLimit] = useState(null); - const [reminderLimitMax, setReminderLimitMax] = useState(0); const location = useLocation(); const queryParams = new URLSearchParams(location.search); const refId = queryParams.get("refId"); @@ -69,7 +58,7 @@ const ClientForm = ({ refClientDetail, const ability = useContext(AbilityContext); const [onReady, setOnReady] = useState(false); const [errors, setErrors] = useState({}); - const [eventDetail, setClientDetail] = useState({}); + const [clientDetail, setClientDetail] = useState({}); const [isCollectData, setIsCollectData] = useState(false); const [userConfirm, setUserConfirm] = useState(false); const [isEditing, setIsEditing] = useState(false); @@ -78,40 +67,40 @@ const ClientForm = ({ refClientDetail, //form data const {register, getValues, setValue} = useForm(); - const [eventDate, setClientDate] = useState(null); - const [awardDate, setAwardDate] = useState(null); - const [deadlineDate, setDeadlineDate] = useState(null); - const [announceDate, setAnnounceDate] = useState(null); - const [selectedRegion, setSelectedRegion] = useState(null); - const [selectedType, setSelectedType] = useState(null); - const [selectedSubDivision, setSelectedSubDivision] = useState([]); - const [fromDate, setFromDate] = useState(null); - const [toDate, setToDate] = useState(null); - const [reminderFlag, setReminderFlag] = useState(false); - const [isFlagFetched, setIsFlagFetched] = useState(false); - - //reminder option - const [selectedFrequency, setSelectedFrequency] = useState(null); - const [nextApplicationDate, setNextApplicationDate] = useState(null); - - //combo list - const [subDivisionList, setSubDivisionList] = useState([]); - - const [eventDateError, setClientDateError] = React.useState(null); + const [joinDate, setJoinDate] = useState(null); + // const [awardDate, setAwardDate] = useState(null); + // const [deadlineDate, setDeadlineDate] = useState(null); + // const [announceDate, setAnnounceDate] = useState(null); + // const [selectedRegion, setSelectedRegion] = useState(null); + // const [selectedType, setSelectedType] = useState(null); + // const [selectedSubDivision, setSelectedSubDivision] = useState([]); + // const [fromDate, setFromDate] = useState(null); + // const [toDate, setToDate] = useState(null); + // const [reminderFlag, setReminderFlag] = useState(false); + // const [isFlagFetched, setIsFlagFetched] = useState(false); + + // //reminder option + // const [selectedFrequency, setSelectedFrequency] = useState(null); + // const [nextApplicationDate, setNextApplicationDate] = useState(null); + + // //combo list + // const [subDivisionList, setSubDivisionList] = useState([]); + + const [joinDateError, setJoinDateError] = React.useState(null); const [awardDateError, setAwardDateError] = React.useState(null); const [deadlineDateError, setDeadlineDateError] = React.useState(null); const [announceDateError, setAnnounceDateError] = React.useState(null); const [fromError, setFromError] = React.useState(null); const [toError, setToError] = React.useState(null); - const [nextApplicationDateError, setNextApplicationDateError] = React.useState(null); + // const [nextApplicationDateError, setNextApplicationDateError] = React.useState(null); - const eventDateErrorMessage = React.useMemo(() => { - switch (eventDateError) { + const joinDateErrorMessage = React.useMemo(() => { + switch (joinDateError) { case 'invalidDate': { return "Invalid date"; } } - }, [eventDateError]); + }, [joinDateError]); const awardDateErrorMessage = React.useMemo(() => { switch (awardDateError) { @@ -153,13 +142,13 @@ const ClientForm = ({ refClientDetail, } }, [toError]); - const nextApplicationDateErrorMessage = React.useMemo(() => { - switch (nextApplicationDateError) { - case 'invalidDate': { - return "Invalid date"; - } - } - }, [nextApplicationDateError]); + // const nextApplicationDateErrorMessage = React.useMemo(() => { + // switch (nextApplicationDateError) { + // case 'invalidDate': { + // return "Invalid date"; + // } + // } + // }, [nextApplicationDateError]); // ==============================|| DELETE WINDOW RELATED ||============================== // const [isWindowOpen, setIsWindowOpen] = React.useState(false); @@ -175,257 +164,222 @@ const ClientForm = ({ refClientDetail, navigate(`/event/maintain/-1?refId=${params.id}`); } - useEffect(()=>{ - if(applicationList.length===0){ - validateReminder(); - } - },[eventDate, nextApplicationDate, deadlineDate]); - - const validateReminder = () =>{ - const values = getValues(); - let firstIssueDate = null; - let reminderDates = []; - if (eventDate !== null && - nextApplicationDate !== null && - values.reminderThreshold !== null && - values.reminderInterval !== null && - values.reminderLimit !== null - ) { - //have value - if(applicationList.length <=0){ - firstIssueDate = eventDate.add(-values.reminderThreshold,'days'); - } - else{ - firstIssueDate = nextApplicationDate.add(-values.reminderThreshold, 'days'); - } - - reminderDates.push(firstIssueDate); - for(let i=1; i < parseInt(values.reminderLimit)+1 ; i++){ - reminderDates.push(firstIssueDate.add(i*values.reminderInterval,'days')) - } - - for(let j=0; j < reminderDates.length ; j++){ - if(reminderDates[j]-deadlineDate > 0){ - setOvertimeWarning(`Estimated reminder exceeds the application deadline, the last reminder will be generated on ${reminderDates[j>1?j-1:0].format('DD/MM/YYYY')}.`); - return false; - } - } - - setOvertimeWarning(""); - return true; - } - return true; - } + // useEffect(()=>{ + // if(applicationList.length===0){ + // validateReminder(); + // } + // },[joinDate, nextApplicationDate, deadlineDate]); + + // const validateReminder = () =>{ + // const values = getValues(); + // let firstIssueDate = null; + // let reminderDates = []; + // if (joinDate !== null && + // nextApplicationDate !== null && + // values.reminderThreshold !== null && + // values.reminderInterval !== null && + // values.reminderLimit !== null + // ) { + // //have value + // if(applicationList.length <=0){ + // firstIssueDate = joinDate.add(-values.reminderThreshold,'days'); + // } + // else{ + // firstIssueDate = nextApplicationDate.add(-values.reminderThreshold, 'days'); + // } + + // reminderDates.push(firstIssueDate); + // for(let i=1; i < parseInt(values.reminderLimit)+1 ; i++){ + // reminderDates.push(firstIssueDate.add(i*values.reminderInterval,'days')) + // } + + // for(let j=0; j < reminderDates.length ; j++){ + // if(reminderDates[j]-deadlineDate > 0){ + // setOvertimeWarning(`Estimated reminder exceeds the application deadline, the last reminder will be generated on ${reminderDates[j>1?j-1:0].format('DD/MM/YYYY')}.`); + // return false; + // } + // } + + // // setOvertimeWarning(""); + // return true; + // } + // return true; + // } function updateData(){ - if(applicationList.length >0){ - notifyDeleteError("Delete restricted. Application exist in this event"); - setIsWindowOpen(false); - } - else{ - axios.delete(`${apiPath}${GET_EVENT_PATH}/${params.id}`, - ) - .then((response) => { - if (response.status === 204) { - notifyDeleteSuccess(); - setIsWindowOpen(false); - returnSearchPage(); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } + // if(applicationList.length >0){ + // notifyDeleteError("Delete restricted. Application exist in this event"); + // setIsWindowOpen(false); + // } + // else{ + axios.delete(`${apiPath}${GET_CLIENT_PATH}/${params.id}`, + ) + .then((response) => { + if (response.status === 204) { + notifyDeleteSuccess(); + setIsWindowOpen(false); + returnSearchPage(); + } + }) + .catch(error => { + console.log(error); + return false; + }); + // } } // ==============================|| DELETE WINDOW RELATED ||============================== // - const validateReminderLimit = (value) => { - const maxValue = reminderLimitMax; // Set the maximum value here - if (/^[0-9]\d*$/.test(value) || value === '') { - if (parseInt(value) > maxValue) { - //console.log(value); - setValue("reminderLimit", maxValue) - } - } - else{ - setValue("reminderLimit", ''); - } - }; - - const handleReminderIntervalChange = (event) => { - const inputValue = event.target.value; - if (/^[0-9]\d*$/.test(inputValue) || inputValue === '') { - setValue("reminderInterval", inputValue); - } - else{ - setValue("reminderInterval", ''); - } - }; - - const handleReminderThresholdChange = (event) => { - const inputValue = event.target.value; - if (/^[0-9]\d*$/.test(inputValue) || inputValue === '') { - setValue("reminderThreshold", inputValue); - } - else{ - setValue("reminderThreshold", ''); - } - }; + // const validateReminderLimit = (value) => { + // const maxValue = reminderLimitMax; // Set the maximum value here + // if (/^[0-9]\d*$/.test(value) || value === '') { + // if (parseInt(value) > maxValue) { + // //console.log(value); + // setValue("reminderLimit", maxValue) + // } + // } + // else{ + // setValue("reminderLimit", ''); + // } + // }; + + // const handleReminderIntervalChange = (event) => { + // const inputValue = event.target.value; + // if (/^[0-9]\d*$/.test(inputValue) || inputValue === '') { + // setValue("reminderInterval", inputValue); + // } + // else{ + // setValue("reminderInterval", ''); + // } + // }; + + // const handleReminderThresholdChange = (event) => { + // const inputValue = event.target.value; + // if (/^[0-9]\d*$/.test(inputValue) || inputValue === '') { + // setValue("reminderThreshold", inputValue); + // } + // else{ + // setValue("reminderThreshold", ''); + // } + // }; useEffect(()=>{ - //if combo list ready - if (subDivisionList.length >0) { + if (!isNewRecord) { setRefClient(refClientDetail); } - },[subDivisionList]); - - useEffect(()=>{ - if(!isObjEmpty(refClient)){ - setIsFlagFetched(true); - } - },[reminderFlag,refClient]); - - useEffect(()=>{ - if(isFlagFetched){ - if(!reminderFlag){ - setReminderInterval(null); - setReminderBefore(null); - setReminderLimit(null); - setValue("reminderThreshold",null); - setValue("reminderLimit",null); - setValue("reminderInterval",null); - } - } - },[isFlagFetched, refClient, reminderFlag]); - - useEffect(()=>{ - setReminderLimitMax(refReminderLimitMax); - if(!isObjEmpty(refClient) ) { - if(reminderFlag){ - setReminderInterval(refReminderInterval); - setReminderBefore(refReminderBefore); - setReminderLimit(refReminderLimit); - } - } - },[reminderFlag, refReminderLimit,refReminderInterval,refReminderLimitMax,refReminderBefore,refClient]); + // //if combo list ready + // if (subDivisionList.length >0) { + // } + },[]); + + // useEffect(()=>{ + // if(!isObjEmpty(refClient)){ + // setIsFlagFetched(true); + // } + // },[reminderFlag,refClient]); + + // useEffect(()=>{ + // if(isFlagFetched){ + // if(!reminderFlag){ + // setReminderInterval(null); + // setReminderBefore(null); + // setReminderLimit(null); + // setValue("reminderThreshold",null); + // setValue("reminderLimit",null); + // setValue("reminderInterval",null); + // } + // } + // },[isFlagFetched, refClient, reminderFlag]); + + // useEffect(()=>{ + // setReminderLimitMax(refReminderLimitMax); + // if(!isObjEmpty(refClient) ) { + // if(reminderFlag){ + // setReminderInterval(refReminderInterval); + // setReminderBefore(refReminderBefore); + // setReminderLimit(refReminderLimit); + // } + // } + // },[reminderFlag, refReminderLimit,refReminderInterval,refReminderLimitMax,refReminderBefore,refClient]); useEffect(()=>{ //if ref data ready if (!isObjEmpty(refClient)) { //checkOvertime(); if(refId !== null){ - setValue("name", refClient.name); - setValue("nameCht", refClient.nameCht); - setValue("description", refClient.description); - setValue("organization", refClient.organization); - setValue("series", refClient.series); + setValue("fullname", refClient.fullname); + setValue("lastname", refClient.lastname); + setValue("firstname", refClient.firstname); + setValue("title", refClient.title); + setValue("email", refClient.email); + setValue("phone1", refClient.phone1); + setValue("phone2", refClient.phone2); + setValue("remarks", refClient.remarks); + setValue("caseManagerId", 1); + setValue("consultantId", 1); } - setSelectedSubDivision(getComboValueByIdList(subDivisionList,refSubDivisionList)); - setSelectedRegion(getComboValueByLabel(EVENT_REGION_COMBO, refClient.region)); - setSelectedType(getComboValueByLabel(EVENT_TYPE_COMBO, refClient.eventType)); - setReminderFlag(refClient.reminderFlag); - setSelectedFrequency(getComboValueByLabel(eventFrequencyCombo, refClient.frequency)); - setClientDate(dayjs(getDateString(refClient.startDate))); - setAwardDate( - refClient.awardDate === null ? null : dayjs(getDateString(refClient.awardDate)) - ); - setNextApplicationDate( - refClient.nextApplicationDate === null ? null : dayjs(getDateString(refClient.nextApplicationDate)) - ); - setAnnounceDate( - refClient.announcementDate === null ? null : dayjs(getDateString(refClient.announcementDate)) - ); - setFromDate( - refClient.eventFrom === null ? null : dayjs(getDateString(refClient.eventFrom)) - ); - setToDate( - refClient.eventTo === null ? null : dayjs(getDateString(refClient.eventTo)) - ); - setDeadlineDate(dayjs(getDateString(refClient.applicationDeadline))); + setJoinDate(dayjs(getDateString(refClient.joinDate))); } },[refClient]); useEffect(()=>{ - if( - !isObjEmpty(refClient) && - selectedSubDivision.length > 0 && - !isObjEmpty(selectedRegion) && - !isObjEmpty(selectedType) && - !isObjEmpty(eventDate) && - !isObjEmpty(deadlineDate) - ){ + if(!isObjEmpty(refClient)) { setOnReady(true); } else if(isNewRecord){ setOnReady(true); setIsEditing(true); } - },[refClient,selectedSubDivision,selectedRegion,selectedType, eventDate,deadlineDate]); - - useEffect(()=>{ - if(selectedFrequency !== null){ - if(selectedFrequency.key === 5 && isNewRecord){ - setReminderBefore(0); - setReminderInterval(0); - setReminderLimit(0); - setValue("reminderThreshold",null); - setValue("reminderLimit",null); - setValue("reminderInterval",null); - } - else if (isFirstInit && refId !== null){ - setValue("reminderThreshold",refClient.reminderThreshold); - setValue("reminderLimit",refClient.reminderLimit); - setValue("reminderInterval",refClient.reminderInterval); - setIsFirstInit(false); - } - else if(isNewRecord){ - setValue("reminderThreshold",refReminderBefore); - setValue("reminderLimit",refReminderLimit); - setValue("reminderInterval",refReminderInterval); - setReminderInterval(refReminderInterval); - setReminderBefore(refReminderBefore); - setReminderLimit(refReminderLimit); - } - - if (isEditing){ - if (eventDate !== null){ - switch(selectedFrequency.key){ - case 1: - setNextApplicationDate(eventDate.add(1,'month')); - break; - case 2: - setNextApplicationDate(eventDate.add(3,'month')); - break; - case 3: - setNextApplicationDate(eventDate.add(1,'year')); - break; - case 4: - setNextApplicationDate(eventDate.add(6,'month')); - break; - default: - setNextApplicationDate(nextApplicationDate); - break; - } - } - } - } - },[selectedFrequency,eventDate]); - - useEffect(() => { - //if state data are ready and assign to different field - axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`) - .then((response) => { - if (response.status === 200) { - setSubDivisionList(response.data.records); - } - }) - .catch(error => { - console.log(error); - return false; - }); - }, []); + },[refClient]); + // },[refClient,selectedSubDivision,selectedRegion,selectedType, joinDate, deadlineDate]); + + // useEffect(()=>{ + // if(selectedFrequency !== null){ + // if(selectedFrequency.key === 5 && isNewRecord){ + // } + // else if (isFirstInit && refId !== null){ + // setIsFirstInit(false); + // } + // else if(isNewRecord){ + // } + + // if (isEditing){ + // if (joinDate !== null){ + // switch(selectedFrequency.key){ + // case 1: + // setNextApplicationDate(joinDate.add(1,'month')); + // break; + // case 2: + // setNextApplicationDate(joinDate.add(3,'month')); + // break; + // case 3: + // setNextApplicationDate(joinDate.add(1,'year')); + // break; + // case 4: + // setNextApplicationDate(joinDate.add(6,'month')); + // break; + // default: + // setNextApplicationDate(nextApplicationDate); + // break; + // } + // } + // } + // } + // },[selectedFrequency,joinDate]); + + // useEffect(() => { + // //if state data are ready and assign to different field + // axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`) + // .then((response) => { + // if (response.status === 200) { + // setSubDivisionList(response.data.records); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // }, []); useEffect(() => { //upload latest data to parent @@ -433,126 +387,131 @@ const ClientForm = ({ refClientDetail, const values = getValues(); const formErrors = {}; - if (isStringEmptyAfterTrim(values.name)) { - formErrors.name = 'Client Name is required'; + if (isStringEmptyAfterTrim(values.fullname)) { + formErrors.fullname = 'Client Name is required'; } - if (selectedRegion === null ) { - formErrors.region = 'Client Region is required'; - } + // if (selectedRegion === null ) { + // formErrors.region = 'Client Region is required'; + // } - if (isStringEmptyAfterTrim(values.organization)) { - formErrors.organization = 'Client Organization is required'; - } + // if (isStringEmptyAfterTrim(values.organization)) { + // formErrors.organization = 'Client Organization is required'; + // } - if (selectedType === null) { - formErrors.type = 'Client Type is required'; - } + // if (selectedType === null) { + // formErrors.type = 'Client Type is required'; + // } - if (eventDate === null) { - formErrors.eventDate = 'Client Date is required'; + if (joinDate === null) { + formErrors.joinDate = 'Join Date is required'; } - if (deadlineDate === null) { - formErrors.deadlineDate = 'Deadline Date is required'; - } + // if (deadlineDate === null) { + // formErrors.deadlineDate = 'Deadline Date is required'; + // } - if (awardDate === null) { - formErrors.awardDate = 'Award Date is required'; - } + // if (awardDate === null) { + // formErrors.awardDate = 'Award Date is required'; + // } - if (selectedSubDivision.length <= 0){ - formErrors.subDivision = 'Sub-Division is required'; - } + // if (selectedSubDivision.length <= 0){ + // formErrors.subDivision = 'Sub-Division is required'; + // } - if(reminderFlag){ - if (selectedFrequency === null){ - formErrors.frequency = 'Frequency is required'; - } + // if(reminderFlag){ + // if (selectedFrequency === null){ + // formErrors.frequency = 'Frequency is required'; + // } - if (!values.reminderThreshold){ - formErrors.threshold = 'Threshold is required'; - } + // if (!values.reminderThreshold){ + // formErrors.threshold = 'Threshold is required'; + // } - if (!values.reminderInterval){ - formErrors.interval = 'Interval is required'; - } + // if (!values.reminderInterval){ + // formErrors.interval = 'Interval is required'; + // } - if (!values.reminderLimit){ - formErrors.limit = 'Limit is required'; - } + // if (!values.reminderLimit){ + // formErrors.limit = 'Limit is required'; + // } - if(applicationList.length===0){ - if(!validateReminder()){ - formErrors.calError = "calError"; - } - } + // if(applicationList.length===0){ + // if(!validateReminder()){ + // formErrors.calError = "calError"; + // } + // } - } + // } setErrors(formErrors); - if (Object.keys(formErrors).length === 0 && - !eventDateError && !awardDateError && - !deadlineDateError && !announceDateError && - !fromError && !toError && !nextApplicationDateError - ) { - axios.get(`${apiPath}${CHECK_EVENT_DUPLICATE}`, - { - params: { - "name": values.name.trim(), - "id": params.id, - }, - }) - .then((response) => { - if (response.status === 200) { - const formErrors = {}; - if(response.data.isTaken){ - formErrors.name = 'Client name must be unique.'; - setErrors(formErrors); - setIsCollectData(false); - setUserConfirm(false); - } - else if(!response.data.isTaken){ - if (Object.keys(formErrors).length === 0) { - let data = {}; - data["id"] = isNewRecord ? params.id : refClientDetail.id; - data["description"] = values.description; - data["name"] = values.name; - data["nameCht"] = values.nameCht; - data["organization"] = values.organization; - data["reminderThreshold"] = values.reminderThreshold; - data["reminderInterval"] = values.reminderInterval; - data["reminderLimit"] = values.reminderLimit; - data["series"] = values.series; - data["region"] = selectedRegion === null ? null : selectedRegion.label; - data["eventType"] = selectedType === null ? null : selectedType.label; - data["frequency"] = selectedFrequency === null ? null : selectedFrequency.label; - data["reminderFlag"] = reminderFlag; - data["startDate"] = eventDate === null ? null : dayjs(eventDate).format('YYYY-MM-DD'); - data["eventFrom"] = fromDate === null ? null : dayjs(fromDate).format('YYYY-MM-DD'); - data["eventTo"] = toDate === null ? null : dayjs(toDate).format('YYYY-MM-DD'); - data["applicationDeadline"] = deadlineDate === null ? null : dayjs(deadlineDate).format('YYYY-MM-DD'); - data["nextApplicationDate"] = nextApplicationDate === null ? null : dayjs(nextApplicationDate).format('YYYY-MM-DD'); - data["announcementDate"] = announceDate === null ? null : dayjs(announceDate).format('YYYY-MM-DD'); - data["awardDate"] = awardDate === null ? null : dayjs(awardDate).format('YYYY-MM-DD'); - data["subDivisionIds"] = isNewRecord ? getIdList(selectedSubDivision) : getNewRecordWithRefList(refSubDivisionList, getIdList(selectedSubDivision)); - data["subDivisionRemoveIds"] = isNewRecord ? [] : getDeletedRecordWithRefList(refSubDivisionList, getIdList(selectedSubDivision)); - setClientDetail(data); - } - } - } - }) - .catch(error => { - console.log(error); - return true; - }); + // if (Object.keys(formErrors).length === 0 //&& + // !joinDateError && !awardDateError && + // !deadlineDateError && !announceDateError && + // !fromError && !toError && !nextApplicationDateError + // ) { + // axios.get(`${apiPath}${CHECK_EVENT_DUPLICATE}`, + // { + // params: { + // "fullname": values.fullname.trim(), + // "id": params.id, + // }, + // }) + // .then((response) => { + // if (response.status === 200) { + // const formErrors = {}; + // if(response.data.isTaken){ + // formErrors.fullname = 'Client name must be unique.'; + // setErrors(formErrors); + // setIsCollectData(false); + // setUserConfirm(false); + // } + // else if(!response.data.isTaken){ + // if (Object.keys(formErrors).length === 0) { + // let data = {}; + // data["id"] = isNewRecord ? params.id : refClientDetail.id; + // data["fullname"] = values.fullname; + // data["lastname"] = values.lastname; + // data["firstname"] = values.firstname; + // data["title"] = values.title; + // data["email"] = values.email; + // data["phone1"] = values.phone1; + // data["phone2"] = values.phone2; + // data["remarks"] = values.remarks; + // data["joinDate"] = joinDate === null ? null : dayjs(joinDate).format('YYYY-MM-DD'); + // setClientDetail(data); + // } + // } + // } + // }) + // .catch(error => { + // console.log(error); + // return true; + // }); + if (Object.keys(formErrors).length === 0) { + let data = {}; + data["id"] = isNewRecord ? params.id : refClientDetail.id; + data["fullname"] = values.fullname; + data["lastname"] = values.lastname; + data["firstname"] = values.firstname; + data["title"] = values.title; + data["email"] = values.email; + data["phone1"] = values.phone1; + data["phone2"] = values.phone2; + data["remarks"] = values.remarks; + data["caseManagerId"] = 1; + data["consultantId"] = 1; + data["joinDate"] = joinDate === null ? null : dayjs(joinDate).format('YYYY-MM-DD'); + setClientDetail(data); } else if(isCollectData){ setUserConfirm(false); setIsCollectData(false); } + // setUserConfirm(false); + // setIsCollectData(false); } }, [isCollectData]); @@ -560,16 +519,16 @@ const ClientForm = ({ refClientDetail, navigate('/client'); } - function createNewApplication(){ - navigate('/application/maintain/-1/'+ params.id); - } + // function createNewApplication(){ + // navigate('/application/maintain/-1/'+ params.id); + // } useEffect(() => { if (userConfirm) { postClient(); } setUserConfirm(false); - }, [eventDetail]); + }, [clientDetail]); const submitData = () => { @@ -583,8 +542,10 @@ const ClientForm = ({ refClientDetail, function postClient(){ setIsUploading(true); - const temp = trimDataBeforePost(eventDetail); - axios.post(`${apiPath}${POST_EVENT_PATH}`, + const temp = trimDataBeforePost(clientDetail); + // console.log("Posting:"); + // console.log(clientDetail); + axios.post(`${apiPath}${POST_CLIENT_PATH}`, temp, ) .then((response) => { @@ -592,7 +553,7 @@ const ClientForm = ({ refClientDetail, notifySaveSuccess(); if(isNewRecord){ setIsUploading(false); - navigate('/event') + navigate('/client') } else{ setIsUploading(false); @@ -646,7 +607,7 @@ const ClientForm = ({ refClientDetail, fullWidth {...register("fullname", { - // value: refClient.fullname, + value: refClient.fullname, })} id='fullname' required @@ -656,8 +617,8 @@ const ClientForm = ({ refClientDetail, }} multiline maxRows={3} - error={!!errors.name} - helperText={errors.name} + error={!!errors.fullname} + helperText={errors.fullname} disabled={!isEditing} autoComplete="off" /> @@ -679,7 +640,7 @@ const ClientForm = ({ refClientDetail, fullWidth {...register("lastname", { - // value: refClient.lastname, + value: refClient.lastname, })} id='lastname' required @@ -710,7 +671,7 @@ const ClientForm = ({ refClientDetail, fullWidth {...register("firstname", { - // value: refClient.firstname, + value: refClient.firstname, })} id='firstname' required @@ -768,122 +729,133 @@ const ClientForm = ({ refClientDetail, - {/* + setClientDate(newValue)} + required='true' + value={joinDate === null ? null : dayjs(joinDate)} + onChange={(newValue) => setJoinDate(newValue)} format="DD/MM/YYYY" - onError={(newError) => setClientDateError(newError)} + onError={(newError) => setJoinDateError(newError)} slotProps={{ field: { clearable: true }, textField: { - error: !!errors.eventDate || eventDateError, - helperText: eventDateError ? eventDateErrorMessage : errors.eventDate, + error: !!errors.joinDate || joinDateError, + helperText: joinDateError ? joinDateErrorMessage : errors.joinDate, }, }} disabled={!isEditing} /> - */} + - + - Series: + Title: - {/* + - */} + - + - Application Deadline: * + Email Address: - {/* - - - setDeadlineDate(newValue)} - format="DD/MM/YYYY" - onError={(newError) => setDeadlineDateError(newError)} - slotProps={{ - field: { clearable: true }, - textField: { - error: !!errors.deadlineDate || deadlineDateError, - helperText: deadlineDateError ? deadlineDateErrorMessage : errors.deadlineDate, - }, - }} - disabled={!isEditing} - /> - - - */} + + + - + - Award Date: * + Phone Number: - {/* - - - setAwardDate(newValue)} - format="DD/MM/YYYY" - onError={(newError) => setAwardDateError(newError)} - slotProps={{ - field: { clearable: true }, - textField: { - error: !!errors.awardDate || awardDateError, - helperText: awardDateError ? awardDateErrorMessage : errors.awardDate, - }, - }} - disabled={!isEditing} - /> - - - */} + + + + + + + + + + + Phone Number (Secondary): + + + + + + @@ -892,7 +864,7 @@ const ClientForm = ({ refClientDetail, - Sub-Divisions: * + Case Manager: @@ -936,34 +908,49 @@ const ClientForm = ({ refClientDetail, - + - Announcement Date: + Consultant: - {/* - - - setAnnounceDate(newValue)} - format="DD/MM/YYYY" - onError={(newError) => setAnnounceDateError(newError)} - slotProps={{ - field: { clearable: true }, - textField: { - helperText: announceDateErrorMessage, - }, - }} - disabled={!isEditing} + {/* + option.label} + onChange={(event, newValue) => { + setSelectedSubDivision(newValue); + }} + renderInput={(params) => ( + + {errors.subDivision.split("\n").map((line, index) => { + return ( + + {line} + + ) + })} + + ) : null + } + {...params} + placeholder="" /> - - + )} + disabled={!isEditing} + isOptionEqualToValue={isOptionEqualToValue} + /> */} @@ -973,18 +960,18 @@ const ClientForm = ({ refClientDetail, - Client Description: + Remarks: - {/* + - */} + {/*row 2*/} @@ -1018,7 +1005,7 @@ const ClientForm = ({ refClientDetail, @@ -1036,8 +1023,8 @@ const ClientForm = ({ refClientDetail, @@ -1089,6 +1076,15 @@ const ClientForm = ({ refClientDetail, Edit + + + diff --git a/src/pages/client/ClientMaintainPage/index.js b/src/pages/client/ClientMaintainPage/index.js index d1a823a..ade8878 100644 --- a/src/pages/client/ClientMaintainPage/index.js +++ b/src/pages/client/ClientMaintainPage/index.js @@ -50,116 +50,112 @@ const ClientPanel = () => { //const [tagCombo, setTagCombo] = useState({}); - function updateApplicationDetail(applicationData) { - setApplicationDetail(applicationData); - } + // function updateApplicationDetail(applicationData) { + // setApplicationDetail(applicationData); + // } useEffect(() => { - getReminderInterval(); - getReminderBefore(); - getReminderLimit(); - getReminderLimitMax(); + // getReminderInterval(); + // getReminderBefore(); + // getReminderLimit(); + // getReminderLimitMax(); if(refId !== null){ - setIsNewRecord(true); + setIsNewRecord(false); getClientDetail(refId); } else if(params.id<0){ setIsNewRecord(true); } else{ + setIsNewRecord(false); getClientDetail(params.id); } - getGroupList(); - getApplicationList(); - }, []); - - function getReminderBefore(){ - axios.get(`${apiPath}${GET_REMINDER_BEFORE}`, - ) - .then((response) => { - if (response.status === 200) { - setReminderBefore(response.data.data); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } - - function getReminderLimit(){ - axios.get(`${apiPath}${GET_REMINDER_LIMIT}`, - ) - .then((response) => { - if (response.status === 200) { - setReminderLimit(response.data.data); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } - - function getReminderLimitMax(){ - axios.get(`${apiPath}${GET_REMINDER_LIMIT_MAX}`, - ) - .then((response) => { - if (response.status === 200) { - setReminderLimitMax(response.data.data); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } + // getGroupList(); + // getApplicationList(); + }, [refId, params.id]); + + // function getReminderBefore(){ + // axios.get(`${apiPath}${GET_REMINDER_BEFORE}`, + // ) + // .then((response) => { + // if (response.status === 200) { + // setReminderBefore(response.data.data); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // } + + // function getReminderLimit(){ + // axios.get(`${apiPath}${GET_REMINDER_LIMIT}`, + // ) + // .then((response) => { + // if (response.status === 200) { + // setReminderLimit(response.data.data); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // } + + // function getReminderLimitMax(){ + // axios.get(`${apiPath}${GET_REMINDER_LIMIT_MAX}`, + // ) + // .then((response) => { + // if (response.status === 200) { + // setReminderLimitMax(response.data.data); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // } useEffect(() => { - if (!isObjEmpty(subDivisionCombo)) { - setOnReady(true); - } - else if(isNewRecord && - Object.keys(clientDetail).length > 0 - ){ + if(isNewRecord || Object.keys(clientDetail).length > 0) { setOnReady(true); } - }, [subDivisionCombo,clientDetail]); - - function getApplicationList(){ - const byDivision = { - clientId: params.id, - userSubDivisionId: ability.can('VIEW', 'ALL_RECORD') ? null : localStorage.getItem('subDivisionId'), - } - axios.get(`${apiPath}${GET_EVENT_APPLICATION_PATH}`, - { - params: byDivision, - } - ) - .then((response) => { - if (response.status === 200) { - setApplicationList(response.data.records); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } - - function getReminderInterval(){ - axios.get(`${apiPath}${GET_REMINDER_INTERVAL}`, - ) - .then((response) => { - if (response.status === 200) { - setReminderInterval(response.data.data); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } + }, [isNewRecord, clientDetail]); + + // function getApplicationList(){ + // const byDivision = { + // clientId: params.id, + // userSubDivisionId: ability.can('VIEW', 'ALL_RECORD') ? null : localStorage.getItem('subDivisionId'), + // } + // axios.get(`${apiPath}${GET_EVENT_APPLICATION_PATH}`, + // { + // params: byDivision, + // } + // ) + // .then((response) => { + // if (response.status === 200) { + // setApplicationList(response.data.records); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // } + + // function getReminderInterval(){ + // axios.get(`${apiPath}${GET_REMINDER_INTERVAL}`, + // ) + // .then((response) => { + // if (response.status === 200) { + // setReminderInterval(response.data.data); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // } function getClientDetail(clientId) { axios.get(`${apiPath}${GET_CLIENT_PATH}/${clientId}`, @@ -167,7 +163,7 @@ const ClientPanel = () => { .then((response) => { if (response.status === 200) { setClientDetail(response.data.data); - setRefSubDivisionList(response.data.clientDivision); + // setRefSubDivisionList(response.data.clientDivision); } }) .catch(error => { @@ -176,19 +172,19 @@ const ClientPanel = () => { }); } - function getGroupList() { - axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`, - ) - .then((response) => { - if (response.status === 200) { - setSubDivisionCombo(response.data.records); - } - }) - .catch(error => { - console.log(error); - return false; - }); - } + // function getGroupList() { + // axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`, + // ) + // .then((response) => { + // if (response.status === 200) { + // setSubDivisionCombo(response.data.records); + // } + // }) + // .catch(error => { + // console.log(error); + // return false; + // }); + // } return ( !onReady ? @@ -209,35 +205,11 @@ const ClientPanel = () => { {/*row 1*/} - - {/*row 2*/} - { - params.id > 0 ? - - - - - - - - : - undefined - } diff --git a/src/pages/client/ClientSearchPage/ClientSearchForm.js b/src/pages/client/ClientSearchPage/ClientSearchForm.js index b5b66c0..aa3e191 100644 --- a/src/pages/client/ClientSearchPage/ClientSearchForm.js +++ b/src/pages/client/ClientSearchPage/ClientSearchForm.js @@ -469,7 +469,6 @@ const ClientSearchForm = ({applySearch, setExpanded,expanded}) => { variant="contained" color="create" onClick={createNewClient} - disabled='true' > New Client diff --git a/src/pages/client/ClientSearchPage/ClientTable.js b/src/pages/client/ClientSearchPage/ClientTable.js index 0445277..ae864b1 100644 --- a/src/pages/client/ClientSearchPage/ClientTable.js +++ b/src/pages/client/ClientSearchPage/ClientTable.js @@ -51,7 +51,7 @@ export default function ClientTable({recordList}) { className="textPrimary" onClick={handleEditClick(id)} color="edit" - disabled={'true'} + // disabled={'true'} // disabled={!ability.can('VIEW','DASHBOARD')} /> @@ -81,7 +81,7 @@ export default function ClientTable({recordList}) { renderCell: (params) => { return (
- ({params.row.title}) {params.value} + {params.row.title ? `(${params.row.title})` : ''} {params.value}
); } @@ -94,7 +94,6 @@ export default function ClientTable({recordList}) { sortComparator: dateComparator, renderCell: (params) => (
- {/* {formattedDate = date.toLocaleDateString()} */} {getDateString(params.row.joinDate, 'dd/MM/yyyy')}
), diff --git a/src/pages/client/ClientSearchPage/index.js b/src/pages/client/ClientSearchPage/index.js index 373b4f6..5f18efa 100644 --- a/src/pages/client/ClientSearchPage/index.js +++ b/src/pages/client/ClientSearchPage/index.js @@ -78,8 +78,8 @@ const ClientSearchPage = () => { // }, []); function applySearch(input) { - console.log("SearchCriteria:") - console.log(input) + // console.log("SearchCriteria:") + // console.log(input) setSearchCriteria(input); } diff --git a/src/utils/CommonFunction.js b/src/utils/CommonFunction.js index bff13b0..4d8c0b1 100644 --- a/src/utils/CommonFunction.js +++ b/src/utils/CommonFunction.js @@ -261,11 +261,11 @@ export function removeObjectWithId(arr, id) { /** * Display the date array in string format, default format is 'yyyy-MM-dd'. * - * @param {*} queryDateArray - The date array to display. + * @param {*} dateInput - The date value to be displayed, can be array or timestamp. * @param {*} [formatOption] - Set to True to display also the timestamp, or input custom format text. */ -export function getDateString(queryDateArray, formatOption=false) { - if (queryDateArray === null || queryDateArray === undefined) { +export function getDateString(dateInput, formatOption=false) { + if (dateInput === null || dateInput === undefined) { return null; } @@ -276,17 +276,26 @@ export function getDateString(queryDateArray, formatOption=false) { dateFormat = formatOption; } - return format( - new Date( + let inputType = 0; // Array + if (!Array.isArray(dateInput)) { + inputType = 1; + } + + let date = new Date(); + if (inputType == 0) { + let queryDateArray = dateInput; + date = new Date( queryDateArray[0], queryDateArray[1]-1, queryDateArray[2], queryDateArray[3] !== undefined ? queryDateArray[3] : 0, queryDateArray[4] !== undefined ? queryDateArray[4] : 0, queryDateArray[5] !== undefined ? queryDateArray[5] : 0 - ), - dateFormat - ); + ); + } else { + date = new Date(dateInput); + } + return format(date, dateFormat); } export const isOptionEqualToValue = (option, value) => { From fcb4625b9b7a124aa2584d779033bc356c4eb3c6 Mon Sep 17 00:00:00 2001 From: kelvinsuen Date: Tue, 17 Jun 2025 12:51:35 +0800 Subject: [PATCH 2/2] update pdf page (wip) --- src/pages/pdf/index.js | 42 ++++++++++++++++++++++++++++++-------- src/routes/ClientRoutes.js | 11 ---------- src/utils/ApiPathConst.js | 1 + 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/pages/pdf/index.js b/src/pages/pdf/index.js index 6848039..661985a 100644 --- a/src/pages/pdf/index.js +++ b/src/pages/pdf/index.js @@ -2,6 +2,10 @@ import React, { useEffect, useRef, useState } from 'react'; // import './App.css'; // For basic styling import axios from 'axios'; +import {apiPath} from "../../auth/utils"; +import { + GET_PDF_PATH +} from "../../utils/ApiPathConst"; // Import your chosen commercial PDF SDK (e.g., PSPDFKit) import PSPDFKit from 'pspdfkit'; @@ -10,28 +14,48 @@ function PDF() { const viewerRef = useRef(null); // Ref for the DOM element where PDF will render const instanceRef = useRef(null); // Ref for the PSPDFKit instance const [pdfLoaded, setPdfLoaded] = useState(false); + const [template,setTemplate] = useState(); + const [viewInstance,setViewInstance] = useState(); useEffect(() => { const loadPdfViewer = async () => { - if (viewerRef.current) { + if (document.getElementById(viewerRef)) { + // if (viewerRef.current) { try { - // 1. Fetch the blank PDF template from your Spring Boot backend - const response = await axios.get('http://localhost:8090/api/pdf/template', { - responseType: 'arraybuffer' // Essential for binary data + //New try + axios.get(`${apiPath}${GET_PDF_PATH}`, { + responseType: 'arraybuffer', // Essential for binary data + }) + .then((response) => { + if (response.status === 200) { + setTemplate(response); + } + }) + .catch(error => { + console.log(error); + return false; }); - const pdfBlob = new Blob([response.data], { type: 'application/pdf' }); + // 1. Fetch the blank PDF template from your Spring Boot backend + // const response = await axios.get(`${apiPath}${GET_PDF_PATH}`, { + // responseType: 'arraybuffer', // Essential for binary data + // }); + const pdfBlob = new Blob(template, { type: 'application/pdf' }); const pdfUrl = URL.createObjectURL(pdfBlob); // 2. Initialize the PDF SDK (e.g., PSPDFKit) + console.log(template); + const instance = await PSPDFKit.load({ - container: viewerRef.current, + // setViewInstance(await PSPDFKit.load({ + container: document.getElementById(viewerRef),//viewerRef.current, document: pdfUrl, // Remember to add your SDK license key if applicable // licenseKey: "YOUR_PSPDFKIT_LICENSE_KEY", - baseUrl: process.env.PUBLIC_URL + '/pspdfkit-lib/', // Path to SDK assets + baseUrl: `${process.env.PUBLIC_URL}/pspdfkit-lib/`//, // Path to SDK assets // Enable form filling UI - formDesignerViewMode: PSPDFKit.FormDesignerViewMode.Enabled + // formDesignerViewMode: PSPDFKit.FormDesignerViewMode.Enabled }); + // })); instanceRef.current = instance; setPdfLoaded(true); @@ -104,7 +128,7 @@ function PDF() { )}
import('pages/client/ClientSearchPage'))); const ClientMaintainPage = Loadable(lazy( () => import('pages/client/ClientMaintainPage'))); -const PDF = Loadable(lazy( () => import('pages/pdf'))); // ==============================|| AUTH ROUTING ||============================== // @@ -41,16 +40,6 @@ const ClientRoutes =() => { ) ), }, - { - path: 'pdf', - element: ( - handleRouteAbility( - ability.can('VIEW', 'DASHBOARD'), - , - - ) - ), - }, ] }; }; diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 4322166..14798e1 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -59,6 +59,7 @@ export const DELETE_FILE_PATH = "/file" export const GET_FILE_PATH = "/file/dl" export const GET_THUMBNAIL_PATH = "/file/thumbnail" export const POST_THUMBNAIL_PATH = "/file/thumbnail/ul" +export const GET_PDF_PATH = "/pdf/template" export const GET_CLIENT_PATH = "/client" export const POST_CLIENT_PATH = "/client/save" export const GET_EVENT_PATH = "/event"