diff --git a/apps/web/src/app/main/my-learning/page.tsx b/apps/web/src/app/main/my-learning/page.tsx
index 0216515..8807119 100644
--- a/apps/web/src/app/main/my-learning/page.tsx
+++ b/apps/web/src/app/main/my-learning/page.tsx
@@ -7,11 +7,14 @@ export default function MyLearningPage() {
<>
diff --git a/apps/web/src/components/models/course/detail/CourseDetailContext.tsx b/apps/web/src/components/models/course/detail/CourseDetailContext.tsx
index b722f3c..0da1702 100755
--- a/apps/web/src/components/models/course/detail/CourseDetailContext.tsx
+++ b/apps/web/src/components/models/course/detail/CourseDetailContext.tsx
@@ -28,6 +28,7 @@ interface CourseDetailContextType {
isHeaderVisible: boolean; // 新增
setIsHeaderVisible: (visible: boolean) => void; // 新增
canEdit?: boolean;
+ userIsLearning?: boolean;
}
interface CourseFormProviderProps {
@@ -43,30 +44,25 @@ export function CourseDetailProvider({
}: CourseFormProviderProps) {
const navigate = useNavigate();
const { read } = useVisitor();
- const { user, hasSomePermissions } = useAuth();
+ const { user, hasSomePermissions, isAuthenticated } = useAuth();
const { lectureId } = useParams();
const { data: course, isLoading }: { data: CourseDto; isLoading: boolean } =
(api.post as any).findFirst.useQuery(
{
where: { id: editId },
- // include: {
- // // sections: { include: { lectures: true } },
- // enrollments: true,
- // terms:true
- // },
-
- select:courseDetailSelect
+ select: courseDetailSelect,
},
{ enabled: Boolean(editId) }
);
+
+ const userIsLearning = useMemo(() => {
+ return (course?.studentIds || []).includes(user?.id);
+ }, [user, course, isLoading]);
const canEdit = useMemo(() => {
- const isAuthor = user?.id === course?.authorId;
- const isDept = course?.depts
- ?.map((dept) => dept.id)
- .includes(user?.deptId);
+ const isAuthor = isAuthenticated && user?.id === course?.authorId;
const isRoot = hasSomePermissions(RolePerms?.MANAGE_ANY_POST);
- return isAuthor || isDept || isRoot;
+ return isAuthor || isRoot;
}, [user, course]);
const [selectedLectureId, setSelectedLectureId] = useState<
string | undefined
@@ -109,6 +105,7 @@ export function CourseDetailProvider({
isHeaderVisible,
setIsHeaderVisible,
canEdit,
+ userIsLearning,
}}>
{children}
diff --git a/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader.tsx b/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader.tsx
index 401484a..e07ad48 100755
--- a/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader.tsx
+++ b/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader.tsx
@@ -10,17 +10,18 @@ import { useAuth } from "@web/src/providers/auth-provider";
import { useNavigate, useParams } from "react-router-dom";
import { UserMenu } from "@web/src/app/main/layout/UserMenu/UserMenu";
import { CourseDetailContext } from "../CourseDetailContext";
-
+import { usePost, useStaff } from "@nice/client";
+import toast from "react-hot-toast";
const { Header } = Layout;
export function CourseDetailHeader() {
- const [searchValue, setSearchValue] = useState("");
const { id } = useParams();
const { isAuthenticated, user, hasSomePermissions, hasEveryPermissions } =
useAuth();
const navigate = useNavigate();
- const { course, canEdit } = useContext(CourseDetailContext);
+ const { course, canEdit, userIsLearning } = useContext(CourseDetailContext);
+ const { update } = useStaff();
return (
@@ -39,20 +40,48 @@ export function CourseDetailHeader() {
{/* */}
+ {isAuthenticated && (
+
+ )}
{canEdit && (
- <>
-
- >
+
)}
{isAuthenticated ? (
diff --git a/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader_BACKUP.tsx b/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader_BACKUP.tsx
deleted file mode 100755
index 0fc9815..0000000
--- a/apps/web/src/components/models/course/detail/CourseDetailHeader/CourseDetailHeader_BACKUP.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-// // components/Header.tsx
-// import { motion, useScroll, useTransform } from "framer-motion";
-// import { useContext, useEffect, useState } from "react";
-// import { CourseDetailContext } from "../CourseDetailContext";
-// import { Avatar, Button, Dropdown } from "antd";
-// import { UserOutlined } from "@ant-design/icons";
-// import { UserMenu } from "@web/src/app/main/layout/UserMenu";
-// import { useAuth } from "@web/src/providers/auth-provider";
-
-// export const CourseDetailHeader = () => {
-// const { scrollY } = useScroll();
-// const { user, isAuthenticated } = useAuth();
-// const [lastScrollY, setLastScrollY] = useState(0);
-// const { course, isHeaderVisible, setIsHeaderVisible, lecture } =
-// useContext(CourseDetailContext);
-// useEffect(() => {
-// const updateHeader = () => {
-// const current = scrollY.get();
-// const direction = current > lastScrollY ? "down" : "up";
-
-// if (direction === "down" && current > 100) {
-// setIsHeaderVisible(false);
-// } else if (direction === "up") {
-// setIsHeaderVisible(true);
-// }
-
-// setLastScrollY(current);
-// };
-
-// // 使用 requestAnimationFrame 来优化性能
-// const unsubscribe = scrollY.on("change", () => {
-// requestAnimationFrame(updateHeader);
-// });
-
-// return () => {
-// unsubscribe();
-// };
-// }, [lastScrollY, scrollY, setIsHeaderVisible]);
-
-// return (
-//
-//
-//
-//
{course?.title}
-//
-
-// {isAuthenticated ? (
-//
}
-// trigger={["click"]}
-// placement="bottomRight">
-//
-// {(user?.showname ||
-// user?.username ||
-// "")[0]?.toUpperCase()}
-//
-//
-// ) : (
-//
-// )}
-//
-//
-// );
-// };
-
-// export default CourseDetailHeader;
diff --git a/apps/web/src/components/models/course/editor/context/CourseEditorContext.tsx b/apps/web/src/components/models/course/editor/context/CourseEditorContext.tsx
index 0fd8040..88571a3 100755
--- a/apps/web/src/components/models/course/editor/context/CourseEditorContext.tsx
+++ b/apps/web/src/components/models/course/editor/context/CourseEditorContext.tsx
@@ -99,10 +99,10 @@ export function CourseFormProvider({
}),
},
terms: {
- connect: termIds.map((id) => ({ id })), // 转换成 connect 格式
+ set: termIds.map((id) => ({ id })), // 转换成 connect 格式
},
depts: {
- connect: deptIds.map((id) => ({ id })),
+ set: deptIds.map((id) => ({ id })),
},
};
// 删除原始的 taxonomy 字段
diff --git a/apps/web/src/components/models/course/editor/form/CourseContentForm/SortableLecture.tsx b/apps/web/src/components/models/course/editor/form/CourseContentForm/SortableLecture.tsx
index 26282d2..a153137 100755
--- a/apps/web/src/components/models/course/editor/form/CourseContentForm/SortableLecture.tsx
+++ b/apps/web/src/components/models/course/editor/form/CourseContentForm/SortableLecture.tsx
@@ -83,7 +83,7 @@ export const SortableLecture: React.FC
= ({
: undefined,
},
resources: {
- connect: [videoUrlId, ...fileIds]
+ set: [videoUrlId, ...fileIds]
.filter(Boolean)
.map((fileId) => ({
fileId,
@@ -109,7 +109,7 @@ export const SortableLecture: React.FC = ({
: undefined,
},
resources: {
- connect: [videoUrlId, ...fileIds]
+ set: [videoUrlId, ...fileIds]
.filter(Boolean)
.map((fileId) => ({
fileId,