159 lines
4.2 KiB
TypeScript
Executable File
159 lines
4.2 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 = 9;
|
|
const [isAll, setIsAll] = useState(true);
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
let coursesData = [];
|
|
let isCourseLoading = false;
|
|
const searchValue = searchParams.get("searchValue");
|
|
|
|
if (!searchParams.get("searchValue")) {
|
|
console.log("no category");
|
|
const { data, isLoading } = api.post.findManyWithPagination.useQuery({
|
|
where: {
|
|
type: PostType.COURSE,
|
|
},
|
|
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,
|
|
terms: isAll
|
|
? {}
|
|
: {
|
|
some: {
|
|
OR: [
|
|
selectedCategory
|
|
? { name: selectedCategory }
|
|
: {},
|
|
selectedLevel
|
|
? { name: selectedLevel }
|
|
: {},
|
|
],
|
|
},
|
|
},
|
|
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(() => {
|
|
if (searchParams.get("searchValue") == "") {
|
|
setSelectedCategory("");
|
|
setSelectedLevel("");
|
|
}
|
|
}, [searchParams.get("searchValue")]);
|
|
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" });
|
|
};
|
|
useEffect(() => {
|
|
setCurrentPage(1);
|
|
}, []);
|
|
|
|
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>
|
|
);
|
|
}
|