diff --git a/apps/web/components/Contexts/CourseContext.tsx b/apps/web/components/Contexts/CourseContext.tsx
index a2f9f161..42c7c9bc 100644
--- a/apps/web/components/Contexts/CourseContext.tsx
+++ b/apps/web/components/Contexts/CourseContext.tsx
@@ -5,43 +5,40 @@ import React, { createContext, useContext, useEffect, useReducer } from 'react'
import useSWR from 'swr'
import { useLHSession } from '@components/Contexts/LHSessionContext'
-export const CourseContext = createContext(null) as any
-export const CourseDispatchContext = createContext(null) as any
+export const CourseContext = createContext(null)
+export const CourseDispatchContext = createContext(null)
-export function CourseProvider({
- children,
- courseuuid,
-}: {
- children: React.ReactNode
- courseuuid: string
-}) {
+export function CourseProvider({ children, courseuuid }: any) {
const session = useLHSession() as any;
const access_token = session?.data?.tokens?.access_token;
- const { data: courseStructureData } = useSWR(
- `${getAPIUrl()}courses/${courseuuid}/meta`,
- (url) => swrFetcher(url, access_token)
- )
- const [courseStructure, dispatchCourseStructure] = useReducer(courseReducer, {
- courseStructure: courseStructureData ? courseStructureData : {},
+
+ const { data: courseStructureData, error } = useSWR(
+ access_token ? `${getAPIUrl()}courses/${courseuuid}/meta` : null,
+ url => swrFetcher(url, access_token)
+ );
+
+ const initialState = {
+ courseStructure: {},
courseOrder: {},
isSaved: true,
- })
+ isLoading: true
+ };
+
+ const [state, dispatch] = useReducer(courseReducer, initialState) as any;
- // When courseStructureData is loaded, update the state
useEffect(() => {
if (courseStructureData) {
- dispatchCourseStructure({
- type: 'setCourseStructure',
- payload: courseStructureData,
- })
+ dispatch({ type: 'setCourseStructure', payload: courseStructureData });
+ dispatch({ type: 'setIsLoaded' });
}
- }, [courseStructureData,session])
+ }, [courseStructureData]);
- if (!courseStructureData) return
+ if (error) return
Failed to load course structure
;
+ if (!courseStructureData) return Loading...
;
return (
-
-
+
+
{children}
@@ -66,6 +63,8 @@ function courseReducer(state: any, action: any) {
return { ...state, isSaved: true }
case 'setIsNotSaved':
return { ...state, isSaved: false }
+ case 'setIsLoaded':
+ return { ...state, isLoading: false }
default:
throw new Error(`Unhandled action type: ${action.type}`)
}
diff --git a/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx b/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx
index 6cb3ab10..38ec8b3c 100644
--- a/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx
+++ b/apps/web/components/Dashboard/Course/EditCourseAccess/EditCourseAccess.tsx
@@ -21,9 +21,9 @@ function EditCourseAccess(props: EditCourseAccessProps) {
const session = useLHSession() as any;
const access_token = session?.data?.tokens?.access_token;
- const course = useCourse() as any
+ const course = useCourse() as any;
+ const { isLoading, courseStructure } = course as any;
const dispatchCourse = useCourseDispatch() as any
- const courseStructure = course.courseStructure
const { data: usergroups } = useSWR(
courseStructure ? `${getAPIUrl()}usergroups/resource/${courseStructure.course_uuid}` : null,
(url) => swrFetcher(url, access_token)
@@ -33,7 +33,7 @@ function EditCourseAccess(props: EditCourseAccessProps) {
React.useEffect(() => {
// This code will run whenever form values are updated
- if (isPublic !== courseStructure.public) {
+ if ((isPublic !== courseStructure.public) && isLoading) {
dispatchCourse({ type: 'setIsNotSaved' })
const updatedCourse = {
...courseStructure,
@@ -126,7 +126,7 @@ function UserGroupsSection({ usergroups }: { usergroups: 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)
+ 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}`)
diff --git a/apps/web/components/Dashboard/Course/EditCourseGeneral/EditCourseGeneral.tsx b/apps/web/components/Dashboard/Course/EditCourseGeneral/EditCourseGeneral.tsx
index 1f6d5ddc..8535fd83 100644
--- a/apps/web/components/Dashboard/Course/EditCourseGeneral/EditCourseGeneral.tsx
+++ b/apps/web/components/Dashboard/Course/EditCourseGeneral/EditCourseGeneral.tsx
@@ -3,13 +3,13 @@ import FormLayout, {
FormLabelAndMessage,
Input,
Textarea,
-} from '@components/StyledElements/Form/Form'
-import { useFormik } from 'formik'
-import { AlertTriangle } from 'lucide-react'
-import * as Form from '@radix-ui/react-form'
-import React from 'react'
-import { useCourse, useCourseDispatch } from '../../../Contexts/CourseContext'
-import ThumbnailUpdate from './ThumbnailUpdate'
+} from '@components/StyledElements/Form/Form';
+import { useFormik } from 'formik';
+import { AlertTriangle } from 'lucide-react';
+import * as Form from '@radix-ui/react-form';
+import React, { useEffect, useState } from 'react';
+import { useCourse, useCourseDispatch } from '../../../Contexts/CourseContext';
+import ThumbnailUpdate from './ThumbnailUpdate';
type EditCourseStructureProps = {
orgslug: string
@@ -17,74 +17,78 @@ type EditCourseStructureProps = {
}
const validate = (values: any) => {
- const errors: any = {}
+ const errors = {} as any;
if (!values.name) {
- errors.name = 'Required'
- }
-
- if (values.name.length > 100) {
- errors.name = 'Must be 100 characters or less'
+ errors.name = 'Required';
+ } else if (values.name.length > 100) {
+ errors.name = 'Must be 100 characters or less';
}
if (!values.description) {
- errors.description = 'Required'
- }
-
- if (values.description.length > 1000) {
- errors.description = 'Must be 1000 characters or less'
+ errors.description = 'Required';
+ } else if (values.description.length > 1000) {
+ errors.description = 'Must be 1000 characters or less';
}
if (!values.learnings) {
- errors.learnings = 'Required'
+ errors.learnings = 'Required';
}
- return errors
-}
+ return errors;
+};
function EditCourseGeneral(props: EditCourseStructureProps) {
- const [error, setError] = React.useState('')
- const course = useCourse() as any
- const dispatchCourse = useCourseDispatch() as any
+ const [error, setError] = useState('');
+ const course = useCourse();
+ const dispatchCourse = useCourseDispatch() as any;
+ const { isLoading, courseStructure } = course as any;
- const courseStructure = course.courseStructure
const formik = useFormik({
initialValues: {
- name: String(courseStructure.name),
- description: String(courseStructure.description),
- about: String(courseStructure.about),
- learnings: String(courseStructure.learnings),
- tags: String(courseStructure.tags),
- public: String(courseStructure.public),
+ name: courseStructure?.name || '',
+ description: courseStructure?.description || '',
+ about: courseStructure?.about || '',
+ learnings: courseStructure?.learnings || '',
+ tags: courseStructure?.tags || '',
+ public: courseStructure?.public || '',
},
validate,
- onSubmit: async (values) => {},
- enableReinitialize: true,
- })
-
- React.useEffect(() => {
- // This code will run whenever form values are updated
- if (formik.values !== formik.initialValues) {
- dispatchCourse({ type: 'setIsNotSaved' })
- const updatedCourse = {
- ...courseStructure,
- name: formik.values.name,
- description: formik.values.description,
- about: formik.values.about,
- learnings: formik.values.learnings,
- tags: formik.values.tags,
- public: formik.values.public,
+ onSubmit: async values => {
+ try {
+ // Add your submission logic here
+ dispatchCourse({ type: 'setIsSaved' });
+ } catch (e) {
+ setError('Failed to save course structure.');
+ }
+ },
+ enableReinitialize: true,
+ }) as any;
+
+ useEffect(() => {
+ if (!isLoading) {
+ const formikValues = formik.values as any;
+ const initialValues = formik.initialValues as any;
+ const valuesChanged = Object.keys(formikValues).some(
+ key => formikValues[key] !== initialValues[key]
+ );
+
+ if (valuesChanged) {
+ dispatchCourse({ type: 'setIsNotSaved' });
+ const updatedCourse = {
+ ...courseStructure,
+ ...formikValues,
+ };
+ dispatchCourse({ type: 'setCourseStructure', payload: updatedCourse });
}
- dispatchCourse({ type: 'setCourseStructure', payload: updatedCourse })
}
- }, [course, formik.values, formik.initialValues])
+ }, [formik.values, isLoading]);
return (
- {' '}
- {course.courseStructure && (
+ {courseStructure && (
- )
+ );
}
-export default EditCourseGeneral
+export default EditCourseGeneral;