Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions src/course-about/CourseAboutPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { Loading } from '@src/generic';
import CourseAboutIntroSlot from '@src/plugin-slots/CourseAboutIntroSlot';
import CourseAboutCourseMediaSlot from '@src/plugin-slots/CourseAboutCourseMediaSlot';
import CourseAboutOverviewSlot from '@src/plugin-slots/CourseAboutOverviewSlot';
import CourseAboutSidebarSlot from '@src/plugin-slots/CourseAboutSidebarSlot';
import { useCourseAboutData } from './data/hooks';
import CourseSidebar from './course-sidebar/CourseSidebar';
import messages from './messages';
import { GRID_LAYOUT } from './layout';

Expand Down Expand Up @@ -57,9 +57,7 @@ const CourseAboutPage = () => {
overviewData={courseAboutData.overview}
courseId={courseId}
/>
<aside>
<CourseSidebar courseAboutData={courseAboutData} />
</aside>
<CourseAboutSidebarSlot courseAboutData={courseAboutData} />
</Stack>
) : (
<Stack gap={4}>
Expand All @@ -77,9 +75,7 @@ const CourseAboutPage = () => {
<Layout.Element className="course-media-wrapper">
<CourseAboutCourseMediaSlot courseAboutData={courseAboutData} />
</Layout.Element>
<aside>
<CourseSidebar courseAboutData={courseAboutData} />
</aside>
<CourseAboutSidebarSlot courseAboutData={courseAboutData} />
</Stack>
)}
</Layout.Element>
Expand Down
133 changes: 133 additions & 0 deletions src/plugin-slots/CourseAboutSidebarSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Course about page sidebar slot

### Slot ID: `org.openedx.frontend.catalog.course_about_page.sidebar`

## Description

This slot is used to replace/modify/hide the entire Course about page sidebar.

### Plugin Props:

* `courseAboutData` - Object. The course about page data object containing course information such as id, name, start/end dates, enrollment details, media, pricing, prerequisites, and other course metadata.

## Examples

### Default content

![Course about page sidebar slot with default content](./images/screenshot_default.png)

### Replaced with custom component

![🦶 in Course about page sidebar slot](./images/screenshot_custom.png)

The following `env.config.tsx` will replace the Course about page sidebar entirely (in this case with a centered `h1` tag)

```tsx
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
'org.openedx.frontend.catalog.course_about_page.sidebar': {
keepDefault: false,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_course_about_page_sidebar_component',
type: DIRECT_PLUGIN,
RenderWidget: () => (
<h1 style={{textAlign: 'center'}}>🦶</h1>
),
},
},
]
}
},
}

export default config;
```

### Custom component with plugin props

![Custom sidebar component with course information in Course about page sidebar slot](./images/screenshot_custom_simplified_sidebar.png)

The following `env.config.tsx` example demonstrates how to replace the Course about page sidebar slot with a custom component that uses the plugin props (`courseAboutData`). In this case, it creates a custom sidebar component that displays key course information in a simplified format with badges and highlights.

```tsx
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
import { Card, Badge, Stack, Chip } from '@openedx/paragon';

const config = {
pluginSlots: {
'org.openedx.frontend.catalog.course_about_page.sidebar': {
keepDefault: false,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_course_about_page_sidebar_component',
type: DIRECT_PLUGIN,
RenderWidget: ({ courseAboutData }) => {
if (!courseAboutData) {
return null;
}

return (
<Card>
<Card.Section>
<Stack gap={3}>
<div>
<h4>{courseAboutData.name}</h4>
<p className="text-muted small">
{courseAboutData.displayOrgWithDefault}/{courseAboutData.displayNumberWithDefault}
</p>
</div>

{courseAboutData.effort && (
<Stack direction="horizontal" gap={2}>
<strong>Effort:</strong> {courseAboutData.effort}
</Stack>
)}

{courseAboutData.pacing && (
<Stack direction="horizontal" gap={2}>
<strong>Pacing:</strong> <Badge>{courseAboutData.pacing}</Badge>
</Stack>
)}

{courseAboutData.language && (
<Stack direction="horizontal" gap={2}>
<strong>Language:</strong> <Chip>{courseAboutData.language}</Chip>
</Stack>
)}

{courseAboutData.start && (
<Stack direction="horizontal" gap={2}>
<strong>Start Date:</strong> {courseAboutData.startDisplay || courseAboutData.start}
</Stack>
)}

{courseAboutData.coursePrice && (
<Stack direction="horizontal" gap={2}>
<strong>Price:</strong> <Badge variant="success">{courseAboutData.coursePrice}</Badge>
</Stack>
)}

{courseAboutData.canEnroll && (
<Badge>Enrollment Available</Badge>
)}
</Stack>
</Card.Section>
</Card>
);
},
},
},
]
}
},
}

export default config;
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/plugin-slots/CourseAboutSidebarSlot/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PluginSlot } from '@openedx/frontend-plugin-framework';

import CourseSidebar from '@src/course-about/course-sidebar/CourseSidebar';
import type { CourseAboutData } from '@src/course-about/types';

const CourseAboutSidebarSlot = ({ courseAboutData }: { courseAboutData: CourseAboutData }) => (
<PluginSlot
id="org.openedx.frontend.catalog.course_about_page.sidebar"
slotOptions={{
mergeProps: true,
}}
pluginProps={{ courseAboutData }}
>
<aside>
<CourseSidebar courseAboutData={courseAboutData} />
</aside>
</PluginSlot>
);

export default CourseAboutSidebarSlot;
1 change: 1 addition & 0 deletions src/plugin-slots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
* [`org.openedx.frontend.catalog.course_about_page.intro_video_modal`](./CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalSlot/)
* [`org.openedx.frontend.catalog.course_about_page.course_image`](./CourseAboutCourseImageSlot/)
* [`org.openedx.frontend.catalog.course_about_page.course_media`](./CourseAboutCourseMediaSlot/)
* [`org.openedx.frontend.catalog.course_about_page.sidebar`](./CourseAboutSidebarSlot/)