-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.tsx
96 lines (84 loc) · 3.29 KB
/
App.tsx
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
import { Link, Outlet, useLocation, useOutlet } from 'react-router-dom'
import { createContext, Dispatch, SetStateAction, useEffect, useState } from 'react'
import { auth } from '../../server/firebase.ts'
import Nav from './Nav.tsx'
import icon from '../../icons/icon.png'
import '../styles/app.scss'
import CacheBuster from 'react-cache-buster'
import { version } from '../../package.json'
import { User as FirebaseUser, UserInfo } from 'firebase/auth';
interface User extends FirebaseUser {
providerData: UserInfo[];
}
export default function App() {
const location = useLocation().key
const [user, setUser] = useState(auth.currentUser)
const [isAuthLoaded, setIsAuthLoaded] = useState(false)
const [isPageLoaded, setIsPageLoaded] = useState(false)
const [showLoading, setShowLoading] = useState(false)
const hasLoaded = isAuthLoaded && isPageLoaded
const loader = hasLoaded ? null : setTimeout(() => {
setShowLoading(true)
}, 2000)
useEffect(() => {
return auth.onAuthStateChanged((user) => {
setUser(user || null)
setIsAuthLoaded(true)
if (!showLoading && typeof loader == "number") clearTimeout(loader)
})
}, [loader, showLoading])
// Reset the loading on location change
useEffect(() => {
return () => {
setIsPageLoaded(false)
}
}, [location])
// Log the outlet component element name
let page = useOutlet()?.props.children.props.routeContext.matches.at(-1).pathname.split('/')[1] || 'home'
if (page == 'logout') page = 'login'
if (!(isPageLoaded && page == "project")) {
// Set the page title
document.title = "SeriesMingle"
if (page !== 'home') document.title = `${page.charAt(0).toUpperCase()}${page.slice(1)} | ${document.title}`
}
const loading = (hasLoaded: boolean) => <div id="loading" className={hasLoaded ? 'loaded' : 'loading'}>
<div className="lds-ripple">
<div></div>
<div></div>
</div>
<span className="scanline"></span>
</div>
return (
<CacheBuster
currentVersion={version}
isEnabled={process.env.NODE_ENV === 'production'}
reloadOnDowngrade={true}
isVerboseMode={true}
loadingComponent={loading(hasLoaded)}
>
{showLoading && loading(hasLoaded)}
{isAuthLoaded &&
<UserContext.Provider value={{ user, setUser }}>
<LoadingContext.Provider value={{ isPageLoaded, setIsPageLoaded }}>
<div id={page}>
<header id="nav-bar">
<Link to="/" id="home-link" aria-label="Home Page">
<img src={icon} alt="SeriesMingle Logo" id="logo" />
</Link>
<input type="checkbox" id="nav-toggle" />
<label htmlFor="nav-toggle" id="nav-toggle-label" aria-label="Toggle Navigation">
<span></span>
<span></span>
<span></span>
</label>
<Nav page={page} user={user} />
</header>
<Outlet />
</div>
</LoadingContext.Provider>
</UserContext.Provider>}
</CacheBuster>
)
}
export const UserContext = createContext({} as { user: User | null, setUser: Dispatch<SetStateAction<User | null>> })
export const LoadingContext = createContext({} as { isPageLoaded: boolean, setIsPageLoaded: Dispatch<SetStateAction<boolean>> })