Convert dashboard and title pages to server components with granular Suspense

Replace fully client-side dashboard and title detail pages with server
component orchestrators that fetch data directly via service functions,
eliminating extra network round-trips through API routes. Each section
streams independently through its own Suspense boundary.

- Extract getUserStats(), getTitleWithChildren(), getRecommendationsForTitle()
  into service layer; update getNewAvailableFeed() to include tmdbId/voteAverage
- Split dashboard into server sections (stats, continue watching, library,
  recommendations) with client children for animations
- Split title page into server hero + client interaction provider with shared
  context for optimistic mutations across actions and seasons
- Add generateMetadata with OG tags, server-side TMDB ID resolution via
  redirect(), loading.tsx and not-found.tsx for both pages
- Add per-section skeleton components, fix ContinueWatchingSkeleton dimensions
- Remove 6 unused API routes (feed/*, titles/[id] GET, titles/[id]/recommendations)
- Remove components/stats-summary.tsx, add lib/types/title.ts for shared types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-02 15:42:42 -05:00
co-authored by Claude Opus 4.6
parent 081f53beac
commit c1867a4f23
33 changed files with 1804 additions and 1654 deletions
@@ -0,0 +1,12 @@
export function WelcomeHeader({ name }: { name?: string | null }) {
return (
<div>
<h1 className="font-display text-3xl tracking-tight">
Welcome back{name ? `, ${name}` : ""}
</h1>
<p className="mt-1 text-sm text-muted-foreground">
Here&apos;s what&apos;s happening with your library
</p>
</div>
);
}