"use client";
import React from "react";
import { Loader2 } from "lucide-react";
import { useAuth } from "@/components/auth/authContext";
import { getBranches } from "@/lib/frontend/apiClient";
import {
decideBranchUi,
BRANCH_UI_DECISION,
} from "@/lib/frontend/rbac/branchUiDecision";
import ForbiddenView from "@/components/system/ForbiddenView";
import NotFoundView from "@/components/system/NotFoundView";
const BRANCH_LIST_STATE = Object.freeze({
IDLE: "idle",
LOADING: "loading",
READY: "ready",
ERROR: "error",
});
function BranchValidationLoading() {
return (
Validating branch...
);
}
export default function BranchGuard({ branch, children }) {
const { status, user } = useAuth();
const isAuthenticated = status === "authenticated" && user;
const needsExistenceCheck =
isAuthenticated && (user.role === "admin" || user.role === "dev");
const [branchList, setBranchList] = React.useState({
status: BRANCH_LIST_STATE.IDLE,
branches: null,
});
React.useEffect(() => {
if (!needsExistenceCheck) return;
let cancelled = false;
setBranchList({ status: BRANCH_LIST_STATE.LOADING, branches: null });
(async () => {
try {
const res = await getBranches();
if (cancelled) return;
const branches = Array.isArray(res?.branches) ? res.branches : [];
setBranchList({ status: BRANCH_LIST_STATE.READY, branches });
} catch (err) {
if (cancelled) return;
// Fail open: do not block navigation if validation fails.
console.error("[BranchGuard] getBranches failed:", err);
setBranchList({ status: BRANCH_LIST_STATE.ERROR, branches: null });
}
})();
return () => {
cancelled = true;
};
// IMPORTANT:
// - depend only on user identity + needsExistenceCheck
// - do NOT depend on branchList.status (would cancel itself when setting LOADING)
}, [needsExistenceCheck, user?.userId]);
if (!isAuthenticated) {
return children;
}
if (needsExistenceCheck && branchList.status === BRANCH_LIST_STATE.LOADING) {
return ;
}
const allowedBranches =
branchList.status === BRANCH_LIST_STATE.READY ? branchList.branches : null;
const decision = decideBranchUi({
user,
branch,
allowedBranches,
});
if (decision === BRANCH_UI_DECISION.FORBIDDEN) {
return ;
}
if (decision === BRANCH_UI_DECISION.NOT_FOUND) {
return ;
}
return children;
}