Spaces:
Paused
Paused
import { MobileOutlined, TwitterOutlined } from '@ant-design/icons' | |
import { Button, Layout, notification, Result, Typography } from 'antd' | |
import 'antd-country-phone-input/dist/index.css' | |
import pwaInstallHandler from 'pwa-install-handler' | |
import React, { lazy, Suspense, useEffect, useState } from 'react' | |
import { useThemeSwitcher } from 'react-css-theme-switcher' | |
import { Helmet } from 'react-helmet' | |
import LoadingScreen from 'react-loading-screen' | |
import { Redirect, Route, Switch, useLocation } from 'react-router-dom' | |
import useSWR from 'swr' | |
import useSWRImmutable from 'swr/immutable' | |
import Footer from './pages/components/Footer' | |
import Navbar from './pages/components/Navbar' | |
import { fetcher } from './utils/Fetcher' | |
const Startup = lazy( | |
() => import(/* webpackChunkName: 'StartupPage' */ './pages/Startup') | |
) | |
const Dashboard = lazy( | |
() => import(/* webpackChunkName: 'DashboardPage' */ './pages/dashboard') | |
) | |
const Settings = lazy( | |
() => import(/* webpackChunkName: 'SettingsPage' */ './pages/Settings') | |
) | |
const View = lazy( | |
() => import(/* webpackChunkName: 'ViewPage' */ './pages/view/index') | |
) | |
const Login = lazy( | |
() => import(/* webpackChunkName: 'LoginPage' */ './pages/Login') | |
) | |
const Admin = lazy( | |
() => import(/* webpackChunkName: 'AdminPage' */ './pages/admin/index') | |
) | |
const NotFound = lazy( | |
() => import(/* webpackChunkName: 'NotFoundPage' */ './pages/errors/NotFound') | |
) | |
function App(): React.ReactElement { | |
const { pathname } = useLocation() | |
const { switcher } = useThemeSwitcher() | |
const { data } = useSWR('/utils/maintenance', fetcher) | |
const { data: me, error: errorMe, mutate: mutateMe } = useSWRImmutable('/users/me', fetcher) | |
const [loading, setLoading] = useState<boolean>(true) | |
useEffect(() => document.querySelector('.App')?.scrollIntoView(), [pathname]) | |
useEffect(() => { | |
if (me?.user.settings?.theme === 'light') { | |
switcher({ theme: 'light' }) | |
} else { | |
switcher({ theme: 'dark' }) | |
} | |
}, [me, errorMe]) | |
useEffect(() => { | |
pwaInstallHandler.addListener(canInstall => { | |
if (canInstall && (!localStorage.getItem('install') || new Date().getTime() - Number(localStorage.getItem('install')) > 5 * 8.64e+7)) { | |
notification.info({ | |
key: 'appInstallInfo', | |
message: 'Install App', | |
description: <> | |
<Typography.Paragraph> | |
You can install the app on your device for a better experience. | |
</Typography.Paragraph> | |
<Typography.Paragraph style={{ textAlign: 'right' }}> | |
<Button type="primary" onClick={pwaInstallHandler.install} icon={<MobileOutlined />} shape="round"> | |
Install Now | |
</Button> | |
</Typography.Paragraph> | |
</>, | |
onClose: () => localStorage.setItem('install', new Date().getTime().toString()) | |
}) | |
} | |
}) | |
pwaInstallHandler.removeListener(_canInstall => { | |
notification.close('appInstallInfo') | |
}) | |
}, []) | |
useEffect(() => { | |
window.addEventListener('message', event => { | |
if (event.data.type === 'files') { | |
localStorage.setItem('files', JSON.stringify(event.data.files)) | |
} | |
}) | |
}, []) | |
useEffect(() => { | |
const url = localStorage.getItem('BASE_URL') | |
if (url && !/^http/.test(url) || /\/startup\?reset\=1/.test(window.location.href)) { | |
localStorage.removeItem('BASE_URL') | |
} else if (url && url !== window.location.origin) { | |
window.location.replace(url as string) | |
} | |
}, []) | |
useEffect(() => { | |
window.addEventListener('load', () => setTimeout(() => { | |
setLoading(false) | |
}, 1500)) | |
}, []) | |
return ( | |
<LoadingScreen | |
loading={loading} | |
bgColor='#141414' | |
spinnerColor='#9ee5f8' | |
textColor='#676767' | |
logoSrc='/logo192.png'> | |
<Layout className="App"> | |
<Helmet> | |
<meta name="theme-color" content={me?.user.settings?.theme === 'dark' ? '#1F1F1F' : '#0088CC'} /> | |
</Helmet> | |
{data?.maintenance ? <div style={{ minHeight: '100vh', paddingTop: '20vh' }}> | |
<Result | |
status="warning" | |
title="This site is under maintenance" | |
subTitle="We're preparing to serve you better." | |
extra={ | |
<Button shape="round" type="primary" icon={<TwitterOutlined />} href="https://twitter.com/teledriveapp"> | |
Follow us for updates | |
</Button> | |
} | |
/> | |
</div> : <> | |
{!/^\/view\/.*/gi.test(pathname) && <Navbar user={me?.user} />} | |
<div style={{ minHeight: '88vh' }}> | |
<Suspense fallback={<></>}> | |
<Switch> | |
<Route path="/startup" exact component={Startup} /> | |
<Route path="/dashboard/:type?" exact component={Dashboard} /> | |
<Route path="/settings" exact component={() => <Settings me={me} error={errorMe} mutate={mutateMe} />} /> | |
<Route path="/view/:id" exact component={View} /> | |
<Route path="/login" exact> | |
{me?.user && !localStorage.getItem('experimental') ? <Redirect to="/dashboard" /> : <Login me={me} />} | |
</Route> | |
<Route path="/admin" exact component={() => <Admin me={me} errorMe={errorMe} />} /> | |
<Route path="/" exact> | |
<Redirect to="/dashboard" /> | |
</Route> | |
<Route component={NotFound} /> | |
</Switch> | |
</Suspense> | |
</div> | |
{/^\/view\/.*/gi.test(pathname) || /\/startup/.test(pathname) ? <></> : <Footer me={me} />} | |
</>} | |
</Layout> | |
</LoadingScreen> | |
) | |
} | |
export default App | |