您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

137 行
3.9 KiB

  1. "use client";
  2. import { CreateGroupInputs, auth, saveGroup } from "@/app/api/group/actions";
  3. import { useRouter } from "next/navigation";
  4. import { useCallback, useState } from "react";
  5. import { FieldErrors, FormProvider, SubmitHandler, useForm } from "react-hook-form";
  6. import { useTranslation } from "react-i18next";
  7. import { Button, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material";
  8. import { Check, Close, Error } from "@mui/icons-material";
  9. import GroupInfo from "./GroupInfo";
  10. import AuthorityAllocation from "./AuthorityAllocation";
  11. import UserAllocation from "./UserAllocation";
  12. import { UserResult } from "@/app/api/user";
  13. interface Props {
  14. auth?: auth[]
  15. users?: UserResult[]
  16. }
  17. const CreateGroup: React.FC<Props> = ({ auth, users }) => {
  18. const formProps = useForm<CreateGroupInputs>();
  19. const [serverError, setServerError] = useState("");
  20. const router = useRouter();
  21. const [tabIndex, setTabIndex] = useState(0);
  22. const { t } = useTranslation("group");
  23. const errors = formProps.formState.errors;
  24. const onSubmit = useCallback<SubmitHandler<CreateGroupInputs>>(
  25. async (data) => {
  26. try {
  27. console.log(data);
  28. const postData = {
  29. ...data,
  30. removeUserIds: [],
  31. removeAuthIds: [],
  32. }
  33. console.log(postData)
  34. await saveGroup(postData)
  35. router.replace("/settings/group")
  36. } catch (e) {
  37. console.log(e);
  38. console.log(data)
  39. if (!data.addUserIds || data.addUserIds.length == 0) {
  40. setServerError(t("Please allocate users."));
  41. } else if (!data.addAuthIds || data.addAuthIds.length == 0) {
  42. setServerError(t("Please allocate auths."));
  43. } else {
  44. setServerError(t("An error has occurred. Please try again later."));
  45. }
  46. }
  47. },
  48. [router]
  49. );
  50. const handleCancel = () => {
  51. router.back();
  52. };
  53. const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
  54. (_e, newValue) => {
  55. setTabIndex(newValue);
  56. },
  57. []
  58. );
  59. const hasErrorsInTab = (
  60. tabIndex: number,
  61. errors: FieldErrors<CreateGroupInputs>,
  62. ) => {
  63. switch (tabIndex) {
  64. case 0:
  65. return Object.keys(errors).length > 0;
  66. default:
  67. false;
  68. }
  69. };
  70. return (
  71. <>
  72. <FormProvider {...formProps}>
  73. <Stack
  74. spacing={2}
  75. component="form"
  76. onSubmit={formProps.handleSubmit(onSubmit)}
  77. >
  78. <Tabs
  79. value={tabIndex}
  80. onChange={handleTabChange}
  81. variant="scrollable"
  82. >
  83. <Tab
  84. label={t("Group Info")}
  85. icon={
  86. hasErrorsInTab(0, errors) ? (
  87. <Error sx={{ marginInlineEnd: 1 }} color="error" />
  88. ) : undefined
  89. }
  90. iconPosition="end"
  91. />
  92. <Tab label={t("Authority Allocation")} iconPosition="end" />
  93. <Tab label={t("User Allocation")} iconPosition="end" />
  94. </Tabs>
  95. {serverError && (
  96. <Typography variant="body2" color="error" alignSelf="flex-end">
  97. {serverError}
  98. </Typography>
  99. )}
  100. {tabIndex === 0 && <GroupInfo/>}
  101. {tabIndex === 1 && <AuthorityAllocation auth={auth!!}/>}
  102. {tabIndex === 2 && <UserAllocation users={users!!}/>}
  103. <Stack direction="row" justifyContent="flex-end" gap={1}>
  104. <Button
  105. variant="outlined"
  106. startIcon={<Close />}
  107. onClick={handleCancel}
  108. >
  109. {t("Cancel")}
  110. </Button>
  111. <Button
  112. variant="contained"
  113. startIcon={<Check />}
  114. type="submit"
  115. // disabled={Boolean(formProps.watch("isGridEditing"))}
  116. >
  117. {t("Confirm")}
  118. </Button>
  119. </Stack>
  120. </Stack>
  121. </FormProvider>
  122. </>
  123. );
  124. };
  125. export default CreateGroup;