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

73 lines
3.1 KiB
TypeScript
Raw Normal View History

2025-02-06 16:32:31 +08:00
import { useState, useMemo } from 'react';
import { mockCourses } from './mockData';
import FilterSection from './components/FilterSection';
import CourseList from './components/CourseList';
export default function CoursesPage() {
const [currentPage, setCurrentPage] = useState(1);
const [selectedCategory, setSelectedCategory] = useState('');
const [selectedLevel, setSelectedLevel] = useState('');
const pageSize = 12;
const filteredCourses = useMemo(() => {
return mockCourses.filter(course => {
const matchCategory = !selectedCategory || course.category === selectedCategory;
const matchLevel = !selectedLevel || course.level === selectedLevel;
return matchCategory && matchLevel;
});
}, [selectedCategory, selectedLevel]);
const paginatedCourses = useMemo(() => {
const startIndex = (currentPage - 1) * pageSize;
return filteredCourses.slice(startIndex, startIndex + pageSize);
}, [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 => {
setSelectedCategory(category);
setCurrentPage(1);
}}
onLevelChange={level => {
setSelectedLevel(level);
setCurrentPage(1);
}}
/>
</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>
);
}