diff --git a/apps/web/app/orgs/[orgslug]/dash/page.tsx b/apps/web/app/orgs/[orgslug]/dash/page.tsx index 9f104e12..acc01033 100644 --- a/apps/web/app/orgs/[orgslug]/dash/page.tsx +++ b/apps/web/app/orgs/[orgslug]/dash/page.tsx @@ -1,7 +1,7 @@ import Image from 'next/image' import React from 'react' import learnhousetextlogo from '../../../../public/learnhouse_logo.png' -import { BookCopy, School, Settings, Users } from 'lucide-react' +import { BookCopy, School, Settings, University, Users } from 'lucide-react' import Link from 'next/link' import AdminAuthorization from '@components/Security/AdminAuthorization' @@ -62,12 +62,13 @@ function DashboardHome() {
- +
- Learn LearnHouse + LearnHouse University
diff --git a/apps/web/components/Contexts/CourseContext.tsx b/apps/web/components/Contexts/CourseContext.tsx index 4df1ac6b..bc615cc3 100644 --- a/apps/web/components/Contexts/CourseContext.tsx +++ b/apps/web/components/Contexts/CourseContext.tsx @@ -34,15 +34,17 @@ export function CourseProvider({ children, courseuuid }: any) { }, [courseStructureData]); if (error) return
Failed to load course structure
; - if (!courseStructureData) return ; + if (!courseStructureData) return ; - return ( - - - {children} - - - ) + if (courseStructureData) { + return ( + + + {children} + + + ) + } } export function useCourse() { diff --git a/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx b/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx index 38ec8b3c..eac3c8db 100644 --- a/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx +++ b/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx @@ -7,7 +7,7 @@ import { unLinkResourcesToUserGroup } from '@services/usergroups/usergroups' import { swrFetcher } from '@services/utils/ts/requests' import { Globe, SquareUserRound, Users, X } from 'lucide-react' import { useLHSession } from '@components/Contexts/LHSessionContext' -import React from 'react' +import React, { useEffect, useState } from 'react' import toast from 'react-hot-toast' import useSWR, { mutate } from 'swr' @@ -17,132 +17,132 @@ type EditCourseAccessProps = { } function EditCourseAccess(props: EditCourseAccessProps) { - const [error, setError] = React.useState('') const session = useLHSession() as any; const access_token = session?.data?.tokens?.access_token; - const course = useCourse() as any; const { isLoading, courseStructure } = course as any; - const dispatchCourse = useCourseDispatch() as any - const { data: usergroups } = useSWR( - courseStructure ? `${getAPIUrl()}usergroups/resource/${courseStructure.course_uuid}` : null, - (url) => swrFetcher(url, access_token) - ) - const [isPublic, setIsPublic] = React.useState(courseStructure.public) + const dispatchCourse = useCourseDispatch() as any; + const { data: usergroups } = useSWR(courseStructure ? `${getAPIUrl()}usergroups/resource/${courseStructure.course_uuid}` : null, (url) => swrFetcher(url, access_token)); + const [isClientPublic, setIsClientPublic] = useState(undefined); - React.useEffect(() => { - // This code will run whenever form values are updated - if ((isPublic !== courseStructure.public) && isLoading) { - dispatchCourse({ type: 'setIsNotSaved' }) - const updatedCourse = { - ...courseStructure, - public: isPublic, - } - dispatchCourse({ type: 'setCourseStructure', payload: updatedCourse }) + useEffect(() => { + if (!isLoading && courseStructure?.public !== undefined) { + setIsClientPublic(courseStructure.public); } - }, [course, isPublic]) + }, [isLoading, courseStructure]); + + useEffect(() => { + if (!isLoading && courseStructure?.public !== undefined && isClientPublic !== undefined) { + if (isClientPublic !== courseStructure.public) { + dispatchCourse({ type: 'setIsNotSaved' }); + const updatedCourse = { + ...courseStructure, + public: isClientPublic, + }; + dispatchCourse({ type: 'setCourseStructure', payload: updatedCourse }); + } + } + }, [isLoading, isClientPublic, courseStructure, dispatchCourse]); + return (
- {' '} -
-
-
-

Access to the course

-

- {' '} - Choose if want your course to be publicly available on the internet or only accessible to signed in users{' '} -

+ {courseStructure && ( +
+
+
+
+

Access to the course

+

+ Choose if you want your course to be publicly available on the internet or only accessible to signed in users +

+
+
+ + {isClientPublic && ( +
+ Active +
+ )} +
+ +
+ Public +
+
+ The Course is publicly available on the internet, it is indexed by search engines and can be accessed by anyone +
+
+
+ } + functionToExecute={() => setIsClientPublic(true)} + status="info" + /> + + {!isClientPublic && ( +
+ Active +
+ )} +
+ +
+ Users Only +
+
+ The Course is only accessible to signed in users, additionally you can choose which UserGroups can access this course +
+
+
+ } + functionToExecute={() => setIsClientPublic(false)} + status="info" + /> +
+ {!isClientPublic && } +
-
- - {isPublic ? ( -
- Active -
- ) : null} -
- -
- Public -
-
- The Course is publicly available on the internet, it is indexed by search engines and can be accessed by anyone -
-
- -
- } - functionToExecute={() => { - setIsPublic(true) - }} - status="info" - > - - {!isPublic ? ( -
- Active -
- ) : null} -
- -
- Users Only -
-
- The Course is only accessible to signed in users, additionaly you can choose which UserGroups can access this course -
-
- -
- } - functionToExecute={() => { - setIsPublic(false) - }} - status="info" - > - - {!isPublic ? () : null} - + )} - ) + ); } - function UserGroupsSection({ usergroups }: { usergroups: any[] }) { - const course = useCourse() as any - const [userGroupModal, setUserGroupModal] = React.useState(false) + const course = useCourse() as any; + const [userGroupModal, setUserGroupModal] = useState(false); const session = useLHSession() as any; const access_token = session?.data?.tokens?.access_token; const removeUserGroupLink = async (usergroup_id: number) => { - const res = await unLinkResourcesToUserGroup(usergroup_id, course.courseStructure.course_uuid, access_token) - if (res.status === 200) { - toast.success('Successfully unliked from usergroup') - mutate(`${getAPIUrl()}usergroups/resource/${course.courseStructure.course_uuid}`) + try { + const res = await unLinkResourcesToUserGroup(usergroup_id, course.courseStructure.course_uuid, access_token); + if (res.status === 200) { + toast.success('Successfully unlinked from usergroup'); + mutate(`${getAPIUrl()}usergroups/resource/${course.courseStructure.course_uuid}`); + } else { + toast.error(`Error ${res.status}: ${res.data.detail}`); + } + } catch (error) { + toast.error('An error occurred while unlinking the user group.'); } - else { - toast.error('Error ' + res.status + ': ' + res.data.detail) - } - } + }; return ( <> -
+

UserGroups

- {' '} - You can choose to give access to this course to specific groups of users only by linking it to a UserGroup{' '} + You can choose to give access to this course to specific groups of users only by linking it to a UserGroup

@@ -152,67 +152,48 @@ function UserGroupsSection({ usergroups }: { usergroups: any[] }) { - <> - - {usergroups?.map((usergroup: any) => ( - - - - - ))} - - + + {usergroups?.map((usergroup: any) => ( + + + + + ))} +
Actions
{usergroup.name} - - - Delete link - - } - functionToExecute={() => { - removeUserGroupLink(usergroup.id) - }} - status="warning" - > -
{usergroup.name} + + + Delete link + + } + functionToExecute={() => removeUserGroupLink(usergroup.id)} + status="warning" + /> +
-
+
- setUserGroupModal(!userGroupModal) - } + isDialogOpen={userGroupModal} + onOpenChange={() => setUserGroupModal(!userGroupModal)} minHeight="no-min" - minWidth='md' - dialogContent={ - - - } + minWidth="md" + dialogContent={} dialogTitle="Link Course to a UserGroup" - dialogDescription={ - 'Choose a UserGroup to link this course to, Users from this UserGroup will have access to this course.' - } + dialogDescription="Choose a UserGroup to link this course to. Users from this UserGroup will have access to this course." dialogTrigger={ - } /> -
- ) + ); } -export default EditCourseAccess \ No newline at end of file +export default EditCourseAccess; diff --git a/apps/web/components/Dashboard/Course/EditCourseStructure/DraggableElements/ActivityElement.tsx b/apps/web/components/Dashboard/Course/EditCourseStructure/DraggableElements/ActivityElement.tsx index d001fa06..a079aa01 100644 --- a/apps/web/components/Dashboard/Course/EditCourseStructure/DraggableElements/ActivityElement.tsx +++ b/apps/web/components/Dashboard/Course/EditCourseStructure/DraggableElements/ActivityElement.tsx @@ -5,6 +5,7 @@ import { revalidateTags } from '@services/utils/ts/requests' import { Eye, File, + FilePenLine, MoreVertical, Pencil, Save, @@ -44,7 +45,7 @@ function ActivityElement(props: ActivitiyElementProps) { const activityUUID = props.activity.activity_uuid async function deleteActivityUI() { - await deleteActivity(props.activity.activity_uuid,access_token) + await deleteActivity(props.activity.activity_uuid, access_token) mutate(`${getAPIUrl()}courses/${props.course_uuid}/meta`) await revalidateTags(['courses'], props.orgslug) router.refresh() @@ -63,7 +64,7 @@ function ActivityElement(props: ActivitiyElementProps) { content: props.activity.content, } - await updateActivity(modifiedActivityCopy, activityUUID,access_token) + await updateActivity(modifiedActivityCopy, activityUUID, access_token) mutate(`${getAPIUrl()}courses/${props.course_uuid}/meta`) await revalidateTags(['courses'], props.orgslug) router.refresh() @@ -144,7 +145,9 @@ function ActivityElement(props: ActivitiyElementProps) { className=" hover:cursor-pointer p-1 px-3 bg-sky-700 rounded-md items-center" rel="noopener noreferrer" > -
Edit
+
+ Edit Page +
)} @@ -159,10 +162,11 @@ function ActivityElement(props: ActivitiyElementProps) { '' )}` } - className=" hover:cursor-pointer p-1 px-3 bg-gray-200 rounded-md" + className=" hover:cursor-pointer p-1 px-3 bg-gray-200 rounded-md font-bold text-xs flex items-center space-x-1" rel="noopener noreferrer" > - + + Preview
{/* Delete Button */} diff --git a/apps/web/components/Objects/Modals/Dash/EditCourseAccess/LinkToUserGroup.tsx b/apps/web/components/Objects/Modals/Dash/EditCourseAccess/LinkToUserGroup.tsx index cc4b8470..867b03eb 100644 --- a/apps/web/components/Objects/Modals/Dash/EditCourseAccess/LinkToUserGroup.tsx +++ b/apps/web/components/Objects/Modals/Dash/EditCourseAccess/LinkToUserGroup.tsx @@ -2,10 +2,11 @@ import { useCourse } from '@components/Contexts/CourseContext'; import { useLHSession } from '@components/Contexts/LHSessionContext'; import { useOrg } from '@components/Contexts/OrgContext'; -import { getAPIUrl } from '@services/config/config'; +import { getAPIUrl, getUriWithOrg } from '@services/config/config'; import { linkResourcesToUserGroup } from '@services/usergroups/usergroups'; import { swrFetcher } from '@services/utils/ts/requests'; import { Info } from 'lucide-react'; +import Link from 'next/link'; import React, { useEffect } from 'react' import toast from 'react-hot-toast'; import useSWR, { mutate } from 'swr' @@ -24,7 +25,7 @@ function LinkToUserGroup(props: LinkToUserGroupProps) { const { data: usergroups } = useSWR( courseStructure && org ? `${getAPIUrl()}usergroups/org/${org.id}` : null, - swrFetcher + (url) => swrFetcher(url, access_token) ) const [selectedUserGroup, setSelectedUserGroup] = React.useState(null) as any @@ -55,19 +56,26 @@ function LinkToUserGroup(props: LinkToUserGroupProps) {

Users that are not part of the UserGroup will no longer have access to this course

+ {usergroups?.length >= 1 && +
+ UserGroup Name -
- UserGroup Name - setSelectedUserGroup(e.target.value)} + defaultValue={selectedUserGroup} + > + {usergroups && usergroups.map((group: any) => ( + + ))} - -
+ + +
} + {usergroups?.length == 0 && +
+ No UserGroups available + Create a UserGroup +
}