diff --git a/src/plugin-slots/PageBannerSlot/Readme.md b/src/plugin-slots/PageBannerSlot/Readme.md new file mode 100644 index 000000000..234b76287 --- /dev/null +++ b/src/plugin-slots/PageBannerSlot/Readme.md @@ -0,0 +1,52 @@ +# Page Banner Slot + +### Slot ID: `org.openedx.frontend.authoring.page_banner.v1` + +### Slot ID Aliases +* `page_banner_slot` + +## Description + +This slot wraps the Paragon `PageBanner` component to allow plugins to replace, modify, or hide the banner shown on pages like Schedule & Details. By default, it renders the standard `PageBanner` with the provided props and children. + +## Example + +The following `env.config.jsx` example replaces the default banner message with a custom message. + +![Screenshot of Custom Page Banner](./screenshot_custom_banner_msg.png) + +```jsx +import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework'; + +const config = { + pluginSlots: { + 'org.openedx.frontend.authoring.page_banner.v1': { + plugins: [ + { + // Hide the default banner contents + op: PLUGIN_OPERATIONS.Hide, + widgetId: 'default_contents', + }, + { + // Insert a custom banner contents + op: PLUGIN_OPERATIONS.Insert, + widget: { + id: 'custom_page_banner_contents', + type: DIRECT_PLUGIN, + RenderWidget: () => ( + <> +

Custom Banner Title

+ + This message was injected via the PageBanner plugin slot. + + + ), + }, + }, + ], + }, + }, +}; + +export default config; +``` \ No newline at end of file diff --git a/src/plugin-slots/PageBannerSlot/index.tsx b/src/plugin-slots/PageBannerSlot/index.tsx new file mode 100644 index 000000000..fa4cfb9a3 --- /dev/null +++ b/src/plugin-slots/PageBannerSlot/index.tsx @@ -0,0 +1,37 @@ +import React, { ReactNode } from 'react'; +import { PluginSlot } from '@openedx/frontend-plugin-framework'; +import { PageBanner } from '@openedx/paragon'; + +export interface PageBannerSlotProps { + show: boolean; + onDismiss: () => void; + children: ReactNode; +} + +const PageBannerSlot: React.FC = ({ + show, + onDismiss, + children, +}) => ( + +
+ + {children} + +
+
+); + +export default PageBannerSlot; diff --git a/src/plugin-slots/PageBannerSlot/screenshot_custom_banner_msg.png b/src/plugin-slots/PageBannerSlot/screenshot_custom_banner_msg.png new file mode 100644 index 000000000..59ae560bf Binary files /dev/null and b/src/plugin-slots/PageBannerSlot/screenshot_custom_banner_msg.png differ diff --git a/src/schedule-and-details/basic-section/index.jsx b/src/schedule-and-details/basic-section/index.jsx index 57146d335..5e0f1fcf7 100644 --- a/src/schedule-and-details/basic-section/index.jsx +++ b/src/schedule-and-details/basic-section/index.jsx @@ -2,8 +2,9 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n'; import { - PageBanner, Button, Card, MailtoLink, Hyperlink, + Button, Card, MailtoLink, Hyperlink, } from '@openedx/paragon'; +import PageBannerSlot from '@src/plugin-slots/PageBannerSlot'; import { Email as EmailIcon } from '@openedx/paragon/icons'; import SectionSubHeader from '../../generic/section-sub-header'; @@ -78,17 +79,15 @@ const BasicSection = ({ ); const renderPageBanner = () => ( - setShowPageBanner(false)} - className="align-items-start" >

{intl.formatMessage(messages.basicBannerTitle, { platformName })}

{intl.formatMessage(messages.basicBannerText)} -
+ ); const renderCoursePromotion = () => (