Первоначальная версия VidConf

This commit is contained in:
2026-07-23 01:04:01 +03:00
commit 896455381a
335 changed files with 61527 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'
import { getMe, login as apiLogin, logout as apiLogout, type CurrentUser } from '@/api/auth'
import { authStore } from '@/auth/authStore'
import { refreshAccessToken } from '@/api/client'
import { AuthContext, type AuthContextValue, type AuthStatus } from '@/auth/authContext'
/**
* Провайдер сессии пользователя.
* При монтировании приложения пытается восстановить сессию через
* silent-refresh (httpOnly refresh-cookie), т.к. access-токен в памяти
* теряется при перезагрузке страницы.
*/
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<CurrentUser | null>(null)
const [status, setStatus] = useState<AuthStatus>('loading')
useEffect(() => {
let cancelled = false
async function bootstrap() {
const restored = await refreshAccessToken()
if (cancelled) return
if (!restored) {
setStatus('unauthenticated')
return
}
try {
const me = await getMe()
if (cancelled) return
setUser(me)
setStatus('authenticated')
} catch {
if (!cancelled) setStatus('unauthenticated')
}
}
void bootstrap()
return () => {
cancelled = true
}
}, [])
const login = useCallback(async (email: string, password: string) => {
const token = await apiLogin(email, password)
authStore.setAccessToken(token.access_token)
const me = await getMe()
setUser(me)
setStatus('authenticated')
}, [])
const logout = useCallback(async () => {
try {
await apiLogout()
} finally {
authStore.setAccessToken(null)
setUser(null)
setStatus('unauthenticated')
}
}, [])
const refreshUser = useCallback(async () => {
const me = await getMe()
setUser(me)
}, [])
const value = useMemo<AuthContextValue>(
() => ({ user, status, login, logout, refreshUser }),
[user, status, login, logout, refreshUser],
)
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}