From be7b9499f2c3ec730daa86d997200cba0dc8b525 Mon Sep 17 00:00:00 2001 From: swve Date: Fri, 24 Jan 2025 22:59:04 +0100 Subject: [PATCH] fix: collections bugs and issues --- apps/api/src/services/courses/collections.py | 54 ++-- .../(withmenu)/collections/new/page.tsx | 261 ++++++++++++------ .../[orgslug]/(withmenu)/collections/page.tsx | 2 +- apps/web/services/media/media.ts | 4 +- 4 files changed, 210 insertions(+), 111 deletions(-) diff --git a/apps/api/src/services/courses/collections.py b/apps/api/src/services/courses/collections.py index d54faedf..774e2393 100644 --- a/apps/api/src/services/courses/collections.py +++ b/apps/api/src/services/courses/collections.py @@ -47,15 +47,23 @@ async def get_collection( # get courses in collection statement_all = ( select(Course) - .join(CollectionCourse, Course.id == CollectionCourse.course_id) - .where(CollectionCourse.org_id == collection.org_id) - .distinct(Course.id) + .join(CollectionCourse) + .where( + CollectionCourse.collection_id == collection.id, + CollectionCourse.org_id == collection.org_id + ) + .distinct() ) statement_public = ( select(Course) - .join(CollectionCourse, Course.id == CollectionCourse.course_id) - .where(CollectionCourse.org_id == collection.org_id, Course.public == True) + .join(CollectionCourse) + .where( + CollectionCourse.collection_id == collection.id, + CollectionCourse.org_id == collection.org_id, + Course.public == True + ) + .distinct() ) if current_user.user_uuid == "user_anonymous": @@ -63,7 +71,7 @@ async def get_collection( else: statement = statement_all - courses = db_session.exec(statement).all() + courses = list(db_session.exec(statement).all()) collection = CollectionRead(**collection.model_dump(), courses=courses) @@ -110,10 +118,11 @@ async def create_collection( # Get courses once again statement = ( select(Course) - .join(CollectionCourse, Course.id == CollectionCourse.course_id) - .distinct(Course.id) + .join(CollectionCourse) + .where(CollectionCourse.collection_id == collection.id) + .distinct() ) - courses = db_session.exec(statement).all() + courses = list(db_session.exec(statement).all()) collection = CollectionRead(**collection.model_dump(), courses=courses) @@ -183,12 +192,11 @@ async def update_collection( # Get courses once again statement = ( select(Course) - .join(CollectionCourse, Course.id == CollectionCourse.course_id) - .where(Course.org_id == collection.org_id) - .distinct(Course.id) + .join(CollectionCourse) + .where(CollectionCourse.collection_id == collection.id) + .distinct() ) - - courses = db_session.exec(statement).all() + courses = list(db_session.exec(statement).all()) collection = CollectionRead(**collection.model_dump(), courses=courses) @@ -255,14 +263,22 @@ async def get_collections( for collection in collections: statement_all = ( select(Course) - .join(CollectionCourse, Course.id == CollectionCourse.course_id) - .where(CollectionCourse.org_id == collection.org_id) - .distinct(Course.id) + .join(CollectionCourse) + .where( + CollectionCourse.collection_id == collection.id, + CollectionCourse.org_id == collection.org_id + ) + .distinct() ) statement_public = ( select(Course) - .join(CollectionCourse, Course.id == CollectionCourse.course_id) - .where(CollectionCourse.org_id == org_id, Course.public == True) + .join(CollectionCourse) + .where( + CollectionCourse.collection_id == collection.id, + CollectionCourse.org_id == org_id, + Course.public == True + ) + .distinct() ) if current_user.id == 0: statement = statement_public diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx index be8cbd01..621ce2fa 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/collections/new/page.tsx @@ -7,17 +7,22 @@ import { getAPIUrl, getUriWithOrg } from '@services/config/config' import { revalidateTags, swrFetcher } from '@services/utils/ts/requests' import { useOrg } from '@components/Contexts/OrgContext' import { useLHSession } from '@components/Contexts/LHSessionContext' +import { Loader2, Image as ImageIcon } from 'lucide-react' +import { toast } from 'react-hot-toast' +import Image from 'next/image' +import { getCourseThumbnailMediaDirectory } from '@services/media/media' function NewCollection(params: any) { const org = useOrg() as any - const session = useLHSession() as any; - const access_token = session?.data?.tokens?.access_token; + const session = useLHSession() as any + const access_token = session?.data?.tokens?.access_token const orgslug = params.params.orgslug const [name, setName] = React.useState('') const [description, setDescription] = React.useState('') const [selectedCourses, setSelectedCourses] = React.useState([]) as any + const [isSubmitting, setIsSubmitting] = useState(false) const router = useRouter() - const { data: courses, error: error } = useSWR( + const { data: courses, error: error, isLoading } = useSWR( `${getAPIUrl()}courses/org_slug/${orgslug}/page/1/limit/10`, (url) => swrFetcher(url, access_token) ) @@ -32,111 +37,189 @@ function NewCollection(params: any) { } const handleDescriptionChange = ( - event: React.ChangeEvent + event: React.ChangeEvent ) => { setDescription(event.target.value) } const handleSubmit = async (e: any) => { e.preventDefault() - - const collection = { - name: name, - description: description, - courses: selectedCourses, - public: isPublic, - org_id: org.id, + + if (!name.trim()) { + toast.error('Please enter a collection name') + return } - await createCollection(collection, session.data?.tokens?.access_token) - await revalidateTags(['collections'], org.slug) - // reload the page - router.refresh() - // wait for 2s before reloading the page - setTimeout(() => { + if (!description.trim()) { + toast.error('Please enter a description') + return + } + + if (selectedCourses.length === 0) { + toast.error('Please select at least one course') + return + } + + setIsSubmitting(true) + try { + const collection = { + name: name.trim(), + description: description.trim(), + courses: selectedCourses, + public: isPublic, + org_id: org.id, + } + await createCollection(collection, session.data?.tokens?.access_token) + await revalidateTags(['collections'], org.slug) + toast.success('Collection created successfully!') router.push(getUriWithOrg(orgslug, '/collections')) - }, 1000) + } catch (error) { + toast.error('Failed to create collection. Please try again.') + } finally { + setIsSubmitting(false) + } + } + + if (error) { + return ( +
+
Failed to load courses. Please try again later.
+
+ ) } return ( - <> -
-
Add new
+
+
+
+

Create New Collection

+

+ Group your courses together in a collection to make them easier to find and manage. +

+
- +
+
+ - - - {!courses ? ( -

Loading...

- ) : ( -
-

Courses

- {courses.map((course: any) => ( -
+ Visibility + { - if (e.target.checked) { - setSelectedCourses([...selectedCourses, course.id]) - } else { - setSelectedCourses( - selectedCourses.filter( - (course_uuid: any) => - course_uuid !== course.course_uuid - ) - ) - } - }} - className="text-blue-500 rounded focus:ring-2 focus:ring-blue-500" - /> + + + + - -
- ))} +