| 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( './pages/Startup') |
| ) |
| const Dashboard = lazy( |
| () => import( './pages/dashboard') |
| ) |
| const Settings = lazy( |
| () => import( './pages/Settings') |
| ) |
| const View = lazy( |
| () => import( './pages/view/index') |
| ) |
| const Login = lazy( |
| () => import( './pages/Login') |
| ) |
| const Admin = lazy( |
| () => import( './pages/admin/index') |
| ) |
| const NotFound = lazy( |
| () => import( './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 |
|
|