Skip to content
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: course banner slot #559

Merged
merged 3 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ exports[`CourseCardBanners render with isEnrolled false 1`] = `
<RelatedProgramsBanner
cardId="test-card-id"
/>
<CourseBanner
<CourseBannerSlot
cardId="test-card-id"
/>
<EntitlementBanner
Expand All @@ -25,7 +25,7 @@ exports[`CourseCardBanners renders default CourseCardBanners 1`] = `
<RelatedProgramsBanner
cardId="test-card-id"
/>
<CourseBanner
<CourseBannerSlot
cardId="test-card-id"
/>
<EntitlementBanner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';

import { reduxHooks } from 'hooks';

import CourseBanner from './CourseBanner';
import CourseBannerSlot from 'plugin-slots/CourseBannerSlot';
import CertificateBanner from './CertificateBanner';
import CreditBanner from './CreditBanner';
import EntitlementBanner from './EntitlementBanner';
Expand All @@ -14,7 +14,7 @@ export const CourseCardBanners = ({ cardId }) => {
return (
<div className="course-card-banners" data-testid="CourseCardBanners">
<RelatedProgramsBanner cardId={cardId} />
<CourseBanner cardId={cardId} />
<CourseBannerSlot cardId={cardId} />
<EntitlementBanner cardId={cardId} />
{isEnrolled && <CertificateBanner cardId={cardId} />}
{isEnrolled && <CreditBanner cardId={cardId} />}
Expand Down
47 changes: 47 additions & 0 deletions src/plugin-slots/CourseBannerSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Course Card Action Slot

### Slot ID: `course_banner_slot`
### Props:
* `cardId`

## Description

This slot is used for replacing or adding content for the `CourseBanner` component. This banner is rendered as a child of the `CourseCard`.

The default CourseBanner looks like this when audit access has expired for the course:
![Screenshot of the default CourseBanner when audit access has expired](./images/course_banner_slot_default.png)

## Example

The following `env.config.jsx` will render a custom implemenation of a CourseBanner under every `CourseCard`.

![Screenshot of custom banner added under CourseCard](./images/course_banner_slot_default.png)

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

const config = {
pluginSlots: {
course_banner_slot: {
keepDefault: false,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_course_banner',
type: DIRECT_PLUGIN,
priority: 60,
RenderWidget: ({ cardId }) => (
<Alert variant="info" className="mb-0">
Course banner for course with {cardId}
</Alert>
),
},
},
],
},
},
}

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.
23 changes: 23 additions & 0 deletions src/plugin-slots/CourseBannerSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import CourseBanner from 'containers/CourseCard/components/CourseCardBanners/CourseBanner';

const CourseBannerSlot = ({ cardId }) => (
<PluginSlot
id="course_banner_slot"
pluginProps={{
cardId,
}}
>
<CourseBanner
cardId={cardId}
/>
</PluginSlot>
);

CourseBannerSlot.propTypes = {
cardId: PropTypes.string.isRequired,
};

export default CourseBannerSlot;