104 lines
3.1 KiB
TypeScript
104 lines
3.1 KiB
TypeScript
import {
|
|
AppShell as MantineAppShell,
|
|
Box,
|
|
Button,
|
|
Group,
|
|
NavLink,
|
|
Stack,
|
|
Text,
|
|
Title,
|
|
} from '@pikku/mantine/core'
|
|
import { Link, Outlet } from '@tanstack/react-router'
|
|
import { asI18n } from '@pikku/react'
|
|
import { useState } from 'react'
|
|
import { m } from '@/i18n/messages'
|
|
import { useLocale } from '@/i18n/config'
|
|
import { usePikkuQuery } from '@project/functions-sdk/pikku/api.gen'
|
|
import { signOut } from '@/lib/auth'
|
|
import { LanguageSelector } from './LanguageSelector'
|
|
import { ThemeSelector } from './ThemeSelector'
|
|
|
|
export function AppShell() {
|
|
useLocale()
|
|
const session = usePikkuQuery('getSession', {})
|
|
const [isSigningOut, setIsSigningOut] = useState(false)
|
|
|
|
return (
|
|
<MantineAppShell
|
|
header={{ height: 88 }}
|
|
navbar={{ width: 250, breakpoint: 'sm' }}
|
|
padding="lg"
|
|
styles={{
|
|
main: {
|
|
background:
|
|
'radial-gradient(circle at top left, rgba(96, 165, 250, 0.12), transparent 26%), linear-gradient(180deg, #10203a 0%, #07111e 56%, #040913 100%)',
|
|
},
|
|
}}
|
|
>
|
|
<MantineAppShell.Header px="lg" py="md">
|
|
<Group justify="space-between" align="center" h="100%">
|
|
<div>
|
|
<Text tt="uppercase" fw={700} fz="xs" c="blue.3" style={{ letterSpacing: '0.18em' }}>
|
|
{m.app_shell__eyebrow()}
|
|
</Text>
|
|
<Title order={2}>{m.app_shell__title()}</Title>
|
|
</div>
|
|
<Group gap="md">
|
|
<LanguageSelector />
|
|
<ThemeSelector />
|
|
<Box
|
|
px="md"
|
|
py="xs"
|
|
style={{
|
|
border: '1px solid var(--mantine-color-dark-4)',
|
|
borderRadius: '1rem',
|
|
background: 'rgba(255,255,255,0.03)',
|
|
}}
|
|
>
|
|
<Text size="xs" c="dimmed">
|
|
{session.data?.name ? asI18n(session.data.name) : m.app_shell__signed_in()}
|
|
</Text>
|
|
<Text fw={600}>
|
|
{session.data?.email ? asI18n(session.data.email) : m.common__loading()}
|
|
</Text>
|
|
</Box>
|
|
<Button
|
|
variant="light"
|
|
radius="md"
|
|
loading={isSigningOut}
|
|
onClick={async () => {
|
|
setIsSigningOut(true)
|
|
try {
|
|
await signOut()
|
|
window.location.href = '/login'
|
|
} finally {
|
|
setIsSigningOut(false)
|
|
}
|
|
}}
|
|
>
|
|
{m.app_shell__sign_out()}
|
|
</Button>
|
|
</Group>
|
|
</Group>
|
|
</MantineAppShell.Header>
|
|
|
|
<MantineAppShell.Navbar p="md">
|
|
<Stack gap="xs">
|
|
<NavLink
|
|
component={Link}
|
|
to="/app"
|
|
label={m.app_shell__nav__message()}
|
|
description={m.app_shell__nav__message_description()}
|
|
variant="filled"
|
|
activeOptions={{ exact: true }}
|
|
/>
|
|
</Stack>
|
|
</MantineAppShell.Navbar>
|
|
|
|
<MantineAppShell.Main>
|
|
<Outlet />
|
|
</MantineAppShell.Main>
|
|
</MantineAppShell>
|
|
)
|
|
}
|