diff --git a/src/app/SessionConsumer.tsx b/src/app/SessionConsumer.tsx index cfa4aa4..1ffb22b 100644 --- a/src/app/SessionConsumer.tsx +++ b/src/app/SessionConsumer.tsx @@ -1,33 +1,41 @@ 'use client' import { useAppDispatch } from '@/hooks/useAppDispatch' import { useAppSelector } from '@/hooks/useAppSelector' -import { setSession, setStatus } from '@/state/sessionSlice' +import { setCurrentUser, setSession, setStatus } from '@/state/sessionSlice' import { AppwriteException } from 'appwrite' -import { getSession } from 'entgamers-database/frontend/session' -import { useEffect, type FC } from 'react' +import { getCurrentUser, getSession } from 'entgamers-database/frontend/session' +import { useCallback, useEffect, type FC } from 'react' const SessionConsumer: FC = () => { const session = useAppSelector((state) => state.session) const dispatch = useAppDispatch() - useEffect(() => { - if (session.status === 'initializing' && session.session === undefined) { + const ensureSession = useCallback(async () => { + try { + if (session.status !== 'initializing' || session.session !== undefined) return dispatch(setStatus('loading')) - getSession('current') - .then((session) => { - dispatch(setSession(session)) - }) - .catch((error) => { - if (error instanceof AppwriteException) { - console.error(error) - } - }) - .finally(() => { - dispatch(setStatus('idle')) - }) + const currentSession = await getSession('current') + const currentUser = await getCurrentUser() + dispatch(setSession(currentSession)) + dispatch(setCurrentUser(currentUser)) + } catch (error) { + dispatch(setSession()) + dispatch(setCurrentUser()) + throw error + } finally { + dispatch(setStatus('idle')) } }, []) + useEffect(() => { + ensureSession() + .catch((error) => { + if (error instanceof AppwriteException) { + console.error(error) + } + }) + }, []) + return ( <> diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx index 10fbd9c..1446559 100644 --- a/src/app/login/LoginForm.tsx +++ b/src/app/login/LoginForm.tsx @@ -7,10 +7,10 @@ import PasswordInput from '@/components/ui/form/PasswordInput' import { useAppDispatch } from '@/hooks/useAppDispatch' import { useAppSelector } from '@/hooks/useAppSelector' import { addAlert } from '@/state/feedbackSlice' -import { setSession, setStatus } from '@/state/sessionSlice' +import { setCurrentUser, setSession, setStatus } from '@/state/sessionSlice' import { nanoid } from '@reduxjs/toolkit' import { AppwriteException } from 'appwrite' -import { login } from 'entgamers-database/frontend/session' +import { getCurrentUser, login } from 'entgamers-database/frontend/session' import { useFormik } from 'formik' import NextLink from 'next/link' import { useRouter } from 'next/navigation' @@ -41,7 +41,9 @@ const LoginForm: FC = () => { dispatch(setStatus('loading')) try { const session = await login(email, password) + const user = await getCurrentUser() dispatch(setSession(session)) + dispatch(setCurrentUser(user)) } catch (error) { if (error instanceof AppwriteException) { dispatch(addAlert({ diff --git a/src/state/sessionSlice.ts b/src/state/sessionSlice.ts index b4fd2a2..c635af7 100644 --- a/src/state/sessionSlice.ts +++ b/src/state/sessionSlice.ts @@ -1,14 +1,16 @@ import { createSlice, type PayloadAction } from '@reduxjs/toolkit' import { type Models } from 'appwrite' +import { type UserWithPreferences } from 'entgamers-database/frontend/session' -export interface SessionState { +export type SessionState = +| { status: 'idle' | 'loading' | 'initializing' session?: Models.Session + user?: UserWithPreferences } const initialState: SessionState = { - status: 'initializing', - session: undefined + status: 'initializing' } const sessionSlice = createSlice({ @@ -16,14 +18,26 @@ const sessionSlice = createSlice({ initialState, reducers: { setStatus: (state, action: PayloadAction) => { - state.status = action.payload + return { + ...state, + status: action.payload + } }, setSession: (state, action: PayloadAction) => { - state.session = action.payload + return { + ...state, + session: action.payload + } + }, + setCurrentUser: (state, action: PayloadAction) => { + return { + ...state, + userPreferences: action.payload + } } } }) -export const { setStatus, setSession } = sessionSlice.actions +export const { setStatus, setSession, setCurrentUser } = sessionSlice.actions export default sessionSlice