You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

381 lines
16 KiB

  1. // material-ui
  2. import {
  3. Button,
  4. CardContent,
  5. Grid, TextField,
  6. Autocomplete,
  7. Typography
  8. } from '@mui/material';
  9. import MainCard from "components/MainCard";
  10. import { useForm } from "react-hook-form";
  11. import * as React from "react";
  12. import * as ComboData from "utils/ComboData";
  13. import * as DateUtils from "utils/DateUtils";
  14. import * as FormatUtils from "utils/FormatUtils";
  15. import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst";
  16. import {ThemeProvider} from "@emotion/react";
  17. import {FormattedMessage, useIntl} from "react-intl";
  18. import {DatePicker} from "@mui/x-date-pickers/DatePicker";
  19. import dayjs from "dayjs";
  20. import {DemoItem} from "@mui/x-date-pickers/internals/demo";
  21. import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
  22. import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
  23. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  24. const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, onGridReady
  25. }) => {
  26. const intl = useIntl();
  27. const { locale } = intl;
  28. const [type, setType] = React.useState([]);
  29. const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatusFull[searchCriteria.statusKey]:ComboData.proofStatusFull[0]);
  30. const [issueSelected, setIssueSelected] = React.useState({});
  31. const [issueCombo, setIssueCombo] = React.useState([]);
  32. const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{});
  33. const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
  34. const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
  35. const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
  36. const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");
  37. React.useEffect(() => {
  38. setFromDateValue(minDate);
  39. }, [minDate]);
  40. React.useEffect(() => {
  41. setToDateValue(maxDate);
  42. }, [maxDate]);
  43. const _sx = {
  44. padding: "4 2 4 2",
  45. boxShadow: 1,
  46. border: 1,
  47. borderColor: '#DDD',
  48. '& .MuiDataGrid-cell': {
  49. borderTop: 1,
  50. borderBottom: 1,
  51. borderColor: "#EEE"
  52. },
  53. '& .MuiDataGrid-footerContainer': {
  54. border: 1,
  55. borderColor: "#EEE"
  56. }
  57. }
  58. const { reset, register, handleSubmit } = useForm()
  59. const onSubmit = (data) => {
  60. let typeArray = [];
  61. let sentDateFrom = "";
  62. let sentDateTo = "";
  63. for (let i = 0; i < type.length; i++) {
  64. typeArray.push(type[i].label);
  65. }
  66. if (fromDateValue != "dd / mm / yyyy" && toDateValue != "dd / mm / yyyy") {
  67. sentDateFrom = DateUtils.dateValue(fromDateValue)
  68. sentDateTo = DateUtils.dateValue(toDateValue)
  69. }
  70. const temp = {
  71. refNo: data.refNo,
  72. code: data.code,
  73. issueId: issueSelected?.id,
  74. gazettGroup: groupSelected?.type,
  75. dateFrom: sentDateFrom,
  76. dateTo: sentDateTo,
  77. statusKey:status?.key,
  78. };
  79. if(status?.type && status?.type != 'all'){
  80. if (status?.type == "Confirmed"){
  81. temp["replyed"] = "T";
  82. temp["action"] = true;
  83. }else if(status?.type == "Re-proofing"){
  84. temp["replyed"] = "T";
  85. temp["action"] = false;
  86. }else if(status?.type == "No Reply"){
  87. temp["replyed"] = "F";
  88. temp["timeOut"] = "T";
  89. }else{
  90. temp["replyed"] = "F";
  91. temp["timeOut"] = "F";
  92. }
  93. }
  94. applySearch(temp);
  95. };
  96. React.useEffect(() => {
  97. if (issueComboData && issueComboData.length > 0) {
  98. setIssueCombo(issueComboData);
  99. if(searchCriteria.issueId!=undefined){
  100. setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
  101. }
  102. }
  103. }, [issueComboData]);
  104. function resetForm() {
  105. setType([]);
  106. setStatus(ComboData.proofStatusFull[0]);
  107. setIssueSelected({});
  108. setGroupSelected({});
  109. setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
  110. setMaxDate(DateUtils.dateValue(new Date()))
  111. reset();
  112. localStorage.setItem('searchCriteria',"")
  113. }
  114. function getIssueLabel(data) {
  115. let issueYear = data.issueYear
  116. let volume = data.volume;
  117. let issueNo = data.issueNo;
  118. let issueDate = data.issueDate;
  119. if (locale === 'zh-HK') {
  120. return issueYear
  121. + " 第" + volume + "卷,"
  122. + " 第" + issueNo + "期,"
  123. + " " + DateUtils.dateFormat(issueDate, "YYYY年MM月DD日")
  124. + " (" + DateUtils.getWeekdayStr_ZH(issueDate) + ")";
  125. } else if (locale === 'zh-CN') {
  126. return issueYear
  127. + " 第" + volume + "卷,"
  128. + " 第" + issueNo + "期,"
  129. + " " + DateUtils.dateFormat(issueDate, "YYYY年MM月DD日")
  130. + " (" + DateUtils.getWeekdayStr_CN(issueDate) + ")";
  131. }
  132. return issueYear
  133. + " Vol. " + FormatUtils.zeroPad(volume, 3)
  134. + ", No. " + FormatUtils.zeroPad(issueNo, 2)
  135. + ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)");
  136. }
  137. return (
  138. <MainCard xs={12} md={12} lg={12}
  139. border={false}
  140. content={false}
  141. sx={_sx}
  142. >
  143. <form onSubmit={handleSubmit(onSubmit)}>
  144. {/*row 1*/}
  145. <CardContent sx={{ px: 2.5, pt: 3 }}>
  146. <Grid item justifyContent="space-between" alignItems="center">
  147. <Typography variant="pnspsFormHeader">
  148. <FormattedMessage id="searchForm"/>
  149. </Typography>
  150. </Grid>
  151. </CardContent>
  152. {/*row 2*/}
  153. <Grid container alignItems={"center"}>
  154. <Grid item xs={12} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  155. <TextField
  156. fullWidth
  157. {...register("refNo")}
  158. id='refNo'
  159. label={intl.formatMessage({id: 'proofId'}) }
  160. defaultValue={searchCriteria.refNo}
  161. InputLabelProps={{
  162. shrink: true
  163. }}
  164. />
  165. </Grid>
  166. <Grid item xs={12} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  167. <TextField
  168. fullWidth
  169. {...register("code")}
  170. id='code'
  171. label={intl.formatMessage({id: 'applicationId'})}
  172. defaultValue={searchCriteria.code}
  173. InputLabelProps={{
  174. shrink: true
  175. }}
  176. />
  177. </Grid>
  178. <Grid item xs={12} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  179. <Autocomplete
  180. {...register("issueId")}
  181. disablePortal
  182. id="issueId"
  183. options={issueCombo}
  184. value={issueSelected}
  185. inputValue={(issueSelected?.id) ? getIssueLabel(issueSelected) : ""}
  186. getOptionLabel={(option) => getIssueLabel(option)}
  187. onChange={(event, newValue) => {
  188. setIssueSelected(newValue);
  189. }}
  190. renderInput={(params) => (
  191. <TextField {...params}
  192. label={intl.formatMessage({id: 'gazetteCount'})}
  193. InputLabelProps={{
  194. shrink: true
  195. }}
  196. />
  197. )}
  198. />
  199. </Grid>
  200. {/* <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  201. <Autocomplete
  202. {...register("gazettGroup")}
  203. disablePortal
  204. id="gazettGroup"
  205. options={ComboData.groupTitle}
  206. value={groupSelected}
  207. inputValue={(groupSelected?.labelCht) ? groupSelected?.labelCht : ""}
  208. getOptionLabel={(option) => option.labelCht}
  209. onChange={(event, newValue) => {
  210. setGroupSelected(newValue);
  211. }}
  212. renderInput={(params) => (
  213. <TextField {...params}
  214. label="憲報類型"
  215. InputLabelProps={{
  216. shrink: true
  217. }}
  218. />
  219. )}
  220. />
  221. </Grid> */}
  222. <Grid item xs={12} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  223. <Grid container spacing={1}>
  224. <Grid item xs={6}>
  225. <LocalizationProvider dateAdapter={AdapterDayjs}>
  226. <DemoItem components={['DatePicker']}>
  227. <DatePicker
  228. id="dateFrom"
  229. // onError={(newError) => setReceiptFromError(newError)}
  230. slotProps={{
  231. field: { readOnly: true, },
  232. // textField: {
  233. // helperText: receiptFromErrorMessage,
  234. // },
  235. }}
  236. format="DD/MM/YYYY"
  237. label={intl.formatMessage({id: 'proofDateFrom'})}
  238. value={minDate === null ? null : dayjs(minDate)}
  239. maxDate={maxDate === null ? null : dayjs(maxDate)}
  240. onChange={(newValue) => {
  241. // console.log(newValue)
  242. if(newValue!=null){
  243. setMinDate(newValue);
  244. }
  245. }}
  246. />
  247. </DemoItem >
  248. </LocalizationProvider>
  249. </Grid>
  250. <Grid item xs={6}>
  251. <LocalizationProvider dateAdapter={AdapterDayjs}>
  252. <DemoItem components={['DatePicker']}>
  253. <DatePicker
  254. id="dateTo"
  255. // onError={(newError) => setReceiptFromError(newError)}
  256. slotProps={{
  257. field: { readOnly: true, },
  258. // textField: {
  259. // helperText: receiptFromErrorMessage,
  260. // },
  261. }}
  262. format="DD/MM/YYYY"
  263. label={intl.formatMessage({id: 'proofDateTo'})}
  264. value={maxDate === null ? null : dayjs(maxDate)}
  265. minDate={minDate === null ? null : dayjs(minDate)}
  266. onChange={(newValue) => {
  267. // console.log(newValue)
  268. if(newValue!=null){
  269. setMaxDate(newValue);
  270. }
  271. }}
  272. />
  273. </DemoItem >
  274. </LocalizationProvider>
  275. </Grid>
  276. </Grid>
  277. </Grid>
  278. {/* <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  279. <TextField
  280. fullWidth
  281. {...register("contact")}
  282. id="contact"
  283. label="聯絡人"
  284. defaultValue={searchCriteria.contact}
  285. InputLabelProps={{
  286. shrink: true
  287. }}
  288. />
  289. </Grid> */}
  290. <Grid item xs={12} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
  291. <Autocomplete
  292. {...register("status")}
  293. disablePortal={false}
  294. size="small"
  295. id="status"
  296. disableClearable
  297. filterOptions={(options) => options}
  298. options={ComboData.proofStatusFull}
  299. value={status}
  300. getOptionLabel={(option) => option.type? intl.formatMessage({ id: option.i18nLabel }) : ""}
  301. inputValue={status? intl.formatMessage({ id: status.i18nLabel }) : ""}
  302. onChange={(event, newValue) => {
  303. if (newValue !== null) {
  304. setStatus(newValue);
  305. }else{
  306. setStatus(ComboData.proofStatus[0]);
  307. }
  308. }}
  309. renderInput={(params) => (
  310. <TextField {...params}
  311. label={intl.formatMessage({id: 'status'})}
  312. />
  313. )}
  314. InputLabelProps={{
  315. shrink: true
  316. }}
  317. />
  318. </Grid>
  319. </Grid>
  320. {/*last row*/}
  321. <Grid container maxWidth justifyContent="flex-end">
  322. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  323. <Grid item sx={{ mr: 3, mb: 3 }}>
  324. <Button
  325. variant="contained"
  326. color="cancel"
  327. onClick={resetForm}
  328. aria-label={intl.formatMessage({id: 'reset'})}
  329. >
  330. <FormattedMessage id="reset"/>
  331. </Button>
  332. </Grid>
  333. <Grid item sx={{mr: 3, mb: 3 }}>
  334. <Button
  335. variant="contained"
  336. type="submit"
  337. aria-label={intl.formatMessage({id: 'submit'})}
  338. disabled={onGridReady}
  339. >
  340. <FormattedMessage id="submit"/>
  341. </Button>
  342. </Grid>
  343. </ThemeProvider>
  344. </Grid>
  345. </form>
  346. </MainCard>
  347. );
  348. };
  349. export default SearchPublicNoticeForm;