feat(auth): tell the user when the session expired

Every 401 from Auth or Core now goes through useSessionExpired: the login page
says the session expired and returns to the last page after login. App no
longer removes a token that only the browser clock calls expired, so a backend
401 is the one signal. A 403 on the profile now shows an error instead.
This commit is contained in:
lobo committed 2026-09-24 13:29:09 +02:00
1 parent 03259d0515
commit d4c0f8d8f3
19 files changed
+351 -35

No files matched your search

+3 -2
View File
@@ -12,6 +12,7 @@ import {Textarea} from '@/components/ui/textarea';
import {cn} from '@/lib/utils';
import {STATUS_META} from './GameStatusBadge.jsx';
import {GAME_PRIORITIES, GAME_STATUSES, NO_PRIORITY, toBacklogRequest} from '../utils/backlog.js';
import useSessionExpired from '../hooks/useSessionExpired.js';
const NOTES_MAX = 2000;
@@ -25,6 +26,7 @@ const toForm = (entry) => ({
export default function BacklogCard({game, onSaved}) {
const {t} = useTranslation();
const navigate = useNavigate();
const expireSession = useSessionExpired();
const [saved, setSaved] = useState(() => toForm(game));
const [form, setForm] = useState(saved);
const [busy, setBusy] = useState(false);
@@ -46,8 +48,7 @@ export default function BacklogCard({game, onSaved}) {
body: JSON.stringify(toBacklogRequest(form)),
});
if (response.status === 401) {
localStorage.removeItem('tbp_jwt');
navigate('/login');
expireSession();
return;
}
if (!response.ok) {
+6 -3
View File
@@ -2,12 +2,15 @@ import {CircleAlert, CircleCheck} from 'lucide-react';
import {Alert, AlertDescription} from '@/components/ui/alert';
export default function FeedbackAlert({message, isError}) {
/**
* @param icon replaces the default icon, e.g. for a note that is neither an error nor a success
*/
export default function FeedbackAlert({message, isError, icon}) {
if (!message) return null;
const Icon = isError ? CircleAlert : CircleCheck;
const Icon = icon ?? (isError ? CircleAlert : CircleCheck);
return (
<Alert variant={isError ? 'destructive' : 'default'}>
<Icon className={isError ? undefined : 'text-emerald-500'}/>
<Icon className={isError ? undefined : icon ? 'text-primary' : 'text-emerald-500'}/>
<AlertDescription>{message}</AlertDescription>
</Alert>
);