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

125 lines
3.8 KiB
TypeScript
Executable File

import { useState, useMemo, useEffect } from "react";
import { mockCourses } from "./mockData";
import FilterSection from "./components/FilterSection";
import CourseList from "./components/CourseList";
import { api } from "@nice/client";
import { courseDetailSelect, CourseDto, LectureType, PostType } from "@nice/common";
import { useSearchParams } from "react-router-dom";
import { set } from "idb-keyval";
export default function CoursesPage() {
const [currentPage, setCurrentPage] = useState(1);
const [selectedCategory, setSelectedCategory] = useState("");
const [selectedLevel, setSelectedLevel] = useState("");
const pageSize = 12;
const [isAll,setIsAll] = useState(true)
const [searchParams, setSearchParams] = useSearchParams();
let coursesData = []
let isCourseLoading = false
if(!searchParams.get('searchValue')){
console.log('no category')
const {data,isLoading} = api.post.findManyWithPagination.useQuery({
where: {
type: PostType.COURSE,
terms:isAll?{}:{
some: {
OR : [
selectedCategory?{name:selectedCategory}:{},
selectedLevel?{name:selectedLevel}:{}
],
},
},
},
select:courseDetailSelect
});
coursesData = data?.items
isCourseLoading = isLoading
}else{
console.log('searchValue:'+searchParams.get('searchValue'))
const searchValue = searchParams.get('searchValue')
const {data,isLoading} = api.post.findManyWithPagination.useQuery({
where: {
type: PostType.COURSE,
OR:[
{ title: { contains: searchValue, mode: 'insensitive' } },
{ subTitle: { contains: searchValue, mode: 'insensitive' } },
{ content: { contains: searchValue, mode: 'insensitive' } },
{ terms: { some: { name: { contains: searchValue, mode: 'insensitive' } } } }
]
},
select:courseDetailSelect
})
coursesData = data?.items
isCourseLoading = isLoading
}
useEffect(() => {
console.log(coursesData)
}, [coursesData]);
const filteredCourses = useMemo(() => {
return isCourseLoading ? [] : coursesData;
}, [isCourseLoading, coursesData, selectedCategory, selectedLevel]);
const paginatedCourses :CourseDto[]= useMemo(() => {
const startIndex = (currentPage - 1) * pageSize;
return isCourseLoading ? [] : (filteredCourses.slice(startIndex, startIndex + pageSize) as any as CourseDto[]);
}, [filteredCourses, currentPage]);
const handlePageChange = (page: number) => {
setCurrentPage(page);
window.scrollTo({ top: 0, behavior: "smooth" });
};
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) => {
console.log(category);
setSelectedCategory(category);
setCurrentPage(1);
setIsAll(!category)
setSearchParams({ searchValue: ''});
}}
onLevelChange={(level) => {
setSelectedLevel(level);
setCurrentPage(1);
setIsAll(!level)
setSearchParams({ searchValue: ''});
}}
/>
</div>
</div>
{/* 右侧课程列表区域 */}
<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">
{filteredCourses.length}
</span>
</div>
<CourseList
courses={paginatedCourses}
total={filteredCourses.length}
pageSize={pageSize}
currentPage={currentPage}
onPageChange={handlePageChange}
/>
</div>
</div>
</div>
</div>
</div>
);
}