PageView.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import React, { useMemo } from 'react';
  2. import { type IPagePopulatedToShowRevision, pagePathUtils } from '@growi/core';
  3. import dynamic from 'next/dynamic';
  4. import {
  5. useIsForbidden, useIsIdenticalPath, useIsNotCreatable, useIsNotFound,
  6. } from '~/stores/context';
  7. import { useIsMobile } from '~/stores/ui';
  8. import type { CommentsProps } from '../Comments';
  9. import { MainPane } from '../Layout/MainPane';
  10. import { PageAlerts } from '../PageAlert/PageAlerts';
  11. import { PageContentFooter } from '../PageContentFooter';
  12. import type { PageSideContentsProps } from '../PageSideContents';
  13. import { UserInfo } from '../User/UserInfo';
  14. import type { UsersHomePageFooterProps } from '../UsersHomePageFooter';
  15. import { PageContents } from './PageContents';
  16. import styles from './PageView.module.scss';
  17. const { isUsersHomePage } = pagePathUtils;
  18. const NotCreatablePage = dynamic(() => import('../NotCreatablePage').then(mod => mod.NotCreatablePage), { ssr: false });
  19. const ForbiddenPage = dynamic(() => import('../ForbiddenPage'), { ssr: false });
  20. const NotFoundPage = dynamic(() => import('../NotFoundPage'), { ssr: false });
  21. const PageSideContents = dynamic<PageSideContentsProps>(() => import('../PageSideContents').then(mod => mod.PageSideContents), { ssr: false });
  22. const Comments = dynamic<CommentsProps>(() => import('../Comments').then(mod => mod.Comments), { ssr: false });
  23. const UsersHomePageFooter = dynamic<UsersHomePageFooterProps>(() => import('../UsersHomePageFooter')
  24. .then(mod => mod.UsersHomePageFooter), { ssr: false });
  25. const IdenticalPathPage = (): JSX.Element => {
  26. const IdenticalPathPage = dynamic(() => import('../IdenticalPathPage').then(mod => mod.IdenticalPathPage), { ssr: false });
  27. return <IdenticalPathPage />;
  28. };
  29. type Props = {
  30. pagePath: string,
  31. page?: IPagePopulatedToShowRevision,
  32. ssrBody?: JSX.Element,
  33. }
  34. export const PageView = (props: Props): JSX.Element => {
  35. const {
  36. pagePath, page, ssrBody,
  37. } = props;
  38. const pageId = page?._id;
  39. const { data: isIdenticalPathPage } = useIsIdenticalPath();
  40. const { data: isForbidden } = useIsForbidden();
  41. const { data: isNotCreatable } = useIsNotCreatable();
  42. const { data: isNotFound } = useIsNotFound();
  43. const { data: isMobile } = useIsMobile();
  44. const specialContents = useMemo(() => {
  45. if (isIdenticalPathPage) {
  46. return <IdenticalPathPage />;
  47. }
  48. if (isForbidden) {
  49. return <ForbiddenPage />;
  50. }
  51. if (isNotCreatable) {
  52. return <NotCreatablePage />;
  53. }
  54. if (isNotFound) {
  55. return <NotFoundPage />;
  56. }
  57. }, [isForbidden, isIdenticalPathPage, isNotCreatable, isNotFound]);
  58. const sideContents = !isNotFound && !isNotCreatable
  59. ? (
  60. <PageSideContents page={page} />
  61. )
  62. : <></>;
  63. const footerContents = !isIdenticalPathPage && !isNotFound && page != null
  64. ? (
  65. <>
  66. { pageId != null && pagePath != null && (
  67. <Comments pageId={pageId} pagePath={pagePath} revision={page.revision} />
  68. ) }
  69. { pagePath != null && isUsersHomePage(pagePath) && (
  70. <UsersHomePageFooter creatorId={page.creator._id}/>
  71. ) }
  72. <PageContentFooter page={page} />
  73. </>
  74. )
  75. : <></>;
  76. const isUsersHomePagePath = isUsersHomePage(pagePath);
  77. const contents = specialContents != null
  78. ? <></>
  79. // TODO: show SSR body
  80. // : (() => {
  81. // const PageContents = dynamic(() => import('./PageContents').then(mod => mod.PageContents), {
  82. // ssr: false,
  83. // // loading: () => ssrBody ?? <></>,
  84. // });
  85. // return <PageContents />;
  86. // })();
  87. : <PageContents />;
  88. return (
  89. <MainPane
  90. sideContents={sideContents}
  91. footerContents={footerContents}
  92. >
  93. <PageAlerts />
  94. { specialContents }
  95. { specialContents == null && (
  96. <>
  97. { isUsersHomePagePath && <UserInfo author={page?.creator} /> }
  98. <div className={`mb-5 ${isMobile ? `page-mobile ${styles['page-mobile']}` : ''}`}>
  99. { contents }
  100. </div>
  101. </>
  102. ) }
  103. </MainPane>
  104. );
  105. };