upd: routing dev
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { ColorSchemeScript, MantineProvider, createTheme } from '@mantine/core'
|
||||
import '@mantine/core/styles.css'
|
||||
import '@mantine/notifications/styles.css'
|
||||
import { ModalsProvider } from '@mantine/modals'
|
||||
import { Notifications } from '@mantine/notifications'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { createRouter, RouterProvider } from '@tanstack/react-router'
|
||||
@@ -64,9 +65,11 @@ export function App() {
|
||||
<ColorSchemeScript defaultColorScheme="auto" />
|
||||
<MantineProvider theme={theme} defaultColorScheme="auto">
|
||||
<Notifications />
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={router} />
|
||||
</QueryClientProvider>
|
||||
<ModalsProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={router} />
|
||||
</QueryClientProvider>
|
||||
</ModalsProvider>
|
||||
</MantineProvider>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -3,6 +3,12 @@ import { useNavigate } from '@tanstack/react-router'
|
||||
|
||||
export type Role = 'USER' | 'ADMIN' | 'DEVELOPER'
|
||||
|
||||
export function getDefaultRoute(role: Role): string {
|
||||
if (role === 'DEVELOPER') return '/dev'
|
||||
if (role === 'ADMIN') return '/dashboard'
|
||||
return '/profile'
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: string
|
||||
name: string
|
||||
@@ -42,7 +48,7 @@ export function useLogin() {
|
||||
}),
|
||||
onSuccess: (data) => {
|
||||
queryClient.setQueryData(['auth', 'session'], data)
|
||||
navigate({ to: data.user.role === 'USER' ? '/profile' : '/dashboard' })
|
||||
navigate({ to: getDefaultRoute(data.user.role) })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
42
src/frontend/hooks/usePresence.ts
Normal file
42
src/frontend/hooks/usePresence.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useSession } from './useAuth'
|
||||
|
||||
export function usePresence() {
|
||||
const { data } = useSession()
|
||||
const [onlineUserIds, setOnlineUserIds] = useState<string[]>([])
|
||||
const wsRef = useRef<WebSocket | null>(null)
|
||||
const reconnectTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (!data?.user) return
|
||||
|
||||
function connect() {
|
||||
const proto = location.protocol === 'https:' ? 'wss' : 'ws'
|
||||
const ws = new WebSocket(`${proto}://${location.host}/ws/presence`)
|
||||
wsRef.current = ws
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
const msg = JSON.parse(e.data)
|
||||
if (msg.type === 'presence') setOnlineUserIds(msg.online)
|
||||
}
|
||||
ws.onclose = () => {
|
||||
wsRef.current = null
|
||||
reconnectTimer.current = setTimeout(connect, 3000)
|
||||
}
|
||||
ws.onerror = () => ws.close()
|
||||
}
|
||||
|
||||
connect()
|
||||
|
||||
return () => {
|
||||
clearTimeout(reconnectTimer.current)
|
||||
if (wsRef.current) {
|
||||
wsRef.current.onclose = null
|
||||
wsRef.current.close()
|
||||
wsRef.current = null
|
||||
}
|
||||
}
|
||||
}, [data?.user?.id, data?.user])
|
||||
|
||||
return { onlineUserIds }
|
||||
}
|
||||
1481
src/frontend/routes/dev.tsx
Normal file
1481
src/frontend/routes/dev.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,8 @@ export const Route = createFileRoute('/login')({
|
||||
queryFn: () => fetch('/api/auth/session', { credentials: 'include' }).then((r) => r.json()),
|
||||
})
|
||||
if (data?.user) {
|
||||
throw redirect({ to: data.user.role === 'USER' ? '/profile' : '/dashboard' })
|
||||
const dest = data.user.role === 'DEVELOPER' ? '/dev' : data.user.role === 'USER' ? '/profile' : '/dashboard'
|
||||
throw redirect({ to: dest })
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) return
|
||||
|
||||
Reference in New Issue
Block a user