From d2b5f0407c56e6f9b22f139805abf5548c2bee88 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Tue, 16 Sep 2025 02:30:49 +0800 Subject: [PATCH] update report in gld page --- src/layout/MainLayout/Header/index.js | 3 + src/pages/Report/FullListForm.js | 230 ++++++++++++++++++++++++++ src/pages/Report/SummaryForm.js | 200 ++++++++++++++++++++++ src/pages/Report/index.js | 106 ++++++++++++ src/routes/GLDUserRoutes.js | 7 +- src/utils/ApiPathConst.js | 2 + 6 files changed, 547 insertions(+), 1 deletion(-) create mode 100644 src/pages/Report/FullListForm.js create mode 100644 src/pages/Report/SummaryForm.js create mode 100644 src/pages/Report/index.js diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js index 8c859eb..e1411b0 100644 --- a/src/layout/MainLayout/Header/index.js +++ b/src/layout/MainLayout/Header/index.js @@ -333,6 +333,9 @@ function Header(props) { : <> } +
  • + Report +
  • diff --git a/src/pages/Report/FullListForm.js b/src/pages/Report/FullListForm.js new file mode 100644 index 0000000..bd75539 --- /dev/null +++ b/src/pages/Report/FullListForm.js @@ -0,0 +1,230 @@ +// material-ui +import { + Button, + Grid, TextField, + Autocomplete, + Typography +} from '@mui/material'; +import MainCard from "components/MainCard"; +import { useForm } from "react-hook-form"; +import * as React from "react"; +import * as DateUtils from "utils/DateUtils"; +import {ThemeProvider} from "@emotion/react"; +import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst"; +import * as FormatUtils from "utils/FormatUtils"; +import * as HttpUtils from "utils/HttpUtils"; +import * as UrlUtils from "utils/ApiPathConst"; + +import {DatePicker} from "@mui/x-date-pickers/DatePicker"; +import dayjs from "dayjs"; +import {DemoItem} from "@mui/x-date-pickers/internals/demo"; +import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; +import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // +const FullListForm = ({ searchCriteria, issueComboData}) => { + + const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); + const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); + + const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); + const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); + + const [issueSelected, setIssueSelected] = React.useState({}); + const [issueCombo, setIssueCombo] = React.useState([]); + const [waitDownload, setWaitDownload] = React.useState(false); + + React.useEffect(() => { + setFromDateValue(minDate); + }, [minDate]); + + React.useEffect(() => { + setToDateValue(maxDate); + }, [maxDate]); + + const marginBottom = 2.5; + const { reset, register, handleSubmit } = useForm() + const doExport = () => { + setWaitDownload(true) + let sentDateFrom = ""; + let sentDateTo = ""; + if( fromDateValue!="dd / mm / yyyy"&&toDateValue!="dd / mm / yyyy"){ + sentDateFrom = DateUtils.dateValue(fromDateValue) + sentDateTo = DateUtils.dateValue(toDateValue) + } + + const temp = { + issueId: issueSelected?.id, + dateFrom: sentDateFrom, + dateTo: sentDateTo + }; + HttpUtils.fileDownload({ + url: UrlUtils.GEN_FULL_LIST, + params: temp, + onResponse: () => { + setTimeout(()=> setWaitDownload(false), 500) + } + }); + }; + + React.useEffect(() => { + if (issueComboData && issueComboData.length > 0) { + setIssueCombo(issueComboData); + if(searchCriteria.issueId!=undefined){ + setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) + } + } + }, [issueComboData]); + + const getIssueLabel=(data)=> { + let issueYear = data.issueYear + let volume = data.volume; + let issueNo = data.issueNo; + let issueDate = data.issueDate; + return issueYear + + " Vol. " + FormatUtils.zeroPad(volume, 3) + + ", No. " + FormatUtils.zeroPad(issueNo, 2) + + ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)"); + } + + function resetForm() { + setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) + setMaxDate(DateUtils.dateValue(new Date())) + reset({contact:""}); + } + + + return ( + + +
    + + {/*row 1*/} + + + Search + + + {/*row 2*/} + + + getIssueLabel(option)} + onChange={(event, newValue) => { + setIssueSelected(newValue); + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + setReceiptFromError(newError)} + slotProps={{ + field: { readOnly: true, }, + // textField: { + // helperText: receiptFromErrorMessage, + // }, + }} + format="DD/MM/YYYY" + label={"Submit Date (From)"} + value={minDate === null ? null : dayjs(minDate)} + maxDate={maxDate === null ? null : dayjs(maxDate)} + onChange={(newValue) => { + // console.log(newValue) + if(newValue!=null){ + setMinDate(newValue); + } + }} + /> + + + + + + + + setReceiptFromError(newError)} + slotProps={{ + field: { readOnly: true, }, + // textField: { + // helperText: receiptFromErrorMessage, + // }, + }} + format="DD/MM/YYYY" + label={"Submit Date (To)"} + value={maxDate === null ? null : dayjs(maxDate)} + minDate={minDate === null ? null : dayjs(minDate)} + onChange={(newValue) => { + // console.log(newValue) + if(newValue!=null){ + setMaxDate(newValue); + } + }} + /> + + + + + + + + + {/*last row*/} + + + + + + + + + + + +
    +
    + ); +}; + +export default FullListForm; diff --git a/src/pages/Report/SummaryForm.js b/src/pages/Report/SummaryForm.js new file mode 100644 index 0000000..78fc601 --- /dev/null +++ b/src/pages/Report/SummaryForm.js @@ -0,0 +1,200 @@ +// material-ui +import { + Button, + Grid, + TextField, + Typography +} from '@mui/material'; +import MainCard from "components/MainCard"; +import { useForm } from "react-hook-form"; +import * as React from "react"; +import * as DateUtils from "utils/DateUtils"; +import {ThemeProvider} from "@emotion/react"; +import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst"; +import * as HttpUtils from "utils/HttpUtils"; +import * as UrlUtils from "utils/ApiPathConst"; + +import {DatePicker} from "@mui/x-date-pickers/DatePicker"; +import dayjs from "dayjs"; +import {DemoItem} from "@mui/x-date-pickers/internals/demo"; +import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; +import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // +const SummaryForm = ({ searchCriteria}) => { + + const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); + const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); + + const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); + const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); + + + const [waitDownload, setWaitDownload] = React.useState(false); + + React.useEffect(() => { + setFromDateValue(minDate); + }, [minDate]); + + React.useEffect(() => { + setToDateValue(maxDate); + }, [maxDate]); + + const marginBottom = 2.5; + const { reset, register, handleSubmit } = useForm() + const onSubmit = (data) => { + setWaitDownload(true) + let sentDateFrom = ""; + let sentDateTo = ""; + if( fromDateValue!="dd / mm / yyyy"&&toDateValue!="dd / mm / yyyy"){ + sentDateFrom = DateUtils.dateValue(fromDateValue) + sentDateTo = DateUtils.dateValue(toDateValue) + } + + const temp = { + dateFrom: sentDateFrom, + dateTo: sentDateTo, + contact: data.contact, + }; + doExport(temp); + }; + + const doExport = (temp) => { + HttpUtils.fileDownload({ + url: UrlUtils.GEN_SUMMARY_LIST, + params: temp, + onResponse: () => { + setTimeout(()=> setWaitDownload(false), 500) + } + }); + }; + + function resetForm() { + setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) + setMaxDate(DateUtils.dateValue(new Date())) + reset({contact:""}); + } + + + return ( + + +
    + + {/*row 1*/} + + + Search + + + {/*row 2*/} + + + + + + + + + + + + setReceiptFromError(newError)} + slotProps={{ + field: { readOnly: true, }, + // textField: { + // helperText: receiptFromErrorMessage, + // }, + }} + format="DD/MM/YYYY" + label={"Submit Date (From)"} + value={minDate === null ? null : dayjs(minDate)} + maxDate={maxDate === null ? null : dayjs(maxDate)} + onChange={(newValue) => { + // console.log(newValue) + if(newValue!=null){ + setMinDate(newValue); + } + }} + /> + + + + + + + + setReceiptFromError(newError)} + slotProps={{ + field: { readOnly: true, }, + // textField: { + // helperText: receiptFromErrorMessage, + // }, + }} + format="DD/MM/YYYY" + label={"Submit Date (To)"} + value={maxDate === null ? null : dayjs(maxDate)} + minDate={minDate === null ? null : dayjs(minDate)} + onChange={(newValue) => { + // console.log(newValue) + if(newValue!=null){ + setMaxDate(newValue); + } + }} + /> + + + + + + + + + {/*last row*/} + + + + + + + + + + + +
    +
    + ); +}; + +export default SummaryForm; diff --git a/src/pages/Report/index.js b/src/pages/Report/index.js new file mode 100644 index 0000000..1c3fa7d --- /dev/null +++ b/src/pages/Report/index.js @@ -0,0 +1,106 @@ +// material-ui +import { + Grid, + Typography, + Stack +} from '@mui/material'; +import MainCard from "components/MainCard"; +import * as React from "react"; +import * as DateUtils from "utils/DateUtils"; +import { getSearchCriteria } from "auth/utils"; +import * as HttpUtils from "utils/HttpUtils"; +import * as UrlUtils from "utils/ApiPathConst"; + +import Loadable from 'components/Loadable'; +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +const FullListForm = Loadable(React.lazy(() => import('./FullListForm'))); +const SummaryForm = Loadable(React.lazy(() => import('./SummaryForm'))); +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' + +const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: '100%', + height: '100%', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' +} + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const ReportSearchPage = () => { + + const [searchCriteria, setSearchCriteria] = React.useState({}); + const [onReady, setOnReady] = React.useState(false); + const [issueCombo, setIssueCombo] = React.useState([]); + + React.useEffect(() => { + getIssueCombo(); + if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ + setSearchCriteria(getSearchCriteria(window.location.pathname)) + }else{ + localStorage.setItem('searchCriteria',"") + setSearchCriteria({ + dateTo: DateUtils.dateValue(new Date()), + dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), + }) + } + }, []); + + function getIssueCombo() { + HttpUtils.get({ + url: UrlUtils.GET_ISSUE_COMBO, + onSuccess: function (responseData) { + let combo = responseData; + setIssueCombo(combo); + } + }); + } + + React.useEffect(() => { + setOnReady(true); + }, [searchCriteria]); + + + return ( + !onReady ? + + + + + + : + + +
    + + Announcement + +
    +
    + {/*row 1*/} + + + + + + + {/*row 2*/} + + + + +
    + ); +} +export default ReportSearchPage; diff --git a/src/routes/GLDUserRoutes.js b/src/routes/GLDUserRoutes.js index 1d10174..0460b75 100644 --- a/src/routes/GLDUserRoutes.js +++ b/src/routes/GLDUserRoutes.js @@ -34,6 +34,7 @@ const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index'))); const ReconReportPage = Loadable(lazy(() => import('pages/Recon'))); const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage'))); const JVMDefault = Loadable(lazy(() => import('pages/JVM'))); +const ReportPage = Loadable(lazy(() => import('pages/Report'))); // ==============================|| MAIN ROUTING ||============================== // @@ -202,7 +203,11 @@ const GLDUserRoutes = { { path: '/user/changePassword', element: - } + }, + { + path: '/setting/report', + element: + }, ] } ] diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index d6ccd49..67a4acd 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -237,6 +237,8 @@ export const GEN_PAYMENT_RECEIPT = apiPath+'/payment/receipt'; //POST export const GEN_GFMIS_XML = apiPath+'/gfmis'; //GET export const VIEW_RECON_REPORT = apiPath+'/reportings/report'; //GET export const GEN_RECON_REPORT = apiPath+'/reportings/download'; //GET +export const GEN_FULL_LIST = apiPath+'/application/export-full-excel'; //GET +export const GEN_SUMMARY_LIST = apiPath+'/application/export-summary-excel'; //GET //Holiday export const GET_HOLIDAY = apiPath+'/holiday/list'; //GET