Spaces:
Paused
Paused
File size: 5,686 Bytes
7262ac3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
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
|