CourseMember.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { useIntl } from "react-intl";
  2. import { useRef, useState } from "react";
  3. import { ActionType, ProList } from "@ant-design/pro-components";
  4. import { Space, Tag, Button, Layout, Popconfirm } from "antd";
  5. import CourseAddMember from "./AddMember";
  6. import { delete_, get } from "../../request";
  7. import {
  8. ICourseMemberDeleteResponse,
  9. ICourseMemberListResponse,
  10. TCourseMemberStatus,
  11. } from "../api/Course";
  12. import { IUser } from "../auth/User";
  13. const { Content } = Layout;
  14. interface IRoleTag {
  15. title: string;
  16. color: string;
  17. }
  18. export interface ICourseMember {
  19. sn?: number;
  20. id?: string;
  21. userId: string;
  22. user?: IUser;
  23. name?: string;
  24. tag?: IRoleTag[];
  25. image: string;
  26. role?: string;
  27. startExp?: number;
  28. endExp?: number;
  29. currentExp?: number;
  30. expByDay?: number;
  31. status?: TCourseMemberStatus;
  32. }
  33. interface IWidget {
  34. courseId?: string;
  35. }
  36. const CourseMemberWidget = ({ courseId }: IWidget) => {
  37. const intl = useIntl(); //i18n
  38. const [canDelete, setCanDelete] = useState(false);
  39. const [memberCount, setMemberCount] = useState<number>();
  40. const ref = useRef<ActionType>();
  41. return (
  42. <Content>
  43. <ProList<ICourseMember>
  44. rowKey="id"
  45. actionRef={ref}
  46. headerTitle={
  47. intl.formatMessage({ id: "group.member" }) +
  48. "-" +
  49. memberCount?.toString()
  50. }
  51. toolBarRender={() => {
  52. return [
  53. canDelete ? (
  54. <CourseAddMember
  55. courseId={courseId}
  56. onCreated={() => {
  57. ref.current?.reload();
  58. }}
  59. />
  60. ) : (
  61. <></>
  62. ),
  63. ];
  64. }}
  65. showActions="hover"
  66. request={async (params = {}, sorter, filter) => {
  67. console.log(params, sorter, filter);
  68. let url = `/v2/course-member?view=course&id=${courseId}`;
  69. const offset =
  70. ((params.current ? params.current : 1) - 1) *
  71. (params.pageSize ? params.pageSize : 20);
  72. url += `&limit=${params.pageSize}&offset=${offset}`;
  73. if (typeof params.keyword !== "undefined") {
  74. url += "&search=" + (params.keyword ? params.keyword : "");
  75. }
  76. const res = await get<ICourseMemberListResponse>(url);
  77. if (res.ok) {
  78. console.log(res.data);
  79. setMemberCount(res.data.count);
  80. if (res.data.role === "owner" || res.data.role === "manager") {
  81. setCanDelete(true);
  82. }
  83. const items: ICourseMember[] = res.data.rows.map((item, id) => {
  84. let member: ICourseMember = {
  85. id: item.id ? item.id : "",
  86. userId: item.user_id,
  87. user: item.user,
  88. name: item.user?.nickName,
  89. tag: [],
  90. image: "",
  91. };
  92. return member;
  93. });
  94. console.log(items);
  95. return {
  96. total: res.data.count,
  97. succcess: true,
  98. data: items,
  99. };
  100. } else {
  101. console.error(res.message);
  102. return {
  103. total: 0,
  104. succcess: false,
  105. data: [],
  106. };
  107. }
  108. }}
  109. pagination={{
  110. showQuickJumper: true,
  111. showSizeChanger: true,
  112. }}
  113. metas={{
  114. title: {
  115. dataIndex: "name",
  116. },
  117. avatar: {
  118. dataIndex: "image",
  119. editable: false,
  120. },
  121. subTitle: {
  122. render: (text, row, index, action) => {
  123. return <Tag>{row.role}</Tag>;
  124. },
  125. },
  126. actions: {
  127. render: (text, row, index, action) => [
  128. canDelete ? (
  129. <Popconfirm
  130. placement="bottomLeft"
  131. title={intl.formatMessage({
  132. id: "forms.message.member.remove",
  133. })}
  134. onConfirm={(
  135. e?: React.MouseEvent<HTMLElement, MouseEvent>
  136. ) => {
  137. console.log("delete", row.id);
  138. delete_<ICourseMemberDeleteResponse>(
  139. "/v2/course-member/" + row.id
  140. ).then((json) => {
  141. if (json.ok) {
  142. console.log("delete ok");
  143. ref.current?.reload();
  144. }
  145. });
  146. }}
  147. okText={intl.formatMessage({ id: "buttons.ok" })}
  148. cancelText={intl.formatMessage({ id: "buttons.cancel" })}
  149. >
  150. <Button size="small" type="link" danger key="link">
  151. {intl.formatMessage({ id: "buttons.remove" })}
  152. </Button>
  153. </Popconfirm>
  154. ) : (
  155. <></>
  156. ),
  157. ],
  158. },
  159. }}
  160. />
  161. </Content>
  162. );
  163. };
  164. export default CourseMemberWidget;