index.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { Box, Grid, TextField, MenuItem, Button, Alert, Snackbar } from '@mui/material';
  2. import * as Yup from 'yup';
  3. import { useFormik } from 'formik';
  4. import { connect, useDispatch } from 'react-redux';
  5. import { actionCartClear, actionPromiseClear } from '../../../reducers';
  6. import { actionOrderUpdate } from '../../../actions/actionOrderUpdate';
  7. import { useContext, useEffect, useState } from 'react';
  8. import { UIContext } from '../../UIContext';
  9. const deliveryOptions = [
  10. { label: 'Нова пошта', value: 'nova-poshta' },
  11. { label: 'Justin', value: 'justin' },
  12. ];
  13. const phoneRegExp =
  14. /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/;
  15. const orderSchema = Yup.object().shape({
  16. name: Yup.string().min(3, 'не меньше 3 символів').max(22, 'не більше 22 символів').required("обов'язкове"),
  17. surname: Yup.string().min(3, 'не меньше 3 символів').max(22, 'не більше 22 символів').required("обов'язкове"),
  18. email: Yup.string().email('не вірний формат').required("обов'язкове"),
  19. address: Yup.string().required("обов'язкове"),
  20. phoneNumber: Yup.string().matches(phoneRegExp, 'не вірний формат').required("обов'язкове"),
  21. delivery: Yup.string()
  22. .required("обов'язкове")
  23. .oneOf(
  24. deliveryOptions.map((option) => option.value),
  25. 'не знайдено'
  26. ),
  27. });
  28. export const OrderForm = ({ onSubmit = null, promiseStatus = null, serverErrors = [] } = {}) => {
  29. const { setAlert } = useContext(UIContext);
  30. const formik = useFormik({
  31. initialValues: {
  32. name: '',
  33. surname: '',
  34. email: '',
  35. address: '',
  36. phoneNumber: '',
  37. delivery: '',
  38. },
  39. validationSchema: orderSchema,
  40. validateOnChange: true,
  41. onSubmit: () => {
  42. onSubmit(formik.values);
  43. },
  44. });
  45. const dispatch = useDispatch();
  46. useEffect(() => {
  47. if (promiseStatus === 'FULFILLED') {
  48. formik.setSubmitting(false);
  49. setAlert({
  50. show: true,
  51. severity: 'success',
  52. message: 'Готово',
  53. });
  54. dispatch(actionPromiseClear('orderUpsert'));
  55. dispatch(actionCartClear());
  56. }
  57. if (promiseStatus === 'REJECTED') {
  58. const errorMessage = serverErrors.reduce((prev, curr) => prev + '\n' + curr.message, '');
  59. setAlert({
  60. show: true,
  61. severity: 'error',
  62. message: errorMessage,
  63. });
  64. formik.setSubmitting(false);
  65. }
  66. }, [promiseStatus]);
  67. return (
  68. <Box className="OrderForm" component="form" onSubmit={formik.handleSubmit}>
  69. <Grid container spacing={2} rowSpacing={1}>
  70. <Grid item xs={6}>
  71. <TextField
  72. id="name"
  73. name="name"
  74. variant="outlined"
  75. label="Ім'я"
  76. size="small"
  77. error={formik.touched.name && Boolean(formik.errors.name)}
  78. value={formik.values.name}
  79. onBlur={formik.handleBlur}
  80. onChange={formik.handleChange}
  81. helperText={formik.touched.name && formik.errors.name}
  82. fullWidth
  83. />
  84. </Grid>
  85. <Grid item xs={6}>
  86. <TextField
  87. id="surname"
  88. name="surname"
  89. variant="outlined"
  90. label="Прізвище"
  91. size="small"
  92. error={formik.touched.surname && Boolean(formik.errors.surname)}
  93. value={formik.values.surname}
  94. onBlur={formik.handleBlur}
  95. onChange={formik.handleChange}
  96. helperText={formik.touched.surname && formik.errors.surname}
  97. fullWidth
  98. />
  99. </Grid>
  100. <Grid item xs={6}>
  101. <TextField
  102. id="email"
  103. name="email"
  104. variant="outlined"
  105. label="Email"
  106. size="small"
  107. error={formik.touched.email && Boolean(formik.errors.email)}
  108. value={formik.values.email}
  109. onBlur={formik.handleBlur}
  110. onChange={formik.handleChange}
  111. helperText={formik.touched.email && formik.errors.email}
  112. fullWidth
  113. />
  114. </Grid>
  115. <Grid item xs={6}>
  116. <TextField
  117. id="phoneNumber"
  118. name="phoneNumber"
  119. variant="outlined"
  120. label="Номер телефону"
  121. size="small"
  122. error={formik.touched.phoneNumber && Boolean(formik.errors.phoneNumber)}
  123. value={formik.values.phoneNumber}
  124. onBlur={formik.handleBlur}
  125. onChange={formik.handleChange}
  126. helperText={formik.touched.phoneNumber && formik.errors.phoneNumber}
  127. fullWidth
  128. />
  129. </Grid>
  130. <Grid item xs={6}>
  131. <TextField
  132. id="address"
  133. name="address"
  134. variant="outlined"
  135. label="Адреса доставки"
  136. size="small"
  137. error={formik.touched.address && Boolean(formik.errors.address)}
  138. value={formik.values.address}
  139. onBlur={formik.handleBlur}
  140. onChange={formik.handleChange}
  141. helperText={formik.touched.address && formik.errors.address}
  142. fullWidth
  143. />
  144. </Grid>
  145. <Grid item xs={6}>
  146. <TextField
  147. id="delivery"
  148. name="delivery"
  149. variant="outlined"
  150. label="Тип доставкі"
  151. size="small"
  152. extAlign="left"
  153. select
  154. value={formik.values.delivery}
  155. error={formik.touched.delivery && Boolean(formik.errors.delivery)}
  156. onBlur={formik.handleBlur}
  157. onChange={formik.handleChange}
  158. helperText={formik.touched.delivery && formik.errors.delivery}
  159. fullWidth
  160. >
  161. {deliveryOptions.map((option) => (
  162. <MenuItem key={option.value} value={option.value} t>
  163. {option.label}
  164. </MenuItem>
  165. ))}
  166. </TextField>
  167. </Grid>
  168. <Grid item xs={12} display="flex" justifyContent="flex-end">
  169. <Button variant="contained" type="submit" disabled={!formik.isValid || formik.isSubmitting}>
  170. Підтвердити
  171. </Button>
  172. </Grid>
  173. </Grid>
  174. </Box>
  175. );
  176. };
  177. export const COrderForm = connect(
  178. (state) => ({
  179. promiseStatus: state.promise.orderUpsert?.status || null,
  180. serverErrors: state.promise?.orderUpsert?.error || [],
  181. }),
  182. {
  183. onClose: () => actionPromiseClear('orderUpsert'),
  184. }
  185. )(OrderForm);