OrderForm.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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 [isNew, setIsNew] = useState(false);
  31. const [promiseTimeOut, setPromiseTimeOut] = useState(null);
  32. const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
  33. const navigate = useNavigate();
  34. const formik = useFormik({
  35. initialValues: {},
  36. validateOnMount: true,
  37. onSubmit: () => {
  38. let orderToSave = {};
  39. !isNew && order?._id && (orderToSave._id = order._id);
  40. orderToSave.status = inputStatus;
  41. inputUser && (orderToSave.owner = inputUser);
  42. orderToSave.orderGoods = inputOrderGoods;
  43. onSaveClick && onSaveClick();
  44. onSave(orderToSave);
  45. setPromiseTimeOut(setTimeout(() => formik.setSubmitting(false), 3000));
  46. },
  47. });
  48. useEffect(() => {
  49. return () => {
  50. promiseTimeOut && clearTimeout(promiseTimeOut);
  51. setPromiseTimeOut(null);
  52. };
  53. }, []);
  54. useEffect(() => {
  55. setInputStatus(order?.status || null);
  56. setInputUser(order?.owner || null);
  57. setInputOrderGoods(order.orderGoods || []);
  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 ? [].concat(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. <>
  133. <Button
  134. variant="contained"
  135. onClick={() => setIsDeleteModalOpen(true)}
  136. disabled={formik.isSubmitting}
  137. color="error"
  138. >
  139. Видалити
  140. </Button>
  141. <Button variant="contained" onClick={() => setIsNew(true)} disabled={formik.isSubmitting} type="submit">
  142. Зберегти як новий
  143. </Button>
  144. </>
  145. )}
  146. <Button variant="contained" onClick={() => setIsNew(false)} disabled={formik.isSubmitting} type="submit">
  147. Зберегти
  148. </Button>
  149. </Stack>
  150. </Grid>
  151. <Grid item xs={6}>
  152. <Box sx={{ mt: 3 }}>
  153. <InputLabel className="form-label">Користувач</InputLabel>
  154. <Select
  155. value={{ value: inputUser?._id || null, label: inputUser?.username || "null" }}
  156. onChange={(e) => setInputUser({ _id: e.value, username: e.label })}
  157. options={userList.map(({ _id, username }) => ({ value: _id, label: username }))}
  158. />
  159. </Box>
  160. </Grid>
  161. </Grid>
  162. {!!order._id && (
  163. <ConfirmModal
  164. open={isDeleteModalOpen}
  165. text="Видалити замовлення?"
  166. onClose={() => setIsDeleteModalOpen(false)}
  167. onNO={() => setIsDeleteModalOpen(false)}
  168. onYES={() => {
  169. onDelete(order);
  170. }}
  171. />
  172. )}
  173. </Box>
  174. );
  175. };
  176. export const COrderForm = connect(
  177. (state) => ({
  178. promiseStatus: state.promise.orderUpsert?.status || null,
  179. serverErrors: state.promise.orderUpsert?.error || null,
  180. order: state.promise?.adminOrderById?.payload || {},
  181. userList: state.promise.adminUsersAll?.payload || [],
  182. deletePromiseStatus: state.promise.orderDelete?.status || null,
  183. }),
  184. {
  185. onSave: (order) => actionOrderUpdate(order),
  186. onClose: () => actionPromisesClear(["orderUpsert", "orderDelete"]),
  187. onDelete: (order) => actionOrderDelete({ order }),
  188. }
  189. )(OrderForm);