index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import { Box, Button, Grid, IconButton, Table, TableBody, TableCell, TableRow, TextField } from "@mui/material";
  2. import { useContext, useEffect, useState } from "react";
  3. import { connect } from "react-redux";
  4. import { actionUpdateAvatar } from "../../../actions/actionUpdateAvatar";
  5. import { actionUserUpdate } from "../../../actions/actionUserUpdate";
  6. import { useFormik } from "formik";
  7. import * as Yup from "yup";
  8. import { UIContext } from "../../UIContext";
  9. import { MdVisibility, MdVisibilityOff } from "react-icons/md";
  10. import { ProfileImageEditor } from "../../common/ProfileImageEditor";
  11. const CProfileImageEditor = connect((state) => ({ avatar: state.promise?.aboutMe?.payload?.avatar || null }), {
  12. onFileDrop: (acceptedFiles) => actionUpdateAvatar(acceptedFiles[0]),
  13. })(ProfileImageEditor);
  14. const profileSchema = Yup.object().shape({
  15. name: Yup.string(),
  16. username: Yup.string().min(3, "Too Short!").max(15, "Too Long!").required("Required"),
  17. password: Yup.string().min(3, "Too Short!").max(15, "Too Long!"),
  18. nick: Yup.string(),
  19. });
  20. export const ProfileForm = ({ profile = {}, promiseStatus, onProfileSave, serverErrors = [] } = {}) => {
  21. const [editMod, setEditMod] = useState(false);
  22. const [showPassword, setShowPassword] = useState(false);
  23. const { setAlert } = useContext(UIContext);
  24. const [promiseTimeOut, setPromiseTimeOut] = useState(null);
  25. const formik = useFormik({
  26. initialValues: {
  27. username: "",
  28. password: "",
  29. name: "",
  30. nick: "",
  31. },
  32. validationSchema: profileSchema,
  33. validateOnChange: true,
  34. validateOnMount: true,
  35. onSubmit: () => {
  36. onProfileSave(formik.values);
  37. setPromiseTimeOut(setTimeout(() => formik.setSubmitting(false), 3000));
  38. },
  39. });
  40. useEffect(() => {
  41. return () => {
  42. promiseTimeOut && clearTimeout(promiseTimeOut);
  43. setPromiseTimeOut(null);
  44. };
  45. }, []);
  46. useEffect(() => {
  47. profile._id && formik.setFieldValue("_id", profile?._id || "");
  48. formik.setFieldValue("username", profile?.username || "");
  49. formik.setFieldValue("nick", profile?.nick || "");
  50. formik.setFieldValue("name", profile?.name || "");
  51. }, [profile]);
  52. useEffect(() => {
  53. if (promiseStatus === "FULFILLED") {
  54. formik.setSubmitting(false);
  55. promiseTimeOut && clearTimeout(promiseTimeOut);
  56. setPromiseTimeOut(null);
  57. setAlert({
  58. show: true,
  59. severity: "success",
  60. message: "Готово",
  61. });
  62. setEditMod(false);
  63. }
  64. if (promiseStatus === "REJECTED") {
  65. const errorMessage = (serverErrors ? [].concat(serverErrors) : []).reduce((prev, curr) => prev + "\n" + curr.message, "");
  66. formik.setSubmitting(false);
  67. promiseTimeOut && clearTimeout(promiseTimeOut);
  68. setPromiseTimeOut(null);
  69. setAlert({
  70. show: true,
  71. severity: "error",
  72. message: errorMessage,
  73. });
  74. }
  75. }, [promiseStatus]);
  76. return (
  77. <Box component="form" className="ProfileForm" onSubmit={formik.handleSubmit}>
  78. <Grid container spacing={3}>
  79. <Grid xs={4} item>
  80. <CProfileImageEditor />
  81. </Grid>
  82. <Grid xs={8} item>
  83. <Table>
  84. <TableBody>
  85. <TableRow>
  86. <TableCell>Username</TableCell>
  87. <TableCell>
  88. {editMod ? (
  89. <TextField
  90. size="small"
  91. id="username"
  92. name="username"
  93. variant="standard"
  94. label="Username"
  95. error={formik.touched.username && Boolean(formik.errors.username)}
  96. value={formik.values.username}
  97. onBlur={formik.handleBlur}
  98. onChange={formik.handleChange}
  99. helperText={`Після зміни username потрібно перезайти в аккаунт!!! \n ${
  100. formik.touched.username ? formik.errors.username || "" : ""
  101. }`}
  102. />
  103. ) : (
  104. formik.values.username
  105. )}
  106. </TableCell>
  107. </TableRow>
  108. <TableRow>
  109. <TableCell>Nick</TableCell>
  110. <TableCell>
  111. {editMod ? (
  112. <TextField
  113. size="small"
  114. id="nick"
  115. name="nick"
  116. variant="standard"
  117. label="Nick"
  118. error={formik.touched.nick && Boolean(formik.errors.nick)}
  119. value={formik.values.nick}
  120. onBlur={formik.handleBlur}
  121. onChange={formik.handleChange}
  122. helperText={formik.touched.nick && formik.errors.nick}
  123. />
  124. ) : (
  125. formik.values.nick
  126. )}
  127. </TableCell>
  128. </TableRow>
  129. <TableRow>
  130. <TableCell>Name</TableCell>
  131. <TableCell>
  132. {editMod ? (
  133. <TextField
  134. size="small"
  135. id="name"
  136. name="name"
  137. variant="standard"
  138. label="Name"
  139. error={formik.touched.name && Boolean(formik.errors.name)}
  140. value={formik.values.name}
  141. onBlur={formik.handleBlur}
  142. onChange={formik.handleChange}
  143. helperText={formik.touched.name && formik.errors.name}
  144. />
  145. ) : (
  146. formik.values.name
  147. )}
  148. </TableCell>
  149. </TableRow>
  150. <TableRow>
  151. <TableCell>Password</TableCell>
  152. <TableCell>
  153. {editMod ? (
  154. <TextField
  155. size="small"
  156. id="password"
  157. name="password"
  158. variant="standard"
  159. label="Password"
  160. type={showPassword ? "text" : "password"}
  161. error={formik.touched.password && Boolean(formik.errors.password)}
  162. value={formik.values.password}
  163. onBlur={formik.handleBlur}
  164. onChange={formik.handleChange}
  165. helperText={formik.touched.password && formik.errors.password}
  166. InputProps={{
  167. endAdornment: (
  168. <IconButton onClick={() => setShowPassword((prev) => !prev)} edge="end">
  169. {showPassword ? <MdVisibilityOff /> : <MdVisibility />}
  170. </IconButton>
  171. ),
  172. }}
  173. />
  174. ) : (
  175. "****************"
  176. )}
  177. </TableCell>
  178. </TableRow>
  179. <TableRow>
  180. <TableCell></TableCell>
  181. <TableCell>
  182. {editMod ? (
  183. <Box display="flex" justifyContent="flex-end">
  184. <Button variant="text" color="error" onClick={() => setEditMod(false)}>
  185. Скасувати
  186. </Button>
  187. <Button variant="text" color="primary" type="submit" disabled={formik.isSubmitting}>
  188. Зберегти
  189. </Button>
  190. </Box>
  191. ) : (
  192. <Box display="flex" justifyContent="flex-end">
  193. <Button onClick={() => setEditMod(true)}>Редагувати</Button>
  194. </Box>
  195. )}
  196. </TableCell>
  197. </TableRow>
  198. </TableBody>
  199. </Table>
  200. </Grid>
  201. </Grid>
  202. </Box>
  203. );
  204. };
  205. export const CProfileForm = connect(
  206. (state) => ({
  207. profile: state.promise?.aboutMe?.payload || {},
  208. promiseStatus: state.promise.userUpsert?.status || null,
  209. serverErrors: state.promise?.userUpsert?.error || [],
  210. }),
  211. {
  212. onProfileSave: (profile = {}) => actionUserUpdate(profile),
  213. }
  214. )(ProfileForm);