FPSMS-frontend
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 

187 строки
4.9 KiB

  1. "use client";
  2. import { useRouter, useSearchParams } from "next/navigation";
  3. import React, {
  4. useCallback,
  5. useEffect,
  6. useLayoutEffect,
  7. useMemo,
  8. useState,
  9. } from "react";
  10. import { useTranslation } from "react-i18next";
  11. import {
  12. Button,
  13. Stack,
  14. Typography,
  15. } from "@mui/material";
  16. import {
  17. FormProvider,
  18. SubmitErrorHandler,
  19. SubmitHandler,
  20. useForm,
  21. } from "react-hook-form";
  22. import { Check, Close, RestartAlt } from "@mui/icons-material";
  23. import {
  24. UserInputs,
  25. adminChangePassword,
  26. editUser,
  27. } from "@/app/api/user/actions";
  28. import UserDetail from "./UserDetail";
  29. import { UserResult, passwordRule } from "@/app/api/user";
  30. interface Props {
  31. user: UserResult & { authIds?: number[] };
  32. rules: passwordRule;
  33. }
  34. const EditUser: React.FC<Props> = ({ user, rules }) => {
  35. console.log(user);
  36. const { t } = useTranslation("user");
  37. const formProps = useForm<UserInputs>();
  38. const searchParams = useSearchParams();
  39. const id = parseInt(searchParams.get("id") || "0");
  40. const router = useRouter();
  41. const [serverError, setServerError] = useState("");
  42. const resetForm = React.useCallback((e?: React.MouseEvent<HTMLButtonElement>) => {
  43. e?.preventDefault();
  44. e?.stopPropagation();
  45. try {
  46. formProps.reset({
  47. username: user.username,
  48. name: user.name,
  49. staffNo: user.staffNo?.toString() ?? "",
  50. addAuthIds: user.authIds ?? [],
  51. removeAuthIds: [],
  52. password: "",
  53. });
  54. formProps.clearErrors();
  55. } catch (error) {
  56. console.log(error);
  57. setServerError(t("An error has occurred. Please try again later."));
  58. }
  59. }, [formProps, user, t]);
  60. useEffect(() => {
  61. resetForm();
  62. }, [user.id]);
  63. const handleCancel = () => {
  64. router.back();
  65. };
  66. const onSubmit = useCallback<SubmitHandler<UserInputs>>(
  67. async (data) => {
  68. try {
  69. let haveError = false;
  70. const regex_pw =
  71. /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,20}$/;
  72. let pw = "";
  73. if (data.password && data.password.length > 0) {
  74. pw = data.password;
  75. if (pw.length < rules.min) {
  76. haveError = true;
  77. formProps.setError("password", {
  78. message: t("The password requires 8-20 characters."),
  79. type: "required",
  80. });
  81. }
  82. if (pw.length > rules.max) {
  83. haveError = true;
  84. formProps.setError("password", {
  85. message: t("The password requires 8-20 characters."),
  86. type: "required",
  87. });
  88. }
  89. if (!regex_pw.test(pw)) {
  90. haveError = true;
  91. formProps.setError("password", {
  92. message: t(
  93. "A combination of uppercase letters, lowercase letters, numbers, and symbols is required.",
  94. ),
  95. type: "required",
  96. });
  97. }
  98. }
  99. const userData = {
  100. username: data.username,
  101. name: data.name,
  102. staffNo: data.staffNo,
  103. locked: false,
  104. addAuthIds: data.addAuthIds || [],
  105. removeAuthIds: data.removeAuthIds || [],
  106. };
  107. const pwData = {
  108. id: id,
  109. password: "",
  110. newPassword: pw,
  111. };
  112. if (haveError) {
  113. return;
  114. }
  115. console.log("passed");
  116. await editUser(id, userData);
  117. if (data.password && data.password.length > 0) {
  118. await adminChangePassword(pwData);
  119. }
  120. router.replace("/settings/user");
  121. } catch (e) {
  122. console.log(e);
  123. setServerError(t("An error has occurred. Please try again later."));
  124. }
  125. },
  126. [router],
  127. );
  128. const onSubmitError = useCallback<SubmitErrorHandler<UserInputs>>(
  129. (errors) => {
  130. console.log(errors);
  131. },
  132. [],
  133. );
  134. return (
  135. <>
  136. {serverError && (
  137. <Typography variant="body2" color="error" alignSelf="flex-end">
  138. {serverError}
  139. </Typography>
  140. )}
  141. <FormProvider {...formProps}>
  142. <Stack
  143. spacing={2}
  144. component="form"
  145. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  146. >
  147. <UserDetail />
  148. <Stack direction="row" justifyContent="flex-end" gap={1}>
  149. <Button
  150. variant="text"
  151. startIcon={<RestartAlt />}
  152. onClick={(e) => {
  153. e.preventDefault();
  154. e.stopPropagation();
  155. resetForm(e);
  156. }}
  157. type="button"
  158. >
  159. {t("Reset")}
  160. </Button>
  161. <Button
  162. variant="outlined"
  163. startIcon={<Close />}
  164. onClick={handleCancel}
  165. type="button"
  166. >
  167. {t("Cancel")}
  168. </Button>
  169. <Button variant="contained" startIcon={<Check />} type="submit">
  170. {t("Confirm")}
  171. </Button>
  172. </Stack>
  173. </Stack>
  174. </FormProvider>
  175. </>
  176. );
  177. };
  178. export default EditUser;