diff --git a/driver-pwa/frontend/src/pages/BalancePage.test.tsx b/driver-pwa/frontend/src/pages/BalancePage.test.tsx
new file mode 100644
index 0000000..a329ccd
--- /dev/null
+++ b/driver-pwa/frontend/src/pages/BalancePage.test.tsx
@@ -0,0 +1,35 @@
+import { describe, it, expect, vi } from "vitest";
+import { render, screen } from "@testing-library/react";
+import { MemoryRouter } from "react-router-dom";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+
+vi.mock("@/api/driver", () => ({
+ getBalance: vi.fn(async () => ({
+ accounts: [
+ { bucket: "Долг аренда", balance: -3200 },
+ { bucket: "Депозит", balance: 5000 },
+ ],
+ })),
+}));
+
+import { BalancePage } from "./BalancePage";
+
+function wrap() {
+ const qc = new QueryClient();
+ return render(
+
+
+
+ );
+}
+
+describe("BalancePage", () => {
+ it("shows hero total (sum of negatives) and account rows", async () => {
+ wrap();
+ expect(await screen.findByText("Долг аренда")).toBeInTheDocument();
+ expect(screen.getByText("Депозит")).toBeInTheDocument();
+ // Appears in both the hero total and the single debt account row.
+ expect(screen.getAllByText("−3 200 ₽").length).toBeGreaterThan(0);
+ expect(screen.getByRole("button", { name: /Пополнить/i })).toBeInTheDocument();
+ });
+});
diff --git a/driver-pwa/frontend/src/pages/BalancePage.tsx b/driver-pwa/frontend/src/pages/BalancePage.tsx
index 0ceefa4..1a75db6 100644
--- a/driver-pwa/frontend/src/pages/BalancePage.tsx
+++ b/driver-pwa/frontend/src/pages/BalancePage.tsx
@@ -1 +1,55 @@
-export function BalancePage() { return null; }
+import { useQuery } from "@tanstack/react-query";
+import { useNavigate } from "react-router-dom";
+import { History, LogOut } from "lucide-react";
+import { getBalance } from "@/api/driver";
+import { formatMoney } from "@/lib/format";
+import { useAuth } from "@/store/auth";
+import { AppHeader } from "@/components/AppHeader";
+import { Spinner } from "@/components/Spinner";
+
+export function BalancePage() {
+ const nav = useNavigate();
+ const clear = useAuth((s) => s.clear);
+ const { data, isLoading } = useQuery({ queryKey: ["balance"], queryFn: getBalance });
+
+ const accounts = data?.accounts ?? [];
+ const totalDebt = accounts.filter((a) => a.balance < 0).reduce((s, a) => s + a.balance, 0);
+
+ return (
+
+
+
+
Общий долг
+
{formatMoney(totalDebt)}
+
+
+ {isLoading ? (
+
+ ) : (
+
+ {accounts.map((a) => (
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+
+ );
+}