@@ -9,9 +9,9 @@ | |||||
}, | }, | ||||
"2fi-production": { | "2fi-production": { | ||||
"REACT_APP_ENV": "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_PROTOCOL": "http", | ||||
"REACT_APP_BACKEND_HOST": "localhost", | |||||
"REACT_APP_BACKEND_HOST": "20.2.170.164", | |||||
"REACT_APP_BACKEND_PORT": "8090", | "REACT_APP_BACKEND_PORT": "8090", | ||||
"REACT_APP_BACKEND_API_PATH": "/api" | "REACT_APP_BACKEND_API_PATH": "/api" | ||||
} | } |
@@ -50,116 +50,112 @@ const ClientPanel = () => { | |||||
//const [tagCombo, setTagCombo] = useState({}); | //const [tagCombo, setTagCombo] = useState({}); | ||||
function updateApplicationDetail(applicationData) { | |||||
setApplicationDetail(applicationData); | |||||
} | |||||
// function updateApplicationDetail(applicationData) { | |||||
// setApplicationDetail(applicationData); | |||||
// } | |||||
useEffect(() => { | useEffect(() => { | ||||
getReminderInterval(); | |||||
getReminderBefore(); | |||||
getReminderLimit(); | |||||
getReminderLimitMax(); | |||||
// getReminderInterval(); | |||||
// getReminderBefore(); | |||||
// getReminderLimit(); | |||||
// getReminderLimitMax(); | |||||
if(refId !== null){ | if(refId !== null){ | ||||
setIsNewRecord(true); | |||||
setIsNewRecord(false); | |||||
getClientDetail(refId); | getClientDetail(refId); | ||||
} | } | ||||
else if(params.id<0){ | else if(params.id<0){ | ||||
setIsNewRecord(true); | setIsNewRecord(true); | ||||
} | } | ||||
else{ | else{ | ||||
setIsNewRecord(false); | |||||
getClientDetail(params.id); | 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(() => { | useEffect(() => { | ||||
if (!isObjEmpty(subDivisionCombo)) { | |||||
setOnReady(true); | |||||
} | |||||
else if(isNewRecord && | |||||
Object.keys(clientDetail).length > 0 | |||||
){ | |||||
if(isNewRecord || Object.keys(clientDetail).length > 0) { | |||||
setOnReady(true); | 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) { | function getClientDetail(clientId) { | ||||
axios.get(`${apiPath}${GET_CLIENT_PATH}/${clientId}`, | axios.get(`${apiPath}${GET_CLIENT_PATH}/${clientId}`, | ||||
@@ -167,7 +163,7 @@ const ClientPanel = () => { | |||||
.then((response) => { | .then((response) => { | ||||
if (response.status === 200) { | if (response.status === 200) { | ||||
setClientDetail(response.data.data); | setClientDetail(response.data.data); | ||||
setRefSubDivisionList(response.data.clientDivision); | |||||
// setRefSubDivisionList(response.data.clientDivision); | |||||
} | } | ||||
}) | }) | ||||
.catch(error => { | .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 ( | return ( | ||||
!onReady ? | !onReady ? | ||||
@@ -209,35 +205,11 @@ const ClientPanel = () => { | |||||
{/*row 1*/} | {/*row 1*/} | ||||
<Grid item xs={12} md={12} lg={12} > | <Grid item xs={12} md={12} lg={12} > | ||||
<ClientForm | <ClientForm | ||||
refReminderInterval={reminderInterval} | |||||
refReminderBefore={reminderBefore} | |||||
refReminderLimit={reminderLimit} | |||||
refReminderLimitMax={reminderLimitMax} | |||||
applicationList={applicationList} | |||||
getClientDetail={getClientDetail} | getClientDetail={getClientDetail} | ||||
refClientDetail={clientDetail} | refClientDetail={clientDetail} | ||||
applicationDetail={applicationDetail} | |||||
updateApplicationDetail={updateApplicationDetail} | |||||
isNewRecord={isNewRecord} | isNewRecord={isNewRecord} | ||||
refSubDivisionList={refSubDivisionList} | |||||
/> | /> | ||||
</Grid> | </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> | </ThemeProvider> | ||||
</Grid> | </Grid> | ||||
@@ -469,7 +469,6 @@ const ClientSearchForm = ({applySearch, setExpanded,expanded}) => { | |||||
variant="contained" | variant="contained" | ||||
color="create" | color="create" | ||||
onClick={createNewClient} | onClick={createNewClient} | ||||
disabled='true' | |||||
> | > | ||||
New Client | New Client | ||||
</Button> | </Button> | ||||
@@ -51,7 +51,7 @@ export default function ClientTable({recordList}) { | |||||
className="textPrimary" | className="textPrimary" | ||||
onClick={handleEditClick(id)} | onClick={handleEditClick(id)} | ||||
color="edit" | color="edit" | ||||
disabled={'true'} | |||||
// disabled={'true'} | |||||
// disabled={!ability.can('VIEW','DASHBOARD')} | // disabled={!ability.can('VIEW','DASHBOARD')} | ||||
/> | /> | ||||
</ThemeProvider> | </ThemeProvider> | ||||
@@ -81,7 +81,7 @@ export default function ClientTable({recordList}) { | |||||
renderCell: (params) => { | renderCell: (params) => { | ||||
return ( | return ( | ||||
<div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}> | <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> | </div> | ||||
); | ); | ||||
} | } | ||||
@@ -94,7 +94,6 @@ export default function ClientTable({recordList}) { | |||||
sortComparator: dateComparator, | sortComparator: dateComparator, | ||||
renderCell: (params) => ( | renderCell: (params) => ( | ||||
<div> | <div> | ||||
{/* {formattedDate = date.toLocaleDateString()} */} | |||||
{getDateString(params.row.joinDate, 'dd/MM/yyyy')} | {getDateString(params.row.joinDate, 'dd/MM/yyyy')} | ||||
</div> | </div> | ||||
), | ), | ||||
@@ -78,8 +78,8 @@ const ClientSearchPage = () => { | |||||
// }, []); | // }, []); | ||||
function applySearch(input) { | function applySearch(input) { | ||||
console.log("SearchCriteria:") | |||||
console.log(input) | |||||
// console.log("SearchCriteria:") | |||||
// console.log(input) | |||||
setSearchCriteria(input); | setSearchCriteria(input); | ||||
} | } | ||||
@@ -2,6 +2,10 @@ | |||||
import React, { useEffect, useRef, useState } from 'react'; | import React, { useEffect, useRef, useState } from 'react'; | ||||
// import './App.css'; // For basic styling | // import './App.css'; // For basic styling | ||||
import axios from 'axios'; | 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 your chosen commercial PDF SDK (e.g., PSPDFKit) | ||||
import PSPDFKit from '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 viewerRef = useRef(null); // Ref for the DOM element where PDF will render | ||||
const instanceRef = useRef(null); // Ref for the PSPDFKit instance | const instanceRef = useRef(null); // Ref for the PSPDFKit instance | ||||
const [pdfLoaded, setPdfLoaded] = useState(false); | const [pdfLoaded, setPdfLoaded] = useState(false); | ||||
const [template,setTemplate] = useState(); | |||||
const [viewInstance,setViewInstance] = useState(); | |||||
useEffect(() => { | useEffect(() => { | ||||
const loadPdfViewer = async () => { | const loadPdfViewer = async () => { | ||||
if (viewerRef.current) { | |||||
if (document.getElementById(viewerRef)) { | |||||
// if (viewerRef.current) { | |||||
try { | 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); | const pdfUrl = URL.createObjectURL(pdfBlob); | ||||
// 2. Initialize the PDF SDK (e.g., PSPDFKit) | // 2. Initialize the PDF SDK (e.g., PSPDFKit) | ||||
console.log(template); | |||||
const instance = await PSPDFKit.load({ | const instance = await PSPDFKit.load({ | ||||
container: viewerRef.current, | |||||
// setViewInstance(await PSPDFKit.load({ | |||||
container: document.getElementById(viewerRef),//viewerRef.current, | |||||
document: pdfUrl, | document: pdfUrl, | ||||
// Remember to add your SDK license key if applicable | // Remember to add your SDK license key if applicable | ||||
// licenseKey: "YOUR_PSPDFKIT_LICENSE_KEY", | // 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 | // Enable form filling UI | ||||
formDesignerViewMode: PSPDFKit.FormDesignerViewMode.Enabled | |||||
// formDesignerViewMode: PSPDFKit.FormDesignerViewMode.Enabled | |||||
}); | }); | ||||
// })); | |||||
instanceRef.current = instance; | instanceRef.current = instance; | ||||
setPdfLoaded(true); | setPdfLoaded(true); | ||||
@@ -104,7 +128,7 @@ function PDF() { | |||||
)} | )} | ||||
</header> | </header> | ||||
<div | <div | ||||
ref={viewerRef} | |||||
id={viewerRef} | |||||
className="pdf-viewer-container" | className="pdf-viewer-container" | ||||
style={{ | style={{ | ||||
width: '100%', | width: '100%', | ||||
@@ -10,7 +10,6 @@ import AbilityContext from "../components/AbilityProvider"; | |||||
// render - login | // render - login | ||||
const ClientSearchPage = Loadable(lazy( () => import('pages/client/ClientSearchPage'))); | const ClientSearchPage = Loadable(lazy( () => import('pages/client/ClientSearchPage'))); | ||||
const ClientMaintainPage = Loadable(lazy( () => import('pages/client/ClientMaintainPage'))); | const ClientMaintainPage = Loadable(lazy( () => import('pages/client/ClientMaintainPage'))); | ||||
const PDF = Loadable(lazy( () => import('pages/pdf'))); | |||||
// ==============================|| AUTH ROUTING ||============================== // | // ==============================|| 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_FILE_PATH = "/file/dl" | ||||
export const GET_THUMBNAIL_PATH = "/file/thumbnail" | export const GET_THUMBNAIL_PATH = "/file/thumbnail" | ||||
export const POST_THUMBNAIL_PATH = "/file/thumbnail/ul" | export const POST_THUMBNAIL_PATH = "/file/thumbnail/ul" | ||||
export const GET_PDF_PATH = "/pdf/template" | |||||
export const GET_CLIENT_PATH = "/client" | export const GET_CLIENT_PATH = "/client" | ||||
export const POST_CLIENT_PATH = "/client/save" | export const POST_CLIENT_PATH = "/client/save" | ||||
export const GET_EVENT_PATH = "/event" | 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'. | * 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. | * @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; | return null; | ||||
} | } | ||||
@@ -276,17 +276,26 @@ export function getDateString(queryDateArray, formatOption=false) { | |||||
dateFormat = formatOption; | 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[0], | ||||
queryDateArray[1]-1, | queryDateArray[1]-1, | ||||
queryDateArray[2], | queryDateArray[2], | ||||
queryDateArray[3] !== undefined ? queryDateArray[3] : 0, | queryDateArray[3] !== undefined ? queryDateArray[3] : 0, | ||||
queryDateArray[4] !== undefined ? queryDateArray[4] : 0, | queryDateArray[4] !== undefined ? queryDateArray[4] : 0, | ||||
queryDateArray[5] !== undefined ? queryDateArray[5] : 0 | queryDateArray[5] !== undefined ? queryDateArray[5] : 0 | ||||
), | |||||
dateFormat | |||||
); | |||||
); | |||||
} else { | |||||
date = new Date(dateInput); | |||||
} | |||||
return format(date, dateFormat); | |||||
} | } | ||||
export const isOptionEqualToValue = (option, value) => { | export const isOptionEqualToValue = (option, value) => { | ||||