Files
study-bible-project/src/hooks/useAuth.js
T
nmemmertandClaude Opus 5.5 49ffefed54
Build and Push Docker Image / build-and-push (push) Successful in 6m28s
Extract auth into hooks/useAuth; move form state into its pages
- useAuth owns authUser/authServerDown, the startup session check, and
  signIn/logout, so every sign-in path runs the same follow-up (switch
  local storage to the account, load reader ink). Previously reader ink
  only loaded on a page refresh, not right after logging in.
- Login/2FA form state now lives in AuthPage, and 2FA setup, password
  change, and podcast name state in SettingsPage (23 fewer context
  values; typing in these forms no longer re-renders all of App).
- Add tests for form sign-in, 2FA, session restore + logout, and the
  Settings podcast-name prefill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 14:44:52 -04:00

45 lines
1.6 KiB
JavaScript

// Who is signed in. Checks the session on startup and exposes signIn/logout so
// every sign-in path (startup, login form, 2FA) runs the same follow-up work.
import { useEffect, useRef, useState } from 'react';
import { getCurrentUser, logoutUser } from '../syncService.js';
// onSignIn(user) runs right after a user becomes signed in (switch local
// storage to their account, load their data). onSignOut() runs after logout.
export function useAuth({ onSignIn, onSignOut }) {
// authUser: undefined = still checking · null = signed out · object = signed in
const [authUser, setAuthUser] = useState(undefined);
const [authServerDown, setAuthServerDown] = useState(false);
// Callbacks come from App and close over its latest state; read them through
// a ref so signIn/logout never call a stale copy.
const callbacksRef = useRef({ onSignIn, onSignOut });
callbacksRef.current = { onSignIn, onSignOut };
const signIn = (user) => {
setAuthUser(user);
callbacksRef.current.onSignIn(user);
};
const logout = async () => {
await logoutUser();
setAuthUser(null);
callbacksRef.current.onSignOut();
};
useEffect(() => {
getCurrentUser().then((result) => {
if (result.ok) {
if (result.user) signIn(result.user);
else setAuthUser(null);
} else {
// Genuine network failure (server unreachable) — fall back to local-only mode.
setAuthServerDown(true);
setAuthUser(null);
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return { authUser, setAuthUser, authServerDown, signIn, logout };
}