layout.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import type React from 'react';
  2. import type { ReactElement, ReactNode } from 'react';
  3. import { useMemo } from 'react';
  4. import type { TFunction } from 'i18next';
  5. import { useTranslation } from 'next-i18next';
  6. import { useCustomTitle } from '~/pages/utils/page-title-customization';
  7. import { AdminPageFrame } from './AdminPageFrame';
  8. import type { AdminCommonProps, AnyUnstatedContainer } from './types';
  9. import { useUnstatedContainers } from './use-unstated-container';
  10. export interface AdminLayoutOptions<P extends AdminCommonProps> {
  11. title: string | ((props: P, t: TFunction) => string);
  12. containerFactories?: Array<() => Promise<AnyUnstatedContainer>>;
  13. }
  14. export function createAdminPageLayout<P extends AdminCommonProps>(
  15. options: AdminLayoutOptions<P>,
  16. ) {
  17. return function getLayout(page: ReactElement<P>): ReactNode {
  18. const Wrapper: React.FC = () => {
  19. const { t } = useTranslation('admin');
  20. const rawTitle =
  21. typeof options.title === 'function'
  22. ? options.title(page.props, t)
  23. : options.title;
  24. const title = useCustomTitle(rawTitle);
  25. const factories = useMemo(() => options.containerFactories ?? [], []);
  26. const containers = useUnstatedContainers(factories);
  27. return (
  28. <AdminPageFrame
  29. title={title}
  30. componentTitle={rawTitle}
  31. isAccessDeniedForNonAdminUser={
  32. page.props.isAccessDeniedForNonAdminUser
  33. }
  34. containers={containers}
  35. >
  36. {page}
  37. </AdminPageFrame>
  38. );
  39. };
  40. return <Wrapper />;
  41. };
  42. }
  43. export default createAdminPageLayout;