OrderForm.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { connect, useDispatch, useSelector } from "react-redux";
  2. import { useState, useEffect, useContext } from "react";
  3. import { actionPromiseClear } from "../../../reducers";
  4. import Select from "react-select";
  5. import { actionOrderUpdate } from "../../../actions/actionOrderUpdate";
  6. import { UIContext } from "../../UIContext";
  7. import { Box, Button, Grid, InputLabel, Stack } from "@mui/material";
  8. import { useFormik } from "formik";
  9. import { statusNumber, statusOptions } from "../../../helpers";
  10. import { OrderGoodsEditor } from "./OrderGoodsEditor";
  11. import { useNavigate } from "react-router-dom";
  12. import { actionOrderDelete } from "../../../actions/actionOrderDelete";
  13. import { ConfirmModal } from "../../common/ConfirmModal";
  14. import { actionPromisesClear } from "../../../actions/actionPromisesClear";
  15. export const OrderForm = ({
  16. serverErrors = [],
  17. onSaveClick,
  18. onSave,
  19. onClose,
  20. onDelete,
  21. userList,
  22. promiseStatus,
  23. deletePromiseStatus,
  24. order = {},
  25. } = {}) => {
  26. const [inputStatus, setInputStatus] = useState(null);
  27. const [inputUser, setInputUser] = useState({});
  28. const { setAlert } = useContext(UIContext);
  29. const goodList = useSelector((state) => state.promise?.goodsAll?.payload || []);
  30. const [inputOrderGoods, setInputOrderGoods] = useState([]);
  31. const [promiseTimeOut, setPromiseTimeOut] = useState(null);
  32. const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
  33. const navigate = useNavigate();
  34. const formik = useFormik({
  35. initialValues: {},
  36. onSubmit: () => {
  37. let orderToSave = {};
  38. order?._id && (orderToSave._id = order._id);
  39. orderToSave.status = inputStatus;
  40. inputUser && (orderToSave.owner = inputUser);
  41. orderToSave.orderGoods = inputOrderGoods;
  42. onSaveClick && onSaveClick();
  43. onSave(orderToSave);
  44. setPromiseTimeOut(setTimeout(() => formik.setSubmitting(false), 3000));
  45. },
  46. });
  47. useEffect(() => {
  48. return () => {
  49. promiseTimeOut && clearTimeout(promiseTimeOut);
  50. setPromiseTimeOut(null);
  51. };
  52. }, []);
  53. useEffect(() => {
  54. setInputStatus(order?.status || null);
  55. setInputUser(order?.owner || null);
  56. setInputOrderGoods(order.orderGoods || []);
  57. formik.validateForm();
  58. }, [order]);
  59. useEffect(() => {
  60. if (promiseStatus === "FULFILLED") {
  61. formik.setSubmitting(false);
  62. promiseTimeOut && clearTimeout(promiseTimeOut);
  63. setPromiseTimeOut(null);
  64. setAlert({
  65. show: true,
  66. severity: "success",
  67. message: "Готово",
  68. });
  69. }
  70. if (promiseStatus === "REJECTED") {
  71. const errorMessage = serverErrors.reduce((prev, curr) => prev + "\n" + curr.message, "");
  72. formik.setSubmitting(false);
  73. promiseTimeOut && clearTimeout(promiseTimeOut);
  74. setPromiseTimeOut(null);
  75. setAlert({
  76. show: true,
  77. severity: "error",
  78. message: errorMessage,
  79. });
  80. }
  81. }, [promiseStatus]);
  82. useEffect(() => {
  83. if (deletePromiseStatus === "FULFILLED") {
  84. formik.setSubmitting(false);
  85. promiseTimeOut && clearTimeout(promiseTimeOut);
  86. setPromiseTimeOut(null);
  87. navigate("/admin/orders/");
  88. }
  89. if (deletePromiseStatus === "REJECTED") {
  90. formik.setSubmitting(false);
  91. promiseTimeOut && clearTimeout(promiseTimeOut);
  92. setPromiseTimeOut(null);
  93. setAlert({
  94. show: true,
  95. severity: "error",
  96. message: "Помилка",
  97. });
  98. }
  99. }, [deletePromiseStatus]);
  100. useEffect(() => {
  101. return () => {
  102. onClose && onClose();
  103. };
  104. }, []);
  105. return (
  106. <Box className="OrderForm" component="form" onSubmit={formik.handleSubmit}>
  107. <Grid container spacing={5}>
  108. <Grid item xs={6}>
  109. <Box sx={{ mt: 3 }}>
  110. <InputLabel className="form-label">Статус</InputLabel>
  111. <Select
  112. value={{
  113. value: inputStatus || null,
  114. label: inputStatus ? statusNumber[inputStatus] : null,
  115. }}
  116. onChange={(e) => setInputStatus(e.value)}
  117. options={statusOptions}
  118. />
  119. </Box>
  120. <Box sx={{ mt: 3 }}>
  121. <InputLabel className="form-label">Товари</InputLabel>
  122. <OrderGoodsEditor
  123. orderGoods={inputOrderGoods}
  124. goodList={goodList}
  125. onChange={(orderGoods) => {
  126. setInputOrderGoods([...orderGoods]);
  127. }}
  128. />
  129. </Box>
  130. <Stack direction="row" sx={{ mt: 3 }} justifyContent="flex-end" spacing={1}>
  131. {!!order._id && (
  132. <Button variant="contained" onClick={() => setIsDeleteModalOpen(true)} color="error">
  133. Видалити
  134. </Button>
  135. )}
  136. <Button variant="contained" disabled={formik.isSubmitting} type="submit">
  137. Зберегти
  138. </Button>
  139. </Stack>
  140. </Grid>
  141. <Grid item xs={6}>
  142. <Box sx={{ mt: 3 }}>
  143. <InputLabel className="form-label">Користувач</InputLabel>
  144. <Select
  145. value={{ value: inputUser?._id || null, label: inputUser?.username || "null" }}
  146. onChange={(e) => setInputUser({ _id: e.value, username: e.label })}
  147. options={userList.map(({ _id, username }) => ({ value: _id, label: username }))}
  148. />
  149. </Box>
  150. </Grid>
  151. </Grid>
  152. {!!order._id && (
  153. <ConfirmModal
  154. open={isDeleteModalOpen}
  155. text="Видалити замовлення?"
  156. onClose={() => setIsDeleteModalOpen(false)}
  157. onNO={() => setIsDeleteModalOpen(false)}
  158. onYES={() => {
  159. onDelete(order);
  160. }}
  161. />
  162. )}
  163. </Box>
  164. );
  165. };
  166. export const COrderForm = connect(
  167. (state) => ({
  168. promiseStatus: state.promise.orderUpsert?.status || null,
  169. serverErrors: state.promise.orderUpsert?.error || null,
  170. order: state.promise?.adminOrderById?.payload || {},
  171. userList: state.promise.adminUsersAll?.payload || [],
  172. deletePromiseStatus: state.promise.orderDelete?.status || null,
  173. }),
  174. {
  175. onSave: (order) => actionOrderUpdate(order),
  176. onClose: () => actionPromisesClear(["orderUpsert", "orderDelete"]),
  177. onDelete: (order) => actionOrderDelete({ order }),
  178. }
  179. )(OrderForm);