diff --git a/apps/frontend/src/layouts/index.test.tsx b/apps/frontend/src/layouts/index.test.tsx
new file mode 100644
index 000000000..005db3749
--- /dev/null
+++ b/apps/frontend/src/layouts/index.test.tsx
@@ -0,0 +1,39 @@
+// @vitest-environment jsdom
+import { render, screen } from "@testing-library/react";
+import { HttpResponse, http } from "msw";
+import { describe, expect, it, vi } from "vitest";
+import "../test/i18n";
+import { API_BASE_URL, server } from "../test/msw-server";
+
+// Only the maintenance wiring is under test; stub the layout's unrelated chrome and hooks.
+vi.mock("../components/Navbar", () => ({ Navbar: () => null }));
+vi.mock("../components/Footer", () => ({ Footer: () => null }));
+vi.mock("../components/Stepper", () => ({ default: () => null }));
+vi.mock("../hooks/useInitTokenBalances", () => ({ useInitTokenBalances: () => undefined }));
+vi.mock("../hooks/useStepper", () => ({ useStepper: () => ({ steps: [] }) }));
+vi.mock("../hooks/useWidgetMode", () => ({ useWidgetMode: () => false }));
+vi.mock("../hooks/ramp/useIsQuoteComponentDisplayed", () => ({ useIsQuoteComponentDisplayed: () => false }));
+
+import { BaseLayout } from "./index";
+
+describe("BaseLayout", () => {
+ it("fetches the maintenance status on mount and shows an active maintenance banner", async () => {
+ server.use(
+ http.get(`${API_BASE_URL}/maintenance/status`, () =>
+ HttpResponse.json({
+ is_maintenance_active: true,
+ maintenance_details: {
+ end_datetime: "2026-10-02T12:00:00Z",
+ message: "Ramps are paused while we upgrade.",
+ start_datetime: "2026-10-02T10:00:00Z",
+ title: "Scheduled maintenance"
+ }
+ })
+ )
+ );
+
+ render(} />);
+
+ expect(await screen.findByText("Scheduled maintenance")).toBeTruthy();
+ });
+});
diff --git a/apps/frontend/src/layouts/index.tsx b/apps/frontend/src/layouts/index.tsx
index 6deb7ae8e..6e8b734a2 100644
--- a/apps/frontend/src/layouts/index.tsx
+++ b/apps/frontend/src/layouts/index.tsx
@@ -1,13 +1,13 @@
-import { FC, ReactNode, useEffect } from "react";
+import { FC, ReactNode } from "react";
import { Footer } from "../components/Footer";
import { MaintenanceBanner } from "../components/MaintenanceBanner";
import { Navbar } from "../components/Navbar";
import Stepper from "../components/Stepper";
import { useIsQuoteComponentDisplayed } from "../hooks/ramp/useIsQuoteComponentDisplayed";
import { useInitTokenBalances } from "../hooks/useInitTokenBalances";
+import { useMaintenanceStatus } from "../hooks/useMaintenanceStatus";
import { useStepper } from "../hooks/useStepper";
import { useWidgetMode } from "../hooks/useWidgetMode";
-import { useFetchMaintenanceStatus } from "../stores/maintenanceStore";
interface BaseLayoutProps {
main: ReactNode;
@@ -21,7 +21,7 @@ export const BaseLayout: FC = ({ main, modals }) => {
const isQuoteComponentDisplayed = useIsQuoteComponentDisplayed();
useInitTokenBalances();
- useFetchMaintenanceStatus();
+ useMaintenanceStatus();
const isStepperHidden = isWidgetMode && isQuoteComponentDisplayed;