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.
 
 

598 line
32 KiB

  1. // material-ui
  2. import {
  3. Grid, Button, Typography,
  4. FormHelperText,
  5. Stack,
  6. IconButton
  7. } from '@mui/material';
  8. import MainCard from "components/MainCard";
  9. import { useEffect, useState, lazy } from "react";
  10. import * as yup from 'yup';
  11. import { useFormik } from 'formik';
  12. import * as FieldUtils from "utils/FieldUtils";
  13. import * as HttpUtils from 'utils/HttpUtils';
  14. import * as UrlUtils from "utils/ApiPathConst";
  15. import * as ComboData from "utils/ComboData";
  16. const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
  17. import Loadable from 'components/Loadable';
  18. import { notifyActiveSuccess, notifyLockSuccess, notifySaveSuccess, notifyVerifySuccess } from 'utils/CommonFunction';
  19. import { useIntl } from "react-intl";
  20. import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
  21. import { ThemeProvider } from "@emotion/react";
  22. import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
  23. import { isGrantedAny } from "auth/utils";
  24. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  25. const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
  26. const intl = useIntl();
  27. const [currentUserData, setCurrentUserData] = useState(formData);
  28. const [editMode, setEditMode] = useState(false);
  29. const [locked, setLocked] = useState(false);
  30. const [onReady, setOnReady] = useState(false);
  31. const [errorMsg, setErrorMsg] = useState("");
  32. const [showId, setshowId] = useState(false);
  33. const handleClickShowId = () => {
  34. setshowId(!showId);
  35. };
  36. const handleMouseDownId = (event) => {
  37. event.preventDefault();
  38. };
  39. useEffect(() => {
  40. //if state data are ready and assign to different field
  41. // console.log(currentApplicationDetailData)
  42. if (Object.keys(currentUserData).length > 0) {
  43. setOnReady(true);
  44. }
  45. }, [currentUserData]);
  46. function getMaxErrStr(num, fieldname) {
  47. return intl.formatMessage({ id: 'noMoreThenNWords' }, { num: num, fieldname: fieldname ? intl.formatMessage({ id: fieldname }) + ": " : "" });
  48. }
  49. const formik = useFormik({
  50. enableReinitialize: true,
  51. initialValues: currentUserData,
  52. validationSchema: yup.object().shape({
  53. enName: yup.string().max(40, getMaxErrStr(40)).when('chName', {
  54. is: (chName) => chName?false:true,
  55. then: yup.string().required(intl.formatMessage({ id: 'userRequireEnglishName' }))
  56. }).nullable(),
  57. chName: yup.string().max(6, getMaxErrStr(6)).nullable(),
  58. addressLine1: yup.string().max(40, getMaxErrStr(40)).required(intl.formatMessage({ id: 'validateAddressLine1' })),
  59. addressLine2: yup.string().max(40, getMaxErrStr(40)).nullable(),
  60. addressLine3: yup.string().max(40, getMaxErrStr(40)).nullable(),
  61. emailAddress: yup.string().email(intl.formatMessage({ id: 'validEmailFormat' })).max(255).required(intl.formatMessage({ id: 'requireEmail' })),
  62. identification: yup.string().min(7, intl.formatMessage({ id: 'requireIdDocNumber' })).required(intl.formatMessage({ id: 'requireIdDocNumber' })),
  63. checkDigit: yup.string().max(1, getMaxErrStr(1)).required(intl.formatMessage({ id: 'requiredNumberInQuote' })).nullable(),
  64. idDocType: yup.string().max(255, getMaxErrStr(255)).required(intl.formatMessage({ id: 'requireIdDocType' })),
  65. tel_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })).required(intl.formatMessage({ id: 'requireDialingCode' })),
  66. fax_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })),
  67. phoneNumber: yup.string().min(8, intl.formatMessage({ id: 'require8Number' })).required(intl.formatMessage({ id: 'requireContactNumber' })),
  68. faxNumber: yup.string().min(8, intl.formatMessage({ id: 'require8Number' })).nullable(),
  69. }),
  70. onSubmit: values => {
  71. if (values.country == null) {
  72. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' }))
  73. } else {
  74. if (values.country.type == "hongKong" && values.district == null) {
  75. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' }))
  76. } else {
  77. HttpUtils.post({
  78. url: UrlUtils.POST_IND_USER + "/" + formData.id,
  79. params: {
  80. prefix: values.prefix,
  81. enName: values.enName,
  82. chName: values.chName,
  83. idDocType: values.idDocType,
  84. mobileNumber: {
  85. countryCode: values.tel_countryCode,
  86. phoneNumber: values.phoneNumber
  87. },
  88. identification: values.identification,
  89. checkDigit: values.checkDigit,
  90. faxNo: {
  91. countryCode: values.fax_countryCode,
  92. faxNumber: values.faxNumber
  93. },
  94. emailAddress: values.emailAddress,
  95. address: {
  96. country: values.country.type,
  97. district: values.district?.type,
  98. addressLine1: values.addressLine1,
  99. addressLine2: values.addressLine2,
  100. addressLine3: values.addressLine3,
  101. },
  102. preferLocale: values.preferLocale.type
  103. },
  104. onSuccess: function () {
  105. notifySaveSuccess();
  106. loadDataFun();
  107. }
  108. });
  109. }
  110. }
  111. }
  112. });
  113. useEffect(() => {
  114. if (Object.keys(formData).length > 0) {
  115. setCurrentUserData(formData);
  116. }
  117. }, [formData]);
  118. useEffect(() => {
  119. setLocked(currentUserData.locked);
  120. }, [currentUserData]);
  121. const onEditClick = () => {
  122. setEditMode(true);
  123. };
  124. const onVerifiedClick = () => {
  125. HttpUtils.get({
  126. url: UrlUtils.GET_IND_USER_VERIFY + "/" + formData.id,
  127. onSuccess: function () {
  128. notifyVerifySuccess()
  129. loadDataFun();
  130. }
  131. });
  132. };
  133. const doLock = () => {
  134. HttpUtils.get({
  135. url: UrlUtils.GET_USER_LOCK + "/" + formData.id,
  136. onSuccess: function () {
  137. notifyLockSuccess()
  138. loadDataFun();
  139. }
  140. });
  141. };
  142. const doUnlock = () => {
  143. HttpUtils.get({
  144. url: UrlUtils.GET_USER_UNLOCK + "/" + formData.id,
  145. onSuccess: function () {
  146. notifyActiveSuccess()
  147. loadDataFun();
  148. }
  149. });
  150. };
  151. return (
  152. <MainCard elevation={0}
  153. border={false}
  154. content={false}
  155. >
  156. {!onReady ?
  157. <LoadingComponent />
  158. :
  159. <form onSubmit={formik.handleSubmit} style={{ padding: 12 }}>
  160. {/*top button*/}
  161. {
  162. isGrantedAny("MAINTAIN_USER") ?
  163. <Grid item xs={12} sm={12} md={12} lg={12} sx={{ mb: 3 }} alignItems={"start"} justifyContent="center">
  164. <Grid container maxWidth justifyContent="flex-start">
  165. {editMode ?
  166. <>
  167. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  168. <Grid item sx={{ mr: 3 }}>
  169. <Button
  170. variant="contained"
  171. onClick={loadDataFun}
  172. color="cancel"
  173. >
  174. Reset & Back
  175. </Button>
  176. </Grid>
  177. <Grid item sx={{ ml: 3, mr: 3 }}>
  178. <Button
  179. variant="contained"
  180. type="submit"
  181. color="success"
  182. >
  183. Save
  184. </Button>
  185. </Grid>
  186. </ThemeProvider>
  187. </>
  188. :
  189. <>
  190. <Grid item sx={{ mr: 3 }}>
  191. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  192. <Button
  193. variant="contained"
  194. onClick={onEditClick}
  195. >
  196. Edit
  197. </Button>
  198. </ThemeProvider>
  199. </Grid>
  200. </>
  201. }
  202. </Grid>
  203. </Grid>
  204. : <></>
  205. }
  206. {/*end top button*/}
  207. <Typography variant="h4" sx={{ mt: 3, mb: 2, borderBottom: "1px solid black" }}>
  208. Individual User Details
  209. </Typography>
  210. <Grid item xs={12} sm={12} md={12} lg={12}>
  211. <Grid container>
  212. <Grid item xs={12}>
  213. <FormHelperText error id="helper-text-address1-signup">
  214. <Typography variant="errorMessage1">
  215. {errorMsg}
  216. </Typography>
  217. </FormHelperText>
  218. </Grid>
  219. <Grid item xs={12} sm={12} md={12} lg={4} >
  220. {FieldUtils.getTextField({
  221. label: "Username:",
  222. valueName: "username",
  223. disabled: true,
  224. form: formik
  225. })}
  226. </Grid>
  227. <Grid item xs={12} sm={12} md={12} lg={4}>
  228. {FieldUtils.getTextField({
  229. label: "English Name:",
  230. valueName: "enName",
  231. disabled: (!editMode),
  232. form: formik
  233. })}
  234. </Grid>
  235. <Grid item xs={12} sm={12} md={12} lg={4}>
  236. {FieldUtils.getTextField({
  237. label: "Created Date:",
  238. valueName: "createDate",
  239. disabled: true,
  240. form: formik
  241. })}
  242. </Grid>
  243. <Grid item xs={12} sm={12} md={12} lg={4}>
  244. {FieldUtils.getTextField({
  245. label: "Prefix:",
  246. valueName: "prefix",
  247. disabled: (!editMode),
  248. form: formik
  249. })}
  250. </Grid>
  251. <Grid item xs={12} sm={12} md={12} lg={4}>
  252. {FieldUtils.getTextField({
  253. label: "Chinese Name:",
  254. valueName: "chName",
  255. disabled: (!editMode),
  256. form: formik
  257. })}
  258. </Grid>
  259. <Grid item xs={12} sm={12} md={12} lg={4}>
  260. {FieldUtils.getTextField({
  261. label: "Last Updated:",
  262. valueName: "modifieDate",
  263. disabled: true,
  264. form: formik
  265. })}
  266. </Grid>
  267. <Grid item xs={12} sm={12} md={12} lg={4}>
  268. {FieldUtils.getComboField({
  269. label: "ID Type:",
  270. valueName: "idDocType",
  271. disabled: (!editMode),
  272. dataList: ComboData.idDocType,
  273. filterOptions: (options) => options,
  274. getOptionLabel: (item) => item ? typeof item === 'string' ? item : (item["type"] ? item["type"] + "-" + item["label"] : "") : "",
  275. onInputChange: (event, newValue, setInputValue) => {
  276. if (newValue == null) {
  277. setInputValue("");
  278. }
  279. let _val = newValue.split("-");
  280. if (_val[0]) {
  281. setInputValue(_val[0]);
  282. }
  283. },
  284. onChange: (event, newValue) => {
  285. if (newValue == null) {
  286. formik.setFieldValue("idDocType", "");
  287. return;
  288. }
  289. formik.setFieldValue("idDocType", newValue.type);
  290. if (newValue.type !== "HKID") {
  291. formik.setFieldValue("checkDigit", "")
  292. }
  293. },
  294. form: formik
  295. })}
  296. </Grid>
  297. <Grid item xs={12} sm={12} md={12} lg={4}>
  298. {FieldUtils.getPhoneField({
  299. label: "Contact Tel:",
  300. valueName: {
  301. code: "tel_countryCode",
  302. num: "phoneNumber"
  303. },
  304. disabled: (!editMode),
  305. form: formik
  306. })}
  307. </Grid>
  308. <Grid item xs={12} sm={12} md={12} lg={4}>
  309. <Grid container alignItems={"center"}>
  310. <Grid item xs={12} md={3} lg={3} sx={{ display: 'flex', alignItems: 'center' }}>
  311. <Typography variant="h5">Verified:</Typography>
  312. </Grid>
  313. {
  314. !isGrantedAny("MAINTAIN_USER") || currentUserData.verifiedBy || editMode ?
  315. <Grid item xs={12} sm={12} md={6} lg={6} sx={{ mb: 2 }}>
  316. {FieldUtils.initField({
  317. valueName: "verifiedStatus",
  318. disabled: true,
  319. form: formik,
  320. })}
  321. </Grid>
  322. :
  323. <>
  324. <Grid item xs={8} sm={8} md={6} lg={4} sx={{ mb: 2 }}>
  325. {FieldUtils.initField({
  326. valueName: "verifiedStatus",
  327. disabled: true,
  328. form: formik,
  329. })}
  330. </Grid>
  331. <Grid item xs={2} sm={2} md={2} lg={2} sx={{ ml: 2, mb: 2 }}>
  332. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  333. <Button
  334. variant="contained"
  335. onClick={onVerifiedClick}
  336. >
  337. Verify
  338. </Button>
  339. </ThemeProvider>
  340. </Grid>
  341. </>
  342. }
  343. </Grid>
  344. </Grid>
  345. <Grid xs={12} sm={12} md={12} lg={4}>
  346. <Grid container alignItems={"center"} sx={{ mb: 2 }}>
  347. <Grid item xs={12} sm={12} md={3} lg={3} sx={{ display: 'flex', alignItems: 'center' }}>
  348. <Typography variant="h5">ID No.:</Typography>
  349. </Grid>
  350. <Grid item xs={12} sm={12} md={9} lg={6}>
  351. <Grid container>
  352. {formik.values.idDocType === "HKID" ?
  353. editMode ?
  354. <>
  355. <Grid item xs={6} sm={6} md={6} lg={7.5} sx={{ mr: 1 }}>
  356. {FieldUtils.initField({
  357. valueName: "identification",
  358. disabled: (!editMode),
  359. form: formik,
  360. placeholder: intl.formatMessage({ id: 'idDocNumber' }),
  361. inputProps: {
  362. maxLength: 7,
  363. onKeyDown: (e) => {
  364. if (e.key === 'Enter') {
  365. e.preventDefault();
  366. }
  367. },
  368. }
  369. })}
  370. </Grid>
  371. <Grid item xs={2} sm={2} md={2} lg={2} style={{ minWidth: 40 }}>
  372. {FieldUtils.initField({
  373. valueName: "checkDigit",
  374. disabled: (!editMode),
  375. form: formik,
  376. })}
  377. </Grid>
  378. </>
  379. :
  380. <Stack direction="row">
  381. <Typography variant="h5" mt={1}>
  382. {formik.values.identification.slice(0, 4)}
  383. </Typography>
  384. <Typography variant="h5" mt={1}>
  385. {showId ? formik.values.identification.slice(4) : "****"}{showId ? '(' + formik.values.checkDigit + ')' : null}
  386. </Typography>
  387. <IconButton
  388. aria-label="toggle id visibility"
  389. onClick={handleClickShowId}
  390. onMouseDown={handleMouseDownId}
  391. edge="end"
  392. size="large"
  393. >
  394. {showId ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  395. </IconButton>
  396. </Stack>
  397. :
  398. editMode ?
  399. <Grid item xs={10} sm={4} md={4} lg={10}>
  400. {FieldUtils.initField({
  401. valueName: "identification",
  402. disabled: (!editMode),
  403. form: formik
  404. })}
  405. </Grid>
  406. :
  407. <Stack direction="row">
  408. <Typography variant="h5" mt={1}>
  409. {formik.values.identification.slice(0, 4)}
  410. </Typography>
  411. <Typography variant="h5" mt={1}>
  412. {showId ? formik.values.identification.slice(4) : "****"}
  413. </Typography>
  414. <IconButton
  415. aria-label="toggle id visibility"
  416. onClick={handleClickShowId}
  417. onMouseDown={handleMouseDownId}
  418. edge="end"
  419. size="large"
  420. >
  421. {showId ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  422. </IconButton>
  423. </Stack>
  424. }
  425. </Grid>
  426. </Grid>
  427. </Grid>
  428. </Grid>
  429. <Grid item xs={12} sm={12} md={12} lg={4}>
  430. {FieldUtils.getPhoneField({
  431. label: "Fax No.:",
  432. valueName: {
  433. code: "fax_countryCode",
  434. num: "faxNumber"
  435. },
  436. disabled: (!editMode),
  437. form: formik
  438. })}
  439. </Grid>
  440. <Grid item xs={12} sm={12} md={12} lg={4}>
  441. {FieldUtils.getTextField({
  442. label: "Last Login:",
  443. valueName: "lastLoginDate",
  444. disabled: true,
  445. form: formik
  446. })}
  447. </Grid>
  448. <Grid item xs={12} sm={12} md={12} lg={4}>
  449. {FieldUtils.getComboField({
  450. label: "Country:",
  451. valueName: "country",
  452. getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
  453. dataList: ComboData.country,
  454. disabled: (!editMode),
  455. form: formik
  456. })}
  457. </Grid>
  458. <Grid item xs={12} sm={12} md={12} lg={4}>
  459. {FieldUtils.getTextField({
  460. label: "Email:",
  461. valueName: "emailAddress",
  462. disabled: (!editMode),
  463. form: formik
  464. })}
  465. </Grid>
  466. <Grid item xs={12} sm={12} md={12} lg={4}>
  467. <Grid container alignItems={"center"} sx={{ mb: 2 }}>
  468. <Grid item xs={12} sm={12} md={3} lg={3} sx={{ display: 'flex', alignItems: 'center' }}>
  469. <Typography variant="h5">Status:</Typography>
  470. </Grid>
  471. {
  472. !isGrantedAny("MAINTAIN_USER") || editMode ?
  473. <Grid item xs={8} sm={8} md={6} lg={6}>
  474. {FieldUtils.initField({
  475. valueName: "status",
  476. disabled: true,
  477. form: formik,
  478. })}
  479. </Grid>
  480. :
  481. <>
  482. <Grid item xs={8} sm={8} md={6} lg={4}>
  483. {FieldUtils.initField({
  484. valueName: "status",
  485. disabled: true,
  486. form: formik,
  487. })}
  488. </Grid>
  489. {
  490. locked ?
  491. <Grid item xs={2} sm={2} md={2} lg={2} sx={{ ml: 2 }}>
  492. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  493. <Button
  494. variant="contained"
  495. color="success"
  496. onClick={doUnlock}
  497. >
  498. Active
  499. </Button>
  500. </ThemeProvider>
  501. </Grid>
  502. :
  503. <Grid item xs={2} sm={2} md={2} lg={2} sx={{ ml: 2 }}>
  504. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  505. <Button
  506. variant="contained"
  507. color="error"
  508. onClick={doLock}
  509. >
  510. Lock
  511. </Button>
  512. </ThemeProvider>
  513. </Grid>
  514. }
  515. </>
  516. }
  517. </Grid>
  518. </Grid>
  519. <Grid item xs={12} sm={12} md={12} lg={4}>
  520. {FieldUtils.getComboField({
  521. label: "District:",
  522. valueName: "district",
  523. dataList: ComboData.district,
  524. getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
  525. disabled: (!editMode),
  526. form: formik
  527. })}
  528. </Grid>
  529. <Grid item xs={12} sm={12} md={12} lg={4}>
  530. {FieldUtils.getComboField({
  531. label: intl.formatMessage({ id: 'language' }) + ":",
  532. valueName: "preferLocale",
  533. dataList: ComboData.Locale,
  534. getOptionLabel: (option) => option.label ? option.label : "",
  535. disabled: (!editMode),
  536. form: formik
  537. })}
  538. </Grid>
  539. <Grid item xs={12} sm={12} md={12} lg={12}>
  540. {FieldUtils.getAddressField({
  541. label: "Address:",
  542. valueName: ["addressLine1", "addressLine2", "addressLine3"],
  543. disabled: (!editMode),
  544. form: formik
  545. })}
  546. </Grid>
  547. </Grid>
  548. </Grid>
  549. </form>
  550. }
  551. </MainCard>
  552. );
  553. };
  554. export default UserInformationCard_Individual;