authContext.jsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. "use client";
  2. import React from "react";
  3. /**
  4. * Auth Context (RHL-020)
  5. *
  6. * Purpose:
  7. * - Provide a tiny, app-wide session state for the UI:
  8. * - status: "unknown" | "loading" | "authenticated" | "unauthenticated" | "error"
  9. * - user: { userId, role, branchId, email, mustChangePassword } | null
  10. * - error: string | null
  11. * - isValidating: boolean (true while a background session re-check runs)
  12. * - retry: () => void | null (re-run the session check)
  13. */
  14. /**
  15. * @typedef {"unknown"|"loading"|"authenticated"|"unauthenticated"|"error"} AuthStatus
  16. */
  17. /**
  18. * @typedef {Object} AuthUser
  19. * @property {string} userId
  20. * @property {string} role
  21. * @property {string|null} branchId
  22. * @property {string|null} email
  23. * @property {boolean} mustChangePassword
  24. */
  25. /**
  26. * @typedef {Object} AuthState
  27. * @property {AuthStatus} status
  28. * @property {AuthUser|null} user
  29. * @property {string|null} error
  30. * @property {boolean} isValidating
  31. * @property {(() => void)|null} retry
  32. */
  33. /** @type {AuthState} */
  34. export const DEFAULT_AUTH_STATE = Object.freeze({
  35. status: "unknown",
  36. user: null,
  37. error: null,
  38. isValidating: false,
  39. retry: null,
  40. });
  41. const AuthContext = React.createContext(DEFAULT_AUTH_STATE);
  42. /**
  43. * Consume the auth context.
  44. *
  45. * @returns {AuthState}
  46. */
  47. export function useAuth() {
  48. return React.useContext(AuthContext);
  49. }
  50. /**
  51. * Provider wrapper.
  52. *
  53. * @param {{ value: Partial<AuthState>, children: React.ReactNode }} props
  54. */
  55. export function AuthProvider({ value, children }) {
  56. const merged = React.useMemo(() => {
  57. return { ...DEFAULT_AUTH_STATE, ...(value || {}) };
  58. }, [value]);
  59. return <AuthContext.Provider value={merged}>{children}</AuthContext.Provider>;
  60. }