File size: 5,686 Bytes
d8cfa7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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