) to trigger the download
+ const blob = new Blob([response.data], { type: 'application/pdf' });
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+
+ link.href = url;
+ link.setAttribute('download', filename);
+ document.body.appendChild(link);
+ link.click();
+
+ // 4. Clean up
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ })
+ .catch((error) => {
+ console.error(`Download failed for ID ${id}:`, error);
+ // Handle error response (e.g., if the backend returns a 404 or a JSON error)
+ alert('Failed to download the PDF file. Check server logs.');
+ });
+ };
+
+ const handleCloseDialog = () => {
+ setIsDialogOpen(false);
+ setCurrentRowId(null);
+ if (fileInputRef.current) {
+ fileInputRef.current.value = ""; // Clear the file input
+ }
+ };
+
+ // Function to handle file selection and API submission
+ const handleFileChange = async (event) => {
+ const file = event.target.files[0];
+
+ if (!file) return;
+
+ if (file.type !== "application/pdf") {
+ alert("Please select a PDF file.");
+ event.target.value = "";
+ return;
+ }
+
+ const uploadUrl = apiPath + '/pdf/upload1';
+
+ // 1. Create FormData
+ const formData = new FormData();
+ formData.append('file', file);
+ formData.append('refId', currentRowId);
+ formData.append('refType', "upload1");
+ setIsUploading(true);
+
+ try {
+ axios.post(`${apiPath}${POST_SIG_UPLOAD1}`,
+ formData,
+ {
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ }
+ }
+ )
+ .then((response) => {
+ if (response.status === 200) {
+ // Optional: Read response if the server returns data
+ alert('Upload success');
+ console.log(`PDF file ${file.name} successfully uploaded for record ID: ${currentRowId}!`);
+
+ }
+ setIsUploading(false);
+ })
+ .catch((error) => {
+ setIsUploading(false);
+ console.log(error);
+ return false;
+ });
+
+
+ } catch (error) {
+ console.error('Upload error:', error);
+ alert(`Error uploading file: ${error.message}`);
+ } finally {
+ // 3. Cleanup and close
+ setIsUploading(false);
+ handleCloseDialog();
+ }
};
+ const handleChooseFile = () => {
+ // Trigger the hidden file input click
+ if (fileInputRef.current) {
+ fileInputRef.current.click();
+ }
+ };
+
const columns = [
{
field: 'actions',
type: 'actions',
- headerName: 'Actions',
- // flex: 0.5,
+ headerName: 'Edit',
width: 100,
cellClassName: 'actions',
getActions: ({id}) => {
@@ -57,28 +206,12 @@ export default function PdfTable({recordList}) {
className="textPrimary"
onClick={handleEditClick(id)}
color="edit"
- // disabled={'true'}
- // disabled={!ability.can('VIEW','DASHBOARD')}
/>
]
},
},
- // {
- // id: 'title',
- // field: 'title',
- // headerName: 'Title',
- // // sortComparator: dateComparator,
- // flex: 0.75,
- // renderCell: (params) => (
- //
- // {params.value}
- //
- // //
- // // {getDateString(params.row.pdfFrom,false)}
- // //
- // ),
- // },
+
{
id: 'templateName',
field: 'templateName',
@@ -86,11 +219,85 @@ export default function PdfTable({recordList}) {
flex: 2,
renderCell: (params) => {
return (
-
+
{params.value} {params.row.vNum}
-
+
);
- }
+ }
+ },
+ {
+ field: 'upload1',
+ type: 'actions',
+ // Multi-line header
+ headerName: (
+
+ Upload Sig.
+
+ ),
+ width: 100,
+ cellClassName: 'actions',
+ getActions: ({ id, row }) => {
+
+ // Check if a file ID exists to determine if a file is present
+ const isUploaded = !!row.upload1FileId;
+
+ // Determine the icon and label based on upload status
+ const upload1Icon = isUploaded
+ ? // Green tick if uploaded
+ : ; // Upload icon if not uploaded
+
+ const upload1Label = isUploaded ? "Update Signature" : "Upload Signature";
+
+ // Define the actions
+ const actions = [
+
+
+
+ ];
+
+ // Conditional rendering logic for Upload 2
+ if (row.templateName === "MLB03S" || row.templateName === "SLGII" || row.templateName === "SLAPP") {
+ actions.push(
+
+ }
+ label="Upload2"
+ className="textPrimary"
+ onClick={handleUpload2Click(id, row.templateName)}
+ color="upload"
+ />
+
+ );
+ }
+
+ return actions;
+ },
+ },
+ {
+ field: 'actions2',
+ type: 'actions',
+ headerName: 'Download',
+ width: 100,
+ cellClassName: 'actions',
+ getActions: ({id}) => {
+ return [
+
+ }
+ label="Download"
+ className="textPrimary"
+ onClick={handleDownloadClick(id, "{params.row.templateName}")}
+ color="download"
+ />
+
+ ]
+ },
},
{
id: 'createDate',
@@ -129,89 +336,6 @@ export default function PdfTable({recordList}) {
),
},
- // {
- // id: 'lastname',
- // field: 'lastname',
- // headerName: 'Last Name',
- // flex: 1.5,
- // sortComparator: dateComparator,
- // renderCell: (params) => (
- //
- // {params.value}
- //
- // //
- // // {getDateString(params.row.startDate,false)}
- // //
- // ),
- // },
- // {
- // id: 'firstname',
- // field: 'firstname',
- // headerName: 'First Name',
- // // sortComparator: dateComparator,
- // flex: 2,
- // renderCell: (params) => (
- //
- // {params.value}
- //
- // //
- // // {getDateString(params.row.applicationDeadline,false)}
- // //
- // ),
- // },
- // {
- // id: 'email',
- // field: 'email',
- // headerName: 'Email',
- // flex: 1.5,
- // renderCell: (params) => {
- // return (
- //
- // {params.value}
- //
- // );
- // }
- // },
- // {
- // id: 'phone1',
- // field: 'phone1',
- // headerName: 'Phone No.',
- // flex: 1,
- // renderCell: (params) => {
- // return (
- //
- // {params.value}
- //
- // );
- // }
- // },
- // {
- // id: 'phone2',
- // field: 'phone2',
- // headerName: '2nd Phone No.',
- // flex: 1,
- // renderCell: (params) => {
- // return (
- //
- // {params.value}
- //
- // );
- // }
- // },
- // {
- // id: 'remarks',
- // field: 'remarks',
- // headerName: 'Remarks',
- // flex: 2,
- // renderCell: (params) => {
- // return (
- //
- // {params.value}
- //
- // );
- // }
- // },
-
];
return (
@@ -219,9 +343,9 @@ export default function PdfTable({recordList}) {
'auto'}
paginationModel={paginationModel}
@@ -234,6 +358,62 @@ export default function PdfTable({recordList}) {
pageSizeOptions={[10]}
autoHeight
/>
+
+ {/* The Upload Dialog Box */}
+
);
-}
+}
\ No newline at end of file
diff --git a/src/pages/pdf/PdfSearchPage/SelectTemplateWindow.js b/src/pages/pdf/PdfSearchPage/SelectTemplateWindow.js
index f8e66fe..7735c9e 100644
--- a/src/pages/pdf/PdfSearchPage/SelectTemplateWindow.js
+++ b/src/pages/pdf/PdfSearchPage/SelectTemplateWindow.js
@@ -21,6 +21,8 @@ export function SelectTemplateWindow({ isWindowOpen, onNormalClose, onConfirmClo
const [templateId, setTemplateId] = React.useState(0)
const [templateList, setTemplateList] = React.useState([])
const fileInputRef = useRef(null);
+ const [currentView, setCurrentView] = useState('prefixSelection');
+ const [selectedPrefix, setSelectedPrefix] = useState(null);
const navigate = useNavigate()
@@ -30,17 +32,27 @@ export function SelectTemplateWindow({ isWindowOpen, onNormalClose, onConfirmClo
useEffect(() => {
axios.get(`${apiPath}${GET_TEMPLATE_PATH}`)
- .then((response) => {
- if (response.status === 200) {
- const record = response.data.records;
- console.log("record", record);
- setTemplateList(record);
- }
- })
- .catch(error => {
- console.log(error);
- return false;
- });
+ .then((response) => {
+ if (response.status === 200) {
+ const record = response.data.records;
+ // Group templates by their prefix
+ const grouped = record.reduce((acc, template) => {
+ const prefix = template.name.split(' ')[0];
+ if (!acc[prefix]) {
+ acc[prefix] = [];
+ }
+ //let's test ML first, so hide all SL forms
+ //if(prefix != "SL")
+ acc[prefix].push(template);
+ return acc;
+ }, {});
+ setTemplateList(grouped); // Store the grouped data
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ return false;
+ });
}, []);
const createNewForm = (templateId) => {
@@ -80,23 +92,54 @@ export function SelectTemplateWindow({ isWindowOpen, onNormalClose, onConfirmClo
- {templateList.length === 0 ? (
-
- No available template, please add!
-
- ) : ( templateList.map(record => (
-
-
-
- )
- ))}
+ {Object.keys(templateList).length === 0 ? (
+
+ No available template, please add!
+
+ ) : (
+ <>
+ {currentView === 'prefixSelection' ? (
+ // Step 1: Show the prefix selection buttons
+ Object.keys(templateList).map(prefix => (
+
+
+
+ ))
+ ) : (
+ // Step 2: Show the templates for the selected prefix
+ <>
+
+
+ Select a {selectedPrefix} Template
+
+ {templateList[selectedPrefix].map(record => (
+
+
+
+ ))}
+ >
+ )}
+ >
+ )}
diff --git a/src/themes/colorConst.js b/src/themes/colorConst.js
index 11941dc..78513ac 100644
--- a/src/themes/colorConst.js
+++ b/src/themes/colorConst.js
@@ -86,6 +86,10 @@ export const LIONER_BUTTON_THEME = createTheme({
main: '#F3AF2B',
contrastText: '#FFFFFF',
},
+ upload:{
+ main: '#6A8B9E',
+ contrastText: '#FFFFFF',
+ },
exportExcel:{
main: '#6A8B9E',
contrastText: '#FFFFFF',
diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js
index 0b5841f..b653b0a 100644
--- a/src/utils/ApiPathConst.js
+++ b/src/utils/ApiPathConst.js
@@ -68,6 +68,8 @@ export const GET_PDF_PATH = "/pdf"
export const POST_PDF_PATH = "/pdf/save"
export const POST_UPLOAD_PDF_PATH = "/pdf2/upload"
export const GET_PDF_TEMPLATE_PATH = "/pdf/template"
+export const POST_MERGE_PDF = "/pdf/merge-pdf"
+export const POST_SIG_UPLOAD1 = "/pdf/upload1"
export const GET_CLIENT_PATH = "/client"
export const POST_CLIENT_PATH = "/client/save"
export const GET_EVENT_PATH = "/event"