Files
sofa/app/(pages)/titles/[id]/_components/title-recommendations.tsx
T
jakeandClaude Opus 4.6 c1867a4f23 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>
2026-03-02 15:42:42 -05:00

22 lines
714 B
TypeScript

import { getRecommendationsForTitle } from "@/lib/services/discovery";
import type { RecommendedTitle } from "@/lib/types/title";
import { RecommendationsGrid } from "./recommendations-grid";
export async function TitleRecommendations({ titleId }: { titleId: string }) {
const recs = await getRecommendationsForTitle(titleId);
if (recs.length === 0) return null;
const recommendations: RecommendedTitle[] = recs.map((r) => ({
id: r.id,
tmdbId: r.tmdbId,
type: r.type,
title: r.title,
posterPath: r.posterPath,
releaseDate: r.releaseDate,
firstAirDate: r.firstAirDate,
voteAverage: r.voteAverage,
}));
return <RecommendationsGrid recommendations={recommendations} />;
}