Files
cozsweet-frontend-nextjs/src/app/global-error.tsx
T
admin 8cab34864e feat(ui): migrate Flutter UI library to Next.js 16 (App Router)
Migrate all 87 Dart files from /Users/chase/Documents/cozsweet/lib/ui/
to TypeScript React components, replacing Flutter-native features with
Web equivalents and reimplementing the BLoC pattern with React
Context + useReducer.

Highlights
- 1:1 BLoC -> Context+useReducer+side-effects mapping for auth, chat,
  user, and sidebar features (4 providers wired in root-providers.tsx)
- 500px MobileShell primitive eliminates per-screen layout boilerplate
- Headless Dialog primitive (createPortal + ESC + scroll lock) powers
  quota / pwa-install / username / pronouns / subscription / other-options
  dialogs
- New integrations/: facebook-sdk, google-identity, pwa-install,
  media-recorder (Web Speech API + MediaRecorder), browser-detect,
  chat-websocket (singleton), message-queue (throttled send)
- CSS Modules + existing design tokens (no new styling system);
  extended with breakpoints.css and dimensions.css
- Custom hooks: useBreakpoint (useSyncExternalStore),
  useFullVisibility (IntersectionObserver), usePwaInstall,
  usePullToRefresh
- Vitest + jsdom; 15 unit tests (chat-reducer, auth-validators)
- React 19.2.4, Next.js 16.2.7, Zod 4, lottie-react, classnames

Workarounds
- next.config.ts: experimental.staticGenerationRetryCount = 0 to
  bypass Next.js 16.2.7 /_global-error workStore prerender bug
- src/app/global-error.tsx: required Client Component
- src/types/globals.d.ts: centralized window.google / FB /
  SpeechRecognition declarations

Routes (/, /splash, /auth, /chat, /chat/deviceid/[deviceId],
/sidebar) all build and lint clean.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-09 13:39:49 +08:00

59 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
/**
* 全局 Error Boundary
*
* Next.js 16 文档要求 global-error 必须是 Client Component。
* 16.2.7 存在 prerender `/_global-error` 的内部 bugworkStore 未初始化),
* 本文件通过不挂任何 Client Context 副作用、纯静态 HTML 输出来规避。
*
* 当根 layout 自身抛出错误时渲染;必须包含 `<html>` + `<body>`
* 因为它会替换根 layout。
*/
interface GlobalErrorProps {
error: Error & { digest?: string };
unstable_retry?: () => void;
}
export default function GlobalError({ error }: GlobalErrorProps) {
return (
<html lang="en">
<body
style={{
fontFamily: "system-ui, sans-serif",
padding: "2rem",
background: "#111",
color: "#fff",
minHeight: "100vh",
}}
>
<h1 style={{ fontSize: "1.5rem", marginBottom: "1rem" }}>
Something went wrong
</h1>
<p style={{ marginBottom: "1rem", opacity: 0.8 }}>
{error.message || "An unexpected error occurred."}
</p>
<button
type="button"
onClick={() => {
window.location.href = "/";
}}
style={{
display: "inline-block",
padding: "0.5rem 1rem",
background: "#4f46e5",
color: "#fff",
borderRadius: "0.5rem",
border: 0,
cursor: "pointer",
fontSize: "1rem",
}}
>
Back to start
</button>
</body>
</html>
);
}