ui and bug fixers 29/09

This commit is contained in:
2026-09-29 14:49:11 +05:30
parent d24072e20a
commit b2646c6cb3
85 changed files with 30050 additions and 750 deletions
@@ -5,6 +5,7 @@
// client-only `roleId` cached by lib/auth-session.ts for anything access-related
// (that cache remains display-only, e.g. for the header's user name).
import { createContext, useContext, useEffect, useState } from "react"
import { useRouter } from "next/navigation"
import { authApi } from "@/lib/api/auth"
import { MeResponse } from "@/types/rbac"
@@ -32,6 +33,10 @@ function readStoredActiveBranch(): ActiveBranch | null {
}
interface AuthContextValue {
/** Re-fetches `/auth/me` — call after changing settings it reflects (e.g. Branch Configuration). */
refresh: () => void
/** The caller's local user id — compare against a document's `createdBy`. */
userId: number | null
roleCode: string | null
roleName: string | null
navCodes: string[]
@@ -62,11 +67,19 @@ interface AuthContextValue {
* everything else. Always false when `branchingEnabled` itself is false.
*/
warehouseBranchingEnabled: boolean
/**
* Independent sub-toggle for Purchase Orders (Settings → Branch Configuration). False means
* POs are one shared pool: no branch picker/column on PO screens. Always false when
* `branchingEnabled` is false.
*/
purchaseOrderBranchingEnabled: boolean
/** True until the first `/auth/me` response lands. */
loading: boolean
}
const AuthContext = createContext<AuthContextValue>({
refresh: () => {},
userId: null,
roleCode: null,
roleName: null,
navCodes: [],
@@ -78,12 +91,17 @@ const AuthContext = createContext<AuthContextValue>({
setActiveBranch: () => {},
branchingEnabled: true,
warehouseBranchingEnabled: true,
purchaseOrderBranchingEnabled: true,
loading: true,
})
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [me, setMe] = useState<MeResponse | null>(null)
const [activeBranch, setActiveBranchState] = useState<ActiveBranch | null>(null)
// Bumped by refresh() to re-fetch /auth/me — e.g. right after Branch Configuration changes,
// so the header and every branch-aware screen update without a full page reload.
const [reloadKey, setReloadKey] = useState(0)
const router = useRouter()
useEffect(() => {
let cancelled = false
@@ -95,12 +113,17 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
.catch(() => {
// Unauthenticated/unreachable — fall back to "no permissions" rather than
// crash the shell; proxy.ts already redirects unauthenticated users to /login.
if (!cancelled) setMe({ roleCode: null, roleName: null, navCodes: [], isAdmin: false, branchId: null, branchName: null, branchingEnabled: true, warehouseBranchingEnabled: true })
if (!cancelled) setMe({ roleCode: null, roleName: null, navCodes: [], isAdmin: false, branchId: null, branchName: null, branchingEnabled: true, warehouseBranchingEnabled: true, mustChangePassword: false, purchaseOrderBranchingEnabled: true, userId: null })
})
return () => {
cancelled = true
}
}, [])
}, [reloadKey])
useEffect(() => {
// Admin-created accounts must replace their issued password before using the app.
if (me?.mustChangePassword) router.replace("/change-password")
}, [me, router])
useEffect(() => {
if (me === null) return
@@ -115,21 +138,29 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
if (typeof window !== "undefined") window.localStorage.setItem(ACTIVE_BRANCH_KEY, JSON.stringify(next))
}
// With branching switched off there is no "current branch" at all — ignore any stale
// header pick (or own-branch pin) so no screen keeps silently filtering by it.
const branchingEnabled = me?.branchingEnabled ?? true
return (
<AuthContext.Provider
value={{
refresh: () => setReloadKey((k) => k + 1),
userId: me?.userId ?? null,
roleCode: me?.roleCode ?? null,
roleName: me?.roleName ?? null,
navCodes: me?.navCodes ?? [],
isAdmin: me?.isAdmin ?? false,
branchId: me?.branchId ?? null,
branchName: me?.branchName ?? null,
activeBranchId: activeBranch?.id ?? null,
activeBranchName: activeBranch?.name ?? null,
activeBranchId: branchingEnabled ? (activeBranch?.id ?? null) : null,
activeBranchName: branchingEnabled ? (activeBranch?.name ?? null) : null,
setActiveBranch,
branchingEnabled: me?.branchingEnabled ?? true,
branchingEnabled,
warehouseBranchingEnabled: me?.warehouseBranchingEnabled ?? true,
loading: me === null,
purchaseOrderBranchingEnabled: me?.purchaseOrderBranchingEnabled ?? true,
// Stays "loading" while a forced password change redirects away, so the shell never flashes.
loading: me === null || me.mustChangePassword,
}}
>
{children}