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.

104 lines
3.5 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. import { useRef, useState } from "react";
  2. import { titleCase } from "text-case";
  3. import Admin from "@/models/admin";
  4. import EditUserModal from "./EditUserModal";
  5. import showToast from "@/utils/toast";
  6. import { useModal } from "@/hooks/useModal";
  7. import ModalWrapper from "@/components/ModalWrapper";
  8. import moment from 'moment';
  9. const ModMap = {
  10. admin: ["admin", "manager", "default"],
  11. manager: ["manager", "default"],
  12. default: [],
  13. };
  14. export default function UserRow({ currUser, user }) {
  15. const rowRef = useRef(null);
  16. const canModify = ModMap[currUser?.role || "default"].includes(user.role);
  17. const [suspended, setSuspended] = useState(user.suspended === 1);
  18. const { isOpen, openModal, closeModal } = useModal();
  19. const handleSuspend = async () => {
  20. if (
  21. !window.confirm(
  22. `您确定要删除吗 ${user.username}?\n在您这样做之后,它们将被注销,并且无法重新登录`
  23. )
  24. )
  25. return false;
  26. const { success, error } = await Admin.updateUser(user.id, {
  27. suspended: suspended ? 0 : 1,
  28. });
  29. if (!success) showToast(error, "error", { clear: true });
  30. if (success) {
  31. showToast(
  32. `User ${!suspended ? "has been suspended" : "is no longer suspended"}.`,
  33. "success",
  34. { clear: true }
  35. );
  36. setSuspended(!suspended);
  37. }
  38. };
  39. const handleDelete = async () => {
  40. if (
  41. !window.confirm(
  42. `您确定要删除吗 ${user.username}?\n在您这样做之后,它们将被注销,并且无法重新登录`
  43. )
  44. )
  45. return false;
  46. const { success, error } = await Admin.deleteUser(user.id);
  47. if (!success) showToast(error, "error", { clear: true });
  48. if (success) {
  49. rowRef?.current?.remove();
  50. showToast("User deleted from system.", "success", { clear: true });
  51. }
  52. };
  53. return (
  54. <>
  55. <tr
  56. ref={rowRef}
  57. className="bg-transparent text-white text-opacity-80 text-sm font-medium"
  58. >
  59. <th scope="row" className="px-6 py-4 whitespace-nowrap">
  60. {user.username}
  61. </th>
  62. <td className="px-6 py-4">{titleCase(user.role)}</td>
  63. <td className="px-6 py-4">{new Date(user.createdAt).toLocaleDateString()}</td>
  64. <td className="px-6 py-4 flex items-center gap-x-6">
  65. {canModify && (
  66. <button
  67. onClick={openModal}
  68. className="text-sm font-medium text-white/80 light:text-black/80 rounded-lg hover:text-white hover:light:text-gray-500 px-2 py-1 hover:bg-white hover:bg-opacity-10"
  69. >
  70. 编辑
  71. </button>
  72. )}
  73. {currUser?.id !== user.id && canModify && (
  74. <>
  75. <button
  76. onClick={handleSuspend}
  77. className="text-sm font-medium text-white/80 light:text-black/80 hover:light:text-orange-500 hover:text-orange-300 rounded-lg px-2 py-1 hover:bg-white hover:light:bg-orange-50 hover:bg-opacity-10"
  78. >
  79. {suspended ? "Unsuspend" : "Suspend"}
  80. </button>
  81. <button
  82. onClick={handleDelete}
  83. className="text-sm font-medium text-white/80 light:text-black/80 hover:light:text-red-500 hover:text-red-300 rounded-lg px-2 py-1 hover:bg-white hover:light:bg-red-50 hover:bg-opacity-10"
  84. >
  85. 删除
  86. </button>
  87. </>
  88. )}
  89. </td>
  90. </tr>
  91. <ModalWrapper isOpen={isOpen}>
  92. <EditUserModal
  93. currentUser={currUser}
  94. user={user}
  95. closeModal={closeModal}
  96. />
  97. </ModalWrapper>
  98. </>
  99. );
  100. }