Skip to content

Commit 6552c44

Browse files
authored
fix: hydration mismatch + offline hook rewrite
fix: hydration mismatch + offline hook rewrite
2 parents e91d0b8 + 3d90c6d commit 6552c44

4 files changed

Lines changed: 52 additions & 40 deletions

File tree

manualtasksforsparsh.md

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,26 @@
101101

102102
---
103103

104-
## Domain & DNS
104+
## WEBSITE COPY REVIEW (NEW)
105+
106+
From latest session:
107+
- [ ] **Review homepage copy** — Verify all 6 sections render correctly:
108+
1. Hero ("Proof without surrender.")
109+
2. Who uses OpenProof (8 audiences)
110+
3. How it works (3 steps)
111+
4. When to timestamp (4 scenarios)
112+
5. What a proof means (proves vs doesn't prove)
113+
6. Privacy by design (4 pillars)
114+
- [ ] **Review About page** — New "Who uses" and "When to use" sections
115+
- [ ] **Review Create/Verify pages** — Updated header copy
116+
- [ ] **Check for hydration errors** — Open DevTools Console, should be clean
117+
- [ ] **Check offline notice** — Should NOT appear on localhost
118+
- [ ] **Deploy to production** — Push latest changes to main triggers Vercel deploy
119+
- [ ] **Verify production** — Visit https://proof.kovina.org, check copy and console
120+
121+
---
122+
123+
## DOMAIN & DNS
105124

106125
- [x] Cloudflare CNAME `proof → cname.vercel-dns.com` — DONE
107126
- [x] Vercel domain `proof.kovina.org` registered — DONE
@@ -111,26 +130,18 @@
111130

112131
---
113132

114-
## v0.9.0 What Was Done (Automated)
115-
116-
These tasks were completed automatically this session:
117-
- [x] Windows MSIX: Updated AppxManifest.xml version to 0.9.0.0
118-
- [x] Windows MSIX: Generated splash screens (620x300, 868x420, 1116x540) with centered icon on black
119-
- [x] PWA: Updated manifest theme_color to #0081CC (brand), background_color to #000000 (black)
120-
- [x] PWA: Added `theme-color` meta tag to layout
121-
- [x] PWA: Created `PwaInstallPrompt` component (beforeinstallprompt handling + update flow notification)
122-
- [x] PWA: Added `/proof/` and `/bundle/` routes to SW static cache
123-
- [x] Android: Initialized Capacitor project with `npx cap add android`
124-
- [x] Android: Created `scripts/cap-build.sh` for static export + Capacitor sync
125-
- [x] Android: Updated capacitor.config.json with 4 plugins (Filesystem, Keyboard, Share, SplashScreen)
126-
- [x] Android: Dynamic routes support static export via `generateStaticParams`
127-
- [x] Icons: All platform icons regenerated from canonical SVG
128-
- [x] Footer: Version updated to v0.9.0
129-
- [x] Lint: 0 errors (6 pre-existing warnings) ✅
130-
- [x] Typecheck: Pass ✅
131-
- [x] Build (Vercel mode): Pass ✅
132-
- [x] Build (Capacitor static export): Pass ✅
133-
- [x] Updated PLATFORM_READINESS.md to v0.9.0
133+
## v0.9.0 — Completed (Automated)
134+
135+
- [x] Windows MSIX: AppxManifest.xml v0.9.0.0, splash screens (620×300, 868×420, 1116×540)
136+
- [x] PWA: manifest theme #0081CC, background #000000, theme-color meta tag
137+
- [x] PWA: PwaInstallPrompt component (beforeinstallprompt + update notification)
138+
- [x] PWA: SW cache extended to /proof/ and /bundle/ routes
139+
- [x] Android: Capacitor project initialized, build script created, 4 plugins configured
140+
- [x] Website copy: Homepage rewritten with 6 sections, About page enhanced, SEO metadata enriched
141+
- [x] Hydration fix: suppressHydrationWarning on <html>, offline hook rewritten with useSyncExternalStore
142+
- [x] Icons: All platform variants regenerated from SVG
143+
- [x] Version references: Footer, create page, about page all v0.9.0
144+
- [x] Lint / typecheck / build: All passing
134145

135146
---
136147

src/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export default function RootLayout({
9696
children: React.ReactNode;
9797
}>) {
9898
return (
99-
<html lang="en" className={`${geistMono.variable} h-full antialiased`}>
99+
<html lang="en" className={`${geistMono.variable} h-full antialiased`} suppressHydrationWarning>
100100
<body className="min-h-full flex flex-col bg-bg-base text-text-primary">
101101
<link rel="manifest" href="/manifest.json" />
102102
<script

src/components/offline-notice.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ export function OfflineNotice() {
88
if (isOnline) return null;
99

1010
return (
11-
<div className="fixed bottom-4 left-4 right-4 z-50 mx-auto max-w-lg rounded-full bg-error/90 px-6 py-3 text-sm font-semibold text-white text-center shadow-lg backdrop-blur-sm">
11+
<div
12+
aria-live="assertive"
13+
className="fixed bottom-4 left-4 right-4 z-50 mx-auto max-w-lg rounded-full bg-error/90 px-6 py-3 text-sm font-semibold text-white text-center shadow-lg backdrop-blur-sm"
14+
role="alert"
15+
>
1216
You are offline. Onchain verification requires an internet connection.
1317
</div>
1418
);

src/lib/offline.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
"use client";
22

3-
import { useEffect, useState } from "react";
3+
import { useSyncExternalStore } from "react";
44

5-
export function useOnlineStatus() {
6-
const [isOnline, setIsOnline] = useState(
7-
typeof navigator !== "undefined" ? navigator.onLine : true,
8-
);
9-
10-
useEffect(() => {
11-
function handleOnline() { setIsOnline(true); }
12-
function handleOffline() { setIsOnline(false); }
5+
function getOnlineSnapshot() {
6+
return typeof navigator !== "undefined" ? navigator.onLine : true;
7+
}
138

14-
window.addEventListener("online", handleOnline);
15-
window.addEventListener("offline", handleOffline);
16-
return () => {
17-
window.removeEventListener("online", handleOnline);
18-
window.removeEventListener("offline", handleOffline);
19-
};
20-
}, []);
9+
function subscribeToOnline(callback: () => void) {
10+
window.addEventListener("online", callback);
11+
window.addEventListener("offline", callback);
12+
return () => {
13+
window.removeEventListener("online", callback);
14+
window.removeEventListener("offline", callback);
15+
};
16+
}
2117

22-
return isOnline;
18+
export function useOnlineStatus() {
19+
return useSyncExternalStore(subscribeToOnline, getOnlineSnapshot, () => true);
2320
}

0 commit comments

Comments
 (0)