Просмотр исходного кода

Merge pull request #2019 from visuddhinanda/agile

add loading in course list
visuddhinanda 2 лет назад
Родитель
Сommit
f788f7d141

+ 18 - 0
dashboard/src/components/course/CourseNewLoading.tsx

@@ -0,0 +1,18 @@
+import { Skeleton } from "antd";
+
+const CourseNewLoading = () => {
+  return (
+    <div style={{ display: "flex", width: "100%" }}>
+      {[1, 1, 1, 1].map((item, id) => {
+        return (
+          <div style={{ height: 400, flex: 2 }}>
+            <Skeleton.Image active={true} />
+            <Skeleton title={{ width: 40 }} paragraph={{ rows: 2 }} active />
+          </div>
+        );
+      })}
+    </div>
+  );
+};
+
+export default CourseNewLoading;

+ 29 - 19
dashboard/src/components/course/LecturerList.tsx

@@ -6,35 +6,45 @@ import { Card, List, message, Typography, Image } from "antd";
 import { ICourse } from "../../pages/library/course/course";
 import { ICourseListResponse } from "../api/Course";
 import { API_HOST, get } from "../../request";
+import CourseNewLoading from "./CourseNewLoading";
 
 const { Meta } = Card;
 const { Paragraph } = Typography;
 
 const LecturerListWidget = () => {
   const [data, setData] = useState<ICourse[]>();
+  const [loading, setLoading] = useState(false);
+
   const navigate = useNavigate();
 
   useEffect(() => {
-    get<ICourseListResponse>(`/v2/course?view=new&limit=4`).then((json) => {
-      if (json.ok) {
-        console.log(json.data);
-        const course: ICourse[] = json.data.rows.map((item) => {
-          return {
-            id: item.id,
-            title: item.title,
-            subtitle: item.subtitle,
-            teacher: item.teacher,
-            intro: item.content,
-            coverUrl: item.cover_url,
-          };
-        });
-        setData(course);
-      } else {
-        message.error(json.message);
-      }
-    });
+    const url = `/v2/course?view=new&limit=4`;
+    console.info("course url", url);
+    setLoading(true);
+    get<ICourseListResponse>(url)
+      .then((json) => {
+        if (json.ok) {
+          console.log(json.data);
+          const course: ICourse[] = json.data.rows.map((item) => {
+            return {
+              id: item.id,
+              title: item.title,
+              subtitle: item.subtitle,
+              teacher: item.teacher,
+              intro: item.content,
+              coverUrl: item.cover_url,
+            };
+          });
+          setData(course);
+        } else {
+          message.error(json.message);
+        }
+      })
+      .finally(() => setLoading(false));
   }, []);
-  return (
+  return loading ? (
+    <CourseNewLoading />
+  ) : (
     <List
       grid={{ gutter: 16, column: 4 }}
       dataSource={data}

+ 55 - 33
dashboard/src/pages/library/course/course.tsx

@@ -13,6 +13,8 @@ import {
   TCourseJoinMode,
 } from "../../../components/api/Course";
 import CourseHead from "../../../components/course/CourseHead";
+import ArticleSkeleton from "../../../components/article/ArticleSkeleton";
+import ErrorResult from "../../../components/general/ErrorResult";
 
 export interface ICourse {
   id: string; //课程ID
@@ -35,43 +37,63 @@ export interface ICourse {
 const Widget = () => {
   const { id } = useParams(); //url 参数
   const [courseInfo, setCourseInfo] = useState<ICourse>();
+  const [loading, setLoading] = useState(false);
+  const [errorCode, setErrorCode] = useState<number>();
+
   useEffect(() => {
-    get<ICourseResponse>(`/v2/course/${id}`).then((json) => {
-      if (json.ok) {
-        console.log(json.data);
-        const course: ICourse = {
-          id: json.data.id,
-          title: json.data.title,
-          subtitle: json.data.subtitle,
-          teacher: json.data.teacher,
-          privacy: json.data.publicity,
-          createdAt: json.data.created_at,
-          updatedAt: json.data.updated_at,
-          anthologyId: json.data.anthology_id,
-          channelId: json.data.channel_id,
-          startAt: json.data.start_at,
-          endAt: json.data.end_at,
-          intro: json.data.content,
-          coverUrl: json.data.cover_url,
-          join: json.data.join,
-          exp: json.data.request_exp,
-        };
-        setCourseInfo(course);
-      } else {
-        message.error(json.message);
-      }
-    });
+    const url = `/v2/course/${id}`;
+    console.info("course url", url);
+    setLoading(true);
+    get<ICourseResponse>(url)
+      .then((json) => {
+        if (json.ok) {
+          console.log(json.data);
+          const course: ICourse = {
+            id: json.data.id,
+            title: json.data.title,
+            subtitle: json.data.subtitle,
+            teacher: json.data.teacher,
+            privacy: json.data.publicity,
+            createdAt: json.data.created_at,
+            updatedAt: json.data.updated_at,
+            anthologyId: json.data.anthology_id,
+            channelId: json.data.channel_id,
+            startAt: json.data.start_at,
+            endAt: json.data.end_at,
+            intro: json.data.content,
+            coverUrl: json.data.cover_url,
+            join: json.data.join,
+            exp: json.data.request_exp,
+          };
+          setCourseInfo(course);
+        } else {
+          message.error(json.message);
+        }
+      })
+      .finally(() => setLoading(false))
+      .catch((e) => {
+        console.error(e);
+        setErrorCode(e);
+      });
   }, [id]);
   return (
     <>
-      <CourseHead {...courseInfo} />
-      <Divider />
-      <CourseIntro {...courseInfo} />
-      <Divider />
-      <TextBook
-        anthologyId={courseInfo?.anthologyId}
-        courseId={courseInfo?.id}
-      />
+      {loading ? (
+        <ArticleSkeleton />
+      ) : errorCode ? (
+        <ErrorResult code={errorCode} />
+      ) : (
+        <div>
+          <CourseHead {...courseInfo} />
+          <Divider />
+          <CourseIntro {...courseInfo} />
+          <Divider />
+          <TextBook
+            anthologyId={courseInfo?.anthologyId}
+            courseId={courseInfo?.id}
+          />
+        </div>
+      )}
     </>
   );
 };

+ 5 - 4
dashboard/src/pages/library/course/list.tsx

@@ -1,9 +1,10 @@
 //课程主页
-import { Layout, Col, Row, Divider } from "antd";
+import { Layout, Col, Row, Divider, Typography } from "antd";
 
 import LecturerList from "../../../components/course/LecturerList";
 import CourseList from "../../../components/course/CourseList";
 const { Content, Header } = Layout;
+const { Title } = Typography;
 
 const Widget = () => {
   // TODO i18n
@@ -23,21 +24,21 @@ const Widget = () => {
           <Col flex="auto"></Col>
           <Col flex="960px">
             <Row>
-              <h1>最新</h1>
+              <Title level={4}>最新</Title>
             </Row>
             <Row>
               <LecturerList />
             </Row>
             <Divider />
             <Row>
-              <h1>开放报名</h1>
+              <Title level={4}>开放报名</Title>
             </Row>
             <Row>
               <CourseList type="open" />
             </Row>
             <Divider />
             <Row>
-              <h1>历史课程</h1>
+              <Title level={4}>历史课程</Title>
             </Row>
             <Row>
               <CourseList type="close" />