| @@ -9,9 +9,9 @@ | |||
| }, | |||
| "2fi-production": { | |||
| "REACT_APP_ENV": "2fi-production", | |||
| "REACT_APP_URL": "http://52.175.12.19:80/", | |||
| "REACT_APP_URL": "http://20.2.170.164/", | |||
| "REACT_APP_BACKEND_PROTOCOL": "http", | |||
| "REACT_APP_BACKEND_HOST": "localhost", | |||
| "REACT_APP_BACKEND_HOST": "20.2.170.164", | |||
| "REACT_APP_BACKEND_PORT": "8090", | |||
| "REACT_APP_BACKEND_API_PATH": "/api" | |||
| } | |||
| @@ -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*/} | |||
| <Grid item xs={12} md={12} lg={12} > | |||
| <ClientForm | |||
| refReminderInterval={reminderInterval} | |||
| refReminderBefore={reminderBefore} | |||
| refReminderLimit={reminderLimit} | |||
| refReminderLimitMax={reminderLimitMax} | |||
| applicationList={applicationList} | |||
| getClientDetail={getClientDetail} | |||
| refClientDetail={clientDetail} | |||
| applicationDetail={applicationDetail} | |||
| updateApplicationDetail={updateApplicationDetail} | |||
| isNewRecord={isNewRecord} | |||
| refSubDivisionList={refSubDivisionList} | |||
| /> | |||
| </Grid> | |||
| {/*row 2*/} | |||
| { | |||
| params.id > 0 ? | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| <MainCard | |||
| sx={{width:CARD_MAX_WIDTH}} | |||
| > | |||
| <ThemeProvider theme={LIONER_FORM_THEME}> | |||
| <ApplicationTable recordList={applicationList}/> | |||
| </ThemeProvider> | |||
| </MainCard> | |||
| </Grid> | |||
| : | |||
| undefined | |||
| } | |||
| </ThemeProvider> | |||
| </Grid> | |||
| @@ -469,7 +469,6 @@ const ClientSearchForm = ({applySearch, setExpanded,expanded}) => { | |||
| variant="contained" | |||
| color="create" | |||
| onClick={createNewClient} | |||
| disabled='true' | |||
| > | |||
| New Client | |||
| </Button> | |||
| @@ -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')} | |||
| /> | |||
| </ThemeProvider> | |||
| @@ -81,7 +81,7 @@ export default function ClientTable({recordList}) { | |||
| renderCell: (params) => { | |||
| return ( | |||
| <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}> | |||
| ({params.row.title}) {params.value} | |||
| {params.row.title ? `(${params.row.title})` : ''} {params.value} | |||
| </div> | |||
| ); | |||
| } | |||
| @@ -94,7 +94,6 @@ export default function ClientTable({recordList}) { | |||
| sortComparator: dateComparator, | |||
| renderCell: (params) => ( | |||
| <div> | |||
| {/* {formattedDate = date.toLocaleDateString()} */} | |||
| {getDateString(params.row.joinDate, 'dd/MM/yyyy')} | |||
| </div> | |||
| ), | |||
| @@ -78,8 +78,8 @@ const ClientSearchPage = () => { | |||
| // }, []); | |||
| function applySearch(input) { | |||
| console.log("SearchCriteria:") | |||
| console.log(input) | |||
| // console.log("SearchCriteria:") | |||
| // console.log(input) | |||
| setSearchCriteria(input); | |||
| } | |||
| @@ -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() { | |||
| )} | |||
| </header> | |||
| <div | |||
| ref={viewerRef} | |||
| id={viewerRef} | |||
| className="pdf-viewer-container" | |||
| style={{ | |||
| width: '100%', | |||
| @@ -10,7 +10,6 @@ import AbilityContext from "../components/AbilityProvider"; | |||
| // render - login | |||
| const ClientSearchPage = Loadable(lazy( () => 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'), | |||
| <PDF />, | |||
| <Navigate to="/" /> | |||
| ) | |||
| ), | |||
| }, | |||
| ] | |||
| }; | |||
| }; | |||
| @@ -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" | |||
| @@ -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) => { | |||