From f0635f9beb0ff85bbea2264a1b19160f0beed257 Mon Sep 17 00:00:00 2001
From: nsfisis <nsfisis@gmail.com>
Date: Sun, 7 Dec 2025 23:41:28 +0900
Subject: feat(client): add offline mode banner indicator
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Displays a prominent banner at the top of all pages when the user
is offline, informing them that changes will sync when reconnected.
Shows pending change count when applicable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---
 src/client/components/OfflineBanner.tsx | 39 +++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 src/client/components/OfflineBanner.tsx

(limited to 'src/client/components/OfflineBanner.tsx')

diff --git a/src/client/components/OfflineBanner.tsx b/src/client/components/OfflineBanner.tsx
new file mode 100644
index 0000000..357db33
--- /dev/null
+++ b/src/client/components/OfflineBanner.tsx
@@ -0,0 +1,39 @@
+import { useSync } from "../stores";
+
+export function OfflineBanner() {
+	const { isOnline, pendingCount } = useSync();
+
+	if (isOnline) {
+		return null;
+	}
+
+	return (
+		<div
+			data-testid="offline-banner"
+			role="status"
+			aria-live="polite"
+			style={{
+				backgroundColor: "#6c757d",
+				color: "white",
+				padding: "0.5rem 1rem",
+				textAlign: "center",
+				fontSize: "0.875rem",
+				display: "flex",
+				alignItems: "center",
+				justifyContent: "center",
+				gap: "0.5rem",
+			}}
+		>
+			<span aria-hidden="true">⚡</span>
+			<span>
+				You're offline. Changes will sync when you reconnect.
+				{pendingCount > 0 && (
+					<span data-testid="offline-pending-count">
+						{" "}
+						({pendingCount} pending)
+					</span>
+				)}
+			</span>
+		</div>
+	);
+}
-- 
cgit v1.2.3-70-g09d2

