-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: implement the community/:slug/learning-module/:id page #1305
base: dev
Are you sure you want to change the base?
Conversation
WalkthroughWalkthroughThe changes encompass the creation of a new learning module page within the community structure, modifications to existing components to utilize a dynamic URL for navigation, and enhancements to data handling by consolidating props. The updates improve the routing and navigation experience for users interacting with learning modules, ensuring that relevant information is accessible through a more cohesive data structure. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant LearningModuleCard
participant Learning
participant LearningModulePage
User->>LearningModuleCard: Click on module card
LearningModuleCard->>Learning: Pass url and challenge data
Learning->>LearningModulePage: Navigate to module page
LearningModulePage->>User: Display learning module content
Assessment against linked issues
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
✅ Deploy Preview for staging-dacade ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Outside diff range, codebase verification and nitpick comments (5)
src/components/sections/challenges/Learning.tsx (1)
46-46
: Inconsistent URL structure detected; verify necessity ofchallenge.id
.The
LearningModuleCard
component uses different URL structures across the codebase. Insrc/components/sections/challenges/Learning.tsx
, the URL includeschallenge.id
, while insrc/components/sections/communities/overview/LearningMaterials.tsx
, it does not. Verify whether the inclusion ofchallenge.id
is necessary in all contexts to ensure consistent navigation behavior.
src/components/sections/challenges/Learning.tsx
: URL includeschallenge.id
.src/components/sections/communities/overview/LearningMaterials.tsx
: URL does not includechallenge.id
.Analysis chain
URL change approved; verify correctness.
The updated URL structure for
LearningModuleCard
is consistent with the new data handling approach. Verify that this URL correctly integrates with the application's routing and that thechallenge.id
is always available when this component is rendered.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the new URL structure is correctly implemented and integrated. # Test: Search for the `LearningModuleCard` URL usage. Expect: Only occurrences with the new URL structure. rg --type typescript -A 5 $'LearningModuleCard'Length of output: 81
Script:
#!/bin/bash # Description: Verify that the new URL structure is correctly implemented and integrated. # Test: Search for the `LearningModuleCard` URL usage. Expect: Only occurrences with the new URL structure. rg --type ts -A 5 $'LearningModuleCard'Length of output: 4317
src/components/cards/LearningModule.tsx (1)
Line range hint
18-69
: Suggestion: Handle emptycourses
array more elegantly.Consider using a more concise conditional rendering syntax for the
courses
array to improve code readability and reduce the use of fragments:- {courses.length ? - <p className="font-medium text-gray text-tertiary text-sm"> - {t('learning-module.course.other.appearances')} - {courses.map((course, index) => - <Fragment key={`related-course-${index}`}> - <Link - key={`other-appearance-course-${index}`} - href={`/communities/${community.slug}/courses/${course?.slug}`} - className="hover:underline ml-1">{course.name} - </Link> - {index !== courses.length - 1 && ","} - </Fragment> - )} - </p> - : - <></>} + {courses.length > 0 && ( + <p className="font-medium text-gray text-tertiary text-sm"> + {t('learning-module.course.other.appearances')} + {courses.map((course, index) => ( + <React.Fragment key={`related-course-${index}`}> + <Link + href={`/communities/${community.slug}/courses/${course?.slug}`} + className="hover:underline ml-1">{course.name} + </Link> + {index !== courses.length - 1 && ","} + </React.Fragment> + ))} + </p> + )}src/pages/communities/[slug]/learning-modules/[id].tsx (1)
1-17
: Documentation Review and Missing File AlertThe codebase is generally well-documented, but there are a few areas that need attention:
Missing Documentation: The following files do not contain JSDoc comments:
src/components/sections/learning-modules/index.tsx
src/hooks/useTypedDispatch.ts
src/hooks/useTypedSelector.ts
Missing File: The file
src/hooks/useNavigation.ts
was not found. Please verify its presence or correct the path if there is a typo.Please ensure that documentation is added to the files where it is missing and verify the existence of the
useNavigation
hook file.Analysis chain
Review of Imports and Initial Setup
The imports and initial setup look well-organized and adhere to the project's structure. The use of custom hooks and components suggests good modularity and reusability. However, ensure that all these components and hooks are properly documented, especially since they are part of a new feature implementation.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Verify that all imported components and hooks have corresponding documentation. # Check for documentation in component files. fd --type f --exec rg --files-with-matches 'Documentation|Comments' {} \;Length of output: 78
Script:
#!/bin/bash # Search for common documentation patterns like JSDoc comments in the imported component and hook files. # Define a pattern for JSDoc comments. JSDOC_PATTERN='\/\*\*' # Search for JSDoc comments in the component and hook files. fd --type f --exec rg --files-with-matches "$JSDOC_PATTERN" {} \;Length of output: 48559
Script:
#!/bin/bash # Search for common documentation patterns like JSDoc comments in the imported component and hook files. # Define a simpler pattern for JSDoc comments. JSDOC_PATTERN='\/\*\*' # Search for JSDoc comments in the component and hook files using a simpler pattern. fd --type f --exec rg --files-with-matches '/\*\*' {} \;Length of output: 14026
Script:
#!/bin/bash # Check for JSDoc comments specifically in the files corresponding to the imports in the file under review. # List of specific files to check based on imports. files_to_check=( "src/components/layout/Default.tsx" "src/components/sections/courses/PageNavigation.tsx" "src/components/sections/courses/Wrapper.tsx" "src/components/sections/learning-modules/index.tsx" "src/components/sections/learning-modules/Header.tsx" "src/hooks/useNavigation.ts" "src/hooks/useTypedDispatch.ts" "src/hooks/useTypedSelector.ts" "src/store/feature/communities/navigation.slice.ts" "src/store/services/community.service.ts" "src/store/services/learningModules.service.ts" "src/utilities/errors/NotFoundError.ts" ) # Search for JSDoc comments in the specified files. for file in "${files_to_check[@]}"; do echo "Checking $file for JSDoc comments:" rg '/\*\*' "$file" || echo "No JSDoc comments found in $file" doneLength of output: 4179
src/types/course.d.ts (1)
179-179
: Approval of the newchallenges
property addition.The addition of the
challenges
property to theLearningModule
type is well-implemented and aligns with the objectives of enhancing learning modules with challenges. The use of an optional array is appropriate for flexibility.Consider adding a brief comment above the
challenges
property to describe its usage or purpose, enhancing maintainability and readability for future developers.src/utilities/CommunityNavigation.ts (1)
118-128
: Review ofsingleLearningModulePath
method.This method correctly constructs a URL for a single learning module using the community slug. The use of
cleanupUrl
ensures that the URL is sanitized, removing any trailing slashes, which is good practice for URL construction.However, the method's documentation could be improved to include more details about the parameters and expected behavior, especially considering the optional nature of the
communitySlug
parameter.Consider enhancing the documentation for this method to provide clearer guidance on how the parameters are used and the importance of the optional
communitySlug
./** * Path for a single learning module from the community found at communities/:slug/learning-module/:id * * @param {string} path - The ID of the learning module. * @param {(string | undefined)} [communitySlug=this.params().slug] - Optional community slug, defaults to the current community slug from the router's parameters. * @returns {string} - The sanitized URL path to the learning module. */
Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Files selected for processing (8)
- src/components/cards/LearningModule.tsx (2 hunks)
- src/components/sections/challenges/Learning.tsx (3 hunks)
- src/components/sections/communities/overview/LearningMaterials.tsx (1 hunks)
- src/pages/communities/[slug]/challenges/[challenge_id]/index.tsx (1 hunks)
- src/pages/communities/[slug]/learning-modules/[id].tsx (1 hunks)
- src/store/feature/communities/navigation.slice.ts (2 hunks)
- src/types/course.d.ts (1 hunks)
- src/utilities/CommunityNavigation.ts (3 hunks)
Additional comments not posted (11)
src/components/sections/challenges/Learning.tsx (1)
14-14
: Prop change approved; verify integration.The change in props simplifies data handling and improves the structure. Ensure that this change is well integrated with the rest of the application.
src/components/sections/communities/overview/LearningMaterials.tsx (3)
Line range hint
1-11
: Imports and setup are correctly configured.The imports and initial setup of the component are appropriate for its functionality.
Line range hint
12-52
: State management and loading state handling are well-implemented.The use of
useMultiSelector
to fetch data and the conditional rendering based on theloading
state are correctly implemented, ensuring a smooth user experience.
53-53
: Dynamic URL generation enhances navigation.The addition of the
url
prop to theLearningModuleCard
component is a significant improvement. It allows users to navigate directly to the specific learning module, which aligns with the PR objectives to enhance user navigation.src/components/cards/LearningModule.tsx (3)
18-18
: Approved: Function signature update.The update to the function signature to include a
url
prop enhances flexibility and decouples the component from specific data dependencies.
69-69
: Approved: Use ofurl
prop for navigation.The direct use of the
url
prop in theLink
component for navigation is a clean and effective way to handle dynamic URLs, promoting better maintainability and flexibility of the component.
Line range hint
18-69
: Verify: Integration ofurl
prop across the application.Ensure that the
url
prop is correctly integrated and utilized across the application, especially in places whereLearningModuleCard
is used. This is crucial to maintain consistency and functionality throughout the application.Run the following script to verify the integration of the
url
prop:Verification successful
Verification Successful: Integration of
url
prop is correct.The
url
prop is consistently and correctly passed toLearningModuleCard
in the application, using dynamic values relevant to the context. This ensures proper functionality and consistency.
- Instances show
url
being constructed withcommunity.slug
,module.id
, and other relevant identifiers.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the integration of the `url` prop across the application. # Test: Search for the usage of `LearningModuleCard`. Expect: Proper passing of the `url` prop. rg --type tsx -A 5 $'LearningModuleCard'Length of output: 67
Script:
#!/bin/bash # Find all .tsx files and search for the usage of LearningModuleCard to verify the integration of the `url` prop. fd --extension tsx --exec rg 'LearningModuleCard' {}Length of output: 550
Script:
#!/bin/bash # Search for the usage of LearningModuleCard with extended context lines to verify the integration of the `url` prop. fd --extension tsx --exec rg 'LearningModuleCard' -A 10 -B 2 {}Length of output: 3441
src/pages/communities/[slug]/learning-modules/[id].tsx (1)
54-56
: Review of getLayout MethodThe
getLayout
method correctly wraps the page component with theDefaultLayout
, providing a consistent layout structure across the application. This method is crucial for maintaining layout consistency and should be checked to ensure it aligns with the overall layout strategy of the application.The implementation of the
getLayout
method is consistent with the application's layout strategy and is approved.src/store/feature/communities/navigation.slice.ts (1)
3-3
: Approved import changes.The addition of
LearningModule
is necessary for the new navigation functionality related to learning modules.src/pages/communities/[slug]/challenges/[challenge_id]/index.tsx (1)
133-133
: Verify the changes in theLearning
component's props.The modification to pass the entire
challenge
object along with thecommunity
prop to theLearning
component is a significant change. This approach simplifies data handling and reduces prop drilling but requires careful integration:
- Ensure that the
Learning
component has been updated to handle the new prop structure effectively.- Check for other usages of the
Learning
component throughout the application to ensure that this change does not break existing functionality.Run the following script to verify the usage of the
Learning
component across the application:src/utilities/CommunityNavigation.ts (1)
2-2
: Review of new import statement.The import of
LearningModule
from "@/types/course" is appropriate and necessary for the new functionalities introduced in this class. This aligns with the PR's objective to enhance navigation for learning modules.
const courses = challenge?.courses | ||
const learningModules = challenge?.learningModules |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic change approved; handle potential null cases.
The logic to derive courses
and learningModules
from the challenge
prop is correct. Consider adding checks or default values to handle cases where challenge
might be null or undefined to prevent runtime errors.
- const courses = challenge?.courses
- const learningModules = challenge?.learningModules
+ const courses = challenge?.courses || []
+ const learningModules = challenge?.learningModules || []
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const courses = challenge?.courses | |
const learningModules = challenge?.learningModules | |
const courses = challenge?.courses || [] | |
const learningModules = challenge?.learningModules || [] |
interface LearningModuleMultiselector { | ||
learningModule: LearningModule, | ||
loading: boolean | ||
} | ||
|
||
export default function LearningModulePage(): ReactElement { | ||
const dispatch = useDispatch(); | ||
const navigation = useNavigation() | ||
const { learningModule } = useMultiSelector<unknown, LearningModuleMultiselector>({ | ||
learningModule: (state: IRootState) => state.learningModules.current, | ||
loading: (state: IRootState) => state.learningModules.loading | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of Interface and MultiSelector Usage
The LearningModuleMultiselector
interface is well-defined, providing clear typing for the state management. The use of useMultiSelector
is appropriate for selecting multiple pieces of state. However, ensure that the generic type <unknown>
is replaced with a more specific type if possible to enhance type safety.
Consider specifying a more accurate type than unknown
for better type safety and clarity in the useMultiSelector
hook usage.
const router = useRouter() | ||
const { query, locale } = router | ||
const paths = useMemo(() => [learningModule?.title], [learningModule?.title]); | ||
|
||
useEffect(() => { | ||
dispatch(initLearningModuleNavigationMenu(navigation.community)); | ||
dispatch(findLearningModule({ id: query?.id as string, locale })) | ||
}, [dispatch, locale]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of useEffect Hook Implementation
The useEffect
hook is used effectively to dispatch actions for initializing navigation and fetching the learning module based on the router's query parameters. This is a critical part of the page's functionality, ensuring that the necessary data is loaded when the component mounts. However, the dependency array includes locale
but not navigation.community
or query.id
, which might lead to bugs if these values change and the component does not re-fetch the data.
Add navigation.community
and query.id
to the dependency array of the useEffect
hook to ensure that the component reacts appropriately to changes in these values.
return ( | ||
<Wrapper paths={paths}> | ||
<div className="py-8 flex flex-col space-y-8 text-gray-700"> | ||
<Header /> | ||
<div className="w-full"> | ||
<LearningModuleSection learningModule={learningModule} /> | ||
<PageNavigation /> | ||
</div> | ||
</div> | ||
</Wrapper> | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of Component Rendering Logic
The rendering logic uses the Wrapper
and LearningModuleSection
components effectively, passing the necessary props. The use of dynamic paths for the Wrapper
component based on the learning module's title is a good touch for dynamic navigation. However, ensure that there is error handling in case learningModule
is null or undefined to prevent runtime errors.
Implement error handling for the learningModule
prop to ensure the component handles cases where the learning module data is not available.
export const getServerSideProps = wrapper.getServerSideProps((store) => async ({ params, locale }) => { | ||
|
||
const learningModuleId = params?.id as string | ||
try { | ||
const communitySlug = params?.slug as string; | ||
const [{ data: community }, { data: learningModule }, translations] = await Promise.all([ | ||
store.dispatch(fetchCurrentCommunity({ slug: communitySlug, locale })), | ||
store.dispatch(findLearningModule({ id: learningModuleId, locale })), | ||
serverSideTranslations(locale as string), | ||
]); | ||
if (!community || !learningModule) throw new NotFoundError(); | ||
return { | ||
props: { | ||
community, | ||
learningModule, | ||
...translations, | ||
}, | ||
}; | ||
} catch (error) { | ||
return { | ||
notFound: true, | ||
}; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of getServerSideProps Function
The getServerSideProps
function is well-implemented, fetching necessary data for the community and learning module based on URL parameters. The use of Promise.all
for concurrent data fetching is efficient. However, the error handling could be improved by logging the error or sending it to a monitoring service to aid in debugging and maintaining the application.
Enhance error handling in the getServerSideProps
function by logging the error or integrating with a monitoring service.
export const initLearningModuleNavigationMenu = (navigation: any) => (dispatch: Dispatch, getState: any) => { | ||
dispatch(setNavigationList([])) | ||
const community = getState().communities.current as Community; | ||
const learningModule = getState().learningModules.current as LearningModule | ||
const menus: List[] = navigation.initForLearningModule({ | ||
community, | ||
learningModule | ||
}) | ||
dispatch(setNavigationList(menus)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest improvements for error handling and type safety.
The function initLearningModuleNavigationMenu
effectively initializes the navigation for learning modules. However, it could be improved by:
- Adding error handling for cases where
community
orlearningModule
might be undefined. - Ensuring type safety rather than using type assertions, which could lead to runtime errors if the assumptions are incorrect.
Consider adding checks and throwing appropriate errors if the required data is not available.
|
||
initForLearningModule({ community, learningModule }: { community: Community; learningModule: LearningModule }): List[] { | ||
|
||
const learningModuleNavigationMenuList: List[] = [ | ||
{ | ||
id: "introduction", | ||
title: "Introduction", | ||
hideTitle: true, | ||
items: [ | ||
{ | ||
label: "communities.navigation.overview", | ||
exact: true, | ||
link: "", | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
const modules = { | ||
id: "learning-modules", | ||
title: "communities.navigation.learning-modules", | ||
hideTitle: false, | ||
items: [{ | ||
id: learningModule.id, | ||
label: `item ${learningModule.title}`, | ||
link: this.singleLearningModulePath(learningModule.id, community?.slug), | ||
exact: false, | ||
subitems: [] | ||
}], | ||
}; | ||
|
||
const challenges = | ||
learningModule?.challenges?.map((challenge) => { | ||
return { | ||
id: challenge?.id, | ||
label: challenge.name, | ||
link: this.challengePath(challenge?.id, community.slug), | ||
exact: false, | ||
}; | ||
}) || []; | ||
|
||
const courses = learningModule?.courses?.map((course) => { | ||
return { | ||
id: course?.id, | ||
label: course.name, | ||
link: this.coursePath("", course.slug, community?.slug), | ||
exact: false, | ||
}; | ||
}) || []; | ||
|
||
learningModuleNavigationMenuList.push(modules) | ||
|
||
// Add connected challenges | ||
if (challenges.length) { | ||
learningModuleNavigationMenuList.push({ | ||
id: "challenges", | ||
title: "communities.navigation.challenge", | ||
items: challenges, | ||
}); | ||
} | ||
|
||
// Add related courses | ||
if (courses.length) { | ||
learningModuleNavigationMenuList.push({ | ||
id: "courses", | ||
title: "communities.overview.courses.title", | ||
items: courses, | ||
}); | ||
} | ||
|
||
return learningModuleNavigationMenuList | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of initForLearningModule
method.
This method effectively initializes a navigation structure for a learning module, incorporating links to related challenges and courses. The use of singleLearningModulePath
within this method ensures consistency in link generation.
However, there are a few areas for improvement:
- The method lacks detailed documentation, which is crucial for understanding its purpose and usage.
- The method constructs a navigation menu but does not handle potential null values gracefully in the destructuring of
community
andlearningModule
. This could lead to runtime errors if either is undefined.
- Enhance the method documentation to clearly describe its functionality and parameters.
- Implement null checks for
community
andlearningModule
to prevent potential runtime errors.
/**
* Initializes navigation for a specific learning module within a community.
* Constructs a navigation menu with links to the learning module, associated challenges, and related courses.
*
* @param {{ community: Community; learningModule: LearningModule }} { community, learningModule } - The community and learning module for which to initialize navigation.
* @returns {List[]} - A list of navigation items structured for the learning module page.
*/
initForLearningModule({ community, learningModule }: { community: Community; learningModule: LearningModule }): List[] {
+ if (!community || !learningModule) {
+ throw new Error("Community and learning module must be provided.");
+ }
const learningModuleNavigationMenuList: List[] = [
{
id: "introduction",
title: "Introduction",
hideTitle: true,
items: [
{
label: "communities.navigation.overview",
exact: true,
link: "",
},
],
},
];
// Remaining implementation...
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
initForLearningModule({ community, learningModule }: { community: Community; learningModule: LearningModule }): List[] { | |
const learningModuleNavigationMenuList: List[] = [ | |
{ | |
id: "introduction", | |
title: "Introduction", | |
hideTitle: true, | |
items: [ | |
{ | |
label: "communities.navigation.overview", | |
exact: true, | |
link: "", | |
}, | |
], | |
}, | |
]; | |
const modules = { | |
id: "learning-modules", | |
title: "communities.navigation.learning-modules", | |
hideTitle: false, | |
items: [{ | |
id: learningModule.id, | |
label: `item ${learningModule.title}`, | |
link: this.singleLearningModulePath(learningModule.id, community?.slug), | |
exact: false, | |
subitems: [] | |
}], | |
}; | |
const challenges = | |
learningModule?.challenges?.map((challenge) => { | |
return { | |
id: challenge?.id, | |
label: challenge.name, | |
link: this.challengePath(challenge?.id, community.slug), | |
exact: false, | |
}; | |
}) || []; | |
const courses = learningModule?.courses?.map((course) => { | |
return { | |
id: course?.id, | |
label: course.name, | |
link: this.coursePath("", course.slug, community?.slug), | |
exact: false, | |
}; | |
}) || []; | |
learningModuleNavigationMenuList.push(modules) | |
// Add connected challenges | |
if (challenges.length) { | |
learningModuleNavigationMenuList.push({ | |
id: "challenges", | |
title: "communities.navigation.challenge", | |
items: challenges, | |
}); | |
} | |
// Add related courses | |
if (courses.length) { | |
learningModuleNavigationMenuList.push({ | |
id: "courses", | |
title: "communities.overview.courses.title", | |
items: courses, | |
}); | |
} | |
return learningModuleNavigationMenuList | |
} | |
/** | |
* Initializes navigation for a specific learning module within a community. | |
* Constructs a navigation menu with links to the learning module, associated challenges, and related courses. | |
* | |
* @param {{ community: Community; learningModule: LearningModule }} { community, learningModule } - The community and learning module for which to initialize navigation. | |
* @returns {List[]} - A list of navigation items structured for the learning module page. | |
*/ | |
initForLearningModule({ community, learningModule }: { community: Community; learningModule: LearningModule }): List[] { | |
if (!community || !learningModule) { | |
throw new Error("Community and learning module must be provided."); | |
} | |
const learningModuleNavigationMenuList: List[] = [ | |
{ | |
id: "introduction", | |
title: "Introduction", | |
hideTitle: true, | |
items: [ | |
{ | |
label: "communities.navigation.overview", | |
exact: true, | |
link: "", | |
}, | |
], | |
}, | |
]; | |
const modules = { | |
id: "learning-modules", | |
title: "communities.navigation.learning-modules", | |
hideTitle: false, | |
items: [{ | |
id: learningModule.id, | |
label: `item ${learningModule.title}`, | |
link: this.singleLearningModulePath(learningModule.id, community?.slug), | |
exact: false, | |
subitems: [] | |
}], | |
}; | |
const challenges = | |
learningModule?.challenges?.map((challenge) => { | |
return { | |
id: challenge?.id, | |
label: challenge.name, | |
link: this.challengePath(challenge?.id, community.slug), | |
exact: false, | |
}; | |
}) || []; | |
const courses = learningModule?.courses?.map((course) => { | |
return { | |
id: course?.id, | |
label: course.name, | |
link: this.coursePath("", course.slug, community?.slug), | |
exact: false, | |
}; | |
}) || []; | |
learningModuleNavigationMenuList.push(modules) | |
// Add connected challenges | |
if (challenges.length) { | |
learningModuleNavigationMenuList.push({ | |
id: "challenges", | |
title: "communities.navigation.challenge", | |
items: challenges, | |
}); | |
} | |
// Add related courses | |
if (courses.length) { | |
learningModuleNavigationMenuList.push({ | |
id: "courses", | |
title: "communities.overview.courses.title", | |
items: courses, | |
}); | |
} | |
return learningModuleNavigationMenuList | |
} |
Submit a pull request
Replace any ":question:" below with information about your pull request.
Pull Request Details
The PR aims to create a new learning module page from the community slug area
Breaking Changes
Creation of a new learning module page
Issues Fixed