feat: added notification APIs

This commit is contained in:
SundasNoreen
2023-05-31 11:50:42 +05:00
parent c4df727178
commit 72e82005c0
6 changed files with 80 additions and 25 deletions

View File

@@ -4,21 +4,25 @@ import React, {
import { Tabs, Tab } from '@edx/paragon';
import { useSelector, useDispatch } from 'react-redux';
import NotificationSections from './NotificationSections';
import { getNotificationTotalUnseenCounts, getSelectedNotificationType } from './data/selectors';
import { fetchNotificationList } from './data/thunks';
import { getNotificationTotalUnseenCounts, getSelectedAppName } from './data/selectors';
import { fetchNotificationList, markNotificationsAsSeen } from './data/thunks';
import { notificationTabsOptions } from './data/constants';
const NotificationTabs = () => {
const notificationUnseenCounts = useSelector(getNotificationTotalUnseenCounts());
const selectedNotificationType = useSelector(getSelectedNotificationType());
const selectedappName = useSelector(getSelectedAppName());
const [activeTab, setActiveTab] = useState(notificationTabsOptions[0].key);
const [loadMoreCount, setLoadMoreCount] = useState(10);
const [page, setPage] = useState(1);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchNotificationList({ notificationType: activeTab, notificationCount: loadMoreCount }));
}, [dispatch, activeTab, loadMoreCount]);
dispatch(fetchNotificationList({
appName: activeTab, notificationCount: loadMoreCount, page, pageSize: 10,
}));
dispatch(markNotificationsAsSeen(activeTab));
}, [dispatch, activeTab, loadMoreCount, page]);
const handleActiveTab = useCallback((tab) => {
setActiveTab(tab);
@@ -26,7 +30,8 @@ const NotificationTabs = () => {
const handleLoadMoreNotification = useCallback((count) => {
setLoadMoreCount(count);
}, []);
setPage(page + 1);
}, [page]);
const tabArray = useMemo(() => notificationTabsOptions.map((option) => (
<Tab
@@ -35,10 +40,10 @@ const NotificationTabs = () => {
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
{option.key === selectedappName
&& <NotificationSections handleLoadMoreNotification={handleLoadMoreNotification} loadMoreCount={loadMoreCount} />}
</Tab>
)), [notificationUnseenCounts, handleLoadMoreNotification, loadMoreCount, selectedNotificationType]);
)), [notificationUnseenCounts, handleLoadMoreNotification, loadMoreCount, selectedappName]);
// This code is used to replace More... text to More to match the UI
const buttons = document.getElementsByClassName('dropdown-toggle');

View File

@@ -1,4 +1,9 @@
import { camelCaseObject } from '@edx/frontend-platform';
import { camelCaseObject, getConfig, snakeCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
export const getNotificationsCountApiUrl = () => `${getConfig().LMS_BASE_URL}/api/notifications/count/`;
export const getNotificationsApiUrl = () => `${getConfig().LMS_BASE_URL}/api/notifications/`;
export const markNotificationsSeenApiUrl = (appName) => `${getConfig().LMS_BASE_URL}/api/notifications/mark-notifications-unseen/${appName}/`;
const parseNotificationList = (notificationList) => {
const currentTime = Date.now();
@@ -11,7 +16,12 @@ const parseNotificationList = (notificationList) => {
});
return { today, earlier };
};
export async function getNotifications(notificationType, notificationCount) {
export async function getNotifications(appName, notificationCount, page, pageSize) {
const params = snakeCaseObject({ page, pageSize });
let { data } = await getAuthenticatedHttpClient().get(getNotificationsApiUrl(), { params });
const notificationData = [
{
type: 'post',
@@ -194,8 +204,7 @@ export async function getNotifications(notificationType, notificationCount) {
];
const { today, earlier } = parseNotificationList(camelCaseObject(notificationData));
const data = {
data = {
discussions: {
TODAY: today,
EARLIER: earlier,
@@ -205,7 +214,8 @@ export async function getNotifications(notificationType, notificationCount) {
EARLIER: earlier,
},
};
const notifications = data[notificationType];
const notifications = data[appName];
const { TODAY = [], EARLIER = [] } = notifications || [];
let todayNotifications = TODAY;
let earlierNotifications = [];
@@ -225,7 +235,8 @@ export async function getNotifications(notificationType, notificationCount) {
}
export async function getNotificationCounts() {
const data = {
let { data } = await getAuthenticatedHttpClient().get(getNotificationsCountApiUrl());
data = {
count: 25,
count_by_app_name: {
reminders: 10,
@@ -236,3 +247,9 @@ export async function getNotificationCounts() {
};
return camelCaseObject(data);
}
export async function markNotificationSeen(appName) {
const { data } = await getAuthenticatedHttpClient()
.put(`${markNotificationsSeenApiUrl(appName)}`);
return camelCaseObject(data);
}

View File

@@ -1,4 +1,4 @@
export const getNotificationStatus = () => state => state.notifications.notificationStatus;
export const getNotificationTotalUnseenCounts = () => state => state.notifications.totalUnseenCounts;
export const getNotifications = () => state => state.notifications.notifications;
export const getSelectedNotificationType = () => state => state.notifications.notificationType;
export const getSelectedAppName = () => state => state.notifications.appName;

View File

@@ -12,19 +12,19 @@ const slice = createSlice({
notificationStatus: 'idle',
notifications: {},
totalUnseenCounts: {},
notificationType: '',
appName: '',
},
reducers: {
fetchNotificationDenied: (state, { payload }) => {
state.notificationType = payload.notificationType;
state.appName = payload.appName;
state.notificationStatus = DENIED;
},
fetchNotificationFailure: (state, { payload }) => {
state.notificationType = payload.notificationType;
state.appName = payload.appName;
state.notificationStatus = FAILED;
},
fetchNotificationRequest: (state, { payload }) => {
state.notificationType = payload.notificationType;
state.appName = payload.appName;
state.notificationStatus = LOADING;
},
fetchNotificationSuccess: (state, { payload }) => {
@@ -45,6 +45,18 @@ const slice = createSlice({
state.notificationStatus = LOADED;
state.totalUnseenCounts = payload;
},
markNotificationsAsSeenRequest: (state) => {
state.notificationStatus = LOADING;
},
markNotificationsAsSeenSuccess: (state) => {
state.notificationStatus = LOADED;
},
markNotificationsAsSeenDenied: (state) => {
state.notificationStatus = DENIED;
},
markNotificationsAsSeenFailure: (state) => {
state.notificationStatus = FAILED;
},
},
});
@@ -57,6 +69,10 @@ export const {
fetchNotificationsCountFailure,
fetchNotificationsCountRequest,
fetchNotificationsCountSuccess,
markNotificationsAsSeenRequest,
markNotificationsAsSeenSuccess,
markNotificationsAsSeenFailure,
markNotificationsAsSeenDenied,
} = slice.actions;
export const notificationsReducer = slice.reducer;

View File

@@ -5,20 +5,26 @@ import {
fetchNotificationsCountFailure,
fetchNotificationsCountRequest,
fetchNotificationsCountSuccess,
markNotificationsAsSeenRequest,
markNotificationsAsSeenSuccess,
markNotificationsAsSeenFailure,
} from './slice';
import {
getNotifications,
getNotificationCounts,
markNotificationSeen,
} from './api';
export const fetchNotificationList = ({ notificationType, notificationCount }) => (
export const fetchNotificationList = ({
appName, notificationCount, page, pageSize,
}) => (
async (dispatch) => {
try {
dispatch(fetchNotificationRequest({ notificationType }));
const data = await getNotifications(notificationType, notificationCount);
dispatch(fetchNotificationRequest({ appName }));
const data = await getNotifications(appName, notificationCount, page, pageSize);
dispatch(fetchNotificationSuccess(data));
} catch (errors) {
dispatch(fetchNotificationFailure({ notificationType }));
dispatch(fetchNotificationFailure({ appName }));
}
}
);
@@ -34,3 +40,15 @@ export const fetchNotificationsCountsList = () => (
}
}
);
export const markNotificationsAsSeen = (appName) => (
async (dispatch) => {
try {
dispatch(markNotificationsAsSeenRequest({ appName }));
const data = await markNotificationSeen(appName);
dispatch(markNotificationsAsSeenSuccess(data));
} catch (errors) {
dispatch(markNotificationsAsSeenFailure({ appName }));
}
}
);

View File

@@ -128,7 +128,6 @@ $white: #fff;
.font-size-12{
font-size: 12px;
}
.font-size-9{
font-size: 9px;
}
@@ -155,7 +154,7 @@ $white: #fff;
.expandable{
position: relative !important;
margin-left: 4px;
padding: 2px 6px;
padding: 2px 5px;
border-radius: 10rem;
font-size: 9px;
}