2. update client & subsidiary contact infotags/Baseline_30082024_FRONTEND_UAT
| @@ -382,9 +382,9 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||||
| fullWidth | fullWidth | ||||
| type="number" | type="number" | ||||
| inputProps={{ step: "0.01" }} | inputProps={{ step: "0.01" }} | ||||
| InputLabelProps={{ | |||||
| shrink: Boolean(watch("subContractFee")), | |||||
| }} | |||||
| // InputLabelProps={{ | |||||
| // shrink: Boolean(watch("subContractFee")), | |||||
| // }} | |||||
| {...register("subContractFee", { valueAsNumber: true })} | {...register("subContractFee", { valueAsNumber: true })} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -412,9 +412,9 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||||
| <Typography variant="overline" display="block"> | <Typography variant="overline" display="block"> | ||||
| {t("Client Details")} | {t("Client Details")} | ||||
| </Typography> | </Typography> | ||||
| <Button LinkComponent={Link} href="/settings/customer"> | |||||
| {/* <Button LinkComponent={Link} href="/settings/customer"> | |||||
| {t("Add or Edit Clients")} | {t("Add or Edit Clients")} | ||||
| </Button> | |||||
| </Button> */} | |||||
| </Stack> | </Stack> | ||||
| <Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> | <Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> | ||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| @@ -142,7 +142,7 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| resetField("addContacts") | resetField("addContacts") | ||||
| // reset({addContacts: defaultValues.addContacts}) | // reset({addContacts: defaultValues.addContacts}) | ||||
| setRows((prev) => defaultValues.addContacts) | setRows((prev) => defaultValues.addContacts) | ||||
| setRowModesModel(rows.reduce((acc, row) => ({...acc, [row.id]: { mode: GridRowModes.View } }), {})) | |||||
| setRowModesModel(rows.reduce((acc, row) => ({ ...acc, [row.id]: { mode: GridRowModes.View } }), {})) | |||||
| } | } | ||||
| }, [defaultValues]) | }, [defaultValues]) | ||||
| @@ -159,6 +159,14 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| headerName: t('Contact Phone'), | headerName: t('Contact Phone'), | ||||
| editable: true, | editable: true, | ||||
| flex: 1, | flex: 1, | ||||
| // type: "number", | |||||
| // valueSetter: ({ value, row }) => { | |||||
| // const phone = value.replace(/\D/g, '') | |||||
| // return { ...row, phone } | |||||
| // }, | |||||
| }, | }, | ||||
| { | { | ||||
| field: 'email', | field: 'email', | ||||
| @@ -232,8 +240,11 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| setError("addContacts", { message: "Contact details include empty fields", type: "required" }) | setError("addContacts", { message: "Contact details include empty fields", type: "required" }) | ||||
| } else { | } else { | ||||
| const errorRows_EmailFormat = rows.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))) | const errorRows_EmailFormat = rows.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))) | ||||
| if (errorRows_EmailFormat.length > 0) { | |||||
| setError("addContacts", { message: "Contact details include empty fields", type: "email_format" }) | |||||
| const errorRows_PhoneFormat = rows.filter(row => !/^[+0-9][0-9\s]*$/.test(String(row.phone))) | |||||
| if (errorRows_EmailFormat.length > 0 || errorRows_PhoneFormat.length > 0) { | |||||
| setError("addContacts", { message: "Contact details include empty fields", type: "format" }) | |||||
| } else { | } else { | ||||
| clearErrors("addContacts") | clearErrors("addContacts") | ||||
| } | } | ||||
| @@ -264,8 +275,8 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| {Boolean(errors.addContacts?.type === "required") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | {Boolean(errors.addContacts?.type === "required") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | ||||
| {t("Please ensure at least one row is created, and all the fields are inputted and saved")} | {t("Please ensure at least one row is created, and all the fields are inputted and saved")} | ||||
| </Typography>} | </Typography>} | ||||
| {Boolean(errors.addContacts?.type === "email_format") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | |||||
| {t("Please ensure all the email formats are correct")} | |||||
| {Boolean(errors.addContacts?.type === "format") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | |||||
| {t("Please ensure all the email and phone formats are correct")} | |||||
| </Typography>} | </Typography>} | ||||
| {/* </div> */} | {/* </div> */} | ||||
| <CustomDatagrid | <CustomDatagrid | ||||
| @@ -284,7 +295,15 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| toolbar: { setRows, setRowModesModel }, | toolbar: { setRows, setRowModesModel }, | ||||
| }} | }} | ||||
| sx={{ | sx={{ | ||||
| height: '100%' | |||||
| height: '100%', | |||||
| '& input[type=number]::-webkit-outer-spin-button': { | |||||
| '-webkit-appearance': 'none', | |||||
| margin: 0 | |||||
| }, | |||||
| '& input[type=number]::-webkit-inner-spin-button': { | |||||
| '-webkit-appearance': 'none', | |||||
| margin: 0 | |||||
| } | |||||
| }} | }} | ||||
| /> | /> | ||||
| <CardActions sx={{ justifyContent: "flex-end" }}> | <CardActions sx={{ justifyContent: "flex-end" }}> | ||||
| @@ -182,9 +182,11 @@ const CustomerSave: React.FC<Props> = ({ | |||||
| formProps.setError("addContacts", { message: "Contact info includes empty fields", type: "required" }) | formProps.setError("addContacts", { message: "Contact info includes empty fields", type: "required" }) | ||||
| } | } | ||||
| if (data.addContacts.length > 0 && data.addContacts.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))).length > 0) { | |||||
| if (data.addContacts.length > 0 | |||||
| && data.addContacts.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))).length > 0 | |||||
| && data.addContacts.filter(row => !/^[+0-9][0-9\s]*$/.test(String(row.phone))).length > 0) { | |||||
| haveError = true | haveError = true | ||||
| formProps.setError("addContacts", { message: "Contact info includes invalid email", type: "email_format" }) | |||||
| formProps.setError("addContacts", { message: "Contact info includes invalid email or phone", type: "format" }) | |||||
| } | } | ||||
| if (haveError) { | if (haveError) { | ||||
| @@ -199,20 +201,20 @@ const CustomerSave: React.FC<Props> = ({ | |||||
| setServerError(""); | setServerError(""); | ||||
| submitDialog(async () => { | submitDialog(async () => { | ||||
| const response = await saveCustomer(data); | |||||
| if (response.message === "Success") { | |||||
| successDialog(t("Submit Success"), t).then(() => { | |||||
| router.replace("/settings/customer"); | |||||
| }) | |||||
| } else { | |||||
| errorDialog(t("Submit Fail"), t).then(() => { | |||||
| formProps.setError("code", { message: response.message, type: "custom" }) | |||||
| setTabIndex(0) | |||||
| return false | |||||
| }) | |||||
| } | |||||
| }, t) | |||||
| const response = await saveCustomer(data); | |||||
| if (response.message === "Success") { | |||||
| successDialog(t("Submit Success"), t).then(() => { | |||||
| router.replace("/settings/customer"); | |||||
| }) | |||||
| } else { | |||||
| errorDialog(t("Submit Fail"), t).then(() => { | |||||
| formProps.setError("code", { message: response.message, type: "custom" }) | |||||
| setTabIndex(0) | |||||
| return false | |||||
| }) | |||||
| } | |||||
| }, t) | |||||
| } catch (e) { | } catch (e) { | ||||
| console.log(e) | console.log(e) | ||||
| setServerError(t("An error has occurred. Please try again later.")); | setServerError(t("An error has occurred. Please try again later.")); | ||||
| @@ -233,8 +233,10 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| } else { | } else { | ||||
| const errorRows_EmailFormat = rows.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))) | const errorRows_EmailFormat = rows.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))) | ||||
| if (errorRows_EmailFormat.length > 0) { | |||||
| setError("addContacts", { message: "Contact details include empty fields", type: "email_format" }) | |||||
| const errorRows_PhoneFormat = rows.filter(row => !/^[+0-9][0-9\s]*$/.test(String(row.phone))) | |||||
| if (errorRows_EmailFormat.length > 0 || errorRows_PhoneFormat.length > 0) { | |||||
| setError("addContacts", { message: "Contact details include empty fields", type: "format" }) | |||||
| } else { | } else { | ||||
| clearErrors("addContacts") | clearErrors("addContacts") | ||||
| } | } | ||||
| @@ -265,8 +267,8 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| {Boolean(errors.addContacts?.type === "required") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | {Boolean(errors.addContacts?.type === "required") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | ||||
| {t("Please ensure at least one row is created, and all the fields are inputted and saved")} | {t("Please ensure at least one row is created, and all the fields are inputted and saved")} | ||||
| </Typography>} | </Typography>} | ||||
| {Boolean(errors.addContacts?.type === "email_format") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | |||||
| {t("Please ensure all the email formats are correct")} | |||||
| {Boolean(errors.addContacts?.type === "format") && <Typography sx={(theme) => ({ color: theme.palette.error.main })} variant="overline" display='inline-block' noWrap> | |||||
| {t("Please ensure all the email and phone formats are correct")} | |||||
| </Typography>} | </Typography>} | ||||
| {/* </div> */} | {/* </div> */} | ||||
| <CustomDatagrid | <CustomDatagrid | ||||
| @@ -285,7 +287,15 @@ const ContactInfo: React.FC<Props> = ({ | |||||
| toolbar: { setRows, setRowModesModel }, | toolbar: { setRows, setRowModesModel }, | ||||
| }} | }} | ||||
| sx={{ | sx={{ | ||||
| height: '100%' | |||||
| height: '100%', | |||||
| '& input[type=number]::-webkit-outer-spin-button': { | |||||
| '-webkit-appearance': 'none', | |||||
| margin: 0 | |||||
| }, | |||||
| '& input[type=number]::-webkit-inner-spin-button': { | |||||
| '-webkit-appearance': 'none', | |||||
| margin: 0 | |||||
| } | |||||
| }} | }} | ||||
| /> | /> | ||||
| <CardActions sx={{ justifyContent: "flex-end" }}> | <CardActions sx={{ justifyContent: "flex-end" }}> | ||||
| @@ -157,9 +157,11 @@ const SubsidiaryDetail: React.FC<Props> = ({ | |||||
| formProps.setError("addContacts", { message: "Contact info includes empty fields", type: "required" }) | formProps.setError("addContacts", { message: "Contact info includes empty fields", type: "required" }) | ||||
| } | } | ||||
| if (data.addContacts.length > 0 && data.addContacts.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))).length > 0) { | |||||
| if (data.addContacts.length > 0 | |||||
| && data.addContacts.filter(row => !/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/.test(String(row.email))).length > 0 | |||||
| && data.addContacts.filter(row => !/^[+0-9][0-9\s]*$/.test(String(row.phone))).length > 0) { | |||||
| haveError = true | haveError = true | ||||
| formProps.setError("addContacts", { message: "Contact info includes invalid email", type: "email_format" }) | |||||
| formProps.setError("addContacts", { message: "Contact info includes invalid email or phone", type: "format" }) | |||||
| } | } | ||||
| if (haveError) { | if (haveError) { | ||||
| @@ -44,7 +44,7 @@ | |||||
| "Contact Email": "Contact Email", | "Contact Email": "Contact Email", | ||||
| "Contact Phone": "Contact Phone", | "Contact Phone": "Contact Phone", | ||||
| "Please ensure at least one row is created, and all the fields are inputted and saved": "Please ensure at least one row is created, and all the fields are inputted and saved", | "Please ensure at least one row is created, and all the fields are inputted and saved": "Please ensure at least one row is created, and all the fields are inputted and saved", | ||||
| "Please ensure all the email formats are correct": "Please ensure all the email formats are correct", | |||||
| "Please ensure all the email and phone formats are correct": "Please ensure all the email and phone formats are correct", | |||||
| "Do you want to submit?": "Do you want to submit?", | "Do you want to submit?": "Do you want to submit?", | ||||
| "Submit Success": "Submit Success", | "Submit Success": "Submit Success", | ||||
| @@ -44,7 +44,7 @@ | |||||
| "Contact Email": "Contact Email", | "Contact Email": "Contact Email", | ||||
| "Contact Phone": "Contact Phone", | "Contact Phone": "Contact Phone", | ||||
| "Please ensure at least one row is created, and all the fields are inputted and saved": "Please ensure at least one row is created, and all the fields are inputted and saved", | "Please ensure at least one row is created, and all the fields are inputted and saved": "Please ensure at least one row is created, and all the fields are inputted and saved", | ||||
| "Please ensure all the email formats are correct": "Please ensure all the email formats are correct", | |||||
| "Please ensure all the email and phone formats are correct": "Please ensure all the email and phone formats are correct", | |||||
| "Do you want to submit?": "Do you want to submit?", | "Do you want to submit?": "Do you want to submit?", | ||||
| "Submit Success": "Submit Success", | "Submit Success": "Submit Success", | ||||
| @@ -44,7 +44,7 @@ | |||||
| "Contact Email": "聯絡電郵", | "Contact Email": "聯絡電郵", | ||||
| "Contact Phone": "聯絡電話", | "Contact Phone": "聯絡電話", | ||||
| "Please ensure at least one row is created, and all the fields are inputted and saved": "請確保已建立至少一行, 及已輸入和儲存所有欄位", | "Please ensure at least one row is created, and all the fields are inputted and saved": "請確保已建立至少一行, 及已輸入和儲存所有欄位", | ||||
| "Please ensure all the email formats are correct": "請確保所有電郵格式輸入正確", | |||||
| "Please ensure all the email and phone formats are correct": "請確保所有電郵和電話格式輸入正確", | |||||
| "Do you want to submit?": "你是否確認要提交?", | "Do you want to submit?": "你是否確認要提交?", | ||||
| "Submit Success": "提交成功", | "Submit Success": "提交成功", | ||||
| @@ -44,7 +44,7 @@ | |||||
| "Contact Email": "聯絡電郵", | "Contact Email": "聯絡電郵", | ||||
| "Contact Phone": "聯絡電話", | "Contact Phone": "聯絡電話", | ||||
| "Please ensure at least one row is created, and all the fields are inputted and saved": "請確保已建立至少一行, 及已輸入和儲存所有欄位", | "Please ensure at least one row is created, and all the fields are inputted and saved": "請確保已建立至少一行, 及已輸入和儲存所有欄位", | ||||
| "Please ensure all the email formats are correct": "請確保所有電郵格式輸入正確", | |||||
| "Please ensure all the email and phone formats are correct": "請確保所有電郵和電話格式輸入正確", | |||||
| "Do you want to submit?": "你是否確認要提交?", | "Do you want to submit?": "你是否確認要提交?", | ||||
| "Submit Success": "提交成功", | "Submit Success": "提交成功", | ||||