OrderForm.js 7.2 KB

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