FPSMS-frontend
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

203 řádky
6.0 KiB

  1. "use client";
  2. import { useCallback, useEffect, useMemo, useState } from "react";
  3. import { useRouter, useSearchParams } from "next/navigation";
  4. import { useTranslation } from "react-i18next";
  5. import {
  6. CreateMaterialInputs,
  7. CreateProductMaterialResponse,
  8. saveMaterial,
  9. } from "@/app/api/settings/material/actions";
  10. import {
  11. FormProvider,
  12. SubmitErrorHandler,
  13. SubmitHandler,
  14. useForm,
  15. } from "react-hook-form";
  16. import { deleteDialog } from "../Swal/CustomAlerts";
  17. import { Box, Button, Grid, Stack, Typography } from "@mui/material";
  18. import { Check, Close, EditNote } from "@mui/icons-material";
  19. import { TypeEnum } from "@/app/utils/typeEnum";
  20. import {
  21. CreateProductInputs,
  22. saveProduct,
  23. } from "@/app/api/settings/product/actions";
  24. import { CreateInputsFields } from "./CreateProductMaterialWrapper";
  25. import MaterialDetails from "./MaterialDetails";
  26. import ProductDetails from "./ProductDetails";
  27. type Props = {
  28. isEditMode: boolean;
  29. type: TypeEnum;
  30. defaultValues: Partial<CreateInputsFields> | undefined;
  31. };
  32. const CreateProductMaterial: React.FC<Props> = ({
  33. isEditMode,
  34. type,
  35. defaultValues,
  36. }) => {
  37. const [serverError, setServerError] = useState("");
  38. const [tabIndex, setTabIndex] = useState(0);
  39. const { t } = useTranslation();
  40. const router = useRouter();
  41. const [title, mode, redirPath] = useMemo(() => {
  42. var title = "";
  43. var mode = "";
  44. var redirPath = "";
  45. if (type === TypeEnum.MATERIAL) {
  46. title = "Material";
  47. redirPath = "/material";
  48. }
  49. if (type === TypeEnum.PRODUCT) {
  50. title = "Product";
  51. redirPath = "/product";
  52. }
  53. if (isEditMode) {
  54. mode = "Edit";
  55. } else {
  56. mode = "Create";
  57. }
  58. return [title, mode, redirPath];
  59. }, [type, isEditMode]);
  60. const formProps = useForm<CreateInputsFields>({
  61. defaultValues: defaultValues ? defaultValues : {},
  62. });
  63. const errors = formProps.formState.errors;
  64. const handleCancel = () => {
  65. router.replace(`/settings/${type}`);
  66. };
  67. const onSubmit = useCallback<SubmitHandler<CreateInputsFields>>(
  68. async (data, event) => {
  69. let hasErrors = false;
  70. try {
  71. // checking humid input
  72. if (data.maxHumid && data.minHumid!! > data.maxHumid!!) {
  73. const message = "minHumid should not be greater than maxHumid";
  74. formProps.setError("minHumid", {
  75. message: message,
  76. type: "required",
  77. });
  78. formProps.setError("maxHumid", {
  79. message: message,
  80. type: "required",
  81. });
  82. hasErrors = true;
  83. }
  84. // checking temp input
  85. if (data.maxTemp && data.minTemp!! > data.maxTemp!!) {
  86. const message = "minTemp should not be greater than maxTemp";
  87. formProps.setError("minTemp", {
  88. message: message,
  89. type: "required",
  90. });
  91. formProps.setError("maxTemp", {
  92. message: message,
  93. type: "required",
  94. });
  95. hasErrors = true;
  96. }
  97. // checking passing rate
  98. if (data.passingRate && data.passingRate > 100) {
  99. const message = "passingRate should not be greater than 100%";
  100. formProps.setError("passingRate", {
  101. message: message,
  102. type: "required",
  103. });
  104. }
  105. // checking sampling rate
  106. if (data.sampleRate && data.sampleRate > 100) {
  107. const message = "sampleRate should not be greater than 100%";
  108. formProps.setError("sampleRate", {
  109. message: message,
  110. type: "required",
  111. });
  112. }
  113. if (hasErrors) {
  114. setServerError(t("An error has occurred. Please try again later."));
  115. return false;
  116. }
  117. console.log("data posted");
  118. console.log(data);
  119. // do api
  120. var response: CreateProductMaterialResponse | undefined;
  121. if (type === TypeEnum.MATERIAL) {
  122. response = await saveMaterial(data as CreateMaterialInputs);
  123. } else if (type === TypeEnum.PRODUCT) {
  124. response = await saveProduct(data as CreateProductInputs);
  125. }
  126. if (response) {
  127. if (!Boolean(response.id)) {
  128. formProps.setError(response.errorPosition!!, {
  129. message: response.message!!,
  130. type: "required",
  131. });
  132. throw response;
  133. } else if (Boolean(response.id)) {
  134. router.replace(redirPath);
  135. }
  136. } else {
  137. throw "no response";
  138. }
  139. } catch (e) {
  140. // backend error
  141. setServerError(t("An error has occurred. Please try again later."));
  142. console.log(e);
  143. }
  144. },
  145. [router, t]
  146. );
  147. // multiple tabs
  148. const onSubmitError = useCallback<SubmitErrorHandler<CreateInputsFields>>(
  149. (errors) => {},
  150. []
  151. );
  152. return (
  153. <>
  154. <FormProvider {...formProps}>
  155. <Stack
  156. spacing={2}
  157. component="form"
  158. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  159. >
  160. <Grid>
  161. <Typography mb={2} variant="h4">
  162. {t(`${mode} ${title}`)}
  163. </Typography>
  164. </Grid>
  165. {serverError && (
  166. <Typography variant="body2" color="error" alignSelf="flex-end">
  167. {serverError}
  168. </Typography>
  169. )}
  170. {type === TypeEnum.MATERIAL && <MaterialDetails />}
  171. {type === TypeEnum.PRODUCT && <ProductDetails />}
  172. <Stack direction="row" justifyContent="flex-end" gap={1}>
  173. <Button
  174. name="submit"
  175. variant="contained"
  176. startIcon={<Check />}
  177. type="submit"
  178. // disabled={submitDisabled}
  179. >
  180. {isEditMode ? t("Save") : t("Confirm")}
  181. </Button>
  182. <Button
  183. variant="outlined"
  184. startIcon={<Close />}
  185. onClick={handleCancel}
  186. >
  187. {t("Cancel")}
  188. </Button>
  189. </Stack>
  190. </Stack>
  191. </FormProvider>
  192. </>
  193. );
  194. };
  195. export default CreateProductMaterial;