diff --git a/src/vertex/app/changelog.md b/src/vertex/app/changelog.md
index f334890af6..1161573fa0 100644
--- a/src/vertex/app/changelog.md
+++ b/src/vertex/app/changelog.md
@@ -3,6 +3,31 @@
> **Note**: This changelog consolidates all recent improvements, features, and fixes to the AirQo Vertex frontend.
---
+
+## Version 1.23.57
+**Released:** June 02, 2026
+
+### Organization Picker Banner Migration
+
+Replaced the `ReusableToast` error call in `OrganizationPicker` with the centralized `useBannerWithDelay` hook. The shimmer progress bar dispatch (`setOrganizationSwitching`) was also moved to just before navigation fires so it only appears when the switch is actually proceeding — errors that occur before navigation never trigger the shimmer.
+
+
+Changes (2)
+
+- **Error Feedback**: Replaced `ReusableToast` with `showBannerWithDelay` (`scoped: false`) for org switch failures. Using the delayed variant ensures the banner is not cleared by `ReusableDialog`'s `hideBanner` cleanup effect that fires when the modal closes.
+- **Shimmer Timing Fix**: Moved `setOrganizationSwitching({ isSwitching: true })` inside the try block just before navigation so the progress bar only appears when switching is guaranteed to proceed. The catch block no longer needs to reset it.
+
+
+
+
+Files Updated (1)
+
+- `src/vertex/components/features/org-picker/organization-picker.tsx` [MODIFIED]
+
+
+
+---
+
## Version 1.23.56
**Released:** May 29, 2026
diff --git a/src/vertex/components/features/org-picker/organization-picker.tsx b/src/vertex/components/features/org-picker/organization-picker.tsx
index 3aeed274b2..3d4f88bd8d 100644
--- a/src/vertex/components/features/org-picker/organization-picker.tsx
+++ b/src/vertex/components/features/org-picker/organization-picker.tsx
@@ -17,7 +17,7 @@ import { UserContext } from "@/core/redux/slices/userSlice";
import { AqGrid01 } from "@airqo/icons-react";
import { Skeleton } from "@/components/ui/skeleton";
import { useRouter, usePathname } from "next/navigation";
-import ReusableToast from "@/components/shared/toast/ReusableToast";
+import { useBannerWithDelay } from "@/core/hooks/useBannerWithDelay";
const formatTitle = (title: string) => {
if (!title) return "";
@@ -32,6 +32,7 @@ const OrganizationPicker: React.FC = () => {
const userGroups = useAppSelector((state) => state.user.userGroups);
const [isModalOpen, setIsModalOpen] = useState(false);
const { isLoading } = useUserContext();
+ const { showBannerWithDelay } = useBannerWithDelay();
const { isSwitching } = useAppSelector((state) => state.user.organizationSwitching);
const pathname = usePathname();
const lastPathname = useRef(pathname);
@@ -53,25 +54,16 @@ const OrganizationPicker: React.FC = () => {
}, [userGroups]);
const handleOrganizationChange = async (group: Group) => {
- // 1. Instant UI Feedback
setIsModalOpen(false);
- // Clear any stale forbidden state from previous context before switching.
dispatch(clearForbiddenState());
- // 2. Start Background Transition
- dispatch(setOrganizationSwitching({
- isSwitching: true,
- switchingTo: group.grp_title
- }));
-
const newContext: UserContext =
group.grp_title.toLowerCase() === "airqo"
? "personal"
: "external-org";
try {
- // 3. Optimized Background Cleanup (Non-blocking)
- // We don't await these to prevent UI blocking
+ // Optimized Background Cleanup (Non-blocking)
const orgScopedQueryKeys = [
["devices"],
["myDevices"],
@@ -93,21 +85,24 @@ const OrganizationPicker: React.FC = () => {
queryClient.removeQueries({ queryKey });
});
- // 4. Update Redux State
+ // Start shimmer just before navigation fires
+ dispatch(setOrganizationSwitching({ isSwitching: true, switchingTo: group.grp_title }));
+
dispatch(setActiveGroup(group));
dispatch(setUserContext(newContext));
- // 5. Trigger Navigation
if (pathname === "/home") {
- // If already on home, we must clear immediately as pathname won't change
dispatch(setOrganizationSwitching({ isSwitching: false, switchingTo: "" }));
router.refresh();
} else {
router.push("/home");
}
} catch {
- ReusableToast({ message: "Failed to switch organization", type: "ERROR" });
- dispatch(setOrganizationSwitching({ isSwitching: false, switchingTo: "" }));
+ showBannerWithDelay({
+ severity: 'error',
+ message: 'Failed to switch organization. Please try again.',
+ scoped: false,
+ });
}
};