From 9b4124872ef6c543fb891a9ba7db46edfc6d5a0b Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 16 Feb 2024 17:02:49 +0800 Subject: [PATCH] add announcement UI --- src/layout/MainLayout/Header/index.js | 3 + .../Announcement/Details/AnnouncementForm.js | 336 ++++++++++++++++++ src/pages/Announcement/Details/index.js | 64 ++++ src/pages/Announcement/Search/DataGrid.js | 83 +++++ src/pages/Announcement/Search/SearchForm.js | 155 ++++++++ src/pages/Announcement/Search/index.js | 104 ++++++ src/pages/dashboard/Public/Message.js | 2 +- src/pages/dashboard/Public/Notice.js | 53 ++- src/routes/GLDUserRoutes.js | 10 + src/themes/buttonConst.js | 4 + src/utils/ApiPathConst.js | 7 +- 11 files changed, 811 insertions(+), 10 deletions(-) create mode 100644 src/pages/Announcement/Details/AnnouncementForm.js create mode 100644 src/pages/Announcement/Details/index.js create mode 100644 src/pages/Announcement/Search/DataGrid.js create mode 100644 src/pages/Announcement/Search/SearchForm.js create mode 100644 src/pages/Announcement/Search/index.js diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js index 7a33057..f06f37b 100644 --- a/src/layout/MainLayout/Header/index.js +++ b/src/layout/MainLayout/Header/index.js @@ -146,6 +146,9 @@ function Header(props) {
  • System Setting
  • +
  • + Announcement +
  • diff --git a/src/pages/Announcement/Details/AnnouncementForm.js b/src/pages/Announcement/Details/AnnouncementForm.js new file mode 100644 index 0000000..0a78ed8 --- /dev/null +++ b/src/pages/Announcement/Details/AnnouncementForm.js @@ -0,0 +1,336 @@ +// material-ui +import { + Grid, + Typography, + Button, + TextField, + Stack, Box +} from '@mui/material'; +import { useFormik } from 'formik'; +import * as yup from 'yup'; +import * as React from "react"; +import * as HttpUtils from "utils/HttpUtils"; +import * as UrlUtils from "utils/ApiPathConst"; +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' +import ForwardIcon from '@mui/icons-material/Forward'; +import Divider from '@mui/material/Divider'; +import {useParams} from "react-router-dom"; +import { useNavigate } from "react-router-dom"; +import { notifyActionSuccess } from 'utils/CommonFunction'; +import { useIntl } from "react-intl"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const AnnouncementForm = ({ loadedData }) => { + const intl = useIntl(); + const params = useParams(); + const navigate = useNavigate(); + + const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: 'auto', + height: 'auto', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' + } + + + const formik = useFormik({ + enableReinitialize: true, + initialValues: loadedData, + validationSchema: yup.object().shape({ + subjectEng: yup.string().max(255).required(), + subjectCht: yup.string().max(255).required(), + subjectChs: yup.string().max(255).required(), + contentEng: yup.string().required(), + contentCht: yup.string().required(), + contentChs: yup.string().required(), + }), + onSubmit: values => { + doSave(values); + } + }); + + const doSave = (values) => { + HttpUtils.post({ + url: UrlUtils.POST_ANNOUNCE_SAVE, + params: { + id: params?.id??0, + announceDate: values.announceDate, + subjectEng: values.subjectEng, + subjectCht: values.subjectCht, + subjectChs: values.subjectChs, + + contentEng: values.contentEng, + contentCht: values.contentCht, + contentChs: values.contentChs, + }, + onSuccess: function () { + notifyActionSuccess(intl.formatMessage({ id: 'submissionSuccess' }) + '!') + navigate("/setting/announcement"); + } + }); + } + + return ( + + +
    + + + Announcement + + +
    +
    + + + + + + +
    + + + + + + + + + + Announce Date: + + + + + + + + + English + + + + Subject: + + + + + + + + + + + Content: + + + + + + + + + Traditional Chinese + + + + Subject: + + + + + + + + + + + Content: + + + + + + + + + + + Simplified Chinese + + + + Subject: + + + + + + + + + + + + Content: + + + + + + + + +
    +
    +
    + +
    + ); +}; + + +export default AnnouncementForm; diff --git a/src/pages/Announcement/Details/index.js b/src/pages/Announcement/Details/index.js new file mode 100644 index 0000000..c24fa0b --- /dev/null +++ b/src/pages/Announcement/Details/index.js @@ -0,0 +1,64 @@ +// material-ui +import * as React from "react"; +import * as HttpUtils from "utils/HttpUtils"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as DateUtils from "utils/DateUtils"; + +import { + Grid, +} from '@mui/material'; + +import { useParams } from 'react-router-dom'; +import Loadable from 'components/Loadable'; +import { lazy } from 'react'; +const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent'))); +const AnnouncementForm = Loadable(lazy(() => import('./AnnouncementForm'))); + + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const CreateForm = () => { + const params = useParams(); + + const [formData, setFormData] = React.useState({}); + const [isLoading, setLoding] = React.useState(true); + + React.useEffect(() => { + loadData(); + }, []); + + const loadData = () => { + setLoding(true); + if (params.id > 0) { + HttpUtils.get({ + url: `${UrlUtils.GET_ANNOUNCE}`+"/"+params.id, + onSuccess: function (responseData) { + responseData["announceDate"] = DateUtils.datetimeFieldFormat(responseData.announceDate); + setFormData(responseData); + } + }); + }else{ + setFormData({"announceDate": DateUtils.datetimeFieldFormat(new Date())}); + } + }; + + React.useEffect(() => { + if (formData !== null && formData != {}) setLoding(false); + }, [formData]); + + return ( + isLoading ? + + + + + + : + + ); +}; + + +export default CreateForm; diff --git a/src/pages/Announcement/Search/DataGrid.js b/src/pages/Announcement/Search/DataGrid.js new file mode 100644 index 0000000..bcbeab0 --- /dev/null +++ b/src/pages/Announcement/Search/DataGrid.js @@ -0,0 +1,83 @@ +// material-ui +import * as React from 'react'; +import { + Button, + Box +} from '@mui/material'; +import * as DateUtils from "utils/DateUtils"; +import { useNavigate } from "react-router-dom"; +import { FiDataGrid } from "components/FiDataGrid"; +// ==============================|| EVENT TABLE ||============================== // + +export default function SearchPublicNoticeTable({ recordList }) { + const [rows, setRows] = React.useState(recordList); + const navigate = useNavigate() + + React.useEffect(() => { + setRows(recordList); + }, [recordList]); + + const handleEditClick = (params) => () => { + navigate('/setting/announcement/details/' + params.id); + }; + + + const columns = [ + { + field: 'announceDate', + headerName: 'Announce Date', + width: 250, + cellClassName: 'announceDate', + renderCell: (params) => { + return ; + }, + }, + { + id: 'subjec', + field: 'subjec', + headerName: 'Subjec', + minWidth: 400, + renderCell: (params) => { + return <> + + {params.row.subjectEng} + {params.row.subjectCht} + {params.row.subjectChs} + + + }, + }, + { + id: 'content', + field: 'content', + headerName: 'Content', + flex:1, + minWidth: 400, + renderCell: (params) => { + return <> + + {params.row.contentEng} + {params.row.contentCht} + {params.row.contentChs} + + + } + }, + ]; + + function handleRowDoubleClick(params) { + navigate('/setting/announcement/details/' + params.id); + } + + return ( +
    + 'auto'} + onRowDoubleClick={handleRowDoubleClick} + /> +
    + ); +} diff --git a/src/pages/Announcement/Search/SearchForm.js b/src/pages/Announcement/Search/SearchForm.js new file mode 100644 index 0000000..500385c --- /dev/null +++ b/src/pages/Announcement/Search/SearchForm.js @@ -0,0 +1,155 @@ +// 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 { useNavigate } from "react-router-dom"; +import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst"; +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { + const navigate = useNavigate() + + const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); + const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); + + const marginBottom = 2.5; + const { reset, register, handleSubmit } = useForm() + const onSubmit = (data) => { + const temp = { + key: data.key, + dateFrom: data.dateFrom, + dateTo: data.dateTo, + }; + applySearch(temp); + }; + + + function resetForm() { + reset(); + } + + + return ( + + +
    + + {/*row 1*/} + + + Search + + + {/*row 2*/} + + + + + + + + + { + setMinDate(DateUtils.dateStr(newValue)); + }} + InputLabelProps={{ + shrink: true + }} + /> + + + + To + + + + { + setMaxDate(DateUtils.dateStr(newValue)); + }} + id="dateTo" + type="date" + //label={"Submit Date(To)"} + defaultValue={searchCriteria.dateTo} + /> + + + + + + + {/*last row*/} + + + + + + + + + + + + + + + +
    +
    + ); +}; + +export default SearchPublicNoticeForm; diff --git a/src/pages/Announcement/Search/index.js b/src/pages/Announcement/Search/index.js new file mode 100644 index 0000000..073f486 --- /dev/null +++ b/src/pages/Announcement/Search/index.js @@ -0,0 +1,104 @@ +// material-ui +import { + Grid, + Typography, + Stack +} from '@mui/material'; +import MainCard from "components/MainCard"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as React from "react"; +import * as HttpUtils from "utils/HttpUtils"; +import * as DateUtils from "utils/DateUtils"; + +import Loadable from 'components/Loadable'; +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); +const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); +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 UserSearchPage_Individual = () => { + + const [record, setRecord] = React.useState([]); + const [searchCriteria, setSearchCriteria] = React.useState({ + dateTo: DateUtils.dateStr(new Date()), + dateFrom: DateUtils.dateStr(new Date().setDate(new Date().getDate() - 90)), + }); + const [onReady, setOnReady] = React.useState(false); + + React.useEffect(() => { + getDataList(); + }, []); + + React.useEffect(() => { + setOnReady(true); + }, [record]); + + React.useEffect(() => { + getDataList(); + }, [searchCriteria]); + + function getDataList() { + HttpUtils.get({ + url: UrlUtils.GET_ANNOUNCE_LIST, + params: searchCriteria, + onSuccess: function (responseData) { + setRecord(responseData); + } + }); + } + + function applySearch(input) { + setSearchCriteria(input); + } + + return ( + !onReady ? + + + + + + : + + +
    + + Announcement + +
    +
    + {/*row 1*/} + + + + {/*row 2*/} + + + + + +
    + ); +} +export default UserSearchPage_Individual; diff --git a/src/pages/dashboard/Public/Message.js b/src/pages/dashboard/Public/Message.js index f959904..8d13377 100644 --- a/src/pages/dashboard/Public/Message.js +++ b/src/pages/dashboard/Public/Message.js @@ -26,7 +26,7 @@ const SearchDemandNoteForm = () => { const loadData = () => { HttpUtils.get({ - url: UrlUtils.GET_MSG_DESHBOARD, + url: UrlUtils.GET_MSG_DASHBOARD, onSuccess: function (response) { let list = [] response.map((item) => { diff --git a/src/pages/dashboard/Public/Notice.js b/src/pages/dashboard/Public/Notice.js index b7a1029..93b2247 100644 --- a/src/pages/dashboard/Public/Notice.js +++ b/src/pages/dashboard/Public/Notice.js @@ -1,29 +1,66 @@ // material-ui import { + Stack, Typography, - Stack } from '@mui/material'; import MainCard from "components/MainCard"; import * as React from "react"; +import * as HttpUtils from "utils/HttpUtils"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as DateUtils from "utils/DateUtils"; + +import { useIntl} from "react-intl"; // ==============================|| DASHBOARD - DEFAULT ||============================== // const SearchDemandNoteForm = () => { + const [itemList, setItemList] = React.useState([]); + const [listData, setListData] = React.useState([]); + const intl = useIntl(); + const { locale } = intl; + + + React.useEffect(() => { + loadData(); + }, []); + + React.useEffect(() => { + let list = [] + if(listData == []) return; + listData.map((item) => { + list.push( + + {locale === 'en' ?item.subjectEng:locale === 'zh-HK' ?item.subjectCht:item.subjectChs} + {DateUtils.datetimeStr(item.announceDate)} + {locale === 'en' ?item.contentEng:locale === 'zh-HK' ?item.contentCht:item.contentChs} + + ) + }); + setItemList(list); + }, [listData,intl]); + + const loadData = () => { + + HttpUtils.get({ + url: UrlUtils.GET_ANNOUNCE_DASHBOARD, + onSuccess: function (response) { + setListData(response); + } + }); + }; + + return ( - - - - + + {itemList} - - ); }; diff --git a/src/routes/GLDUserRoutes.js b/src/routes/GLDUserRoutes.js index 475de96..a2f78c8 100644 --- a/src/routes/GLDUserRoutes.js +++ b/src/routes/GLDUserRoutes.js @@ -20,6 +20,8 @@ const DemandNote_Details = Loadable(lazy(() => import('pages/DemandNote/Details' const GFMIS_Search = Loadable(lazy(() => import('pages/GFMIS'))); const UserMaintainPage = Loadable(lazy(() => import('pages/User/GLDUserProfile'))); const SystemSetting = Loadable(lazy(() => import('pages/Setting/SystemSetting'))); +const AnnouncementDetails = Loadable(lazy(() => import('pages/Announcement/Details'))); +const AnnouncementSearch = Loadable(lazy(() => import('pages/Announcement/Search'))); // ==============================|| MAIN ROUTING ||============================== // @@ -90,6 +92,14 @@ const GLDUserRoutes = { path: '/setting/sys', element: }, + { + path: '/setting/announcement', + element: + }, + { + path: '/setting/announcement/details/:id', + element: + }, ] }, ] diff --git a/src/themes/buttonConst.js b/src/themes/buttonConst.js index 6ac414b..025c764 100644 --- a/src/themes/buttonConst.js +++ b/src/themes/buttonConst.js @@ -47,6 +47,10 @@ export const PNSPS_BUTTON_THEME = createTheme({ main: '#448DF2', contrastText: '#FFFFFF', }, + green:{ + main: '#4ac234', + contrastText: '#FFFFFF', + }, orange: { main: '#ed9740', light: '#ff5e5e', diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 17e98f6..c3433e8 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -49,7 +49,12 @@ export const GET_PUB_ORG_MARK_AS_NON_CREDITOR = apiPath+'/org/pub/mark-as-non-cr export const GET_MSG_DETAILS = apiPath+'/msg/details'; export const GET_MSG_LIST = apiPath+'/msg/list'; -export const GET_MSG_DESHBOARD = apiPath+'/msg/list/deshboard'; +export const GET_MSG_DASHBOARD = apiPath+'/msg/list/deshboard'; + +export const POST_ANNOUNCE_SAVE = apiPath+'/announcement/save'; +export const GET_ANNOUNCE = apiPath+'/announcement'; +export const GET_ANNOUNCE_LIST = apiPath+'/announcement/list'; +export const GET_ANNOUNCE_DASHBOARD = apiPath+'/announcement/dashboard'; export const CHECK_OVERDUE = apiPath+'/application/check-overdue';