diff --git a/apps/web/src/app/main/courses/components/CourseCard.tsx b/apps/web/src/app/main/courses/components/CourseCard.tsx
index d549a1e..5d7c3cd 100755
--- a/apps/web/src/app/main/courses/components/CourseCard.tsx
+++ b/apps/web/src/app/main/courses/components/CourseCard.tsx
@@ -1,9 +1,10 @@
import { Card, Rate, Tag } from 'antd';
import { Course } from '../mockData';
import { UserOutlined, ClockCircleOutlined } from '@ant-design/icons';
+import { CourseDto } from '@nice/common';
interface CourseCardProps {
- course: Course;
+ course: CourseDto;
}
export default function CourseCard({ course }: CourseCardProps) {
@@ -14,7 +15,7 @@ export default function CourseCard({ course }: CourseCardProps) {
cover={
}
@@ -23,7 +24,7 @@ export default function CourseCard({ course }: CourseCardProps) {
{course.title}
- {course.instructor}
+ {course.subTitle}
{course.rating}
@@ -31,7 +32,7 @@ export default function CourseCard({ course }: CourseCardProps) {
- {course.enrollments} 人在学
+ {course.enrollments?.length} 人在学
@@ -39,8 +40,8 @@ export default function CourseCard({ course }: CourseCardProps) {
- {course.category}
- {course.level}
+ {course.terms[0].name}
+ {course.terms[1].name}
diff --git a/apps/web/src/app/main/courses/components/CourseList.tsx b/apps/web/src/app/main/courses/components/CourseList.tsx
index 3d67b1c..f3e3177 100755
--- a/apps/web/src/app/main/courses/components/CourseList.tsx
+++ b/apps/web/src/app/main/courses/components/CourseList.tsx
@@ -1,9 +1,9 @@
import { Pagination, Empty } from 'antd';
import { Course } from '../mockData';
import CourseCard from './CourseCard';
-
+import {CourseDto} from '@nice/common'
interface CourseListProps {
- courses: Course[];
+ courses: CourseDto[];
total: number;
pageSize: number;
currentPage: number;
diff --git a/apps/web/src/app/main/courses/components/FilterSection.tsx b/apps/web/src/app/main/courses/components/FilterSection.tsx
index 6de4312..6fe06c4 100755
--- a/apps/web/src/app/main/courses/components/FilterSection.tsx
+++ b/apps/web/src/app/main/courses/components/FilterSection.tsx
@@ -75,7 +75,7 @@ export default function FilterSection({
:
(
<>
- 全部课程
+ 全部课程
{gateGory.categories.map(category => (
{category}
diff --git a/apps/web/src/app/main/courses/page.tsx b/apps/web/src/app/main/courses/page.tsx
index cfdd484..c860a82 100755
--- a/apps/web/src/app/main/courses/page.tsx
+++ b/apps/web/src/app/main/courses/page.tsx
@@ -1,9 +1,11 @@
-import { useState, useMemo } from "react";
+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 { LectureType, PostType } from "@nice/common";
+import { courseDetailSelect, CourseDto, LectureType, PostType } from "@nice/common";
+import { useSearchParams } from "react-router-dom";
+import { set } from "idb-keyval";
export default function CoursesPage() {
@@ -11,43 +13,57 @@ export default function CoursesPage() {
const [selectedCategory, setSelectedCategory] = useState("");
const [selectedLevel, setSelectedLevel] = useState("");
const pageSize = 12;
- const { data, isLoading } = api.post.findManyWithPagination.useQuery({
- where: {
- type: PostType.COURSE,
- terms: {
- some: {
- AND: [
- ...(selectedCategory
- ? [
- {
- name: selectedCategory,
- },
- ]
- : []),
- ...(selectedLevel
- ? [
- {
- name: selectedLevel,
- },
- ]
- : []),
- ],
+ const [isAll,setIsAll] = useState(true)
+ const [searchParams, setSearchParams] = useSearchParams();
+ let coursesData = []
+ let isCourseLoading = false
+ if(!searchParams.get('searchValue')){
+ console.log('no category')
+ const {data,isLoading} = api.post.findManyWithPagination.useQuery({
+ where: {
+ type: PostType.COURSE,
+ terms:isAll?{}:{
+ some: {
+ OR : [
+ selectedCategory?{name:selectedCategory}:{},
+ selectedLevel?{name:selectedLevel}:{}
+ ],
+ },
},
+
},
- },
- });
- const filteredCourses = useMemo(() => {
- return mockCourses.filter((course) => {
- const matchCategory =
- !selectedCategory || course.category === selectedCategory;
- const matchLevel = !selectedLevel || course.level === selectedLevel;
- return matchCategory && matchLevel;
+ select:courseDetailSelect
});
- }, [selectedCategory, selectedLevel]);
+ 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,
+ 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(() => {
+ console.log(coursesData)
+ }, [coursesData]);
+ const filteredCourses = useMemo(() => {
+ return isCourseLoading ? [] : coursesData;
+ }, [isCourseLoading, coursesData, selectedCategory, selectedLevel]);
- const paginatedCourses = useMemo(() => {
+ const paginatedCourses :CourseDto[]= useMemo(() => {
const startIndex = (currentPage - 1) * pageSize;
- return filteredCourses.slice(startIndex, startIndex + pageSize);
+ return isCourseLoading ? [] : (filteredCourses.slice(startIndex, startIndex + pageSize) as any as CourseDto[]);
}, [filteredCourses, currentPage]);
const handlePageChange = (page: number) => {
@@ -55,6 +71,8 @@ export default function CoursesPage() {
window.scrollTo({ top: 0, behavior: "smooth" });
};
+
+
return (
@@ -69,10 +87,14 @@ export default function CoursesPage() {
console.log(category);
setSelectedCategory(category);
setCurrentPage(1);
+ setIsAll(!category)
+ setSearchParams({ searchValue: ''});
}}
onLevelChange={(level) => {
setSelectedLevel(level);
setCurrentPage(1);
+ setIsAll(!level)
+ setSearchParams({ searchValue: ''});
}}
/>
diff --git a/apps/web/src/app/main/layout/MainHeader.tsx b/apps/web/src/app/main/layout/MainHeader.tsx
index 80ea733..cc2325d 100755
--- a/apps/web/src/app/main/layout/MainHeader.tsx
+++ b/apps/web/src/app/main/layout/MainHeader.tsx
@@ -35,6 +35,10 @@ export function MainHeader() {
className="w-72 rounded-full"
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
+ onPressEnter={()=>{
+ //console.log(searchValue)
+ navigate(`/courses/?searchValue=${searchValue}`)
+ }}
/>
{isAuthenticated && (
diff --git a/packages/common/src/models/post.ts b/packages/common/src/models/post.ts
index fa030b6..4a1aa99 100755
--- a/packages/common/src/models/post.ts
+++ b/packages/common/src/models/post.ts
@@ -77,5 +77,5 @@ export type Course = Post & {
export type CourseDto = Course & {
enrollments?: Enrollment[];
sections?: SectionDto[];
- terms: Term[];
+ terms: TermDto[];
};
diff --git a/packages/common/src/models/select.ts b/packages/common/src/models/select.ts
index 5417c1c..36e072d 100755
--- a/packages/common/src/models/select.ts
+++ b/packages/common/src/models/select.ts
@@ -70,28 +70,27 @@ export const courseDetailSelect: Prisma.PostSelect = {
title: true,
subTitle: true,
content: true,
-
- level: true,
- // requirements: true,
- // objectives: true,
- // skills: true,
- // audiences: true,
- // totalDuration: true,
- // totalLectures: true,
- // averageRating: true,
- // numberOfReviews: true,
- // numberOfStudents: true,
- // completionRate: true,
- state: true,
// isFeatured: true,
createdAt: true,
- publishedAt: true,
+ updatedAt: true,
// 关联表选择
- children: {
- include: {
- children: true,
+ terms:{
+ select:{
+ id:true,
+ name:true,
+ taxonomy:{
+ select:{
+ id:true,
+ slug:true
+ }
+ }
+ }
+ },
+ enrollments: {
+ select: {
+ id: true,
},
},
- enrollments: true,
meta: true,
+ rating: true,
};