| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // ---------------------------------------------------------------------------
- // Folder: components/auth
- // File: authContext.js
- // Relative Path: components/auth/authContext.js
- // ---------------------------------------------------------------------------
- "use client";
- import React from "react";
- /**
- * Auth Context (RHL-020)
- *
- * Purpose:
- * - Provide a tiny, app-wide session state for the UI:
- * - status: "unknown" | "loading" | "authenticated" | "unauthenticated" | "error"
- * - user: { userId, role, branchId } | null
- * - error: string | null
- *
- * Why this file exists:
- * - Keep auth state accessible without prop-drilling.
- * - Keep the context/hook independent from Next.js routing.
- * - Avoid importing next/navigation in components that only need auth state
- * (helps SSR/unit tests and keeps dependencies clean).
- */
- /**
- * @typedef {"unknown"|"loading"|"authenticated"|"unauthenticated"|"error"} AuthStatus
- */
- /**
- * @typedef {Object} AuthUser
- * @property {string} userId
- * @property {string} role
- * @property {string|null} branchId
- */
- /**
- * @typedef {Object} AuthState
- * @property {AuthStatus} status
- * @property {AuthUser|null} user
- * @property {string|null} error
- */
- /** @type {AuthState} */
- export const DEFAULT_AUTH_STATE = Object.freeze({
- status: "unknown",
- user: null,
- error: null,
- });
- /**
- * The actual React context.
- * We provide a safe default so components can render even without a provider
- * (useful for SSR tests that render AppShell in isolation).
- */
- const AuthContext = React.createContext(DEFAULT_AUTH_STATE);
- /**
- * Consume the auth context.
- *
- * @returns {AuthState}
- */
- export function useAuth() {
- return React.useContext(AuthContext);
- }
- /**
- * Provider wrapper.
- *
- * We keep it very small and predictable:
- * - merge provided value with DEFAULT_AUTH_STATE to guarantee all fields exist
- * - avoid surprises when callers pass partial objects
- *
- * @param {{ value: Partial<AuthState>, children: React.ReactNode }} props
- */
- export function AuthProvider({ value, children }) {
- const merged = React.useMemo(() => {
- return { ...DEFAULT_AUTH_STATE, ...(value || {}) };
- }, [value]);
- return <AuthContext.Provider value={merged}>{children}</AuthContext.Provider>;
- }
|