Skip to content

Commit

Permalink
feat: add sitewidebanner to publisher (#993)
Browse files Browse the repository at this point in the history
  • Loading branch information
AfaqShuaib09 authored Dec 20, 2024
1 parent db74a23 commit 4a6684f
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 5 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ NEW_RELIC_APP_ID=null
NEW_RELIC_LICENSE_KEY=null
APP_ID=''
MFE_CONFIG_API_URL=''
SITEWIDE_BANNER_CONTENT = ""
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ ADDITIONAL_METADATA_REQUIRED_FIELDS='{}'
IS_NEW_SLUG_FORMAT_ENABLED='false'
MARKETING_SITE_PREVIEW_URL_ROOT=''
COURSE_URL_SLUGS_PATTERN = '{}'
SITEWIDE_BANNER_CONTENT = ""
8 changes: 5 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@
"@edx/frontend-component-footer": "npm:@edx/frontend-component-footer-edx@^7.1.0",
"@edx/frontend-platform": "^8.0.0",
"@edx/openedx-atlas": "^0.6.0",
"@openedx/paragon": "^21.11.3",
"@edx/tinymce-language-selector": "1.1.0",
"@fortawesome/free-regular-svg-icons": "6.6.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@fortawesome/react-fontawesome": "0.2.2",
"@openedx/paragon": "^21.11.3",
"@tinymce/tinymce-react": "3.9.0",
"classnames": "2.5.1",
"core-js": "3.38.1",
"fast-json-stable-stringify": "2.1.0",
"font-awesome": "4.7.0",
"history": "4.10.1",
"js-cookie": "^3.0.5",
"jsx-to-string": "1.4.0",
"moment": "2.30.1",
"moment-timezone": "0.5.45",
Expand All @@ -46,6 +47,7 @@
"react": "^17.0.2",
"react-autosuggest": "10.1.0",
"react-beautiful-dnd": "13.1.1",
"react-bootstrap": "^1.6.5",
"react-copy-to-clipboard": "5.1.0",
"react-dom": "^17.0.2",
"react-helmet": "6.1.0",
Expand All @@ -64,8 +66,8 @@
},
"devDependencies": {
"@edx/browserslist-config": "^1.2.0",
"@openedx/frontend-build": "^14.0.14",
"@edx/stylelint-config-edx": "^2.3.0",
"@openedx/frontend-build": "^14.0.14",
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"axios": "0.27.2",
"axios-mock-adapter": "1.22.0",
Expand Down
54 changes: 54 additions & 0 deletions src/components/SitewideBanner/SitewideBanner.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { shallow } from 'enzyme';
import Cookies from 'js-cookie';
import { Alert } from 'react-bootstrap';
import SitewideBanner from './index';

describe('SitewideBanner', () => {
it('renders correctly when visible', () => {
const wrapper = shallow(
<SitewideBanner
message="Dummy Message"
type="success"
dismissible
cookieName="bannerCookie"
cookieExpiryDays={7}
/>,
);

expect(wrapper.find(Alert).props().variant).toBe('success');
expect(wrapper.find(Alert).props().dismissible).toBe(true);
const alertContent = wrapper.find(Alert)
.dive()
.find('div')
.first()
.html();
expect(alertContent).toContain('Dummy Message');
});

it('calls handleDismiss and sets cookie when dismissed', () => {
const setCookieMock = jest.spyOn(Cookies, 'set');
const wrapper = shallow(
<SitewideBanner
message="This is a test message"
type="warning"
dismissible
cookieName="bannerCookie"
cookieExpiryDays={7}
/>,
);
wrapper.find(Alert).simulate('close');
expect(wrapper.isEmptyRender()).toBe(true);
expect(setCookieMock).toHaveBeenCalledWith('bannerCookie', 'true', {
expires: 7,
});
setCookieMock.mockRestore();
});

it('handles non-dismissible banner correctly', () => {
const wrapper = shallow(
<SitewideBanner message="Non-dismissible message" dismissible={false} />,
);
expect(wrapper.find(Alert).props().dismissible).toBe(false);
});
});
59 changes: 59 additions & 0 deletions src/components/SitewideBanner/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Cookies from 'js-cookie';
import {
Alert, Container,
} from 'react-bootstrap';

const SitewideBanner = ({
message, type, dismissible, cookieName, cookieExpiryDays,
}) => {
const [isVisible, setIsVisible] = useState(true);

useEffect(() => {
if (cookieName && Cookies.get(cookieName)) {
setIsVisible(false);
}
}, [cookieName]);

const handleDismiss = () => {
setIsVisible(false);
if (cookieName) {
Cookies.set(cookieName, 'true', { expires: cookieExpiryDays });
}
};

if (isVisible) {
return (
<Alert
variant={type}
dismissible={dismissible}
onClose={handleDismiss}
className="mb-4"
>
<Container>
<div dangerouslySetInnerHTML={{ __html: message }} />

Check warning on line 35 in src/components/SitewideBanner/index.jsx

View workflow job for this annotation

GitHub Actions / tests

Dangerous property 'dangerouslySetInnerHTML' found
</Container>
</Alert>
);
} else { // eslint-disable-line no-else-return
return null;
}
};

SitewideBanner.propTypes = {
message: PropTypes.string.isRequired,
type: PropTypes.oneOf(['primary', 'success', 'warning', 'danger', 'info', 'secondary', 'light', 'dark']),
dismissible: PropTypes.bool,
cookieName: PropTypes.string,
cookieExpiryDays: PropTypes.number,
};

SitewideBanner.defaultProps = {
type: 'info',
dismissible: false,
cookieName: null,
cookieExpiryDays: 7,
};

export default SitewideBanner;
8 changes: 8 additions & 0 deletions src/containers/MainApp/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@ import EditStaffer from '../EditStaffer';
import CreateCollaborator from '../CreateCollaborator';
import EditCollaborator from '../EditCollaborator';
import EditCourse from '../EditCourse';
import SitewideBanner from '../../components/SitewideBanner';

const MainApp = () => (
<div>
<Header />
<SitewideBanner
message={process.env.SITEWIDE_BANNER_CONTENT || ''}
type="warning"
dismissible
cookieName="publisherSiteWideBannerDismissed"
cookieExpiryDays={30}
/>
<main>
<Routes>
<Route path="/course-runs/:courseRunKey" element={<CourseRunRedirectComponent />} />
Expand Down

0 comments on commit 4a6684f

Please sign in to comment.