Public Access
refactor(session): one session store for login, logout and 401
This commit is contained in:
1 parent
2a22789435
commit
cbafa3d540
23 files changed
+246
-280
No files matched your search
@@ -4,6 +4,7 @@ import {act, cleanup, fireEvent, render, screen, waitFor} from '@testing-library
|
||||
import {createMemoryRouter, RouterProvider, useLocation, useNavigate} from 'react-router-dom';
|
||||
import GameLibrary from './GameLibrary.jsx';
|
||||
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
|
||||
import {CurrentUserProvider} from '../context/CurrentUserContext.jsx';
|
||||
import {fetchRoutes, json} from '../test/fetchRoutes.js';
|
||||
|
||||
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
|
||||
@@ -14,6 +15,7 @@ const DEBOUNCE_WAIT_MS = 700;
|
||||
const page = {content: [{appid: 220, name: 'Half-Life 2', playtimeMinutes: 0, status: 'BACKLOG'}], page: 0, size: 20, totalElements: 1, totalPages: 1};
|
||||
|
||||
const answer = (games = page.content, hasSteamId = true) => fetchRoutes({
|
||||
'GET /api/users/me': json(200, {settings: {}}),
|
||||
'GET /api/library/games': json(200, {...page, content: games, totalElements: games.length, totalPages: games.length ? 1 : 0}),
|
||||
'GET /api/library/games-count': json(200, {count: games.length, hasSteamId}),
|
||||
});
|
||||
@@ -34,7 +36,7 @@ function renderLibrary(initialEntry = '/library') {
|
||||
}
|
||||
const router = createMemoryRouter([{
|
||||
path: '/library',
|
||||
element: <PreferencesProvider><GameLibrary/><Spy/></PreferencesProvider>,
|
||||
element: <PreferencesProvider><CurrentUserProvider><GameLibrary/><Spy/></CurrentUserProvider></PreferencesProvider>,
|
||||
}], {initialEntries: [initialEntry]});
|
||||
render(<RouterProvider router={router}/>);
|
||||
return {
|
||||
|
||||
@@ -11,7 +11,7 @@ import {Skeleton} from '@/components/ui/skeleton';
|
||||
import GameCover from '../components/GameCover.jsx';
|
||||
import Logo from '../components/Logo.jsx';
|
||||
import StatCard from '../components/StatCard.jsx';
|
||||
import {hasSession} from '../utils/auth.js';
|
||||
import useSession from '../hooks/useSession.js';
|
||||
|
||||
import usePublicStats from '../hooks/usePublicStats.js';
|
||||
|
||||
@@ -39,6 +39,7 @@ function RankedGames({title, games, formatValue}) {
|
||||
export default function LandingPage() {
|
||||
const {t, i18n} = useTranslation();
|
||||
const {data, isLoading} = usePublicStats();
|
||||
const {active} = useSession();
|
||||
|
||||
const auth = data.auth;
|
||||
const core = data.core;
|
||||
@@ -65,7 +66,7 @@ export default function LandingPage() {
|
||||
<h1 className="text-4xl font-bold tracking-tight md:text-6xl">{t('MAIN.WELCOME')}</h1>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-lg text-muted-foreground">{t('MAIN.DESCRIPTION')}</p>
|
||||
<Button asChild size="lg" className="mt-10">
|
||||
{hasSession() ? (
|
||||
{active ? (
|
||||
<Link to="/dashboard">{t('NAV.TO_DASHBOARD')}<ArrowRight/></Link>
|
||||
) : (
|
||||
<Link to="/login">{t('MAIN.GET_STARTED')}<ArrowRight/></Link>
|
||||
|
||||
@@ -10,7 +10,6 @@ import AuthLayout from '../components/AuthLayout.jsx';
|
||||
import FeedbackAlert from '../components/FeedbackAlert.jsx';
|
||||
import {hasSession, markSession, safeReturnPath} from '../utils/auth.js';
|
||||
import {clientFetch} from '../utils/api.js';
|
||||
import {useCurrentUserActions} from '../context/CurrentUserContext.jsx';
|
||||
|
||||
const LOGIN_ERROR_KEY = {
|
||||
INVALID_CREDENTIALS: 'LOGIN.ERROR_INVALID_CREDENTIALS',
|
||||
@@ -21,7 +20,6 @@ const LOGIN_ERROR_KEY = {
|
||||
export default function LoginPage() {
|
||||
const {t} = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const {reload: reloadUser} = useCurrentUserActions();
|
||||
const {state} = useLocation();
|
||||
const target = safeReturnPath(state?.from) ?? '/dashboard';
|
||||
|
||||
@@ -56,7 +54,6 @@ export default function LoginPage() {
|
||||
|
||||
if (response.ok) {
|
||||
markSession();
|
||||
reloadUser();
|
||||
navigate(target, {replace: true});
|
||||
} else {
|
||||
const minutes = Math.ceil(Number(response.headers.get('Retry-After') ?? 900) / 60);
|
||||
|
||||
@@ -11,7 +11,7 @@ import GameCover from '../components/GameCover.jsx';
|
||||
import GameStatusBadge, {STATUS_META} from '../components/GameStatusBadge.jsx';
|
||||
import {GAME_STATUSES} from '../utils/limits.js';
|
||||
import {formatPlaytime} from '../utils/games.js';
|
||||
import {hasSession} from '../utils/auth.js';
|
||||
import useSession from '../hooks/useSession.js';
|
||||
import {normalizeProfileStyle} from '../utils/profileStyle.js';
|
||||
import {DEFAULT_PROFILE, PROFILE_TILES, PROFILE_TITLES, normalizeLayout, saveTiles} from '../utils/tiles.js';
|
||||
import useCurrentUser from '../hooks/useCurrentUser.js';
|
||||
@@ -37,7 +37,7 @@ export default function PublicProfilePage() {
|
||||
const [error, setError] = useState(null);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [reloads, setReloads] = useState(0);
|
||||
const viewer = useCurrentUser(hasSession());
|
||||
const viewer = useCurrentUser(useSession().active);
|
||||
const runSave = useSaveResponse();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -154,7 +154,7 @@ export default function PublicProfilePage() {
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
<TileGrid tiles={PROFILE_TILES} titles={PROFILE_TITLES} layout={layout} renderTile={renderTile} editing={editing}
|
||||
<TileGrid tiles={PROFILE_TILES} titles={PROFILE_TITLES} layout={layout} renderTile={renderTile} editing={owner && editing}
|
||||
defaultLayout={DEFAULT_PROFILE} onSave={saveLayout} onCancel={() => setEditing(false)}/>
|
||||
</PageContainer>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user