-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_app.tsx
More file actions
95 lines (92 loc) · 2.86 KB
/
Copy path_app.tsx
File metadata and controls
95 lines (92 loc) · 2.86 KB
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
import { Button } from '@astryxdesign/core/Button'
import {
createFileRoute,
Link,
Outlet,
redirect,
useNavigate,
} from '@tanstack/react-router'
import { useState } from 'react'
import { JobCreationDialog } from '../components/job-creation-dialog'
import { ThemeToggle } from '../components/theme-toggle'
import { authClient, getSession, isAdmin } from '../lib/auth'
import { clearProtectedQueries } from '../lib/query'
export const Route = createFileRoute('/_app')({
beforeLoad: async ({ location }) => {
const session = await getSession()
if (!session)
throw redirect({ to: '/sign-in', search: { redirect: location.href } })
return { session }
},
component: AppLayout,
})
function AppLayout() {
const { session } = Route.useRouteContext()
const navigate = useNavigate()
const [signingOut, setSigningOut] = useState(false)
const [isJobDialogOpen, setIsJobDialogOpen] = useState(false)
async function signOut() {
setSigningOut(true)
await authClient.signOut()
clearProtectedQueries()
await navigate({ to: '/sign-in', search: { redirect: undefined } })
}
return (
<div className="app-shell">
<header className="app-header">
<div className="app-bar">
<Link to="/jobs" className="brand">
Job Manager
</Link>
<nav className="app-nav" aria-label="Main navigation">
<Link to="/jobs" activeProps={{ 'aria-current': 'page' }}>
My jobs
</Link>
<Button
label="Create job"
variant="secondary"
onClick={() => setIsJobDialogOpen(true)}
/>
{isAdmin(session) && (
<>
<Link to="/admin" activeProps={{ 'aria-current': 'page' }}>
All jobs
</Link>
<Link
to="/admin/users"
activeProps={{ 'aria-current': 'page' }}
>
Users
</Link>
</>
)}
</nav>
<div className="account">
<span className="avatar" aria-hidden="true">
{session.user.name.slice(0, 1).toUpperCase()}
</span>
<span className="account-copy">
<strong>{session.user.name}</strong>
<span>{session.user.email}</span>
</span>
<ThemeToggle />
<Button
label={signingOut ? 'Signing out…' : 'Sign out'}
variant="secondary"
isLoading={signingOut}
onClick={() => void signOut()}
/>
</div>
</div>
</header>
<main className="app-content">
<Outlet />
</main>
<JobCreationDialog
isAdmin={isAdmin(session)}
isOpen={isJobDialogOpen}
onOpenChange={setIsJobDialogOpen}
/>
</div>
)
}