refactor: refactor components

This commit is contained in:
SundasNoreen
2023-05-29 23:15:15 +05:00
parent 642be093c7
commit c4df727178
11 changed files with 282 additions and 335 deletions

View File

@@ -54,47 +54,45 @@ const NotificationRowItem = ({ notification }) => {
const iconComponent = getIconByType(notification.type);
return (
<div className="d-flex mb-2">
<div className="mr-2 py-4 pr-2.5">
<Icon
src={iconComponent && iconComponent.icon}
style={{ height: '23.33px', width: '23.33px' }}
className={iconComponent && iconComponent.class}
/>
</div>
<div className="row d-flex w-100 py-0 px-0 py-2.5">
<div style={{ display: 'contents' }} className="col-md-12 w-100">
<span className="col-md-11 px-0 text-primary-500 mb-2 w-100 notification-item-content overflow-hidden">
{notification?.respondingUser} {' '}
<span className="text-gray-500">{getContentMessageByType()} </span>
{notification?.targetUser && (
<>
{notification?.targetUser}
<span className="text-gray-500">
{(authenticatedUser && authenticatedUser.username) !== notification.author
? intl.formatMessage(messages.notificationResponseOnOtherPostLabel)
: intl.formatMessage(messages.notificationResponseOnYourPostLabel)}
</span>
</>
)}
<a className="text-primary-500" href={notification.URL}>
{' '}{notification?.notificationContent}
</a>
</span>
<div className="col-md-1 d-flex flex-column justify-content-end mb-2">
{notification.status === 'unread' && <div className="bg-brand-500 rounded unread" />}
</div>
<div className="w-100 px-0 py-0 d-flex flex-row align-items-center">
<span className="text-gray-500 mb-2 w-100 font-size-12">
<span className="">{notification?.courseName}</span>
<span className="font-size-12 text-light-700 px-1.5">
{intl.formatMessage(messages.fullStop)}
</span>
<span>
{timeago.format(notification?.time, 'time-locale')}
</span>
<div className="d-flex mb-2 align-items-center">
<Icon
src={iconComponent && iconComponent.icon}
style={{ height: '23.33px', width: '23.33px' }}
className={iconComponent && `${iconComponent.class} mr-4`}
/>
<div className="d-flex w-100" style={{ borderRadius: '100%' }}>
<div className="d-flex align-items-center w-100">
<div className="py-2 w-100">
<span className="line-height-24 px-0 text-primary-500 mb-2 w-100 notification-item-content overflow-hidden">
{notification?.respondingUser } {' '}
<span className="text-gray-500">{getContentMessageByType()} </span>
{notification?.targetUser && (
<>
{notification.targetUser}
<span className="text-gray-500">
{(authenticatedUser && authenticatedUser.username) !== notification.author
? intl.formatMessage(messages.notificationResponseOnOtherPostLabel)
: intl.formatMessage(messages.notificationResponseOnYourPostLabel)}
</span>
</>
)}
<a className="text-primary-500" href={notification.URL}>
{' '}{notification?.notificationContent}
</a>
</span>
<div className="w-100 px-0 py-0 d-flex flex-row align-items-center">
<span className="font-size-12 text-gray-500 line-height-20">
<span>{notification?.courseName}</span>
<span className="text-light-700 px-1.5">{intl.formatMessage(messages.fullStop)}</span>
<span>{timeago.format(notification?.time, 'time-locale')}</span>
</span>
</div>
</div>
{!notification.isRead && (
<div className="d-flex py-1.5 px-1.5 ml-2">
<span className="bg-brand-500 rounded unread" />
</div>
)}
</div>
</div>
</div>

View File

@@ -14,40 +14,47 @@ const NotificationSections = ({ handleLoadMoreNotification, loadMoreCount }) =>
return (
notifications && (
<div className="pt-4 py-2.5">
<div className="d-flex flex-row align-items-center pb-2">
<span className="w-100 px-0 text-gray-500">
{TODAY && TODAY.length > 0 && intl.formatMessage(messages.notificationTodayHeading)}
</span>
{totalCount > 0 && (
<span className="w-100 px-0 text-right text-info-500">
{intl.formatMessage(messages.notificationMarkAsRead)}
</span>
<div className="mt-4 px-4">
<div className="d-flex flex-row justify-content-between pb-2">
{TODAY && TODAY.length > 0 && (
<>
<span className="text-gray-500">
{ intl.formatMessage(messages.notificationTodayHeading)}
</span>
{totalCount > 0 && (
<span className="text-info-500 line-height-24">
{intl.formatMessage(messages.notificationMarkAsRead)}
</span>
)}
</>
)}
</div>
<div>
{TODAY && TODAY.map(
(notification) => <NotificationRowItem notification={notification} />,
)}
<div className="d-flex pb-2 notification-section">
<span className="w-100 px-0 text-gray-500">
{EARLIER && EARLIER.length > 0
<div className="d-flex flex-row justify-content-between pb-2">
<span className="text-gray-500">
{EARLIER && EARLIER.length > 0
&& intl.formatMessage(messages.notificationEarlierHeading)}
</span>
{totalCount > 0 && TODAY && TODAY.length === 0 && (
<span className="text-info-500 line-height-24">
{intl.formatMessage(messages.notificationMarkAsRead)}
</span>
</div>
)}
</div>
{EARLIER && EARLIER.map(
(notification) => <NotificationRowItem notification={notification} />,
)}
{loadMoreCount < totalCount && (
<Button
variant="primary"
className="mb-2 mb-sm-0 w-100 bg-primary-500"
onClick={() => handleLoadMoreNotification(loadMoreCount + 10)}
>
{intl.formatMessage(messages.loadMoreNotifications)}
</Button>
<Button
variant="primary"
className="w-100 bg-primary-500"
onClick={() => handleLoadMoreNotification(loadMoreCount + 10)}
>
{intl.formatMessage(messages.loadMoreNotifications)}
</Button>
)}
</div>
</div>
)
);

View File

@@ -32,8 +32,8 @@ const NotificationTabs = () => {
<Tab
eventKey={option.key}
title={option.title}
notification={notificationUnseenCounts[option.title]}
tabClassName="d-flex flex-row align-items-center pt-0 pb-2.5 line-height-24 px-0 mr-4"
notification={notificationUnseenCounts.countByAppName[option.key]}
tabClassName="pt-0 pb-2.5 px-2.5 d-flex flex-row align-items-center line-height-24"
>
{option.key === selectedNotificationType
&& <NotificationSections handleLoadMoreNotification={handleLoadMoreNotification} loadMoreCount={loadMoreCount} />}
@@ -47,15 +47,14 @@ const NotificationTabs = () => {
}
return (
activeTab && (
<Tabs
variant="tabs"
defaultActiveKey={activeTab}
className="notification-tabs"
onSelect={handleActiveTab}
className="px-2.5"
>
{tabArray}
</Tabs>
)
);
};

View File

@@ -3,14 +3,16 @@ import React, {
} from 'react';
import { NotificationsNone, Settings } from '@edx/paragon/icons';
import {
Badge, Form, Icon, IconButton, OverlayTrigger, Popover,
Badge, Icon, IconButton, OverlayTrigger, Popover,
} from '@edx/paragon';
import { useSelector, useDispatch } from 'react-redux';
import { useIntl } from '@edx/frontend-platform/i18n';
import classNames from 'classnames';
import NotificationTabs from './NotificationTabs';
import { getNotificationTotalUnseenCounts, getNotificationStatus } from './data/selectors';
import { fetchNotificationsCountsList } from './data/thunks';
import { messages } from './messages';
import { useIsOnDesktop, useIsOnXLDesktop } from './data/hook';
const Notifications = () => {
const [showNotificationTray, setShowNotificationTray] = useState(false);
@@ -20,6 +22,8 @@ const Notifications = () => {
const dispatch = useDispatch();
const notificationStatus = useSelector(getNotificationStatus());
const notificationCounts = useSelector(getNotificationTotalUnseenCounts());
const isOnDesktop = useIsOnDesktop();
const isOnXLDesktop = useIsOnXLDesktop();
useEffect(() => {
if (notificationStatus === 'idle') {
@@ -57,14 +61,18 @@ const Notifications = () => {
overlay={(
<Popover
id="popover-positioned-bottom"
className="notification-tray-container pt-4.5 pb-4 px-4 overflow-auto d-flex flex-column
align-items-start position-absolute mt-2"
style={{ maxHeight: 'calc(100% - 68px)', minHeight: '1220px', minWidth: '549px' }}
className={classNames('notification-tray-container pt-4.5 pb-4.5 overflow-auto rounded-0 border-0', {
'w-100': !isOnDesktop,
'notificationbar-desktop-width': isOnDesktop && !isOnXLDesktop,
'w-25 notificationbar-XL-width': isOnXLDesktop,
})}
data-testid="notificationbar"
>
<div ref={popoverRef}>
<Popover.Title
as="h3"
style={{ border: 'none' }}
className="d-flex flex-row justify-content-between py-0 px-0 mb-4"
className="d-flex flex-row justify-content-between py-0 mb-4 border-0 px-4"
>
<h2 className="text-primary-500 font-size-18 line-height-24">
{intl.formatMessage(messages.notificationTitle)}
@@ -78,38 +86,26 @@ const Notifications = () => {
</Popover>
)}
>
<>
{/* {notificationCounts?.Total > 0 && (
<Badge variant="danger position-absolute px-1.5 py-1.5 d-flex flex-row justify-content-center
align-items-center zindex-1"
>
<Form.Label className="count font-size-9 mt-2">{notificationCounts?.Total}</Form.Label>
</Badge>
)} */}
<div className="" ref={buttonRef}>
<IconButton
isActive={showNotificationTray}
alt="notification bell icon"
onClick={() => { handleNotificationTray(!showNotificationTray); }}
src={NotificationsNone}
iconAs={Icon}
variant="light"
iconClassNames="text-primary-500"
className="ml-4 mr-1 my-3"
style={{ width: '36px', height: '36px' }}
/>
<Badge
variant="danger"
pill
className="font-weight-normal px-1"
style={{
fontSize: '9px', border: '2px solid white', right: '-3px', top: '18px', fontWeight: '600',
}}
>
{ notificationCounts?.Total > 0 && notificationCounts?.Total}
</Badge>
</div>
</>
<div ref={buttonRef}>
<IconButton
isActive={showNotificationTray}
alt="notification bell icon"
onClick={() => { handleNotificationTray(!showNotificationTray); }}
src={NotificationsNone}
iconAs={Icon}
variant="light"
iconClassNames="text-primary-500"
className="ml-4 mr-1 my-3"
style={{ width: '36px', height: '36px' }}
/>
<Badge
variant="danger"
pill
className="font-weight-normal px-1 font-size-9 notification-badge"
>
{ notificationCounts?.count > 0 && notificationCounts?.count}
</Badge>
</div>
</OverlayTrigger>
);
};

View File

@@ -1,6 +1,4 @@
import { getConfig } from '@edx/frontend-platform';
export const getApiBaseUrl = () => getConfig().LMS_BASE_URL;
import { camelCaseObject } from '@edx/frontend-platform';
const parseNotificationList = (notificationList) => {
const currentTime = Date.now();
@@ -17,190 +15,185 @@ export async function getNotifications(notificationType, notificationCount) {
const notificationData = [
{
type: 'post',
respondingUser: 'SCM_Lead',
notificationContent: 'Hello and welcome to SC0x!',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1684996319038',
},
{
type: 'post',
respondingUser: 'SCM_Lead',
notificationContent: 'Hello and welcome to SC0x!',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1684996319038',
},
{
type: 'post',
respondingUser: 'SCM_Lead',
notificationContent: 'Hello and welcome to SC0x!',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1684996319038',
responding_user: 'SCM_Lead',
notification_content: 'Hello and welcome to SC0x!',
target_user: '',
course_name: 'Supply Chain Analytics',
content_content_url: '',
is_read: false,
is_seen: false,
time: '1685361282018',
},
{
type: 'help',
respondingUser: 'MITx_Learner',
notificationContent: 'What grade does a student need to get in order to pass the course and earn a certificate?',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1684996339844',
responding_user: 'MITx_Learner',
notification_content: 'What grade does a student need to get in order to pass the course and earn a certificate?',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1685361282018',
},
{
type: 'post',
respondingUser: 'SCM_Lead',
notificationContent: 'Hello and welcome to SC0x!',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'SCM_Lead',
notification_content: 'Hello and welcome to SC0x!',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1684253634808',
author: '',
},
{
type: 'help',
respondingUser: 'MITx_Learner',
notificationContent: 'What grade does a student need to get in order to pass the course and earn a certificate?',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'MITx_Learner',
notification_content: 'What grade does a student need to get in order to pass the course and earn a certificate?',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1684253736371',
author: '',
},
{
type: 'respond',
respondingUser: 'MITx_Learner',
notificationContent: 'Cant find linear regression in section 3 review',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'MITx_Learner',
notification_content: 'Cant find linear regression in section 3 review',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1684253736371',
author: '',
},
{
type: 'comment',
respondingUser: 'MITx_Learner',
notificationContent: 'Cant find linear regression in section 3 review',
targetUser: 'MITx_Experts ',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'MITx_Learner',
notification_content: 'Cant find linear regression in section 3 review',
target_user: 'MITx_Experts ',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1684253736371',
author: '',
},
{
type: 'question',
respondingUser: 'MITx_Learner',
notificationContent: 'Examples of quadratic equations in supply chains',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'MITx_Learner',
notification_content: 'Examples of quadratic equations in supply chains',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1684253736371',
author: '',
},
{
type: 'comment',
respondingUser: 'MITx_Learner',
notificationContent: 'What grade does a student need to get in order to pass the course and earn a certificate?',
targetUser: 'MITx_Experts ',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'MITx_Learner',
notification_content: 'What grade does a student need to get in order to pass the course and earn a certificate?',
target_user: 'MITx_Experts ',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
time: '1684253736371',
is_seen: false,
author: 'testuser',
},
{
type: 'comment',
respondingUser: 'MITx_Learner',
notificationContent: 'Convexity of f(x)=1/x , x>1',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'MITx_Learner',
notification_content: 'Convexity of f(x)=1/x , x>1',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
time: '1684253736371',
is_seen: false,
author: 'testuser',
},
{
type: 'answer',
respondingUser: 'SCM_Lead',
notificationContent: 'Quiz in section 3 - Please explain the F-Significance value',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: 'SCM_Lead',
notification_content: 'Quiz in section 3 - Please explain the F-Significance value',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
time: '1685096268835',
is_seen: false,
author: 'testuser',
},
{
type: 'endorsed',
respondingUser: '',
notificationContent: 'Quiz in section 3 - Please explain the F-Significance value',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
responding_user: '',
notification_content: 'Quiz in section 3 - Please explain the F-Significance value',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1685096268835',
author: 'testuser',
},
{
type: 'reported',
respondingUser: 'MITx Learners',
notificationContent: '“Here are the exam answers. Question 1 - CSA stands for Compliance Safety Ac...”',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1685096268835',
responding_user: 'MITx Learners',
notification_content: '“Here are the exam answers. Question 1 - CSA stands for Compliance Safety Ac...”',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1685212056931',
author: '',
},
{
type: 'postLiked',
respondingUser: 'SCM_Lead',
notificationContent: 'Retaking the course',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1685096268835',
responding_user: 'SCM_Lead',
notification_content: 'Retaking the course',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1685212056931',
author: '',
},
{
type: 'commentLiked',
respondingUser: 'MITx_Expert ',
notificationContent: 'Final exam answers',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1685096268835',
responding_user: 'MITx_Expert ',
notification_content: 'Final exam answers',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1685212056931',
author: '',
},
{
type: 'edited',
respondingUser: 'MITx_Expert ',
notificationContent: 'Question 1',
targetUser: '',
courseName: 'Supply Chain Analytics',
URL: '',
status: 'unread',
time: '1685096268835',
responding_user: 'MITx_Expert ',
notification_content: 'Question 1',
target_user: '',
course_name: 'Supply Chain Analytics',
content_url: '',
is_read: false,
is_seen: false,
time: '1685212056931',
author: '',
},
];
const { today, earlier } = parseNotificationList(notificationData);
const { today, earlier } = parseNotificationList(camelCaseObject(notificationData));
const data = {
discussions: {
@@ -233,11 +226,13 @@ export async function getNotifications(notificationType, notificationCount) {
export async function getNotificationCounts() {
const data = {
Total: 25,
Reminders: 10,
Discussions: 5,
Grades: 4,
Authoring: 6,
count: 25,
count_by_app_name: {
reminders: 10,
discussions: 5,
grades: 4,
authoring: 6,
},
};
return data;
return camelCaseObject(data);
}

View File

@@ -0,0 +1,10 @@
import { breakpoints, useWindowSize } from '@edx/paragon';
export function useIsOnDesktop() {
const windowSize = useWindowSize();
return windowSize.width >= breakpoints.medium.minWidth;
}
export function useIsOnXLDesktop() {
const windowSize = useWindowSize();
return windowSize.width >= breakpoints.extraLarge.minWidth;
}