diff --git a/api/app/application/courses_repository.py b/api/app/application/courses_repository.py index 6dd6964..72436c9 100644 --- a/api/app/application/courses_repository.py +++ b/api/app/application/courses_repository.py @@ -1,10 +1,10 @@ -from typing import List, Optional +from typing import List, Optional, Sequence from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from app.domain.models import Course +from app.domain.models import Course, CourseTeacher, Enrollment class CoursesRepository: @@ -22,6 +22,32 @@ class CoursesRepository: result = await self.db.execute(query) return result.scalars().all() + async def get_all_for_teacher(self, user_id: int) -> Optional[Sequence[Course]]: + query = ( + select(Course) + .options( + selectinload(Course.teachers), + selectinload(Course.enrollments) + ) + .join(Course.teachers) + .filter(CourseTeacher.teacher_id == user_id) + ) + result = await self.db.execute(query) + return result.scalars().all() + + async def get_all_for_enrollment(self, user_id: int) -> Optional[Sequence[Course]]: + query = ( + select(Course) + .options( + selectinload(Course.teachers), + selectinload(Course.enrollments) + ) + .join(Course.enrollments) + .filter(Enrollment.user_id == user_id) + ) + result = await self.db.execute(query) + return result.scalars().all() + async def get_by_id(self, course_id: int) -> Optional[Course]: query = ( select(Course) diff --git a/api/app/controllers/courses_router.py b/api/app/controllers/courses_router.py index 4a9c016..49f55ea 100644 --- a/api/app/controllers/courses_router.py +++ b/api/app/controllers/courses_router.py @@ -30,6 +30,20 @@ async def get_all_courses( return await courses_service.get_all() +@courses_router.get( + '/for-me/', + response_model=Optional[List[CourseRead]], + summary='Return all for current user', + description='Return all current user', +) +async def get_fors_for_teacher( + db: AsyncSession = Depends(get_db), + user: User = Depends(require_auth_user), +): + courses_service = CoursesService(db) + return await courses_service.get_all_for_me(user) + + @courses_router.get( '/{course_id}/', response_model=Optional[CourseRead], diff --git a/api/app/infrastructure/courses_service.py b/api/app/infrastructure/courses_service.py index f9cd492..dff2e92 100644 --- a/api/app/infrastructure/courses_service.py +++ b/api/app/infrastructure/courses_service.py @@ -4,13 +4,16 @@ from fastapi import HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.application.courses_repository import CoursesRepository +from app.core.constants import UserRoles from app.domain.entities.courses import CourseRead, CourseCreate, CourseCreated -from app.domain.models import Course +from app.domain.models import Course, User +from app.settings import Settings class CoursesService: def __init__(self, db: AsyncSession): self.courses_repository = CoursesRepository(db) + self.settings = Settings() async def get_all(self) -> List[CourseRead]: courses = await self.courses_repository.get_all() @@ -22,6 +25,27 @@ class CoursesService: return response + async def get_all_for_me(self, user: User) -> Optional[List[CourseRead]]: + if user.role.title == self.settings.root_role_name: + courses = await self.courses_repository.get_all() + + elif user.role.title == UserRoles.TEACHER: + courses = await self.courses_repository.get_all_for_teacher(user.id) + + elif user.role.title == UserRoles.STUDENT: + courses = await self.courses_repository.get_all_for_enrollment(user.id) + + else: + courses = [] + + response = [] + for course in courses: + response.append( + CourseRead.model_validate(course) + ) + + return response + async def get_by_id(self, course_id: int) -> Optional[CourseRead]: course = await self.courses_repository.get_by_id(course_id) if course is None: diff --git a/web/src/Api/coursesApi.js b/web/src/Api/coursesApi.js index e296f9b..91d57da 100644 --- a/web/src/Api/coursesApi.js +++ b/web/src/Api/coursesApi.js @@ -14,6 +14,13 @@ export const coursesApi = createApi({ }), providesTags: ['course'], }), + getAllMyCourses: builder.query({ + query: () => ({ + url: "/courses/for-me/", + method: "GET", + }), + providesTags: ['course'], + }), getCourseById: builder.query({ query: (courseId) => ({ url: `/courses/${courseId}/`, @@ -72,6 +79,7 @@ export const coursesApi = createApi({ export const { useGetAllCoursesQuery, + useGetAllMyCoursesQuery, useGetCourseByIdQuery, useCreateCourseMutation, useUpdateCourseMutation, diff --git a/web/src/Components/Pages/CourseDetailPage/Components/UpdateLessonModalForm/UpdateLessonModalForm.jsx b/web/src/Components/Pages/CourseDetailPage/Components/UpdateLessonModalForm/UpdateLessonModalForm.jsx new file mode 100644 index 0000000..f7b4984 --- /dev/null +++ b/web/src/Components/Pages/CourseDetailPage/Components/UpdateLessonModalForm/UpdateLessonModalForm.jsx @@ -0,0 +1,79 @@ +import useUpdateLessonModalForm from "./useUpdateLessonModalForm.js"; +import {Button, Form, Input, InputNumber, Modal, Upload} from "antd"; +import JoditEditor from "jodit-react"; +import LoadingIndicator from "../../../../Widgets/LoadingIndicator/LoadingIndicator.jsx"; + +const {TextArea} = Input; + +const UpdateLessonModalForm = ({courseId}) => { + const { + isModalOpen, + handleCancel, + handleOk, + form, + joditConfig, + editorRef, + isLoading, + initialContent, + currentLesson, + } = useUpdateLessonModalForm({courseId}); + + if (isLoading) { + return + + + } + + return ( + + Отмена + , + , + ]} + maskClosable={false} + keyboard={false} + > +
+ + + + + +