|
@@ -51,8 +51,12 @@ const BRANCH_LIST_STATE = Object.freeze({
|
|
|
ERROR: "error",
|
|
ERROR: "error",
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+// Header polish:
|
|
|
|
|
+// - remove subtle outline shadow (crisp header UI)
|
|
|
|
|
+// - normalize padding when an icon is present
|
|
|
const TOPNAV_BUTTON_CLASS = "shadow-none has-[>svg]:px-3";
|
|
const TOPNAV_BUTTON_CLASS = "shadow-none has-[>svg]:px-3";
|
|
|
|
|
|
|
|
|
|
+// Active nav style (blue like multi-branch selection)
|
|
|
const ACTIVE_NAV_BUTTON_CLASS =
|
|
const ACTIVE_NAV_BUTTON_CLASS =
|
|
|
"border-blue-600 bg-blue-50 text-blue-900 hover:bg-blue-50 " +
|
|
"border-blue-600 bg-blue-50 text-blue-900 hover:bg-blue-50 " +
|
|
|
"dark:border-blue-900 dark:bg-blue-950 dark:text-blue-50 dark:hover:bg-blue-950";
|
|
"dark:border-blue-900 dark:bg-blue-950 dark:text-blue-50 dark:hover:bg-blue-950";
|
|
@@ -67,11 +71,14 @@ export default function QuickNav() {
|
|
|
const isAdminDev =
|
|
const isAdminDev =
|
|
|
isAuthenticated && (user.role === "admin" || user.role === "dev");
|
|
isAuthenticated && (user.role === "admin" || user.role === "dev");
|
|
|
const isBranchUser = isAuthenticated && user.role === "branch";
|
|
const isBranchUser = isAuthenticated && user.role === "branch";
|
|
|
-
|
|
|
|
|
const canRevalidate = typeof retry === "function";
|
|
const canRevalidate = typeof retry === "function";
|
|
|
|
|
|
|
|
|
|
+ // Persisted selection for admin/dev:
|
|
|
const [selectedBranch, setSelectedBranch] = React.useState(null);
|
|
const [selectedBranch, setSelectedBranch] = React.useState(null);
|
|
|
|
|
|
|
|
|
|
+ // Init gate: prevent “localStorage sync” from running on every state change
|
|
|
|
|
+ const initRef = React.useRef({ userId: null });
|
|
|
|
|
+
|
|
|
const [branchList, setBranchList] = React.useState({
|
|
const [branchList, setBranchList] = React.useState({
|
|
|
status: BRANCH_LIST_STATE.IDLE,
|
|
status: BRANCH_LIST_STATE.IDLE,
|
|
|
branches: null,
|
|
branches: null,
|
|
@@ -101,8 +108,13 @@ export default function QuickNav() {
|
|
|
!knownBranches.includes(routeBranch),
|
|
!knownBranches.includes(routeBranch),
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
|
|
+ // A) Initialize selectedBranch once per authenticated admin/dev user
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
|
- if (!isAuthenticated) return;
|
|
|
|
|
|
|
+ if (!isAuthenticated) {
|
|
|
|
|
+ initRef.current.userId = null;
|
|
|
|
|
+ setSelectedBranch(null);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (isBranchUser) {
|
|
if (isBranchUser) {
|
|
|
const own = user.branchId;
|
|
const own = user.branchId;
|
|
@@ -110,12 +122,19 @@ export default function QuickNav() {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (!isAdminDev) return;
|
|
|
|
|
+
|
|
|
|
|
+ const uid = String(user.userId || "");
|
|
|
|
|
+ if (!uid) return;
|
|
|
|
|
+
|
|
|
|
|
+ if (initRef.current.userId === uid) return;
|
|
|
|
|
+ initRef.current.userId = uid;
|
|
|
|
|
+
|
|
|
const fromStorage = safeReadLocalStorageBranch(STORAGE_KEY_LAST_BRANCH);
|
|
const fromStorage = safeReadLocalStorageBranch(STORAGE_KEY_LAST_BRANCH);
|
|
|
- if (fromStorage && fromStorage !== selectedBranch) {
|
|
|
|
|
- setSelectedBranch(fromStorage);
|
|
|
|
|
- }
|
|
|
|
|
- }, [isAuthenticated, isBranchUser, user?.branchId, selectedBranch]);
|
|
|
|
|
|
|
+ setSelectedBranch(fromStorage || null);
|
|
|
|
|
+ }, [isAuthenticated, isBranchUser, isAdminDev, user?.userId, user?.branchId]);
|
|
|
|
|
|
|
|
|
|
+ // B) Fetch branch list once for admin/dev
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
|
|
|
|
@@ -132,7 +151,6 @@ export default function QuickNav() {
|
|
|
setBranchList({ status: BRANCH_LIST_STATE.READY, branches });
|
|
setBranchList({ status: BRANCH_LIST_STATE.READY, branches });
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
if (cancelled) return;
|
|
if (cancelled) return;
|
|
|
-
|
|
|
|
|
console.error("[QuickNav] getBranches failed:", err);
|
|
console.error("[QuickNav] getBranches failed:", err);
|
|
|
setBranchList({ status: BRANCH_LIST_STATE.ERROR, branches: null });
|
|
setBranchList({ status: BRANCH_LIST_STATE.ERROR, branches: null });
|
|
|
}
|
|
}
|
|
@@ -143,38 +161,31 @@ export default function QuickNav() {
|
|
|
};
|
|
};
|
|
|
}, [isAdminDev, user?.userId]);
|
|
}, [isAdminDev, user?.userId]);
|
|
|
|
|
|
|
|
|
|
+ // C) Ensure selectedBranch is valid once we have the list
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
if (!knownBranches || knownBranches.length === 0) return;
|
|
if (!knownBranches || knownBranches.length === 0) return;
|
|
|
|
|
|
|
|
- if (!selectedBranch || !knownBranches.includes(selectedBranch)) {
|
|
|
|
|
- const next = knownBranches[0];
|
|
|
|
|
- setSelectedBranch(next);
|
|
|
|
|
- safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, next);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (selectedBranch && knownBranches.includes(selectedBranch)) return;
|
|
|
|
|
+
|
|
|
|
|
+ const next = knownBranches[0];
|
|
|
|
|
+ setSelectedBranch(next);
|
|
|
|
|
+ safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, next);
|
|
|
}, [isAdminDev, knownBranches, selectedBranch]);
|
|
}, [isAdminDev, knownBranches, selectedBranch]);
|
|
|
|
|
|
|
|
|
|
+ // D) Sync selectedBranch to the current route branch ONLY if it exists
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
if (!routeBranch) return;
|
|
if (!routeBranch) return;
|
|
|
if (!knownBranches) return;
|
|
if (!knownBranches) return;
|
|
|
|
|
|
|
|
- const isKnownRouteBranch = knownBranches.includes(routeBranch);
|
|
|
|
|
- if (!isKnownRouteBranch) return;
|
|
|
|
|
|
|
+ if (!knownBranches.includes(routeBranch)) return;
|
|
|
|
|
+ if (routeBranch === selectedBranch) return;
|
|
|
|
|
|
|
|
- if (routeBranch !== selectedBranch) {
|
|
|
|
|
- setSelectedBranch(routeBranch);
|
|
|
|
|
- safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, routeBranch);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ setSelectedBranch(routeBranch);
|
|
|
|
|
+ safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, routeBranch);
|
|
|
}, [isAdminDev, routeBranch, knownBranches, selectedBranch]);
|
|
}, [isAdminDev, routeBranch, knownBranches, selectedBranch]);
|
|
|
|
|
|
|
|
- React.useEffect(() => {
|
|
|
|
|
- if (!isAdminDev) return;
|
|
|
|
|
- if (!selectedBranch) return;
|
|
|
|
|
-
|
|
|
|
|
- safeWriteLocalStorageBranch(STORAGE_KEY_LAST_BRANCH, selectedBranch);
|
|
|
|
|
- }, [isAdminDev, selectedBranch]);
|
|
|
|
|
-
|
|
|
|
|
if (!isAuthenticated) return null;
|
|
if (!isAuthenticated) return null;
|
|
|
|
|
|
|
|
const effectiveBranch = isBranchUser ? user.branchId : selectedBranch;
|
|
const effectiveBranch = isBranchUser ? user.branchId : selectedBranch;
|