This commit is contained in:
Rao 2025-02-24 22:00:31 +08:00
commit 890449ffff
4 changed files with 184 additions and 126 deletions

View File

@ -56,11 +56,11 @@ interface Course {
progress: number; progress: number;
thumbnail: string; thumbnail: string;
} }
interface CoursesSectionProps { interface CoursesSectionProps {
title: string; title: string;
description: string; description: string;
courses: Course[]; courses: Course[];
isLoading:boolean
initialVisibleCoursesCount?: number; initialVisibleCoursesCount?: number;
} }
@ -68,6 +68,7 @@ const CoursesSection: React.FC<CoursesSectionProps> = ({
title, title,
description, description,
courses, courses,
isLoading,
initialVisibleCoursesCount = 8, initialVisibleCoursesCount = 8,
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -76,15 +77,31 @@ const CoursesSection: React.FC<CoursesSectionProps> = ({
const gateGory: GetTaxonomyProps = useGetTaxonomy({ const gateGory: GetTaxonomyProps = useGetTaxonomy({
type: TaxonomySlug.CATEGORY, type: TaxonomySlug.CATEGORY,
}) })
const { data } = api.post.findMany.useQuery({ // const { data } = api.post.findMany.useQuery({
take: 8, // where: {}, // 必选参数
} // include: { // 关联查询
) // instructors: true
useEffect(() => { // },
console.log(data,'成功') // orderBy: { // 排序规则
}, [data]) // createdAt: 'desc'
// },
// take: 8
// })
// useEffect(() => {
// // 添加空值保护
// if (data && data.length > 0) {
// console.log('有效数据:', data)
// // 执行后续操作
// } else {
// console.log('无数据或加载中')
// }
// }, [data])
// const formatted = data?.map(course => ({
// id: course.id,
// title: course.title
// }));
const handleClick = (course: Course) => { const handleClick = (course: Course) => {
navigate(`/courses?courseId=${course.id}/detail`); navigate(`/course?courseId=${course.id}/detail`);
} }
const filteredCourses = useMemo(() => { const filteredCourses = useMemo(() => {
@ -93,7 +110,7 @@ const CoursesSection: React.FC<CoursesSectionProps> = ({
: courses.filter((course) => course.category === selectedCategory); : courses.filter((course) => course.category === selectedCategory);
}, [selectedCategory, courses]); }, [selectedCategory, courses]);
const displayedCourses = filteredCourses.slice(0, visibleCourses); const displayedCourses = isLoading ? [] : filteredCourses.slice(0, visibleCourses);
return ( return (
<section className="relative py-20 overflow-hidden bg-gradient-to-b from-gray-50 to-white"> <section className="relative py-20 overflow-hidden bg-gradient-to-b from-gray-50 to-white">
<div className="max-w-screen-2xl mx-auto px-6 relative"> <div className="max-w-screen-2xl mx-auto px-6 relative">
@ -235,7 +252,7 @@ const CoursesSection: React.FC<CoursesSectionProps> = ({
))} ))}
</div> </div>
{filteredCourses.length >= visibleCourses && ( {filteredCourses?.length >= visibleCourses && (
<div className='flex items-center gap-4 justify-between mt-12'> <div className='flex items-center gap-4 justify-between mt-12'>
<div className='h-[1px] flex-grow bg-gradient-to-r from-transparent via-gray-300 to-transparent'></div> <div className='h-[1px] flex-grow bg-gradient-to-r from-transparent via-gray-300 to-transparent'></div>
<div className="flex justify-end"> <div className="flex justify-end">

View File

@ -3,123 +3,161 @@ import CategorySection from './components/CategorySection';
import CoursesSection from './components/CoursesSection'; import CoursesSection from './components/CoursesSection';
import FeaturedTeachersSection from './components/FeaturedTeachersSection'; import FeaturedTeachersSection from './components/FeaturedTeachersSection';
import { api } from '@nice/client'; import { api } from '@nice/client';
import { useEffect } from 'react'; import { useEffect, useState } from 'react';
interface Courses{
id: number;
title: string;
instructor: string;
students: number;
rating: number;
level: string;
duration: string;
category: string;
progress: number;
thumbnail: string;
}
const HomePage = () => { const HomePage = () => {
const mockCourses = [ // const mockCourses = [
{ // {
id: 1, // id: 1,
title: 'Python 零基础入门', // title: 'Python 零基础入门',
instructor: '张教授', // instructor: '张教授',
students: 12000, // students: 12000,
rating: 4.8, // rating: 4.8,
level: '入门', // level: '入门',
duration: '36小时', // duration: '36小时',
category: '编程语言', // category: '编程语言',
progress: 16, // progress: 16,
thumbnail: '/images/course1.jpg', // 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: {
id: 2, createdAt: 'desc' // 按创建时间降序排列
title: '数据结构与算法',
instructor: '李教授',
students: 8500,
rating: 4.9,
level: '进阶',
duration: '48小时',
category: '计算机基础',
progress: 35,
thumbnail: '/images/course2.jpg',
}, },
{ take: 8 // 只获取前8个课程
id: 3, });
title: '前端开发实战', useEffect(() => {
instructor: '王教授', if (data) {
students: 10000, console.log('mockCourses data:', data);
rating: 4.7, }
level: '中级', }, [data]);
duration: '42小时',
category: '前端开发', // 数据处理逻辑
progress: 68, // 修正依赖数组
thumbnail: '/images/course3.jpg', return (
}, <div className="min-h-screen">
{ <HeroSection />
id: 4, <CoursesSection
title: 'Java企业级开发', title="推荐课程"
instructor: '刘教授', description="最受欢迎的精品课程,助你快速成长"
students: 9500, courses={data}
rating: 4.6, isLoading={isLoading}
level: '高级', />
duration: '56小时', {/* {formattedCourses.map((course)=>{
category: '编程语言', return (
progress: 15, <>
thumbnail: '/images/course4.jpg', <span>course.title</span>
}, </>
{ )
id: 5, })} */}
title: '人工智能基础', {/* <CoursesSection
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',
},
];
return (
<div className="min-h-screen">
<HeroSection />
<CoursesSection
title="推荐课程"
description="最受欢迎的精品课程,助你快速成长"
courses={mockCourses}
/>
{/* <CoursesSection
title="热门课程" title="热门课程"
description="最受欢迎的精品课程,助你快速成长" description="最受欢迎的精品课程,助你快速成长"
courses={mockCourses} courses={mockCourses}
/> */} /> */}
<CategorySection /> <CategorySection />
{/* <FeaturedTeachersSection /> */} {/* <FeaturedTeachersSection /> */}
</div> </div>
); );
}; };
export default HomePage; export default HomePage;

View File

@ -3,15 +3,15 @@ import { AppConfigSlug, BaseSetting } from "@nice/common";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
export function useAppConfig() { export function useAppConfig() {
const utils = api.useUtils() const utils = api.useUtils();
const [baseSetting, setBaseSetting] = useState<BaseSetting | undefined>(); const [baseSetting, setBaseSetting] = useState<BaseSetting | undefined>();
const { data, isLoading }: { data: any; isLoading: boolean } = const { data, isLoading }: { data: any; isLoading: boolean } =
api.app_config.findFirst.useQuery({ api.app_config.findFirst.useQuery({
where: { slug: AppConfigSlug.BASE_SETTING } where: { slug: AppConfigSlug.BASE_SETTING },
}); });
const handleMutationSuccess = useCallback(() => { const handleMutationSuccess = useCallback(() => {
utils.app_config.invalidate() utils.app_config.invalidate();
}, [utils]); }, [utils]);
// Use the generic success handler in mutations // Use the generic success handler in mutations
@ -28,7 +28,6 @@ export function useAppConfig() {
if (data?.meta) { if (data?.meta) {
setBaseSetting(JSON.parse(data?.meta)); setBaseSetting(JSON.parse(data?.meta));
} }
}, [data, isLoading]); }, [data, isLoading]);
const splashScreen = useMemo(() => { const splashScreen = useMemo(() => {
return baseSetting?.appConfig?.splashScreen; return baseSetting?.appConfig?.splashScreen;
@ -36,8 +35,10 @@ export function useAppConfig() {
const devDept = useMemo(() => { const devDept = useMemo(() => {
return baseSetting?.appConfig?.devDept; return baseSetting?.appConfig?.devDept;
}, [baseSetting]); }, [baseSetting]);
const slides = useMemo(() => {
return baseSetting?.appConfig?.slides || [];
}, [baseSetting]);
return { return {
create, create,
deleteMany, deleteMany,
update, update,
@ -45,5 +46,6 @@ export function useAppConfig() {
splashScreen, splashScreen,
devDept, devDept,
isLoading, isLoading,
slides,
}; };
} }

View File

@ -43,6 +43,7 @@ export interface BaseSetting {
appConfig?: { appConfig?: {
splashScreen?: string; splashScreen?: string;
devDept?: string; devDept?: string;
slides?: [];
}; };
} }
export type RowModelResult = { export type RowModelResult = {