Status.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * 报名按钮
  3. * 已经报名显示报名状态
  4. * 未报名显示报名按钮以及必要的提示
  5. */
  6. import { Space, Typography } from "antd";
  7. import { useEffect, useState } from "react";
  8. import { useIntl } from "react-intl";
  9. import { _Link } from "react-router";
  10. import { get } from "../../request";
  11. import type {
  12. ICourseDataResponse,
  13. ICourseMemberData,
  14. ICourseMemberResponse,
  15. TCourseMemberStatus,
  16. } from "../../api/Course";
  17. import { useAppSelector } from "../../hooks";
  18. import { currentUser } from "../../reducers/current-user";
  19. import UserAction from "./UserAction";
  20. import { getStatusColor, getStudentActionsByStatus } from "./RolePower";
  21. import LoginButton from "../auth/LoginButton";
  22. const { Paragraph, Text } = Typography;
  23. interface IWidget {
  24. data?: ICourseDataResponse;
  25. }
  26. const StatusWidget = ({ data }: IWidget) => {
  27. const intl = useIntl();
  28. const [currMember, setCurrMember] = useState<ICourseMemberData>();
  29. const user = useAppSelector(currentUser);
  30. const numberOfStudent = data?.members?.filter(
  31. (value) =>
  32. value.role === "student" &&
  33. (value.status === "accepted" ||
  34. value.status === "applied" ||
  35. value.status === "joined")
  36. ).length;
  37. useEffect(() => {
  38. /**
  39. * 获取该课程我的报名状态
  40. */
  41. if (typeof data?.id === "undefined") {
  42. return;
  43. }
  44. const url = `/v2/course-member/${data?.id}`;
  45. console.info("api request", url);
  46. get<ICourseMemberResponse>(url).then((json) => {
  47. console.debug("course member", json);
  48. if (json.ok) {
  49. setCurrMember(json.data);
  50. }
  51. });
  52. }, [data?.id]);
  53. let labelStatus = "";
  54. let operation: React.ReactNode | undefined;
  55. let currStatus: TCourseMemberStatus = "none";
  56. if (currMember?.status) {
  57. currStatus = currMember.status;
  58. }
  59. const actions = getStudentActionsByStatus(
  60. currStatus,
  61. data?.join,
  62. data?.start_at,
  63. data?.end_at,
  64. data?.sign_up_start_at,
  65. data?.sign_up_end_at
  66. );
  67. console.debug("getStudentActionsByStatus", currStatus, data?.join, actions);
  68. if (user) {
  69. labelStatus = intl.formatMessage({
  70. id: `course.member.status.${currStatus}.label`,
  71. });
  72. operation = (
  73. <Space>
  74. {actions?.map((item, id) => {
  75. if (item === "apply" && data?.number !== 0) {
  76. if (
  77. numberOfStudent &&
  78. data?.number &&
  79. numberOfStudent >= data?.number
  80. ) {
  81. return <Text type="danger">{"名额已满"}</Text>;
  82. }
  83. }
  84. return (
  85. <UserAction
  86. key={id}
  87. action={item}
  88. currUser={currMember}
  89. courseId={data?.id}
  90. courseName={data?.title}
  91. signUpMessage={data?.sign_up_message}
  92. user={{
  93. id: user.id,
  94. nickName: user.nickName,
  95. userName: user.realName,
  96. }}
  97. onStatusChanged={(status: ICourseMemberData | undefined) => {
  98. setCurrMember(status);
  99. }}
  100. />
  101. );
  102. })}
  103. </Space>
  104. );
  105. } else {
  106. //未登录
  107. labelStatus = "未登录";
  108. operation = <LoginButton target="_blank" />;
  109. }
  110. return data?.id ? (
  111. <Paragraph>
  112. <div style={{ color: getStatusColor(currStatus) }}>{labelStatus}</div>
  113. {operation}
  114. </Paragraph>
  115. ) : (
  116. <></>
  117. );
  118. };
  119. export default StatusWidget;