P0-3/4/5: route error boundary, null guards, slug fallback, search
P0-3 (category page crash):
- Add src/app/error.tsx and src/app/global-error.tsx so any future render
error shows a real ref id instead of the bare client-exception toast.
- NewsPageClient: null-guard every field accessed during search/category/
sort filtering and article render (title, excerpt, author, tags,
category, date, image, alt). The user-visible link
/news?category=live-production now also hydrates filter state from
?category= and ?search= search-params, so the dropdown actually filters.
P0-4 (/articles/[slug] 404s):
- /articles/[slug] and /news/[slug]: on slug miss, redirect("/news")
instead of notFound(). Dead links from the hardcoded NewsTicker /
FeaturedBento / ArticleFeed arrays now land on the news index instead
of dead-ending on 404.
- legacy-source: add searchLegacyArticles() (title/excerpt/author ilike).
P0-5 (header search):
- Header: wire Enter on the desktop and mobile search inputs and make
both search icons clickable buttons. Submits to /search?q=<query>.
- New /search route: server component that runs searchLegacyArticles
and renders results in the same card style as /news.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
33
src/app/global-error.tsx
Normal file
33
src/app/global-error.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function GlobalError({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
useEffect(() => {
|
||||
console.error("[global error]", error);
|
||||
}, [error]);
|
||||
return (
|
||||
<html>
|
||||
<body style={{ background: "#0d0d0d", color: "#e0e0e0", fontFamily: "system-ui", padding: 24, minHeight: "100vh" }}>
|
||||
<div style={{ maxWidth: 480, margin: "10vh auto", textAlign: "center" }}>
|
||||
<h2 style={{ fontSize: 22, marginBottom: 12 }}>Something went wrong</h2>
|
||||
<p style={{ marginBottom: 12, color: "#888" }}>BroadcastBeat hit an unexpected error.</p>
|
||||
{error?.digest && (
|
||||
<p style={{ fontSize: 12, opacity: 0.5, marginBottom: 16, fontFamily: "monospace" }}>ref: {error.digest}</p>
|
||||
)}
|
||||
<button
|
||||
onClick={() => reset()}
|
||||
style={{ padding: "8px 16px", background: "#3b82f6", color: "white", border: 0, cursor: "pointer", borderRadius: 2 }}
|
||||
>
|
||||
Try again
|
||||
</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user