add
This commit is contained in:
parent
1fe33f9f6c
commit
96351ac9ac
|
@ -5,30 +5,18 @@ import { useMemo } from "react";
|
|||
import CourseCard from "./CourseCard";
|
||||
|
||||
export function CoursesContainer() {
|
||||
const { selectedTerms, searchCondition } = useMainContext();
|
||||
const termFilters = useMemo(() => {
|
||||
return Object.entries(selectedTerms)
|
||||
.filter(([, terms]) => terms.length > 0)
|
||||
.map(([, terms]) => terms);
|
||||
}, [selectedTerms]);
|
||||
|
||||
const {searchCondition, termsCondition } = useMainContext();
|
||||
return (
|
||||
<>
|
||||
<PostList
|
||||
renderItem={(post) => <CourseCard course={post} edit={false}></CourseCard>}
|
||||
renderItem={(post) => (
|
||||
<CourseCard course={post} edit={false}></CourseCard>
|
||||
)}
|
||||
params={{
|
||||
pageSize: 12,
|
||||
where: {
|
||||
type: PostType.COURSE,
|
||||
AND: termFilters.map((termFilter) => ({
|
||||
terms: {
|
||||
some: {
|
||||
id: {
|
||||
in: termFilter, // 确保至少有一个 term.id 在当前 termFilter 中
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
...termsCondition,
|
||||
...searchCondition,
|
||||
},
|
||||
}}
|
||||
|
|
|
@ -43,7 +43,8 @@ export function MainHeader() {
|
|||
onPressEnter={(e) => {
|
||||
if (
|
||||
!window.location.pathname.startsWith("/courses/") &&
|
||||
!window.location.pathname.startsWith("my")
|
||||
!window.location.pathname.startsWith("/my") &&
|
||||
!window.location.pathname.startsWith("/path")
|
||||
) {
|
||||
navigate(`/courses/`);
|
||||
window.scrollTo({
|
||||
|
|
|
@ -16,6 +16,7 @@ interface MainContextType {
|
|||
setSearchValue?: React.Dispatch<React.SetStateAction<string>>;
|
||||
setSelectedTerms?: React.Dispatch<React.SetStateAction<SelectedTerms>>;
|
||||
searchCondition?: Prisma.PostWhereInput;
|
||||
termsCondition?: Prisma.PostWhereInput;
|
||||
}
|
||||
|
||||
const MainContext = createContext<MainContextType | null>(null);
|
||||
|
@ -26,7 +27,27 @@ interface MainProviderProps {
|
|||
export function MainProvider({ children }: MainProviderProps) {
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [selectedTerms, setSelectedTerms] = useState<SelectedTerms>({}); // 初始化状态
|
||||
const termFilters = useMemo(() => {
|
||||
return Object.entries(selectedTerms)
|
||||
.filter(([, terms]) => terms.length > 0)
|
||||
?.map(([, terms]) => terms);
|
||||
}, [selectedTerms]);
|
||||
|
||||
const termsCondition: Prisma.PostWhereInput = useMemo(() => {
|
||||
return termFilters && termFilters?.length > 0
|
||||
? {
|
||||
AND: termFilters.map((termFilter) => ({
|
||||
terms: {
|
||||
some: {
|
||||
id: {
|
||||
in: termFilter, // 确保至少有一个 term.id 在当前 termFilter 中
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
}
|
||||
: {};
|
||||
}, [termFilters]);
|
||||
const searchCondition: Prisma.PostWhereInput = useMemo(() => {
|
||||
const containTextCondition: Prisma.StringNullableFilter = {
|
||||
contains: searchValue,
|
||||
|
@ -57,6 +78,7 @@ export function MainProvider({ children }: MainProviderProps) {
|
|||
selectedTerms,
|
||||
setSelectedTerms,
|
||||
searchCondition,
|
||||
termsCondition,
|
||||
}}>
|
||||
{children}
|
||||
</MainContext.Provider>
|
||||
|
|
|
@ -20,7 +20,8 @@ export const NavigationMenu = () => {
|
|||
return [
|
||||
...baseItems,
|
||||
{ key: "my-duty", path: "/my-duty", label: "我创建的" },
|
||||
{ key: "my-learning", path: "/my-learning", label: "我学习的" },
|
||||
{ key: "my-learning", path: "/my-learning", label: "我的课表" },
|
||||
{ key: "my-path", path: "/my-path", label: "我的路径" },
|
||||
];
|
||||
}
|
||||
}, [isAuthenticated]);
|
||||
|
@ -31,6 +32,7 @@ export const NavigationMenu = () => {
|
|||
<Menu
|
||||
mode="horizontal"
|
||||
className="border-none font-medium"
|
||||
disabledOverflow={true}
|
||||
selectedKeys={[selectedKey]}
|
||||
onClick={({ key }) => {
|
||||
const selectedItem = menuItems.find((item) => item.key === key);
|
||||
|
|
|
@ -86,20 +86,7 @@ export function UserMenu() {
|
|||
setModalOpen(true);
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: <UserOutlined className="text-lg" />,
|
||||
label: "我创建的课程",
|
||||
action: () => {
|
||||
navigate("/my-duty");
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: <UserOutlined className="text-lg" />,
|
||||
label: "我学习的课程",
|
||||
action: () => {
|
||||
navigate("/my-learning");
|
||||
},
|
||||
},
|
||||
|
||||
canManageAnyStaff && {
|
||||
icon: <SettingOutlined className="text-lg" />,
|
||||
label: "设置",
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import PostList from "@web/src/components/models/course/list/PostList";
|
||||
import { useAuth } from "@web/src/providers/auth-provider";
|
||||
|
||||
import CourseCard from "../../courses/components/CourseCard";
|
||||
import { PostType } from "@nice/common";
|
||||
import { useMainContext } from "../../layout/MainProvider";
|
||||
|
||||
export default function MyDutyPage() {
|
||||
const { user } = useAuth();
|
||||
const { searchCondition, termsCondition } = useMainContext();
|
||||
return (
|
||||
<>
|
||||
<PostList
|
||||
renderItem={(post) => (
|
||||
<CourseCard edit course={post}></CourseCard>
|
||||
)}
|
||||
params={{
|
||||
pageSize: 12,
|
||||
where: {
|
||||
type: PostType.COURSE,
|
||||
authorId: user.id,
|
||||
...termsCondition,
|
||||
...searchCondition,
|
||||
},
|
||||
}}
|
||||
cols={4}></PostList>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
import { api } from "@nice/client";
|
||||
import { useMainContext } from "../../layout/MainProvider";
|
||||
import TermParentSelector from "@web/src/components/models/term/term-parent-selector";
|
||||
|
||||
export default function PathFilter() {
|
||||
const { data: taxonomies } = api.taxonomy.getAll.useQuery({});
|
||||
const { selectedTerms, setSelectedTerms } = useMainContext();
|
||||
const handleTermChange = (slug: string, selected: string[]) => {
|
||||
setSelectedTerms({
|
||||
...selectedTerms,
|
||||
[slug]: selected, // 更新对应 slug 的选择
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div className="bg-white p-6 rounded-lg shadow-sm space-y-6 h-full">
|
||||
{taxonomies?.map((tax, index) => {
|
||||
const items = Object.entries(selectedTerms).find(
|
||||
([key, items]) => key === tax.slug
|
||||
)?.[1];
|
||||
return (
|
||||
<div key={index}>
|
||||
<h3 className="text-lg font-medium mb-4">
|
||||
{tax?.name}
|
||||
</h3>
|
||||
<TermParentSelector
|
||||
value={items}
|
||||
slug = {tax?.slug}
|
||||
className="w-70 max-h-[500px] overscroll-contain overflow-x-hidden"
|
||||
onChange={(selected) =>
|
||||
handleTermChange(
|
||||
tax?.slug,
|
||||
selected as string[]
|
||||
)
|
||||
}
|
||||
taxonomyId={tax?.id}
|
||||
></TermParentSelector>
|
||||
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,17 +1,9 @@
|
|||
import PostList from "@web/src/components/models/course/list/PostList";
|
||||
import { useMainContext } from "../../layout/MainProvider";
|
||||
import { PostType, Prisma } from "@nice/common";
|
||||
import { useMemo } from "react";
|
||||
import PathCard from "./PathCard";
|
||||
|
||||
export function PathListContainer() {
|
||||
const { searchValue, selectedTerms, searchCondition } = useMainContext();
|
||||
const termFilters = useMemo(() => {
|
||||
return Object.entries(selectedTerms)
|
||||
.filter(([, terms]) => terms.length > 0)
|
||||
.map(([, terms]) => terms);
|
||||
}, [selectedTerms]);
|
||||
|
||||
const { searchCondition, termsCondition } = useMainContext();
|
||||
return (
|
||||
<>
|
||||
<PostList
|
||||
|
@ -20,15 +12,7 @@ export function PathListContainer() {
|
|||
pageSize: 12,
|
||||
where: {
|
||||
type: PostType.PATH,
|
||||
AND: termFilters.map((termFilter) => ({
|
||||
terms: {
|
||||
some: {
|
||||
id: {
|
||||
in: termFilter, // 确保至少有一个 term.id 在当前 termFilter 中
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
...termsCondition,
|
||||
...searchCondition,
|
||||
},
|
||||
}}
|
||||
|
@ -36,5 +20,4 @@ export function PathListContainer() {
|
|||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PathListContainer;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import FilterSection from "../../courses/components/FilterSection";
|
||||
import PathFilter from "../components/PathFilter";
|
||||
|
||||
import PathListContainer from "../components/PathListContainer";
|
||||
|
||||
export function PathListLayout() {
|
||||
|
@ -9,7 +9,7 @@ export function PathListLayout() {
|
|||
<div className=" flex">
|
||||
<div className="w-1/6">
|
||||
<FilterSection></FilterSection>
|
||||
{/* <PathFilter></PathFilter> */}
|
||||
|
||||
</div>
|
||||
<div className="w-5/6 p-4 ">
|
||||
<PathListContainer></PathListContainer>
|
||||
|
|
Loading…
Reference in New Issue