首页、最近学习页面重构代码

This commit is contained in:
禺狨 2023-07-04 15:30:46 +08:00
parent 74b806b13d
commit cd93d27e06
5 changed files with 235 additions and 267 deletions

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { Image, ProgressBar } from "antd-mobile"; import { Image, ProgressBar } from "antd-mobile";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import styles from "./courses-model.module.scss"; import styles from "./courses-model.module.scss";
@ -9,7 +9,8 @@ interface PropInterface {
title: string; title: string;
thumb: string; thumb: string;
isRequired: number; isRequired: number;
progress: number; record: any;
hourCount: number;
} }
export const CoursesModel: React.FC<PropInterface> = ({ export const CoursesModel: React.FC<PropInterface> = ({
@ -17,9 +18,22 @@ export const CoursesModel: React.FC<PropInterface> = ({
title, title,
thumb, thumb,
isRequired, isRequired,
progress, record,
hourCount,
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const [userCourseProgress, setUserCourseProgress] = useState(0);
useEffect(() => {
if (record?.progress) {
setUserCourseProgress(Math.floor(record.progress / 100));
} else if (hourCount && hourCount > 0) {
setUserCourseProgress(1);
} else {
setUserCourseProgress(0);
}
}, [record, hourCount]);
return ( return (
<> <>
<div <div
@ -41,7 +55,7 @@ export const CoursesModel: React.FC<PropInterface> = ({
{isRequired === 0 && ( {isRequired === 0 && (
<div className={styles["active-type"]}></div> <div className={styles["active-type"]}></div>
)} )}
{progress == 0 && ( {userCourseProgress == 0 && (
<> <>
<ProgressBar <ProgressBar
percent={0} percent={0}
@ -56,9 +70,9 @@ export const CoursesModel: React.FC<PropInterface> = ({
<span className={styles["no-pro"]}></span> <span className={styles["no-pro"]}></span>
</> </>
)} )}
{progress > 0 && progress < 100 && ( {userCourseProgress > 0 && userCourseProgress < 100 && (
<ProgressBar <ProgressBar
percent={progress} percent={userCourseProgress}
text text
style={{ style={{
flex: 1, flex: 1,
@ -69,7 +83,7 @@ export const CoursesModel: React.FC<PropInterface> = ({
}} }}
/> />
)} )}
{progress >= 100 && ( {userCourseProgress >= 100 && (
<div className={styles["success"]}> <div className={styles["success"]}>
<Image <Image
width={20} width={20}

View File

@ -8,6 +8,10 @@ import { useNavigate, useLocation } from "react-router-dom";
import { Footer, TabBarFooter, Empty } from "../../components"; import { Footer, TabBarFooter, Empty } from "../../components";
import { CoursesModel } from "./compenents/courses-model"; import { CoursesModel } from "./compenents/courses-model";
type LocalUserLearnHourRecordModel = {
[key: number]: UserLearnHourRecordModel;
};
const IndexPage = () => { const IndexPage = () => {
const ref = useRef<DropdownRef>(null); const ref = useRef<DropdownRef>(null);
const navigate = useNavigate(); const navigate = useNavigate();
@ -22,7 +26,8 @@ const IndexPage = () => {
const [categoryText, setCategoryText] = useState<string>( const [categoryText, setCategoryText] = useState<string>(
String(result.get("catName") || "所有分类") String(result.get("catName") || "所有分类")
); );
const [learnCourseRecords, setLearnCourseRecords] = useState<any>({}); const [learnCourseRecords, setLearnCourseRecords] =
useState<LocalUserLearnHourRecordModel>({});
const [learnCourseHourCount, setLearnCourseHourCount] = useState<any>({}); const [learnCourseHourCount, setLearnCourseHourCount] = useState<any>({});
const systemConfig = useSelector((state: any) => state.systemConfig.value); const systemConfig = useSelector((state: any) => state.systemConfig.value);
const currentDepId = useSelector( const currentDepId = useSelector(
@ -293,38 +298,14 @@ const IndexPage = () => {
<> <>
{coursesList.map((item: any) => ( {coursesList.map((item: any) => (
<div className={styles["item"]} key={item.id}> <div className={styles["item"]} key={item.id}>
{learnCourseRecords[item.id] && (
<CoursesModel <CoursesModel
id={item.id} id={item.id}
title={item.title} title={item.title}
thumb={item.thumb} thumb={item.thumb}
isRequired={item.is_required} isRequired={item.is_required}
progress={Math.floor( record={learnCourseRecords[item.id]}
learnCourseRecords[item.id].progress / 100 hourCount={learnCourseHourCount[item.id]}
)}
></CoursesModel> ></CoursesModel>
)}
{!learnCourseRecords[item.id] &&
learnCourseHourCount[item.id] &&
learnCourseHourCount[item.id] > 0 && (
<CoursesModel
id={item.id}
title={item.title}
thumb={item.thumb}
isRequired={item.is_required}
progress={1}
></CoursesModel>
)}
{!learnCourseRecords[item.id] &&
!learnCourseHourCount[item.id] && (
<CoursesModel
id={item.id}
title={item.title}
thumb={item.thumb}
isRequired={item.is_required}
progress={0}
></CoursesModel>
)}
</div> </div>
))} ))}
<Footer></Footer> <Footer></Footer>

View File

@ -0,0 +1,74 @@
.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;
}
.success {
display: flex;
align-items: center;
font-size: 12px;
font-weight: 400;
color: #ff4d4f;
}
}
}
}

View File

@ -0,0 +1,97 @@
import React, { useEffect, useState } 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;
record: any;
}
export const CoursesModel: React.FC<PropInterface> = ({
id,
title,
thumb,
isRequired,
record,
}) => {
const navigate = useNavigate();
const [userCourseProgress, setUserCourseProgress] = useState(0);
useEffect(() => {
if (record?.progress) {
setUserCourseProgress(Math.floor(record.progress / 100));
} else {
setUserCourseProgress(1);
}
}, [record]);
return (
<>
<div
className={styles["item"]}
onClick={() => {
navigate(`/course/${id}`);
}}
>
<Image
width={100}
height={75}
style={{ borderRadius: 8, marginRight: 15 }}
src={thumb}
/>
<div className={styles["info"]}>
<div className={styles["title"]}>{title}</div>
<div className={styles["status-content"]}>
{isRequired === 1 && <div className={styles["type"]}></div>}
{isRequired === 0 && (
<div className={styles["active-type"]}></div>
)}
{userCourseProgress == 1 && (
<ProgressBar
percent={1}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
{userCourseProgress > 1 && userCourseProgress < 100 && (
<ProgressBar
percent={userCourseProgress}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
{userCourseProgress >= 100 && (
<div className={styles["success"]}>
<Image
width={20}
height={20}
src={mediaIcon}
style={{ marginRight: 5 }}
/>
<span>!</span>
</div>
)}
</div>
</div>
</div>
<div className="sp-line"></div>
</>
);
};

View File

@ -1,18 +1,16 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { Image, ProgressBar, Skeleton } from "antd-mobile"; import { Skeleton } from "antd-mobile";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
import { useNavigate } from "react-router-dom";
import { course } from "../../api/index"; import { course } from "../../api/index";
import { TabBarFooter, Empty } from "../../components"; import { TabBarFooter, Empty } from "../../components";
import mediaIcon from "../../assets/images/commen/icon-medal.png"; import { CoursesModel } from "./compenents/courses-model";
import moment from "moment"; import moment from "moment";
const StudyPage = () => { const StudyPage = () => {
const navigate = useNavigate();
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [todayCourses, setTodayCourses] = useState<any>([]); const [todayCourses, setTodayCourses] = useState<CourseModel[]>([]);
const [yesterdayCourses, setYesterdayCourses] = useState<any>([]); const [yesterdayCourses, setYesterdayCourses] = useState<CourseModel[]>([]);
const [courses, setCourses] = useState<any>([]); const [courses, setCourses] = useState<CourseModel[]>([]);
useEffect(() => { useEffect(() => {
document.title = "最近学习"; document.title = "最近学习";
@ -26,9 +24,9 @@ const StudyPage = () => {
setLoading(true); setLoading(true);
course.latestLearn().then((res: any) => { course.latestLearn().then((res: any) => {
let data = res.data; let data = res.data;
let today: any = []; let today: CourseModel[] = [];
let yesterday: any = []; let yesterday: CourseModel[] = [];
let box: any = []; let box: CourseModel[] = [];
if (data && data.length > 0) { if (data && data.length > 0) {
data.map((item: any) => { data.map((item: any) => {
if ( if (
@ -79,7 +77,6 @@ const StudyPage = () => {
</div> </div>
))} ))}
{!loading && courses.length === 0 && <Empty></Empty>} {!loading && courses.length === 0 && <Empty></Empty>}
{/* <div className={styles["label"]}>更早</div> */}
{!loading && ( {!loading && (
<> <>
{todayCourses.length > 0 && ( {todayCourses.length > 0 && (
@ -88,78 +85,13 @@ const StudyPage = () => {
{todayCourses.map((item: any, index: number) => ( {todayCourses.map((item: any, index: number) => (
<div key={index} style={{ width: "100%" }}> <div key={index} style={{ width: "100%" }}>
{item.course && ( {item.course && (
<div <CoursesModel
className={styles["item"]} id={item.course.id}
onClick={() => { title={item.course.title}
navigate(`/course/${item.course.id}`); thumb={item.course.thumb}
}} isRequired={item.course.is_required}
> record={item.record}
<Image ></CoursesModel>
src={item.course.thumb}
width={100}
height={75}
style={{ borderRadius: 8, marginRight: 15 }}
/>
<div className={styles["item-info"]}>
<div className={styles["item-title"]}>
{item.course.title}
</div>
<div className={styles["item-record"]}>
{item.course.is_required === 1 && (
<div className={styles["type"]}></div>
)}
{item.course.is_required === 0 && (
<div className={styles["active-type"]}>
</div>
)}
{item.record && (
<>
{item.record.progress < 10000 && (
<ProgressBar
percent={Math.floor(
item.record.progress / 100
)}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
{item.record.progress >= 10000 && (
<>
<Image
width={20}
height={20}
src={mediaIcon}
/>
<span className={styles["tip"]}>
!
</span>
</>
)}
</>
)}
{!item.record && (
<ProgressBar
percent={1}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
</div>
</div>
</div>
)} )}
</div> </div>
))} ))}
@ -171,78 +103,13 @@ const StudyPage = () => {
{yesterdayCourses.map((item: any, index: number) => ( {yesterdayCourses.map((item: any, index: number) => (
<div key={index} style={{ width: "100%" }}> <div key={index} style={{ width: "100%" }}>
{item.course && ( {item.course && (
<div <CoursesModel
className={styles["item"]} id={item.course.id}
onClick={() => { title={item.course.title}
navigate(`/course/${item.course.id}`); thumb={item.course.thumb}
}} isRequired={item.course.is_required}
> record={item.record}
<Image ></CoursesModel>
src={item.course.thumb}
width={100}
height={75}
style={{ borderRadius: 8, marginRight: 15 }}
/>
<div className={styles["item-info"]}>
<div className={styles["item-title"]}>
{item.course.title}
</div>
<div className={styles["item-record"]}>
{item.course.is_required === 1 && (
<div className={styles["type"]}></div>
)}
{item.course.is_required === 0 && (
<div className={styles["active-type"]}>
</div>
)}
{item.record && (
<>
{item.record.progress < 10000 && (
<ProgressBar
percent={Math.floor(
item.record.progress / 100
)}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
{item.record.progress >= 10000 && (
<>
<Image
width={20}
height={20}
src={mediaIcon}
/>
<span className={styles["tip"]}>
!
</span>
</>
)}
</>
)}
{!item.record && (
<ProgressBar
percent={1}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
</div>
</div>
</div>
)} )}
</div> </div>
))} ))}
@ -254,78 +121,13 @@ const StudyPage = () => {
{courses.map((item: any, index: number) => ( {courses.map((item: any, index: number) => (
<div key={index} style={{ width: "100%" }}> <div key={index} style={{ width: "100%" }}>
{item.course && ( {item.course && (
<div <CoursesModel
className={styles["item"]} id={item.course.id}
onClick={() => { title={item.course.title}
navigate(`/course/${item.course.id}`); thumb={item.course.thumb}
}} isRequired={item.course.is_required}
> record={item.record}
<Image ></CoursesModel>
src={item.course.thumb}
width={100}
height={75}
style={{ borderRadius: 8, marginRight: 15 }}
/>
<div className={styles["item-info"]}>
<div className={styles["item-title"]}>
{item.course.title}
</div>
<div className={styles["item-record"]}>
{item.course.is_required === 1 && (
<div className={styles["type"]}></div>
)}
{item.course.is_required === 0 && (
<div className={styles["active-type"]}>
</div>
)}
{item.record && (
<>
{item.record.progress < 10000 && (
<ProgressBar
percent={Math.floor(
item.record.progress / 100
)}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
{item.record.progress >= 10000 && (
<>
<Image
width={20}
height={20}
src={mediaIcon}
/>
<span className={styles["tip"]}>
!
</span>
</>
)}
</>
)}
{!item.record && (
<ProgressBar
percent={1}
text
style={{
flex: 1,
"--fill-color": "#FF4D4F",
"--track-color": "#F6F6F6",
"--track-width": "8px",
"--text-width": "27px",
}}
/>
)}
</div>
</div>
</div>
)} )}
</div> </div>
))} ))}