25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 

214 satır
5.9 KiB

  1. "use client";
  2. import { useRouter, useSearchParams } from "next/navigation";
  3. import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react";
  4. import SearchResults, { Column } from "../SearchResults";
  5. // import { TeamResult } from "@/app/api/team";
  6. import { useTranslation } from "react-i18next";
  7. import {
  8. Button,
  9. Card,
  10. CardContent,
  11. Grid,
  12. Stack,
  13. Tab,
  14. Tabs,
  15. TabsProps,
  16. TextField,
  17. Typography,
  18. } from "@mui/material";
  19. import {
  20. FieldErrors,
  21. FormProvider,
  22. SubmitErrorHandler,
  23. SubmitHandler,
  24. useForm,
  25. useFormContext,
  26. } from "react-hook-form";
  27. import { Check, Close, Error, RestartAlt } from "@mui/icons-material";
  28. import { StaffResult } from "@/app/api/staff";
  29. import { UserInputs, adminChangePassword, editUser, fetchUserDetails } from "@/app/api/user/actions";
  30. import UserDetail from "./UserDetail";
  31. import { UserResult, passwordRule } from "@/app/api/user";
  32. import { auth, fetchAuth } from "@/app/api/group/actions";
  33. import AuthAllocation from "./AuthAllocation";
  34. interface Props {
  35. user: UserResult,
  36. rules: passwordRule,
  37. auths: auth[]
  38. }
  39. const EditUser: React.FC<Props> = async ({
  40. user,
  41. rules,
  42. auths
  43. }) => {
  44. const { t } = useTranslation();
  45. const formProps = useForm<UserInputs>();
  46. const searchParams = useSearchParams();
  47. const id = parseInt(searchParams.get("id") || "0");
  48. const [tabIndex, setTabIndex] = useState(0);
  49. const router = useRouter();
  50. const [serverError, setServerError] = useState("");
  51. const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
  52. (_e, newValue) => {
  53. setTabIndex(newValue);
  54. },
  55. []
  56. );
  57. const errors = formProps.formState.errors;
  58. useEffect(() => {
  59. try {
  60. const addAuthIds = auths && auths.length > 0
  61. ? auths.filter((item) => item.v === 1).map((item) => item.id).sort((a, b) => a - b)
  62. : []
  63. formProps.reset({
  64. name: user.username,
  65. email: user.email,
  66. addAuthIds: addAuthIds
  67. });
  68. } catch (error) {
  69. console.log(error);
  70. setServerError(t("An error has occurred. Please try again later."));
  71. }
  72. }, [user, auths]);
  73. const hasErrorsInTab = (
  74. tabIndex: number,
  75. errors: FieldErrors<UserResult>
  76. ) => {
  77. switch (tabIndex) {
  78. case 0:
  79. return Object.keys(errors).length > 0;
  80. default:
  81. false;
  82. }
  83. };
  84. const handleCancel = () => {
  85. router.back();
  86. };
  87. const onSubmit = useCallback<SubmitHandler<UserInputs>>(
  88. async (data) => {
  89. try {
  90. let haveError = false
  91. let regex_pw = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,20}$/
  92. let pw = ''
  93. if (data.password && data.password.length > 0) {
  94. pw = data.password
  95. if (pw.length < rules.min) {
  96. haveError = true
  97. formProps.setError("password", { message: t("The password requires 8-20 characters."), type: "required" })
  98. }
  99. if (pw.length > rules.max) {
  100. haveError = true
  101. formProps.setError("password", { message: t("The password requires 8-20 characters."), type: "required" })
  102. }
  103. if (!regex_pw.test(pw)) {
  104. haveError = true
  105. formProps.setError("password", { message: "A combination of uppercase letters, lowercase letters, numbers, and symbols is required.", type: "required" })
  106. }
  107. }
  108. const userData = {
  109. name: data.name,
  110. locked: false,
  111. addAuthIds: data.addAuthIds || [],
  112. removeAuthIds: data.removeAuthIds || [],
  113. }
  114. const pwData = {
  115. id: id,
  116. password: "",
  117. newPassword: pw
  118. }
  119. if (haveError) {
  120. return
  121. }
  122. console.log("passed")
  123. await editUser(id, userData);
  124. if (data.password && data.password.length > 0) {
  125. await adminChangePassword(pwData);
  126. }
  127. router.replace("/settings/staff");
  128. } catch (e) {
  129. console.log(e);
  130. setServerError(t("An error has occurred. Please try again later."));
  131. }
  132. },
  133. [router]
  134. );
  135. const onSubmitError = useCallback<SubmitErrorHandler<UserInputs>>(
  136. (errors) => {
  137. console.log(errors);
  138. },
  139. []
  140. );
  141. return (
  142. <>
  143. {serverError && (
  144. <Typography variant="body2" color="error" alignSelf="flex-end">
  145. {serverError}
  146. </Typography>
  147. )}
  148. <FormProvider {...formProps}>
  149. <Stack
  150. spacing={2}
  151. component="form"
  152. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  153. >
  154. <Stack
  155. direction="row"
  156. justifyContent="space-between"
  157. flexWrap="wrap"
  158. rowGap={2}
  159. >
  160. <Tabs
  161. value={tabIndex}
  162. onChange={handleTabChange}
  163. variant="scrollable"
  164. >
  165. <Tab
  166. label={t("User Detail")}
  167. icon={
  168. hasErrorsInTab(0, errors) ? (
  169. <Error sx={{ marginInlineEnd: 1 }} color="error" />
  170. ) : undefined
  171. }
  172. iconPosition="end"
  173. />
  174. <Tab label={t("User Authority")} iconPosition="end" />
  175. </Tabs>
  176. </Stack>
  177. {tabIndex == 0 && <UserDetail />}
  178. {tabIndex === 1 && <AuthAllocation auths={auths!}/>}
  179. <Stack direction="row" justifyContent="flex-end" gap={1}>
  180. <Button
  181. variant="text"
  182. startIcon={<RestartAlt />}
  183. // onClick={() => console.log("asdasd")}
  184. >
  185. {t("Reset")}
  186. </Button>
  187. <Button
  188. variant="outlined"
  189. startIcon={<Close />}
  190. onClick={handleCancel}
  191. >
  192. {t("Cancel")}
  193. </Button>
  194. <Button variant="contained" startIcon={<Check />} type="submit">
  195. {t("Confirm")}
  196. </Button>
  197. </Stack>
  198. </Stack>
  199. </FormProvider>
  200. </>
  201. );
  202. };
  203. export default EditUser;