Merge branch 'main' of http://113.45.157.195:3003/insiinc/re-mooc
This commit is contained in:
commit
890449ffff
|
@ -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">
|
||||||
|
|
|
@ -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;
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ export interface BaseSetting {
|
||||||
appConfig?: {
|
appConfig?: {
|
||||||
splashScreen?: string;
|
splashScreen?: string;
|
||||||
devDept?: string;
|
devDept?: string;
|
||||||
|
slides?: [];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export type RowModelResult = {
|
export type RowModelResult = {
|
||||||
|
|
Loading…
Reference in New Issue