FPSMS-frontend
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

205 行
6.2 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. CreateItemInputs,
  7. saveItem,
  8. } from "@/app/api/settings/item/actions";
  9. import {
  10. FormProvider,
  11. SubmitErrorHandler,
  12. SubmitHandler,
  13. useForm,
  14. } from "react-hook-form";
  15. import { deleteDialog } from "../Swal/CustomAlerts";
  16. import { Box, Button, Grid, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material";
  17. import { Check, Close, EditNote } from "@mui/icons-material";
  18. import { TypeEnum } from "@/app/utils/typeEnum";
  19. import ProductDetails from "./ProductDetails";
  20. import { CreateItemResponse } from "@/app/api/utils";
  21. import QcDetails from "./QcDetails";
  22. import { ItemQc } from "@/app/api/settings/item";
  23. import { saveItemQcChecks } from "@/app/api/settings/qcCheck/actions";
  24. import { useGridApiRef } from "@mui/x-data-grid";
  25. type Props = {
  26. isEditMode: boolean;
  27. // type: TypeEnum;
  28. defaultValues: Partial<CreateItemInputs> | undefined;
  29. qcChecks: ItemQc[]
  30. };
  31. const CreateItem: React.FC<Props> = ({
  32. isEditMode,
  33. // type,
  34. defaultValues,
  35. qcChecks
  36. }) => {
  37. // console.log(type)
  38. const apiRef = useGridApiRef();
  39. const params = useSearchParams()
  40. console.log(params.get("id"))
  41. const [serverError, setServerError] = useState("");
  42. const [tabIndex, setTabIndex] = useState(0);
  43. const { t } = useTranslation("items");
  44. const router = useRouter();
  45. const title = "Product / Material"
  46. const [mode, redirPath] = useMemo(() => {
  47. // var typeId = TypeEnum.CONSUMABLE_ID
  48. var title = "";
  49. var mode = "";
  50. var redirPath = "";
  51. // if (type === TypeEnum.MATERIAL) {
  52. // typeId = TypeEnum.MATERIAL_ID
  53. // title = "Material";
  54. // redirPath = "/settings/material";
  55. // }
  56. // if (type === TypeEnum.PRODUCT) {
  57. // typeId = TypeEnum.PRODUCT_ID
  58. title = "Product";
  59. redirPath = "/settings/items";
  60. // }
  61. // if (type === TypeEnum.BYPRODUCT) {
  62. // typeId = TypeEnum.BYPRODUCT_ID
  63. // title = "By-Product";
  64. // redirPath = "/settings/byProduct";
  65. // }
  66. if (isEditMode) {
  67. mode = "Edit";
  68. } else {
  69. mode = "Create";
  70. }
  71. return [mode, redirPath];
  72. }, [isEditMode]);
  73. // console.log(typeId)
  74. const formProps = useForm<CreateItemInputs>({
  75. defaultValues: defaultValues ? defaultValues : {
  76. },
  77. });
  78. const errors = formProps.formState.errors;
  79. const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
  80. (_e, newValue) => {
  81. setTabIndex(newValue);
  82. },
  83. [],
  84. );
  85. const handleCancel = () => {
  86. router.replace(`/settings/product`);
  87. };
  88. const onSubmit = useCallback<SubmitHandler<CreateItemInputs & {}>>(
  89. async (data, event) => {
  90. let hasErrors = false;
  91. console.log(errors)
  92. // console.log(apiRef.current.getCellValue(2, "lowerLimit"))
  93. // apiRef.current.
  94. try {
  95. if (hasErrors) {
  96. setServerError(t("An error has occurred. Please try again later."));
  97. return false;
  98. }
  99. console.log("data posted");
  100. console.log(data);
  101. const qcCheck = data.qcChecks.length > 0 ? data.qcChecks.filter((q) => data.qcChecks_active.includes(q.id!!)).map((qc) => {
  102. return {
  103. qcItemId: qc.id,
  104. instruction: qc.instruction,
  105. lowerLimit: qc.lowerLimit,
  106. upperLimit: qc.upperLimit,
  107. itemId: parseInt(params.get("id")!.toString())
  108. }
  109. }) : []
  110. const test = data.qcChecks.filter((q) => data.qcChecks_active.includes(q.id!!))
  111. // TODO:
  112. // 1. check field ( directly modify col def / check here )
  113. // 2. set error change tab index
  114. console.log(test)
  115. console.log(qcCheck)
  116. // return
  117. // do api
  118. console.log("asdad")
  119. var responseI = await saveItem(data);
  120. console.log("asdad")
  121. var responseQ = await saveItemQcChecks(qcCheck)
  122. if (responseI && responseQ) {
  123. if (!Boolean(responseI.id)) {
  124. formProps.setError(responseI.errorPosition!! as keyof CreateItemInputs, {
  125. message: responseI.message!!,
  126. type: "required",
  127. });
  128. } else if (!Boolean(responseQ.id)) {
  129. } else if (Boolean(responseI.id) && Boolean(responseQ.id)) {
  130. router.replace(redirPath);
  131. }
  132. }
  133. } catch (e) {
  134. // backend error
  135. setServerError(t("An error has occurred. Please try again later."));
  136. console.log(e);
  137. }
  138. },
  139. [apiRef, router, t]
  140. );
  141. // multiple tabs
  142. const onSubmitError = useCallback<SubmitErrorHandler<CreateItemInputs>>(
  143. (errors) => {},
  144. []
  145. );
  146. return (
  147. <>
  148. <FormProvider {...formProps}>
  149. <Stack
  150. spacing={2}
  151. component="form"
  152. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  153. >
  154. <Grid>
  155. <Typography mb={2} variant="h4">
  156. {t(`${mode} ${title}`)}
  157. </Typography>
  158. </Grid>
  159. <Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable">
  160. <Tab label={t("Product / Material Details")} iconPosition="end"/>
  161. <Tab label={t("Qc items")} iconPosition="end" />
  162. </Tabs>
  163. {serverError && (
  164. <Typography variant="body2" color="error" alignSelf="flex-end">
  165. {serverError}
  166. </Typography>
  167. )}
  168. {tabIndex === 0 && <ProductDetails />}
  169. {tabIndex === 1 && <QcDetails apiRef={apiRef} />}
  170. {/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */}
  171. {/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */}
  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 CreateItem;