Make each admin page specify is own layout. Closes #2584

This commit is contained in:
Gabe Kangas 2023-01-15 23:11:44 -08:00
parent 3b232f31e1
commit 2853752937
No known key found for this signature in database
GPG key ID: 4345B2060657F330
24 changed files with 167 additions and 37 deletions

View file

@ -1,6 +1,5 @@
/* eslint-disable @next/next/no-css-tags */ /* eslint-disable @next/next/no-css-tags */
import { AppProps } from 'next/app'; import { FC, ReactElement } from 'react';
import { FC } from 'react';
import ServerStatusProvider from '../../utils/server-status-context'; import ServerStatusProvider from '../../utils/server-status-context';
import AlertMessageProvider from '../../utils/alert-message-context'; import AlertMessageProvider from '../../utils/alert-message-context';
import { MainLayout } from '../admin/MainLayout'; import { MainLayout } from '../admin/MainLayout';
@ -12,7 +11,12 @@ edited or maintained. Instead we are using css modules everywhere. So if you
need to change a style rewrite the css file as a css module and import it need to change a style rewrite the css file as a css module and import it
into the component that needs it, removing it from this global list. into the component that needs it, removing it from this global list.
*/ */
export const AdminLayout: FC<AppProps> = ({ Component, pageProps }) => (
type AdminLayoutProps = {
page: ReactElement;
};
export const AdminLayout: FC<AdminLayoutProps> = ({ page }) => (
<> <>
<link rel="stylesheet" href="/styles/admin/main-layout.css" /> <link rel="stylesheet" href="/styles/admin/main-layout.css" />
<link rel="stylesheet" href="/styles/admin/form-textfields.css" /> <link rel="stylesheet" href="/styles/admin/form-textfields.css" />
@ -26,9 +30,7 @@ export const AdminLayout: FC<AppProps> = ({ Component, pageProps }) => (
<ServerStatusProvider> <ServerStatusProvider>
<AlertMessageProvider> <AlertMessageProvider>
<MainLayout> <MainLayout>{page}</MainLayout>
<Component {...pageProps} />
</MainLayout>
</AlertMessageProvider> </AlertMessageProvider>
</ServerStatusProvider> </ServerStatusProvider>
</> </>

View file

@ -14,9 +14,6 @@ import { AppProps } from 'next/app';
import { ReactElement, ReactNode } from 'react'; import { ReactElement, ReactNode } from 'react';
import { NextPage } from 'next'; import { NextPage } from 'next';
import { RecoilRoot } from 'recoil'; import { RecoilRoot } from 'recoil';
import { Router, useRouter } from 'next/router';
import { AdminLayout } from '../components/layouts/AdminLayout';
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & { export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode; getLayout?: (page: ReactElement) => ReactNode;
@ -27,12 +24,6 @@ type AppPropsWithLayout = AppProps & {
}; };
export default function App({ Component, pageProps }: AppPropsWithLayout) { export default function App({ Component, pageProps }: AppPropsWithLayout) {
const router = useRouter() as Router;
const isAdminPage = router.pathname.startsWith('/admin');
if (isAdminPage) {
return <AdminLayout pageProps={pageProps} Component={Component} router={router} />;
}
const layout = Component.getLayout ?? (page => page); const layout = Component.getLayout ?? (page => page);
return layout( return layout(

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, ReactElement } from 'react';
import { import {
Table, Table,
Tag, Tag,
@ -23,6 +23,8 @@ import {
CREATE_ACCESS_TOKEN, CREATE_ACCESS_TOKEN,
} from '../../utils/apis'; } from '../../utils/apis';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Title, Paragraph } = Typography; const { Title, Paragraph } = Typography;
// Lazy loaded components // Lazy loaded components
@ -271,4 +273,9 @@ const AccessTokens = () => {
</div> </div>
); );
}; };
AccessTokens.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default AccessTokens; export default AccessTokens;

View file

@ -1,7 +1,7 @@
import { Button, Checkbox, Form, Input, Modal, Space, Table, Typography } from 'antd'; import { Button, Checkbox, Form, Input, Modal, Space, Table, Typography } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import React, { useContext, useEffect, useState } from 'react'; import React, { ReactElement, useContext, useEffect, useState } from 'react';
import { FormStatusIndicator } from '../../components/admin/FormStatusIndicator'; import { FormStatusIndicator } from '../../components/admin/FormStatusIndicator';
import { ExternalAction } from '../../interfaces/external-action'; import { ExternalAction } from '../../interfaces/external-action';
import { import {
@ -13,6 +13,8 @@ import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../utils/inp
import { ServerStatusContext } from '../../utils/server-status-context'; import { ServerStatusContext } from '../../utils/server-status-context';
import { isValidUrl, DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls'; import { isValidUrl, DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Title, Paragraph } = Typography; const { Title, Paragraph } = Typography;
// Lazy loaded components // Lazy loaded components
@ -375,4 +377,8 @@ const Actions = () => {
</div> </div>
); );
}; };
Actions.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default Actions; export default Actions;

View file

@ -1,6 +1,6 @@
import { Button, Space, Table, Typography, Upload } from 'antd'; import { Button, Space, Table, Typography, Upload } from 'antd';
import { RcFile } from 'antd/lib/upload'; import { RcFile } from 'antd/lib/upload';
import React, { useEffect, useState } from 'react'; import React, { ReactElement, useEffect, useState } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import FormStatusIndicator from '../../../components/admin/FormStatusIndicator'; import FormStatusIndicator from '../../../components/admin/FormStatusIndicator';
@ -16,6 +16,8 @@ import {
import { RESET_TIMEOUT } from '../../../utils/config-constants'; import { RESET_TIMEOUT } from '../../../utils/config-constants';
import { URL_CUSTOM_EMOJIS } from '../../../utils/constants'; import { URL_CUSTOM_EMOJIS } from '../../../utils/constants';
import { AdminLayout } from '../../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const DeleteOutlined = dynamic(() => import('@ant-design/icons/DeleteOutlined'), { const DeleteOutlined = dynamic(() => import('@ant-design/icons/DeleteOutlined'), {
@ -189,4 +191,8 @@ const Emoji = () => {
); );
}; };
Emoji.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default Emoji; export default Emoji;

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, ReactElement } from 'react';
import { Table, Typography, Button } from 'antd'; import { Table, Typography, Button } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { ColumnsType } from 'antd/es/table'; import { ColumnsType } from 'antd/es/table';
@ -16,6 +16,8 @@ import { isEmptyObject } from '../../../utils/format';
import { MessageVisiblityToggle } from '../../../components/admin/MessageVisiblityToggle'; import { MessageVisiblityToggle } from '../../../components/admin/MessageVisiblityToggle';
import { UserPopover } from '../../../components/admin/UserPopover'; import { UserPopover } from '../../../components/admin/UserPopover';
import { AdminLayout } from '../../../components/layouts/AdminLayout';
const { Title } = Typography; const { Title } = Typography;
// Lazy loaded components // Lazy loaded components
@ -261,3 +263,7 @@ export default function Chat() {
</div> </div>
); );
} }
Chat.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect, useContext } from 'react'; import React, { useState, useEffect, useContext, ReactElement } from 'react';
import { Tabs } from 'antd'; import { Tabs } from 'antd';
import { ServerStatusContext } from '../../../utils/server-status-context'; import { ServerStatusContext } from '../../../utils/server-status-context';
import { import {
@ -12,6 +12,8 @@ import { UserTable } from '../../../components/admin/UserTable';
import { ClientTable } from '../../../components/admin/ClientTable'; import { ClientTable } from '../../../components/admin/ClientTable';
import { BannedIPsTable } from '../../../components/admin/BannedIPsTable'; import { BannedIPsTable } from '../../../components/admin/BannedIPsTable';
import { AdminLayout } from '../../../components/layouts/AdminLayout';
export const FETCH_INTERVAL = 10 * 1000; // 10 sec export const FETCH_INTERVAL = 10 * 1000; // 10 sec
export default function ChatUsers() { export default function ChatUsers() {
@ -108,3 +110,7 @@ export default function ChatUsers() {
return <Tabs defaultActiveKey="1" items={items} />; return <Tabs defaultActiveKey="1" items={items} />;
} }
ChatUsers.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,5 +1,5 @@
import { Typography } from 'antd'; import { Typography } from 'antd';
import React, { useContext, useEffect, useState } from 'react'; import React, { ReactElement, useContext, useEffect, useState } from 'react';
import { TEXTFIELD_TYPE_TEXTAREA } from '../../components/admin/TextField'; import { TEXTFIELD_TYPE_TEXTAREA } from '../../components/admin/TextField';
import { TextFieldWithSubmit } from '../../components/admin/TextFieldWithSubmit'; import { TextFieldWithSubmit } from '../../components/admin/TextFieldWithSubmit';
import { ToggleSwitch } from '../../components/admin/ToggleSwitch'; import { ToggleSwitch } from '../../components/admin/ToggleSwitch';
@ -26,6 +26,8 @@ import {
} from '../../utils/config-constants'; } from '../../utils/config-constants';
import { ServerStatusContext } from '../../utils/server-status-context'; import { ServerStatusContext } from '../../utils/server-status-context';
import { AdminLayout } from '../../components/layouts/AdminLayout';
export default function ConfigChat() { export default function ConfigChat() {
const { Title } = Typography; const { Title } = Typography;
const [formDataValues, setFormDataValues] = useState(null); const [formDataValues, setFormDataValues] = useState(null);
@ -220,3 +222,7 @@ export default function ConfigChat() {
</div> </div>
); );
} }
ConfigChat.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,6 +1,6 @@
/* eslint-disable react/no-unescaped-entities */ /* eslint-disable react/no-unescaped-entities */
import { Typography, Modal, Button, Row, Col, Alert } from 'antd'; import { Typography, Modal, Button, Row, Col, Alert } from 'antd';
import React, { useContext, useEffect, useState } from 'react'; import React, { ReactElement, useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
TEXTFIELD_TYPE_TEXT, TEXTFIELD_TYPE_TEXT,
@ -27,6 +27,8 @@ import {
import { ServerStatusContext } from '../../utils/server-status-context'; import { ServerStatusContext } from '../../utils/server-status-context';
import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../utils/input-statuses'; import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../utils/input-statuses';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const FederationInfoModal = ({ cancelPressed, okPressed }) => ( const FederationInfoModal = ({ cancelPressed, okPressed }) => (
<Modal <Modal
width="70%" width="70%"
@ -343,4 +345,9 @@ const ConfigFederation = () => {
</div> </div>
); );
}; };
ConfigFederation.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default ConfigFederation; export default ConfigFederation;

View file

@ -1,5 +1,5 @@
import { Alert, Button, Col, Row, Typography } from 'antd'; import { Alert, Button, Col, Row, Typography } from 'antd';
import React, { useContext, useEffect, useState } from 'react'; import React, { ReactElement, useContext, useEffect, useState } from 'react';
import Link from 'next/link'; import Link from 'next/link';
import Discord from '../../components/admin/notification/discord'; import Discord from '../../components/admin/notification/discord';
@ -15,6 +15,8 @@ import { ServerStatusContext } from '../../utils/server-status-context';
import { UpdateArgs } from '../../types/config-section'; import { UpdateArgs } from '../../types/config-section';
import { isValidUrl } from '../../utils/urls'; import { isValidUrl } from '../../utils/urls';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Title } = Typography; const { Title } = Typography;
export default function ConfigNotify() { export default function ConfigNotify() {
@ -147,3 +149,7 @@ export default function ConfigNotify() {
</> </>
); );
} }
ConfigNotify.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,7 +1,9 @@
import React from 'react'; import React, { ReactElement } from 'react';
import { Typography } from 'antd'; import { Typography } from 'antd';
import EditSocialLinks from '../../components/admin/config/general/EditSocialLinks'; import EditSocialLinks from '../../components/admin/config/general/EditSocialLinks';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Title } = Typography; const { Title } = Typography;
export default function ConfigSocialThings() { export default function ConfigSocialThings() {
@ -13,3 +15,7 @@ export default function ConfigSocialThings() {
</div> </div>
); );
} }
ConfigSocialThings.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,9 +1,11 @@
import { Col, Collapse, Row, Typography } from 'antd'; import { Col, Collapse, Row, Typography } from 'antd';
import React from 'react'; import React, { ReactElement } from 'react';
import { CodecSelector as VideoCodecSelector } from '../../components/admin/CodecSelector'; import { CodecSelector as VideoCodecSelector } from '../../components/admin/CodecSelector';
import { VideoLatency } from '../../components/admin/VideoLatency'; import { VideoLatency } from '../../components/admin/VideoLatency';
import { CurrentVariantsTable } from '../../components/admin/CurrentVariantsTable'; import { CurrentVariantsTable } from '../../components/admin/CurrentVariantsTable';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Panel } = Collapse; const { Panel } = Collapse;
const { Title } = Typography; const { Title } = Typography;
@ -48,3 +50,7 @@ export default function ConfigVideoSettings() {
</div> </div>
); );
} }
ConfigVideoSettings.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,9 +1,11 @@
import React from 'react'; import React, { ReactElement } from 'react';
import { Tabs } from 'antd'; import { Tabs } from 'antd';
import GeneralConfig from '../../../../components/admin/config/general/GeneralConfig'; import GeneralConfig from '../../../../components/admin/config/general/GeneralConfig';
import AppearanceConfig from '../../../../components/admin/config/general/AppearanceConfig'; import AppearanceConfig from '../../../../components/admin/config/general/AppearanceConfig';
import { AdminLayout } from '../../../../components/layouts/AdminLayout';
export default function PublicFacingDetails() { export default function PublicFacingDetails() {
return ( return (
<div className="config-public-details-page"> <div className="config-public-details-page">
@ -26,3 +28,7 @@ export default function PublicFacingDetails() {
</div> </div>
); );
} }
PublicFacingDetails.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,10 +1,12 @@
import React from 'react'; import React, { ReactElement } from 'react';
import { Tabs } from 'antd'; import { Tabs } from 'antd';
import StreamKeys from '../../../../components/admin/config/server/StreamKeys'; import StreamKeys from '../../../../components/admin/config/server/StreamKeys';
import ServerConfig from '../../../../components/admin/config/server/ServerConfig'; import ServerConfig from '../../../../components/admin/config/server/ServerConfig';
import StorageConfig from '../../../../components/admin/config/server/StorageConfig'; import StorageConfig from '../../../../components/admin/config/server/StorageConfig';
import { AdminLayout } from '../../../../components/layouts/AdminLayout';
export default function PublicFacingDetails() { export default function PublicFacingDetails() {
return ( return (
<div className="config-public-details-page"> <div className="config-public-details-page">
@ -32,3 +34,7 @@ export default function PublicFacingDetails() {
</div> </div>
); );
} }
PublicFacingDetails.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'; import React, { ReactElement, useEffect, useState } from 'react';
import { Table, Typography } from 'antd'; import { Table, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table/interface'; import { ColumnsType } from 'antd/lib/table/interface';
import format from 'date-fns/format'; import format from 'date-fns/format';
@ -6,6 +6,8 @@ import { FEDERATION_ACTIONS, fetchData } from '../../../utils/apis';
import { isEmptyObject } from '../../../utils/format'; import { isEmptyObject } from '../../../utils/format';
import { AdminLayout } from '../../../components/layouts/AdminLayout';
const { Title, Paragraph } = Typography; const { Title, Paragraph } = Typography;
export interface Action { export interface Action {
@ -134,3 +136,7 @@ export default function FediverseActions() {
</div> </div>
); );
} }
FediverseActions.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,4 +1,4 @@
import React, { useEffect, useState, useContext } from 'react'; import React, { useEffect, useState, useContext, ReactElement } from 'react';
import { Table, Avatar, Button, Tabs } from 'antd'; import { Table, Avatar, Button, Tabs } from 'antd';
import { ColumnsType, SortOrder } from 'antd/lib/table/interface'; import { ColumnsType, SortOrder } from 'antd/lib/table/interface';
import format from 'date-fns/format'; import format from 'date-fns/format';
@ -13,6 +13,8 @@ import {
} from '../../../utils/apis'; } from '../../../utils/apis';
import { isEmptyObject } from '../../../utils/format'; import { isEmptyObject } from '../../../utils/format';
import { AdminLayout } from '../../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const UserAddOutlined = dynamic(() => import('@ant-design/icons/UserAddOutlined'), { const UserAddOutlined = dynamic(() => import('@ant-design/icons/UserAddOutlined'), {
@ -352,3 +354,7 @@ export default function FediverseFollowers() {
</div> </div>
); );
} }
FediverseFollowers.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,10 +1,12 @@
import { Row, Col, Typography } from 'antd'; import { Row, Col, Typography } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { ReactElement, useEffect, useState } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../../utils/apis'; import { fetchData, FETCH_INTERVAL, HARDWARE_STATS } from '../../utils/apis';
import { Chart } from '../../components/admin/Chart'; import { Chart } from '../../components/admin/Chart';
import { StatisticItem } from '../../components/admin/StatisticItem'; import { StatisticItem } from '../../components/admin/StatisticItem';
import { AdminLayout } from '../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const BulbOutlined = dynamic(() => import('@ant-design/icons/BulbOutlined'), { const BulbOutlined = dynamic(() => import('@ant-design/icons/BulbOutlined'), {
@ -123,3 +125,7 @@ export default function HardwareInfo() {
</> </>
); );
} }
HardwareInfo.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -2,9 +2,11 @@ import { Button, Card, Col, Divider, Result, Row } from 'antd';
import Meta from 'antd/lib/card/Meta'; import Meta from 'antd/lib/card/Meta';
import Title from 'antd/lib/typography/Title'; import Title from 'antd/lib/typography/Title';
import React from 'react'; import React, { ReactElement } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { AdminLayout } from '../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const ApiTwoTone = dynamic(() => import('@ant-design/icons/ApiTwoTone'), { const ApiTwoTone = dynamic(() => import('@ant-design/icons/ApiTwoTone'), {
@ -258,3 +260,7 @@ export default function Help() {
</div> </div>
); );
} }
Help.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,5 +1,5 @@
/* eslint-disable @next/next/no-css-tags */ /* eslint-disable @next/next/no-css-tags */
import React, { useState, useEffect, useContext } from 'react'; import React, { useState, useEffect, useContext, ReactElement } from 'react';
import { Skeleton, Card, Statistic, Row, Col } from 'antd'; import { Skeleton, Card, Statistic, Row, Col } from 'antd';
import { formatDistanceToNow, formatRelative } from 'date-fns'; import { formatDistanceToNow, formatRelative } from 'date-fns';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
@ -12,6 +12,8 @@ import { LOGS_WARN, fetchData, FETCH_INTERVAL } from '../../utils/apis';
import { formatIPAddress, isEmptyObject } from '../../utils/format'; import { formatIPAddress, isEmptyObject } from '../../utils/format';
import { NewsFeed } from '../../components/admin/NewsFeed'; import { NewsFeed } from '../../components/admin/NewsFeed';
import { AdminLayout } from '../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const UserOutlined = dynamic(() => import('@ant-design/icons/UserOutlined'), { const UserOutlined = dynamic(() => import('@ant-design/icons/UserOutlined'), {
@ -189,3 +191,7 @@ export default function Home() {
</div> </div>
); );
} }
Home.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,8 +1,10 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, ReactElement } from 'react';
import { LogTable } from '../../components/admin/LogTable'; import { LogTable } from '../../components/admin/LogTable';
import { LOGS_ALL, fetchData } from '../../utils/apis'; import { LOGS_ALL, fetchData } from '../../utils/apis';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const FETCH_INTERVAL = 5 * 1000; // 5 sec const FETCH_INTERVAL = 5 * 1000; // 5 sec
export default function Logs() { export default function Logs() {
@ -32,3 +34,7 @@ export default function Logs() {
return <LogTable logs={logs} pageSize={20} />; return <LogTable logs={logs} pageSize={20} />;
} }
Logs.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -1,12 +1,14 @@
/* eslint-disable react/no-unescaped-entities */ /* eslint-disable react/no-unescaped-entities */
// import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons'; // import { BulbOutlined, LaptopOutlined, SaveOutlined } from '@ant-design/icons';
import { Row, Col, Typography, Space, Statistic, Card, Alert, Spin } from 'antd'; import { Row, Col, Typography, Space, Statistic, Card, Alert, Spin } from 'antd';
import React, { ReactNode, useEffect, useState } from 'react'; import React, { ReactElement, ReactNode, useEffect, useState } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { fetchData, FETCH_INTERVAL, API_STREAM_HEALTH_METRICS } from '../../utils/apis'; import { fetchData, FETCH_INTERVAL, API_STREAM_HEALTH_METRICS } from '../../utils/apis';
import { Chart } from '../../components/admin/Chart'; import { Chart } from '../../components/admin/Chart';
import { StreamHealthOverview } from '../../components/admin/StreamHealthOverview'; import { StreamHealthOverview } from '../../components/admin/StreamHealthOverview';
import { AdminLayout } from '../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const ClockCircleOutlined = dynamic(() => import('@ant-design/icons/ClockCircleOutlined'), { const ClockCircleOutlined = dynamic(() => import('@ant-design/icons/ClockCircleOutlined'), {
@ -424,4 +426,9 @@ const StreamHealth = () => {
</> </>
); );
}; };
StreamHealth.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default StreamHealth; export default StreamHealth;

View file

@ -1,8 +1,10 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, ReactElement } from 'react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import { Table, Typography } from 'antd'; import { Table, Typography } from 'antd';
import { getGithubRelease } from '../../utils/apis'; import { getGithubRelease } from '../../utils/apis';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Title } = Typography; const { Title } = Typography;
const AssetTable = assets => { const AssetTable = assets => {
@ -72,4 +74,9 @@ const Logs = () => {
</div> </div>
); );
}; };
Logs.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default Logs; export default Logs;

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect, useContext } from 'react'; import React, { useState, useEffect, useContext, ReactElement } from 'react';
import { Row, Col, Typography, Menu, Dropdown, Spin, Alert } from 'antd'; import { Row, Col, Typography, Menu, Dropdown, Spin, Alert } from 'antd';
import { getUnixTime, sub } from 'date-fns'; import { getUnixTime, sub } from 'date-fns';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
@ -10,6 +10,8 @@ import { ServerStatusContext } from '../../utils/server-status-context';
import { VIEWERS_OVER_TIME, ACTIVE_VIEWER_DETAILS, fetchData } from '../../utils/apis'; import { VIEWERS_OVER_TIME, ACTIVE_VIEWER_DETAILS, fetchData } from '../../utils/apis';
import { AdminLayout } from '../../components/layouts/AdminLayout';
// Lazy loaded components // Lazy loaded components
const DownOutlined = dynamic(() => import('@ant-design/icons/DownOutlined'), { const DownOutlined = dynamic(() => import('@ant-design/icons/DownOutlined'), {
@ -157,3 +159,7 @@ export default function ViewersOverTime() {
</> </>
); );
} }
ViewersOverTime.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};

View file

@ -13,10 +13,12 @@ import {
Tooltip, Tooltip,
} from 'antd'; } from 'antd';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import React, { useEffect, useState } from 'react'; import React, { ReactElement, useEffect, useState } from 'react';
import { CREATE_WEBHOOK, DELETE_WEBHOOK, fetchData, WEBHOOKS } from '../../utils/apis'; import { CREATE_WEBHOOK, DELETE_WEBHOOK, fetchData, WEBHOOKS } from '../../utils/apis';
import { isValidUrl, DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls'; import { isValidUrl, DEFAULT_TEXTFIELD_URL_PATTERN } from '../../utils/urls';
import { AdminLayout } from '../../components/layouts/AdminLayout';
const { Title, Paragraph } = Typography; const { Title, Paragraph } = Typography;
// Lazy loaded components // Lazy loaded components
@ -254,4 +256,9 @@ const Webhooks = () => {
</div> </div>
); );
}; };
Webhooks.getLayout = function getLayout(page: ReactElement) {
return <AdminLayout page={page} />;
};
export default Webhooks; export default Webhooks;