InAppNotificationPage.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import type { FC } from 'react';
  2. import React, { useState } from 'react';
  3. import { LoadingSpinner } from '@growi/ui/dist/components';
  4. import { useTranslation } from 'next-i18next';
  5. import { apiv3Put } from '~/client/util/apiv3-client';
  6. import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
  7. import { useShowPageLimitationXL } from '~/stores-universal/context';
  8. import { useSWRxInAppNotifications, useSWRxInAppNotificationStatus } from '~/stores/in-app-notification';
  9. import CustomNavAndContents from '../CustomNavigation/CustomNavAndContents';
  10. import PaginationWrapper from '../PaginationWrapper';
  11. import InAppNotificationList from './InAppNotificationList';
  12. export const InAppNotificationPage: FC = () => {
  13. const { t } = useTranslation('commons');
  14. const { data: showPageLimitationXL } = useShowPageLimitationXL();
  15. const limit = showPageLimitationXL != null ? showPageLimitationXL : 20;
  16. const InAppNotificationCategoryByStatus = (status?: InAppNotificationStatuses) => {
  17. const [activePage, setActivePage] = useState(1);
  18. const offset = (activePage - 1) * limit;
  19. let categoryStatus;
  20. switch (status) {
  21. case InAppNotificationStatuses.STATUS_UNOPENED:
  22. categoryStatus = InAppNotificationStatuses.STATUS_UNOPENED;
  23. break;
  24. default:
  25. }
  26. const { data: notificationData, mutate: mutateNotificationData } = useSWRxInAppNotifications(limit, offset, categoryStatus);
  27. const { mutate: mutateAllNotificationData } = useSWRxInAppNotifications(limit, offset, undefined);
  28. const { mutate: mutateNotificationCount } = useSWRxInAppNotificationStatus();
  29. const setAllNotificationPageNumber = (selectedPageNumber): void => {
  30. setActivePage(selectedPageNumber);
  31. };
  32. if (notificationData == null) {
  33. return (
  34. <div className="wiki" data-testid="grw-in-app-notification-page-spinner">
  35. <div className="text-muted text-center">
  36. <LoadingSpinner className="me-1 fs-3" />
  37. </div>
  38. </div>
  39. );
  40. }
  41. const updateUnopendNotificationStatusesToOpened = async() => {
  42. await apiv3Put('/in-app-notification/all-statuses-open');
  43. // mutate notification statuses in 'UNREAD' Category
  44. mutateNotificationData();
  45. // mutate notification statuses in 'ALL' Category
  46. mutateAllNotificationData();
  47. mutateNotificationCount();
  48. };
  49. return (
  50. <>
  51. {(status === InAppNotificationStatuses.STATUS_UNOPENED && notificationData.totalDocs > 0)
  52. && (
  53. <div className="mb-2 d-flex justify-content-end">
  54. <button
  55. type="button"
  56. className="btn btn-outline-primary"
  57. onClick={updateUnopendNotificationStatusesToOpened}
  58. >
  59. {t('in_app_notification.mark_all_as_read')}
  60. </button>
  61. </div>
  62. )}
  63. { notificationData != null && notificationData.docs.length === 0
  64. // no items
  65. ? t('in_app_notification.no_unread_messages')
  66. // render list-group
  67. : (
  68. <InAppNotificationList inAppNotificationData={notificationData} />
  69. )
  70. }
  71. {notificationData.totalDocs > 0 && (
  72. <div className="mt-4">
  73. <PaginationWrapper
  74. activePage={activePage}
  75. changePage={setAllNotificationPageNumber}
  76. totalItemsCount={notificationData.totalDocs}
  77. pagingLimit={notificationData.limit}
  78. align="center"
  79. size="sm"
  80. />
  81. </div>
  82. ) }
  83. </>
  84. );
  85. };
  86. const navTabMapping = {
  87. user_infomation: {
  88. Icon: () => <></>,
  89. Content: () => InAppNotificationCategoryByStatus(),
  90. i18n: t('in_app_notification.all'),
  91. },
  92. external_accounts: {
  93. Icon: () => <></>,
  94. Content: () => InAppNotificationCategoryByStatus(InAppNotificationStatuses.STATUS_UNOPENED),
  95. i18n: t('in_app_notification.unopend'),
  96. },
  97. };
  98. return (
  99. <div data-testid="grw-in-app-notification-page">
  100. <CustomNavAndContents navTabMapping={navTabMapping} tabContentClasses={['mt-4']} />
  101. </div>
  102. );
  103. };
  104. InAppNotificationPage.displayName = 'InAppNotificationPage';