ShareLinkPageView.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import React, { useMemo } from 'react';
  2. import type { IPagePopulatedToShowRevision } from '@growi/core';
  3. import dynamic from 'next/dynamic';
  4. import type { RendererConfig } from '~/interfaces/services/renderer';
  5. import type { IShareLinkHasId } from '~/interfaces/share-link';
  6. import { generateSSRViewOptions } from '~/services/renderer/renderer';
  7. import { useIsNotFound } from '~/stores/page';
  8. import { useViewOptions } from '~/stores/renderer';
  9. import loggerFactory from '~/utils/logger';
  10. import { MainPane } from './Layout/MainPane';
  11. import RevisionRenderer from './Page/RevisionRenderer';
  12. import ShareLinkAlert from './Page/ShareLinkAlert';
  13. import type { PageSideContentsProps } from './PageSideContents';
  14. const logger = loggerFactory('growi:Page');
  15. const PageSideContents = dynamic<PageSideContentsProps>(() => import('./PageSideContents').then(mod => mod.PageSideContents), { ssr: false });
  16. const ForbiddenPage = dynamic(() => import('./ForbiddenPage'), { ssr: false });
  17. type Props = {
  18. pagePath: string,
  19. rendererConfig: RendererConfig,
  20. page?: IPagePopulatedToShowRevision,
  21. shareLink?: IShareLinkHasId,
  22. isExpired: boolean,
  23. disableLinkSharing: boolean,
  24. }
  25. export const ShareLinkPageView = (props: Props): JSX.Element => {
  26. const {
  27. pagePath, rendererConfig,
  28. page, shareLink,
  29. isExpired, disableLinkSharing,
  30. } = props;
  31. const { data: isNotFoundMeta } = useIsNotFound();
  32. const { data: viewOptions } = useViewOptions();
  33. const isNotFound = isNotFoundMeta || page == null || shareLink == null;
  34. const specialContents = useMemo(() => {
  35. if (disableLinkSharing) {
  36. return <ForbiddenPage isLinkSharingDisabled={props.disableLinkSharing} />;
  37. }
  38. }, [disableLinkSharing, props.disableLinkSharing]);
  39. const sideContents = !isNotFound
  40. ? (
  41. <PageSideContents page={page} />
  42. )
  43. : null;
  44. const Contents = () => {
  45. if (isNotFound) {
  46. return <></>;
  47. }
  48. if (isExpired) {
  49. return (
  50. <>
  51. <h2 className="text-muted mt-4">
  52. <i className="icon-ban" aria-hidden="true" />
  53. <span> Page is expired</span>
  54. </h2>
  55. </>
  56. );
  57. }
  58. const rendererOptions = viewOptions ?? generateSSRViewOptions(rendererConfig, pagePath);
  59. const markdown = page.revision.body;
  60. return (
  61. <>
  62. <RevisionRenderer rendererOptions={rendererOptions} markdown={markdown} />
  63. </>
  64. );
  65. };
  66. return (
  67. <MainPane
  68. sideContents={sideContents}
  69. >
  70. { specialContents }
  71. { specialContents == null && (
  72. <>
  73. { isNotFound && (
  74. <h2 className="text-muted mt-4">
  75. <i className="icon-ban" aria-hidden="true" />
  76. <span> Page is not found</span>
  77. </h2>
  78. ) }
  79. { !isNotFound && (
  80. <>
  81. <ShareLinkAlert expiredAt={shareLink.expiredAt} createdAt={shareLink.createdAt} />
  82. <div className="mb-5">
  83. <Contents />
  84. </div>
  85. </>
  86. ) }
  87. </>
  88. ) }
  89. </MainPane>
  90. );
  91. };