Skip to content

Commit

Permalink
feat: added notification preferences settings at account level
Browse files Browse the repository at this point in the history
  • Loading branch information
awais-ansari committed Nov 14, 2024
1 parent 45bcfdd commit 27c686f
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 278 deletions.
9 changes: 6 additions & 3 deletions src/account-settings/AccountSettingsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
} from './data/constants';
import { fetchSiteLanguages } from './site-language';
import { fetchCourseList } from '../notification-preferences/data/thunks';
import NotificationSettings from '../notification-preferences/NotificationSettings';
import { withLocation, withNavigate } from './hoc';

class AccountSettingsPage extends React.Component {
Expand Down Expand Up @@ -727,7 +728,7 @@ class AccountSettingsPage extends React.Component {
{...editableFieldProps}
/>
</div>
<div className="account-section pt-3 mb-5" id="social-media">
<div className="account-section pt-3" id="social-media">
<h2 className="section-heading h4 mb-3">
{this.props.intl.formatMessage(messages['account.settings.section.social.media'])}
</h2>
Expand Down Expand Up @@ -763,8 +764,10 @@ class AccountSettingsPage extends React.Component {
{...editableFieldProps}
/>
</div>

<div className="account-section pt-3 mb-5" id="site-preferences" ref={this.navLinkRefs['#site-preferences']}>
<div className="border border-light-700 my-6" />
<NotificationSettings />
<div className="border border-light-700 my-6" />
<div className="account-section mb-5" id="site-preferences" ref={this.navLinkRefs['#site-preferences']}>
<h2 className="section-heading h4 mb-3">
{this.props.intl.formatMessage(messages['account.settings.section.site.preferences'])}
</h2>
Expand Down
22 changes: 1 addition & 21 deletions src/account-settings/JumpNav.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { breakpoints, useWindowSize, Icon } from '@openedx/paragon';
import { OpenInNew } from '@openedx/paragon/icons';
import { breakpoints, useWindowSize } from '@openedx/paragon';
import classNames from 'classnames';
import React from 'react';
import { useSelector } from 'react-redux';
import { NavHashLink } from 'react-router-hash-link';
import Scrollspy from 'react-scrollspy';
import { Link } from 'react-router-dom';
import messages from './AccountSettingsPage.messages';
import { selectShowPreferences } from '../notification-preferences/data/selectors';

const JumpNav = ({
intl,
}) => {
const stickToTop = useWindowSize().width > breakpoints.small.minWidth;
const showPreferences = useSelector(selectShowPreferences());

return (
<div className={classNames('jump-nav px-2.25', { 'jump-nav-sm position-sticky pt-3': stickToTop })}>
Expand Down Expand Up @@ -65,21 +60,6 @@ const JumpNav = ({
</li>
)}
</Scrollspy>
{showPreferences && (
<>
<hr />
<Scrollspy
className="list-unstyled"
>
<li>
<Link to="/notifications" target="_blank" rel="noopener noreferrer">
<span>{intl.formatMessage(messages['notification.preferences.notifications.label'])}</span>
<Icon className="d-inline-block align-bottom ml-1" src={OpenInNew} />
</Link>
</li>
</Scrollspy>
</>
)}
</div>
);
};
Expand Down
16 changes: 16 additions & 0 deletions src/divider/Divider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import PropTypes from 'prop-types';
import classNames from 'classnames';

const Divider = ({ className, ...props }) => (
<div className={classNames('divider', className)} {...props} />
);

Divider.propTypes = {
className: PropTypes.string,
};

Divider.defaultProps = {
className: undefined,
};

export default Divider;
2 changes: 2 additions & 0 deletions src/divider/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as Divider } from './Divider';
4 changes: 0 additions & 4 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import messages from './i18n';

import './index.scss';
import Head from './head/Head';
import NotificationCourses from './notification-preferences/NotificationCourses';
import NotificationPreferences from './notification-preferences/NotificationPreferences';

subscribe(APP_READY, () => {
ReactDOM.render(
Expand All @@ -38,8 +36,6 @@ subscribe(APP_READY, () => {
</div>
)}
>
<Route path="/notifications/:courseId" element={<NotificationPreferences />} />
<Route path="/notifications" element={<NotificationCourses />} />
<Route
path="/id-verification/*"
element={<IdVerificationPageSlot />}
Expand Down
16 changes: 15 additions & 1 deletion src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ $fa-font-path: "~font-awesome/fonts";
}

.dropdown-item:active,
.dropdown-item:focus,
.dropdown-item:focus,
.btn-tertiary:not(:disabled):not(.disabled).active {
background-color: $light-300 !important;
}
Expand All @@ -131,6 +131,20 @@ $fa-font-path: "~font-awesome/fonts";
.h-4\.5 {
height: 36px;
}

.course-dropdown{
#course-dropdown-btn {
width: 100%;
font-size: 14px !important;
padding-top: 10px !important;
padding-bottom: 10px !important;
border: 1px solid $light-500 !important;
}

.dropdown-item {
font-size: 14px !important;
}
}
}

.usabilla_live_button_container {
Expand Down
85 changes: 0 additions & 85 deletions src/notification-preferences/NotificationCourses.jsx

This file was deleted.

97 changes: 0 additions & 97 deletions src/notification-preferences/NotificationCourses.test.jsx

This file was deleted.

69 changes: 69 additions & 0 deletions src/notification-preferences/NotificationCoursesDropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { useIntl } from '@edx/frontend-platform/i18n';
import { Dropdown } from '@openedx/paragon';

import { IDLE_STATUS, SUCCESS_STATUS } from '../constants';
import { selectCourseList, selectCourseListStatus, selectSelectedCourseId } from './data/selectors';
import { fetchCourseList, setSelectedCourse } from './data/thunks';
import messages from './messages';

const NotificationCoursesDropdown = () => {
const intl = useIntl();
const dispatch = useDispatch();
const coursesList = useSelector(selectCourseList());
const courseListStatus = useSelector(selectCourseListStatus());
const selectedCourseId = useSelector(selectSelectedCourseId());
const selectedCourse = useMemo(
() => coursesList.find((course) => course.id === selectedCourseId),
[coursesList, selectedCourseId],
);

const handleCourseSelection = useCallback((courseId) => {
dispatch(setSelectedCourse(courseId));
}, [dispatch]);

const fetchCourses = useCallback((page = 1, pageSize = 99999) => {
dispatch(fetchCourseList(page, pageSize));
}, [dispatch]);

useEffect(() => {
if (courseListStatus === IDLE_STATUS) {
fetchCourses();
}
}, [courseListStatus, fetchCourses]);

return (
courseListStatus === SUCCESS_STATUS && (
<div className="mb-5">
<h5 className="text-primary-500 mb-3">{intl.formatMessage(messages.notificationDropdownlabel)}</h5>
<Dropdown className="course-dropdown">
<Dropdown.Toggle
variant="outline-primary"
id="course-dropdown-btn"
className="w-100 justify-content-between small"
>
{selectedCourse?.name}
</Dropdown.Toggle>
<Dropdown.Menu className="w-100">
{coursesList.map((course) => (
<Dropdown.Item
className="w-100"
key={course.id}
active={course.id === selectedCourse?.id}
eventKey={course.id}
onSelect={handleCourseSelection}
>
{course.name}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
<span className="x-small text-gray-500">{intl.formatMessage(messages.notificationDropdownApplies)}</span>
</div>
)
);
};

export default NotificationCoursesDropdown;
Loading

0 comments on commit 27c686f

Please sign in to comment.