origin/apps/web/src/app/main/courses/page.tsx

181 lines
4.8 KiB
TypeScript
Raw Normal View History

2025-02-24 20:53:42 +08:00
import { useState, useMemo, useEffect } from "react";
2025-02-20 20:02:27 +08:00
import { mockCourses } from "./mockData";
import FilterSection from "./components/FilterSection";
import CourseList from "./components/CourseList";
import { api } from "@nice/client";
2025-02-25 12:31:37 +08:00
import {
courseDetailSelect,
CourseDto,
LectureType,
PostType,
} from "@nice/common";
2025-02-24 20:53:42 +08:00
import { useSearchParams } from "react-router-dom";
import { set } from "idb-keyval";
2025-02-06 16:32:31 +08:00
2025-02-25 12:56:53 +08:00
interface paginationData {
items:CourseDto[],
totalPages:number
}
2025-02-06 16:32:31 +08:00
export default function CoursesPage() {
2025-02-20 20:02:27 +08:00
const [currentPage, setCurrentPage] = useState(1);
const [selectedCategory, setSelectedCategory] = useState("");
const [selectedLevel, setSelectedLevel] = useState("");
2025-02-25 12:56:53 +08:00
const pageSize = 12;
const [isAll,setIsAll] = useState(true)
2025-02-24 20:53:42 +08:00
const [searchParams, setSearchParams] = useSearchParams();
2025-02-25 12:56:53 +08:00
const [coursesData, setCoursesData] = useState<CourseDto[]>([]);
const [isCourseLoading, setIsCourseLoading] = useState(false);
const [totalPagesNum, setTotalPagesNum] = useState(0);
if(!searchParams.get('searchValue') && !searchParams.get('searchValue')){
const {data,isLoading} :{ data:paginationData,isLoading:boolean} = api.post.findManyWithPagination.useQuery({
2025-02-24 20:53:42 +08:00
where: {
type: PostType.COURSE,
2025-02-25 12:31:37 +08:00
terms: isAll
? {}
: {
some: {
OR: [
selectedCategory
? { name: selectedCategory }
: {},
selectedLevel
? { name: selectedLevel }
: {},
],
},
},
2025-02-20 20:02:27 +08:00
},
2025-02-25 12:56:53 +08:00
pageSize,
page:currentPage,
select:courseDetailSelect,
2025-02-20 20:02:27 +08:00
});
2025-02-25 12:56:53 +08:00
console.log(data)
useEffect(()=>{
console.log(currentPage);
setIsCourseLoading(isLoading)
setCoursesData(data?.items)
setTotalPagesNum(data?.totalPages)
},[currentPage,data])
2025-02-24 20:53:42 +08:00
}else{
console.log('searchValue:'+searchParams.get('searchValue'))
const searchValue = searchParams.get('searchValue')
2025-02-25 12:56:53 +08:00
const {data,isLoading} :{ data:paginationData,isLoading:boolean}= api.post.findManyWithPagination.useQuery({
2025-02-24 20:53:42 +08:00
where: {
type: PostType.COURSE,
2025-02-25 12:31:37 +08:00
OR: [
{ title: { contains: searchValue, mode: "insensitive" } },
{
subTitle: {
contains: searchValue,
mode: "insensitive",
},
},
{ content: { contains: searchValue, mode: "insensitive" } },
{
terms: {
some: {
name: {
contains: searchValue,
mode: "insensitive",
},
},
},
},
],
2025-02-24 20:53:42 +08:00
},
2025-02-25 12:56:53 +08:00
select:courseDetailSelect,
pageSize,
page:currentPage,
2025-02-24 20:53:42 +08:00
})
2025-02-25 12:56:53 +08:00
useEffect(()=>{
setIsCourseLoading(isLoading)
setCoursesData(data?.items)
setTotalPagesNum(data?.totalPages)
},[currentPage])
2025-02-24 20:53:42 +08:00
}
useEffect(() => {
2025-02-25 12:31:37 +08:00
if (searchParams.get("searchValue") == "") {
setSelectedCategory("");
setSelectedLevel("");
2025-02-24 21:43:05 +08:00
}
2025-02-25 12:31:37 +08:00
}, [searchParams.get("searchValue")]);
2025-02-24 20:53:42 +08:00
const filteredCourses = useMemo(() => {
return isCourseLoading ? [] : coursesData;
}, [isCourseLoading, coursesData, selectedCategory, selectedLevel]);
2025-02-20 20:13:11 +08:00
2025-02-25 12:31:37 +08:00
const paginatedCourses: CourseDto[] = useMemo(() => {
2025-02-20 20:02:27 +08:00
const startIndex = (currentPage - 1) * pageSize;
2025-02-25 12:31:37 +08:00
return isCourseLoading
? []
: (filteredCourses.slice(
startIndex,
startIndex + pageSize
) as any as CourseDto[]);
2025-02-20 20:02:27 +08:00
}, [filteredCourses, currentPage]);
2025-02-20 20:13:11 +08:00
2025-02-20 20:02:27 +08:00
const handlePageChange = (page: number) => {
setCurrentPage(page);
window.scrollTo({ top: 0, behavior: "smooth" });
};
2025-02-25 12:31:37 +08:00
useEffect(() => {
setCurrentPage(1);
}, []);
2025-02-24 20:53:42 +08:00
2025-02-20 20:02:27 +08:00
return (
<div className="min-h-screen bg-gray-50">
<div className="container mx-auto px-4 py-8">
<div className="flex gap-4">
{/* 左侧筛选区域 */}
<div className="lg:w-1/5">
<div className="sticky top-24">
<FilterSection
selectedCategory={selectedCategory}
selectedLevel={selectedLevel}
onCategoryChange={(category) => {
2025-02-24 11:50:56 +08:00
console.log(category);
2025-02-20 20:02:27 +08:00
setSelectedCategory(category);
setCurrentPage(1);
2025-02-24 20:53:42 +08:00
setIsAll(!category)
2025-02-25 12:56:53 +08:00
setSearchParams(prev => {
prev.delete('searchValue');
return prev;
});
2025-02-20 20:02:27 +08:00
}}
onLevelChange={(level) => {
setSelectedLevel(level);
setCurrentPage(1);
2025-02-24 20:53:42 +08:00
setIsAll(!level)
2025-02-25 12:56:53 +08:00
setSearchParams(prev => {
prev.delete('searchValue');
return prev;
});
2025-02-20 20:02:27 +08:00
}}
/>
</div>
</div>
2025-02-06 16:32:31 +08:00
2025-02-20 20:02:27 +08:00
{/* 右侧课程列表区域 */}
<div className="lg:w-4/5">
<div className="bg-white p-6 rounded-lg shadow-sm">
<div className="flex justify-between items-center mb-6">
<span className="text-gray-600">
2025-02-25 12:56:53 +08:00
{totalPagesNum * pageSize || 0}
2025-02-20 20:02:27 +08:00
</span>
</div>
<CourseList
courses={paginatedCourses}
2025-02-25 12:56:53 +08:00
total={totalPagesNum * pageSize}
2025-02-20 20:02:27 +08:00
pageSize={pageSize}
currentPage={currentPage}
onPageChange={handlePageChange}
/>
</div>
</div>
</div>
</div>
</div>
);
}