diff --git a/apps/web/src/app/main/courses/components/CourseCard.tsx b/apps/web/src/app/main/courses/components/CourseCard.tsx index bd9af23..9a9f37d 100755 --- a/apps/web/src/app/main/courses/components/CourseCard.tsx +++ b/apps/web/src/app/main/courses/components/CourseCard.tsx @@ -6,7 +6,7 @@ import { PlayCircleOutlined, TeamOutlined, } from "@ant-design/icons"; -import { CourseDto } from "@nice/common"; +import { CourseDto, TaxonomySlug } from "@nice/common"; import { useNavigate } from "react-router-dom"; interface CourseCardProps { @@ -44,6 +44,7 @@ export default function CourseCard({ course }: CourseCardProps) { className="px-3 py-1 rounded-full bg-blue-100 text-blue-600 border-0"> {course.terms?.[0].name} + { - const allCategories = isLoading ? [] : data?.map((course) => course.name); - return [...Array.from(new Set(allCategories))]; - }, [data]); - return { categories, isLoading } + const { data, isLoading }: { data: TermDto[]; isLoading: boolean } = + api.term.findMany.useQuery({ + where: { + taxonomy: { + slug: type, + }, + }, + include: { + children: true, + }, + take: 10, // 只取前10个 + orderBy: {}, + }); + const categories = useMemo(() => { + const allCategories = isLoading + ? [] + : data?.map((course) => course.name); + return [...Array.from(new Set(allCategories))]; + }, [data]); + return { categories, isLoading }; } - // 不同分类跳转 function useFetchCoursesByCategory(category: string) { - const isAll = category === '全部'; - const { data, isLoading }: { data: CourseDto[], isLoading: boolean } = api.post.findMany.useQuery({ - where: isAll ? {} : { - terms: { - some: { - name: category - }, - }, - }, - take: 8, - include: { - terms: true, - depts:true - } - }); + const isAll = category === "全部"; + const { data, isLoading }: { data: CourseDto[]; isLoading: boolean } = + api.post.findMany.useQuery({ + where: isAll + ? {} + : { + terms: { + some: { + name: category, + }, + }, + }, + take: 8, + include: { + terms: true, + depts: true, + }, + }); - return { data, isLoading }; + return { data, isLoading }; } - - - const { Title, Text } = Typography; - -interface Course { - id: number; - title: string; - instructor: string; - students: number; - rating: number; - level: string; - duration: string; - category: string; - progress: number; - thumbnail: string; -} interface CoursesSectionProps { - title: string; - description: string; - courses: Course[]; - isLoading: boolean - initialVisibleCoursesCount?: number; + title: string; + description: string; + initialVisibleCoursesCount?: number; } - const CoursesSection: React.FC = ({ - title, - description, - initialVisibleCoursesCount = 8, + title, + description, }) => { - const navigate = useNavigate(); - const [selectedCategory, setSelectedCategory] = useState('全部'); - const [visibleCourses, setVisibleCourses] = useState(initialVisibleCoursesCount); - const gateGory: GetTaxonomyProps = useGetTaxonomy({ - type: TaxonomySlug.CATEGORY, - }) + const navigate = useNavigate(); + const [selectedCategory, setSelectedCategory] = useState("全部"); + const gateGory: GetTaxonomyProps = useGetTaxonomy({ + type: TaxonomySlug.CATEGORY, + }); + const { data, isLoading: isDataLoading } = + useFetchCoursesByCategory(selectedCategory); + const filteredCourses = useMemo(() => { + return selectedCategory === "全部" + ? data + : data?.filter((c) => + c.terms.some((t) => t.name === selectedCategory) + ); + }, [selectedCategory, data]); + const displayedCourses = isDataLoading ? [] : filteredCourses; + return ( +
+
+
+
+ + {title} + + + {description} + +
+
- const { data, isLoading: isDataLoading } = useFetchCoursesByCategory(selectedCategory); - // useEffect(() => { - // console.log('data:', data) - // }) - const handleClick = (course: CourseDto) => { - navigate(`/course/${course.id}/detail`); - } +
+ {gateGory.isLoading ? ( + + ) : ( + <> + setSelectedCategory("全部")} + className={`px-6 py-2 text-base cursor-pointer rounded-full transition-all duration-300 ${ + selectedCategory === "全部" + ? "bg-blue-600 text-white shadow-lg" + : "bg-white text-gray-600 hover:bg-gray-100" + }`}> + 全部 + + {gateGory.categories.map((category) => ( + { + setSelectedCategory(category); + }} + className={`px-6 py-2 text-base cursor-pointer rounded-full transition-all duration-300 ${ + selectedCategory === category + ? "bg-blue-600 text-white shadow-lg" + : "bg-white text-gray-600 hover:bg-gray-100" + }`}> + {category} + + ))} + + )} +
- useEffect(() => { - console.log('data:', data) - }) - - // const { data: depts, isLoading: isDeptLoading }: { data: CourseDto[], isLoading: boolean } = api.post.findMany.useQuery({ - // where: {}, - // include: { - // depts: true, - // }, - // orderBy: { - // createdAt: 'desc' // 按创建时间降序排列 - // }, - // take: 8 // 只获取前8个课程 - // }); - - - - const filteredCourses = useMemo(() => { - return selectedCategory === '全部' - ? data - : data?.filter(c => c.terms.some(t => t.name === selectedCategory)); - }, [selectedCategory, data]); - - const displayedCourses = isDataLoading ? [] : filteredCourses?.slice(0, visibleCourses); - - return ( -
-
-
-
- - {title} - - - {description} - -
-
- -
- {gateGory.isLoading ? : - ( - <> - setSelectedCategory("全部")} - className={`px-6 py-2 text-base cursor-pointer rounded-full transition-all duration-300 ${selectedCategory === "全部" - ? 'bg-blue-600 text-white shadow-lg' - : 'bg-white text-gray-600 hover:bg-gray-100' - }`} - >全部 - {gateGory.categories.map((category) => ( - { - setSelectedCategory(category) - console.log(category) - }} - className={`px-6 py-2 text-base cursor-pointer rounded-full transition-all duration-300 ${selectedCategory === category - ? 'bg-blue-600 text-white shadow-lg' - : 'bg-white text-gray-600 hover:bg-gray-100' - }`} - - > - {category} - - - )) - } - - - ) - } -
- -
- {displayedCourses.length === 0 ? ( -
- -
- ) : displayedCourses?.map((course) => ( - handleClick(course)} - key={course.id} - hoverable - className="group overflow-hidden rounded-2xl border border-gray-200 bg-white - shadow-xl hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-2" - cover={ -
-
-
- -
- } - > -
-
- - {course.terms[0].name} - - - {course.terms[1].name} - -
- - <button > {course.title}</button> - - -
- -
- - {course?.depts[0]?.name} - -
- - 观看次数{course?.meta?.views}次 - -
- - -
- -
- -
- - ))} -
- - {filteredCourses?.length >= visibleCourses && ( -
-
-
- -
-
- )} -
-
- ); +
+ {displayedCourses.length === 0 ? ( +
+ +
+ ) : ( + displayedCourses?.map((course) => ( + + )) + )} +
+ { +
+
+
+ +
+
+ } +
+
+ ); }; - export default CoursesSection; diff --git a/apps/web/src/app/main/home/page.tsx b/apps/web/src/app/main/home/page.tsx index 7250975..0cf5123 100755 --- a/apps/web/src/app/main/home/page.tsx +++ b/apps/web/src/app/main/home/page.tsx @@ -1,163 +1,18 @@ import HeroSection from "./components/HeroSection"; import CategorySection from "./components/CategorySection"; import CoursesSection from "./components/CoursesSection"; -import FeaturedTeachersSection from "./components/FeaturedTeachersSection"; -import { api } from "@nice/client"; -import { useEffect, useState } from "react"; -import TermTree from "@web/src/components/models/term/term-tree"; -interface Courses { - id: number; - title: string; - instructor: string; - students: number; - rating: number; - level: string; - duration: string; - category: string; - progress: number; - thumbnail: string; -} -const HomePage = () => { - // { - // id: 1, - // title: 'Python 零基础入门', - // instructor: '张教授', - // students: 12000, - // rating: 4.8, - // level: '入门', - // duration: '36小时', - // category: '编程语言', - // progress: 16, - // thumbnail: '/images/course1.jpg', - // }, - // { - // id: 2, - // title: '数据结构与算法', - // instructor: '李教授', - // students: 8500, - // rating: 4.9, - // level: '进阶', - // duration: '48小时', - // category: '计算机基础', - // progress: 35, - // thumbnail: '/images/course2.jpg', - // }, - // { - // id: 3, - // title: '前端开发实战', - // instructor: '王教授', - // students: 10000, - // rating: 4.7, - // level: '中级', - // duration: '42小时', - // category: '前端开发', - // progress: 68, - // thumbnail: '/images/course3.jpg', - // }, - // { - // id: 4, - // title: 'Java企业级开发', - // instructor: '刘教授', - // students: 9500, - // rating: 4.6, - // level: '高级', - // duration: '56小时', - // category: '编程语言', - // progress: 15, - // thumbnail: '/images/course4.jpg', - // }, - // { - // id: 5, - // title: '人工智能基础', - // instructor: '陈教授', - // students: 11000, - // rating: 4.9, - // level: '中级', - // duration: '45小时', - // category: '人工智能', - // progress: 20, - // thumbnail: '/images/course5.jpg', - // }, - // { - // id: 6, - // title: '大数据分析', - // instructor: '赵教授', - // students: 8000, - // rating: 4.8, - // level: '进阶', - // duration: '50小时', - // category: '数据科学', - // progress: 45, - // thumbnail: '/images/course6.jpg', - // }, - // { - // id: 7, - // title: '云计算实践', - // instructor: '孙教授', - // students: 7500, - // rating: 4.7, - // level: '高级', - // duration: '48小时', - // category: '云计算', - // progress: 15, - // thumbnail: '/images/course7.jpg', - // }, - // { - // id: 8, - // title: '移动应用开发', - // instructor: '周教授', - // students: 9000, - // rating: 4.8, - // level: '中级', - // duration: '40小时', - // category: '移动开发', - // progress: 70, - // thumbnail: '/images/course8.jpg', - // }, - // ]; - const { data, isLoading }: { data: Courses[]; isLoading: boolean } = - api.post.findMany.useQuery({ - where: {}, - include: { - instructors: true, - }, - orderBy: { - createdAt: "desc", // 按创建时间降序排列 - }, - take: 8, // 只获取前8个课程 - }); - useEffect(() => { - if (data) { - console.log("mockCourses data:", data); - } - }, [data]); - // 数据处理逻辑 - // 修正依赖数组 + +const HomePage = () => { + return (
- - {/* {formattedCourses.map((course)=>{ - return ( - <> - course.title - - ) - })} */} - {/* */} - {/* */}
); };