You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 line
3.8KB

  1. import { yupResolver } from "@hookform/resolvers/yup";
  2. import { Box, Button, Stack, Typography } from "@mui/material";
  3. import { HasChildren } from "@types";
  4. import { changeLoginPassword, getLoginUsers } from "api/login-user";
  5. import { PageID, TabID } from "codes/page";
  6. import { UserRole } from "codes/user";
  7. import { FormProvider, RHFTextField } from "components/hook-form";
  8. import useAPICall from "hooks/useAPICall";
  9. import useAuth from "hooks/useAuth";
  10. import useDashboard from "hooks/useDashBoard";
  11. import useSnackbarCustom from "hooks/useSnackbarCustom";
  12. import { useEffect, useState } from "react";
  13. import { useForm } from "react-hook-form";
  14. import { useParams } from "react-router-dom";
  15. import * as Yup from "yup";
  16. type AreaBoxProps = {
  17. title: string;
  18. } & HasChildren;
  19. function AreaBox({ title, children }: AreaBoxProps) {
  20. return (
  21. <Box sx={{ maxWidth: 500 }}>
  22. <Typography variant="subtitle1">{title}</Typography>
  23. {children}
  24. </Box>
  25. );
  26. }
  27. type FormProps = {
  28. password: string;
  29. password_retype: string;
  30. };
  31. export default function ChangePassword() {
  32. const { setHeaderTitle, setTabs } = useDashboard(
  33. PageID.DASHBOARD_LOGIN_USER_CHANGE_PASSWORD,
  34. TabID.NONE
  35. );
  36. const { initialized, userId, role } = useAuth();
  37. const { success, error } = useSnackbarCustom();
  38. const { id: paramUserId } = useParams();
  39. const [timestamp, setTimestamp] = useState("");
  40. const [mode, setMode] = useState<"input" | "done">("input");
  41. const form = useForm<FormProps>({
  42. defaultValues: {
  43. password: "",
  44. password_retype: "",
  45. },
  46. resolver: yupResolver(
  47. Yup.object().shape({
  48. password: Yup.string().required("必須項目です"),
  49. password_retype: Yup.string()
  50. .required("必須項目です")
  51. .test("retype", "入力が一致しません", function (value) {
  52. return this.parent.password === value;
  53. }),
  54. })
  55. ),
  56. });
  57. const { callAPI: callGetLoginUsers } = useAPICall({
  58. apiMethod: getLoginUsers,
  59. onSuccess: ({ data: { records } }) => {
  60. if (records.length === 1) {
  61. setTimestamp(records[0].updated_at);
  62. }
  63. },
  64. });
  65. const { callAPI: callChangeLoginPassword, makeSendData } = useAPICall({
  66. apiMethod: changeLoginPassword,
  67. backDrop: true,
  68. form,
  69. onSuccess: () => {
  70. success("登録しました");
  71. setMode("done");
  72. },
  73. onFailed: () => {
  74. error("失敗しました");
  75. },
  76. });
  77. const fetch = () => {
  78. callGetLoginUsers({
  79. id: paramUserId,
  80. });
  81. };
  82. const handleSubmt = (data: FormProps) => {
  83. const sendData = makeSendData({ ...data, timestamp });
  84. if (userId === paramUserId) {
  85. // 自身の場合はパラメータなしで送信する
  86. } else {
  87. sendData.id = paramUserId ?? "";
  88. }
  89. callChangeLoginPassword(sendData);
  90. };
  91. useEffect(() => {
  92. if (initialized) {
  93. fetch();
  94. }
  95. }, [initialized]);
  96. useEffect(() => {
  97. setHeaderTitle("パスワード変更");
  98. setTabs(null);
  99. }, []);
  100. return (
  101. <>
  102. {mode === "input" && (
  103. <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmt)}>
  104. <Box>
  105. <Stack spacing={2}>
  106. <AreaBox title="ログインパスワード">
  107. <RHFTextField name="password" type="password" />
  108. </AreaBox>
  109. <AreaBox title="ログインパスワード(再入力)">
  110. <RHFTextField name="password_retype" type="password" />
  111. </AreaBox>
  112. <Stack direction="row">
  113. <Button variant="contained" type="submit">
  114. 登録
  115. </Button>
  116. </Stack>
  117. </Stack>
  118. </Box>
  119. </FormProvider>
  120. )}
  121. {mode === "done" && <Box>変更完了しました</Box>}
  122. </>
  123. );
  124. }