diff --git a/src/components/footer/index.module.scss b/src/components/footer/index.module.scss index bea2937..3079b2f 100644 --- a/src/components/footer/index.module.scss +++ b/src/components/footer/index.module.scss @@ -6,4 +6,5 @@ color: rgba(0, 0, 0, 0.3); line-height: 12px; margin: 30px 0px; + text-align: center; } diff --git a/src/main.scss b/src/main.scss index 1d68176..a7f5983 100644 --- a/src/main.scss +++ b/src/main.scss @@ -82,3 +82,32 @@ code { .adm-progress-bar-text { color: #ff4d4f !important; } + +.adm-tabs-header { + border-bottom: none !important; +} + +.adm-tabs-tab { + color: rgba(0, 0, 0, 0.45); +} + +.adm-tabs-tab-active { + font-weight: 500; + color: rgba(0, 0, 0, 0.88); +} + +.adm-dropdown-item { + justify-content: left !important; + .adm-dropdown-item-title { + padding: 8px 0px !important; + .adm-dropdown-item-title-text { + font-size: 14px; + font-weight: 400; + color: rgba(0, 0, 0, 0.45); + } + } +} + +.adm-popup-body { + border-radius: 0px 0px 16px 16px; +} diff --git a/src/pages/index/compenents/courses-model.module.scss b/src/pages/index/compenents/courses-model.module.scss new file mode 100644 index 0000000..5a87d3a --- /dev/null +++ b/src/pages/index/compenents/courses-model.module.scss @@ -0,0 +1,67 @@ +.item { + width: 100%; + height: 75px; + display: flex; + flex-direction: row; + align-items: center; + .info { + flex: 1; + height: 75px; + display: flex; + flex-direction: column; + justify-content: space-between; + .title { + width: 100%; + height: 42px; + font-size: 15px; + font-weight: 400; + color: rgba(0, 0, 0, 0.88); + line-height: 21px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .status-content { + width: 100%; + display: flex; + align-items: center; + .type { + width: 46px; + height: 24px; + background: rgba(255, 77, 79, 0.1); + border-radius: 4px; + font-size: 12px; + font-weight: 400; + color: #ff4d4f; + display: flex; + align-items: center; + justify-content: center; + margin-right: 20px; + } + .active-type { + width: 46px; + height: 24px; + background: rgba(#ff9900, 0.1); + border-radius: 4px; + font-size: 12px; + font-weight: 400; + color: #ff9900; + display: flex; + align-items: center; + justify-content: center; + margin-right: 20px; + } + + .no-pro { + height: 12px; + font-size: 12px; + font-weight: 400; + color: rgba(0, 0, 0, 0.45); + line-height: 12px; + margin-left: 10px; + } + } + } +} diff --git a/src/pages/index/compenents/courses-model.tsx b/src/pages/index/compenents/courses-model.tsx new file mode 100644 index 0000000..63722a5 --- /dev/null +++ b/src/pages/index/compenents/courses-model.tsx @@ -0,0 +1,86 @@ +import React from "react"; +import { Image, ProgressBar } from "antd-mobile"; +import { useNavigate } from "react-router-dom"; +import styles from "./courses-model.module.scss"; +import mediaIcon from "../../../assets/images/commen/icon-medal.png"; + +interface PropInterface { + id: number; + title: string; + thumb: string; + isRequired: number; + progress: number; +} + +export const CoursesModel: React.FC = ({ + id, + title, + thumb, + isRequired, + progress, +}) => { + const navigate = useNavigate(); + return ( +
{ + navigate(`/course/${id}`); + }} + > + +
+
{title}
+
+ {isRequired === 1 &&
必修课
} + {isRequired === 0 && ( +
选修课
+ )} + {progress == 0 && ( + <> + + 未学习 + + )} + {progress > 0 && progress < 100 && ( + + )} + {progress >= 100 && ( +
+ + 恭喜你学完此套课程! +
+ )} +
+
+
+ ); +}; diff --git a/src/pages/index/index.module.scss b/src/pages/index/index.module.scss index e69de29..f5733a3 100644 --- a/src/pages/index/index.module.scss +++ b/src/pages/index/index.module.scss @@ -0,0 +1,133 @@ +.tabs-box { + width: 100%; + float: left; + height: 40px; + background-color: #ffffff; + box-sizing: border-box; + padding: 0px 8px; + position: fixed; + top: 0; + z-index: 10; +} + +.category-box { + width: 100%; + float: left; + height: auto; + box-sizing: border-box; + padding: 20px; +} + +.category-content { + width: 100%; + float: left; + height: auto; + background-color: #ffffff; + box-sizing: border-box; + padding: 20px 20px 0px 20px; + text-align: left; + position: fixed; + top: 40px; + z-index: 10; +} + +.category-box { + width: 100%; + height: 330px; + box-sizing: border-box; + padding: 10px 20px 20px 20px; + overflow-x: hidden; + overflow-y: auto; + .category-item { + width: 100%; + float: left; + height: auto; + .category-tit { + width: 100%; + font-size: 14px; + font-weight: 400; + color: rgba(0, 0, 0, 0.88); + line-height: 30px; + margin-bottom: 15px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + + .active-category-item { + width: 100%; + float: left; + height: auto; + .category-tit { + width: 100%; + font-size: 14px; + font-weight: 400; + color: #ff4d4f; + line-height: 30px; + margin-bottom: 15px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } +} + +.child-item { + width: 100%; + float: left; + height: auto; + box-sizing: border-box; + padding-left: 20px; + .category-tit { + width: 100%; + font-size: 14px; + font-weight: 400; + color: rgba(0, 0, 0, 0.88); + line-height: 30px; + margin-bottom: 15px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +.active-child-item { + width: 100%; + float: left; + height: auto; + box-sizing: border-box; + padding-left: 20px; + .category-tit { + width: 100%; + font-size: 14px; + font-weight: 400; + color: #ff4d4f; + line-height: 30px; + margin-bottom: 15px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +.list-box { + width: 100%; + height: auto; + box-sizing: border-box; + padding: 96px 20px 55px 20px; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + .item { + width: 100%; + height: auto; + box-sizing: border-box; + padding-top: 30px; + padding-bottom: 30px; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + &:first-child { + padding-top: 20px; + } + } +} diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 5ff417a..5d98cc2 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1,29 +1,280 @@ -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; +import { Dropdown, SpinLoading, Tabs } from "antd-mobile"; +import { DropdownRef } from "antd-mobile/es/components/dropdown"; import { user } from "../../api/index"; import styles from "./index.module.scss"; import { useSelector } from "react-redux"; -import { Footer, TabBarFooter } from "../../components"; +import { Footer, TabBarFooter, Empty } from "../../components"; +import { CoursesModel } from "./compenents/courses-model"; const IndexPage = () => { + const ref = useRef(null); const systemConfig = useSelector((state: any) => state.systemConfig.value); const [loading, setLoading] = useState(false); - const [tabKey, setTabKey] = useState(0); - const departments = useSelector( - (state: any) => state.loginUser.value.departments - ); + const [tabKey, setTabKey] = useState("0"); + const [coursesList, setCoursesList] = useState([]); + const [categories, setCategories] = useState([]); + const [categoryId, setCategoryId] = useState(0); + const [categoryText, setCategoryText] = useState("所有分类"); + const [learnCourseRecords, setLearnCourseRecords] = useState({}); + const [learnCourseHourCount, setLearnCourseHourCount] = useState({}); const currentDepId = useSelector( (state: any) => state.loginUser.value.currentDepId ); + const items = [ + { + key: "0", + label: `全部`, + }, + { + key: "1", + label: `必修课`, + }, + { + key: "2", + label: `选修课`, + }, + { + key: "3", + label: `已学完`, + }, + { + key: "4", + label: `未学完`, + }, + ]; + useEffect(() => { document.title = systemConfig.systemName || "首页"; }, [systemConfig]); + useEffect(() => { + getParams(); + }, []); + + useEffect(() => { + if (currentDepId === 0) { + return; + } + getData(); + }, [tabKey, currentDepId, categoryId]); + + const getData = () => { + setLoading(true); + user.courses(currentDepId, categoryId).then((res: any) => { + const records = res.data.learn_course_records; + setLearnCourseRecords(records); + setLearnCourseHourCount(res.data.user_course_hour_count); + if (Number(tabKey) === 0) { + setCoursesList(res.data.courses); + } else if (Number(tabKey) === 1) { + const arr: any = []; + res.data.courses.map((item: any) => { + if (item.is_required === 1) { + arr.push(item); + } + }); + setCoursesList(arr); + } else if (Number(tabKey) === 2) { + const arr: any = []; + res.data.courses.map((item: any) => { + if (item.is_required === 0) { + arr.push(item); + } + }); + setCoursesList(arr); + } else if (Number(tabKey) === 3) { + const arr: any = []; + res.data.courses.map((item: any) => { + if (records[item.id] && records[item.id].progress >= 10000) { + arr.push(item); + } + }); + setCoursesList(arr); + } else if (Number(tabKey) === 4) { + const arr: any = []; + res.data.courses.map((item: any) => { + if ( + !records[item.id] || + (records[item.id] && records[item.id].progress < 10000) + ) { + arr.push(item); + } + }); + setCoursesList(arr); + } + setLoading(false); + }); + }; + + const getParams = () => { + user.coursesCategories().then((res: any) => { + const categories = res.data.categories; + if (JSON.stringify(categories) !== "{}") { + const new_arr: any[] = checkArr(categories, 0); + new_arr.unshift({ + key: 0, + title: "所有分类", + }); + setCategories(new_arr); + } + }); + }; + + const checkArr = (categories: any[], id: number) => { + const arr = []; + for (let i = 0; i < categories[id].length; i++) { + if (!categories[categories[id][i].id]) { + arr.push({ + title: categories[id][i].name, + key: categories[id][i].id, + }); + } else { + const new_arr: any[] = checkArr(categories, categories[id][i].id); + arr.push({ + title: categories[id][i].name, + key: categories[id][i].id, + children: new_arr, + }); + } + } + return arr; + }; + + const renderChildCategory = (data: any) => { + return ( + <> + {data.map((item: any) => ( +
+
{ + setCategoryId(item.key); + setCategoryText(item.title); + ref.current?.close(); + }} + > + {item.title} +
+ {item.children && + item.children.length > 0 && + renderChildCategory(item.children)} +
+ ))} + + ); + }; + return (
-
- 我是首页 -
+
+ { + setTabKey(key); + }} + style={{ + "--fixed-active-line-width": "20px", + "--active-line-height": "3px", + "--active-title-color": "rgba(0,0,0,0.88)", + "--title-font-size": "16px", + }} + > + {items.map((item) => ( + + ))} + +
+
+ + +
+ {categories.map((item: any) => ( +
+
{ + setCategoryId(item.key); + setCategoryText(item.title); + ref.current?.close(); + }} + > + {item.title} +
+ {item.children && + item.children.length > 0 && + renderChildCategory(item.children)} +
+ ))} +
+
+
+
+
+ {loading && ( +
+ +
+ )} + {!loading && coursesList.length === 0 && } + {!loading && coursesList.length > 0 && ( + <> + {coursesList.map((item: any) => ( +
+ {learnCourseRecords[item.id] && ( + + )} + {!learnCourseRecords[item.id] && + learnCourseHourCount[item.id] && + learnCourseHourCount[item.id] > 0 && ( + + )} + {!learnCourseRecords[item.id] && + !learnCourseHourCount[item.id] && ( + + )} +
+ ))} +
+ + )}
diff --git a/src/pages/study/index.module.scss b/src/pages/study/index.module.scss index b42ad87..ab37fe3 100644 --- a/src/pages/study/index.module.scss +++ b/src/pages/study/index.module.scss @@ -30,7 +30,7 @@ height: 75px; display: flex; align-items: center; - margin-bottom: 20px; + margin-bottom: 30px; .item-info { flex: 1; height: 75px; diff --git a/src/pages/study/index.tsx b/src/pages/study/index.tsx index cf1e831..e456709 100644 --- a/src/pages/study/index.tsx +++ b/src/pages/study/index.tsx @@ -1,12 +1,5 @@ import { useState, useEffect } from "react"; -import { - Button, - Toast, - Input, - Image, - ProgressBar, - SpinLoading, -} from "antd-mobile"; +import { Image, ProgressBar, SpinLoading } from "antd-mobile"; import styles from "./index.module.scss"; import { useNavigate } from "react-router-dom"; import { course } from "../../api/index";