mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 05:05:38 -04:00
Fix missing userStatus on title cards across dashboard, recommendations, and filmography
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ export async function LibrarySection({ userId }: { userId: string }) {
|
|||||||
posterPath: tmdbImageUrl(t.posterPath, "w500"),
|
posterPath: tmdbImageUrl(t.posterPath, "w500"),
|
||||||
releaseDate: t.releaseDate ?? t.firstAirDate,
|
releaseDate: t.releaseDate ?? t.firstAirDate,
|
||||||
voteAverage: t.voteAverage,
|
voteAverage: t.voteAverage,
|
||||||
|
userStatus: t.userStatus as "watchlist" | "in_progress" | "completed",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ interface TitleGridItem {
|
|||||||
posterPath: string | null;
|
posterPath: string | null;
|
||||||
releaseDate?: string | null;
|
releaseDate?: string | null;
|
||||||
voteAverage?: number | null;
|
voteAverage?: number | null;
|
||||||
|
userStatus?: "watchlist" | "in_progress" | "completed" | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TitleGrid({ items }: { items: TitleGridItem[] }) {
|
export function TitleGrid({ items }: { items: TitleGridItem[] }) {
|
||||||
@@ -29,6 +30,7 @@ export function TitleGrid({ items }: { items: TitleGridItem[] }) {
|
|||||||
posterPath={t.posterPath}
|
posterPath={t.posterPath}
|
||||||
releaseDate={t.releaseDate}
|
releaseDate={t.releaseDate}
|
||||||
voteAverage={t.voteAverage}
|
voteAverage={t.voteAverage}
|
||||||
|
userStatus={t.userStatus}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -18,9 +18,13 @@ type Sort = "newest" | "rating";
|
|||||||
|
|
||||||
interface FilmographyGridProps {
|
interface FilmographyGridProps {
|
||||||
credits: PersonCredit[];
|
credits: PersonCredit[];
|
||||||
|
userStatuses?: Record<string, "watchlist" | "in_progress" | "completed">;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FilmographyGrid({ credits }: FilmographyGridProps) {
|
export function FilmographyGrid({
|
||||||
|
credits,
|
||||||
|
userStatuses,
|
||||||
|
}: FilmographyGridProps) {
|
||||||
const [filter, setFilter] = useState<Filter>("all");
|
const [filter, setFilter] = useState<Filter>("all");
|
||||||
const [sort, setSort] = useState<Sort>("newest");
|
const [sort, setSort] = useState<Sort>("newest");
|
||||||
|
|
||||||
@@ -128,6 +132,7 @@ export function FilmographyGrid({ credits }: FilmographyGridProps) {
|
|||||||
posterPath={credit.posterPath}
|
posterPath={credit.posterPath}
|
||||||
releaseDate={credit.releaseDate ?? credit.firstAirDate}
|
releaseDate={credit.releaseDate ?? credit.firstAirDate}
|
||||||
voteAverage={credit.voteAverage}
|
voteAverage={credit.voteAverage}
|
||||||
|
userStatus={userStatuses?.[credit.titleId]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
getOrFetchPerson,
|
getOrFetchPerson,
|
||||||
getOrFetchPersonByTmdbId,
|
getOrFetchPersonByTmdbId,
|
||||||
} from "@/lib/services/person";
|
} from "@/lib/services/person";
|
||||||
|
import { getUserStatusesByTitleIds } from "@/lib/services/tracking";
|
||||||
import { FilmographyGrid } from "./_components/filmography-grid";
|
import { FilmographyGrid } from "./_components/filmography-grid";
|
||||||
import { PersonHero } from "./_components/person-hero";
|
import { PersonHero } from "./_components/person-hero";
|
||||||
|
|
||||||
@@ -47,11 +48,18 @@ export default async function PersonDetailPage({
|
|||||||
if (!person) notFound();
|
if (!person) notFound();
|
||||||
|
|
||||||
const filmography = getLocalFilmography(person.id);
|
const filmography = getLocalFilmography(person.id);
|
||||||
|
const session = await getSession();
|
||||||
|
const userStatuses = session
|
||||||
|
? getUserStatusesByTitleIds(
|
||||||
|
session.user.id,
|
||||||
|
filmography.map((c) => c.titleId),
|
||||||
|
)
|
||||||
|
: {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-10">
|
<div className="space-y-10">
|
||||||
<PersonHero person={person} />
|
<PersonHero person={person} />
|
||||||
<FilmographyGrid credits={filmography} />
|
<FilmographyGrid credits={filmography} userStatuses={userStatuses} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import type { RecommendedTitle } from "@/lib/types/title";
|
|||||||
|
|
||||||
export function RecommendationsGrid({
|
export function RecommendationsGrid({
|
||||||
recommendations,
|
recommendations,
|
||||||
|
userStatuses,
|
||||||
}: {
|
}: {
|
||||||
recommendations: RecommendedTitle[];
|
recommendations: RecommendedTitle[];
|
||||||
|
userStatuses?: Record<string, "watchlist" | "in_progress" | "completed">;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
@@ -30,6 +32,7 @@ export function RecommendationsGrid({
|
|||||||
posterPath={rec.posterPath}
|
posterPath={rec.posterPath}
|
||||||
releaseDate={rec.releaseDate ?? rec.firstAirDate}
|
releaseDate={rec.releaseDate ?? rec.firstAirDate}
|
||||||
voteAverage={rec.voteAverage}
|
voteAverage={rec.voteAverage}
|
||||||
|
userStatus={userStatuses?.[rec.id]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import { getSession } from "@/lib/auth/session";
|
||||||
import { getRecommendationsForTitle } from "@/lib/services/discovery";
|
import { getRecommendationsForTitle } from "@/lib/services/discovery";
|
||||||
|
import { getUserStatusesByTitleIds } from "@/lib/services/tracking";
|
||||||
import type { RecommendedTitle } from "@/lib/types/title";
|
import type { RecommendedTitle } from "@/lib/types/title";
|
||||||
import { RecommendationsGrid } from "./recommendations-grid";
|
import { RecommendationsGrid } from "./recommendations-grid";
|
||||||
|
|
||||||
@@ -17,5 +19,18 @@ export async function TitleRecommendations({ titleId }: { titleId: string }) {
|
|||||||
voteAverage: r.voteAverage,
|
voteAverage: r.voteAverage,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return <RecommendationsGrid recommendations={recommendations} />;
|
const session = await getSession();
|
||||||
|
const userStatuses = session
|
||||||
|
? getUserStatusesByTitleIds(
|
||||||
|
session.user.id,
|
||||||
|
recommendations.map((r) => r.id),
|
||||||
|
)
|
||||||
|
: {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RecommendationsGrid
|
||||||
|
recommendations={recommendations}
|
||||||
|
userStatuses={userStatuses}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,6 +370,7 @@ export function getNewAvailableFeed(userId: string, days = 14) {
|
|||||||
firstAirDate: titles.firstAirDate,
|
firstAirDate: titles.firstAirDate,
|
||||||
voteAverage: titles.voteAverage,
|
voteAverage: titles.voteAverage,
|
||||||
popularity: titles.popularity,
|
popularity: titles.popularity,
|
||||||
|
userStatus: userTitleStatus.status,
|
||||||
})
|
})
|
||||||
.from(titles)
|
.from(titles)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
|
|||||||
@@ -451,6 +451,36 @@ export function getUserStatusesByTmdbIds(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getUserStatusesByTitleIds(
|
||||||
|
userId: string,
|
||||||
|
titleIds: string[],
|
||||||
|
): Record<string, "watchlist" | "in_progress" | "completed"> {
|
||||||
|
if (titleIds.length === 0) return {};
|
||||||
|
|
||||||
|
const rows = db
|
||||||
|
.select({
|
||||||
|
titleId: userTitleStatus.titleId,
|
||||||
|
status: userTitleStatus.status,
|
||||||
|
})
|
||||||
|
.from(userTitleStatus)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(userTitleStatus.userId, userId),
|
||||||
|
inArray(userTitleStatus.titleId, titleIds),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.all();
|
||||||
|
|
||||||
|
const result: Record<string, "watchlist" | "in_progress" | "completed"> = {};
|
||||||
|
for (const row of rows) {
|
||||||
|
result[row.titleId] = row.status as
|
||||||
|
| "watchlist"
|
||||||
|
| "in_progress"
|
||||||
|
| "completed";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export function getEpisodeProgressByTmdbIds(
|
export function getEpisodeProgressByTmdbIds(
|
||||||
userId: string,
|
userId: string,
|
||||||
tmdbIds: { tmdbId: number; type: string }[],
|
tmdbIds: { tmdbId: number; type: string }[],
|
||||||
|
|||||||
Reference in New Issue
Block a user