mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-20 17:22:16 +00:00
fix more details modal stuff
This commit is contained in:
parent
0b54fc5182
commit
db6fc4355d
5 changed files with 158 additions and 38 deletions
|
|
@ -79,7 +79,19 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) {
|
||||||
undefined,
|
undefined,
|
||||||
formattedLanguage,
|
formattedLanguage,
|
||||||
);
|
);
|
||||||
setImdbData(imdbMetadata);
|
// Transform the data to match the expected format
|
||||||
|
if (
|
||||||
|
typeof imdbMetadata.imdb_rating === "number" &&
|
||||||
|
typeof imdbMetadata.votes === "number"
|
||||||
|
) {
|
||||||
|
setImdbData({
|
||||||
|
rating: imdbMetadata.imdb_rating,
|
||||||
|
votes: imdbMetadata.votes,
|
||||||
|
trailer_url: imdbMetadata.trailer_url || null,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setImdbData(null);
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch Rotten Tomatoes data
|
// Fetch Rotten Tomatoes data
|
||||||
if (data.type === "movie") {
|
if (data.type === "movie") {
|
||||||
|
|
@ -176,15 +188,16 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 bg-cover bg-center opacity-60 before:absolute before:inset-0 before:bg-[radial-gradient(circle_at_center,_transparent_0%,_rgba(0,0,0,0.5)_80%)]"
|
className="absolute inset-0 bg-cover bg-top opacity-60 before:absolute before:inset-0 before:bg-[radial-gradient(circle_at_center,_transparent_0%,_rgba(0,0,0,0.5)_80%)]"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: data.backdrop
|
backgroundImage: data.backdrop
|
||||||
? `url(${data.backdrop})`
|
? `url(${data.backdrop})`
|
||||||
: undefined,
|
: undefined,
|
||||||
|
backgroundPosition: "center top",
|
||||||
maskImage:
|
maskImage:
|
||||||
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 120px)",
|
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 150px)",
|
||||||
WebkitMaskImage:
|
WebkitMaskImage:
|
||||||
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 120px)",
|
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 150px)",
|
||||||
zIndex: -1,
|
zIndex: -1,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -204,6 +217,7 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) {
|
||||||
seasons={
|
seasons={
|
||||||
data.type === "show" ? data.seasonData?.seasons.length : undefined
|
data.type === "show" ? data.seasonData?.seasons.length : undefined
|
||||||
}
|
}
|
||||||
|
imdbData={imdbData}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Two Column Layout - Stacked on Mobile */}
|
{/* Two Column Layout - Stacked on Mobile */}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ export function DetailsHeader({
|
||||||
voteCount,
|
voteCount,
|
||||||
releaseDate,
|
releaseDate,
|
||||||
seasons,
|
seasons,
|
||||||
|
imdbData,
|
||||||
}: DetailsHeaderProps) {
|
}: DetailsHeaderProps) {
|
||||||
const formatDate = (dateString?: string) => {
|
const formatDate = (dateString?: string) => {
|
||||||
if (!dateString) return null;
|
if (!dateString) return null;
|
||||||
|
|
@ -30,7 +31,7 @@ export function DetailsHeader({
|
||||||
<div className="flex items-center gap-2 text-sm text-white/80">
|
<div className="flex items-center gap-2 text-sm text-white/80">
|
||||||
{voteAverage && (
|
{voteAverage && (
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<Icon icon={Icons.RISING_STAR} className="text-yellow-400" />
|
<Icon icon={Icons.TMDB} />
|
||||||
<span>{voteAverage.toFixed(1)}</span>
|
<span>{voteAverage.toFixed(1)}</span>
|
||||||
{voteCount && (
|
{voteCount && (
|
||||||
<span className="text-white/60">
|
<span className="text-white/60">
|
||||||
|
|
@ -39,6 +40,20 @@ export function DetailsHeader({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{imdbData?.rating && (
|
||||||
|
<>
|
||||||
|
<span className="text-white/60">•</span>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Icon icon={Icons.IMDB} className="text-yellow-400" />
|
||||||
|
<span>{imdbData.rating.toFixed(1)}</span>
|
||||||
|
{imdbData.votes && (
|
||||||
|
<span className="text-white/60">
|
||||||
|
({imdbData.votes.toLocaleString()})
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{releaseDate && (
|
{releaseDate && (
|
||||||
<>
|
<>
|
||||||
<span className="text-white/60">•</span>
|
<span className="text-white/60">•</span>
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ export function DetailsModal({ id, data, minimal }: DetailsModalProps) {
|
||||||
darken
|
darken
|
||||||
close={modal.hide}
|
close={modal.hide}
|
||||||
show={modal.isShown}
|
show={modal.isShown}
|
||||||
durationClass="duration-400"
|
durationClass="duration-500"
|
||||||
>
|
>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<html data-no-scroll />
|
<html data-no-scroll />
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,128 @@
|
||||||
export function DetailsSkeleton() {
|
export function DetailsSkeleton() {
|
||||||
|
// Static arrays of unique identifiers for skeleton elements
|
||||||
|
const episodeSkeletons = [
|
||||||
|
"episode-skeleton-1",
|
||||||
|
"episode-skeleton-2",
|
||||||
|
"episode-skeleton-3",
|
||||||
|
"episode-skeleton-4",
|
||||||
|
];
|
||||||
|
const castSkeletons = [
|
||||||
|
"cast-skeleton-1",
|
||||||
|
"cast-skeleton-2",
|
||||||
|
"cast-skeleton-3",
|
||||||
|
"cast-skeleton-4",
|
||||||
|
"cast-skeleton-5",
|
||||||
|
"cast-skeleton-6",
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="animate-pulse">
|
<div className="relative h-full flex flex-col animate-pulse">
|
||||||
<div className="relative">
|
{/* Backdrop */}
|
||||||
{/* Backdrop */}
|
<div
|
||||||
<div className="h-64 relative -mt-12">
|
className="relative -mt-12 z-20"
|
||||||
<div
|
style={{
|
||||||
className="absolute inset-0 bg-mediaCard-hoverBackground"
|
height: "500px",
|
||||||
style={{
|
}}
|
||||||
maskImage:
|
>
|
||||||
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 60px)",
|
{/* Title/Logo positioned on backdrop */}
|
||||||
WebkitMaskImage:
|
<div className="absolute inset-x-0 bottom-20 z-30 px-6">
|
||||||
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 60px)",
|
<div className="h-12 w-64 bg-white/10 rounded-lg" />{" "}
|
||||||
}}
|
{/* Logo/Title placeholder */}
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{/* Content */}
|
<div
|
||||||
<div className="px-6 pb-6 mt-[-30px]">
|
className="absolute inset-0 bg-white/10"
|
||||||
<div className="h-8 w-3/4 bg-white/10 rounded mb-3" /> {/* Title */}
|
style={{
|
||||||
<div className="space-y-2 mb-6">
|
maskImage:
|
||||||
|
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 120px)",
|
||||||
|
WebkitMaskImage:
|
||||||
|
"linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1) 120px)",
|
||||||
|
zIndex: -1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="px-6 pb-6 mt-[-70px] flex-grow relative z-30">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex flex-wrap items-center gap-4 mb-6">
|
||||||
|
<div className="h-10 w-32 bg-white/10 rounded-lg" />{" "}
|
||||||
|
{/* Play button */}
|
||||||
|
<div className="h-10 w-32 bg-white/10 rounded-lg" />{" "}
|
||||||
|
{/* Trailer button */}
|
||||||
|
<div className="h-10 w-32 bg-white/10 rounded-lg" />{" "}
|
||||||
|
{/* Share button */}
|
||||||
|
<div className="flex-1" />
|
||||||
|
<div className="h-6 w-24 bg-white/10 rounded-lg" /> {/* Rating */}
|
||||||
|
<div className="h-6 w-24 bg-white/10 rounded-lg" />{" "}
|
||||||
|
{/* Release date */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Two Column Layout */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 md:gap-6 pt-4">
|
||||||
|
{/* Left Column - Main Content (2/3) */}
|
||||||
|
<div className="md:col-span-2">
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<div className="h-4 bg-white/10 rounded w-full" />
|
<div className="space-y-2 mb-6">
|
||||||
<div className="h-4 bg-white/10 rounded w-full" />
|
<div className="h-4 bg-white/10 rounded w-full" />
|
||||||
<div className="h-4 bg-white/10 rounded w-full" />
|
<div className="h-4 bg-white/10 rounded w-full" />
|
||||||
<div className="h-4 bg-white/10 rounded w-3/4" />
|
<div className="h-4 bg-white/10 rounded w-3/4" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Genres */}
|
||||||
|
<div className="flex flex-wrap gap-2 mb-6">
|
||||||
|
<div className="h-6 w-20 bg-white/10 rounded-full" />
|
||||||
|
<div className="h-6 w-24 bg-white/10 rounded-full" />
|
||||||
|
<div className="h-6 w-16 bg-white/10 rounded-full" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Director and Cast */}
|
||||||
|
<div className="space-y-4 mb-6">
|
||||||
|
<div className="h-4 w-48 bg-white/10 rounded" /> {/* Director */}
|
||||||
|
<div className="h-4 w-64 bg-white/10 rounded" /> {/* Cast */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Additional details */}
|
|
||||||
<div className="grid grid-cols-2 gap-3 mb-6">
|
{/* Right Column - Details Info (1/3) */}
|
||||||
<div className="h-4 bg-white/10 rounded w-3/4" />
|
<div className="md:col-span-1">
|
||||||
<div className="h-4 bg-white/10 rounded w-3/4" />
|
<div className="bg-video-context-border p-4 rounded-lg border-buttons-primary bg-opacity-80">
|
||||||
<div className="h-4 bg-white/10 rounded w-3/4" />
|
<div className="space-y-3">
|
||||||
<div className="h-4 bg-white/10 rounded w-3/4" />
|
<div className="h-4 w-32 bg-white/10 rounded" /> {/* Runtime */}
|
||||||
|
<div className="h-4 w-24 bg-white/10 rounded" />{" "}
|
||||||
|
{/* Language */}
|
||||||
|
<div className="h-4 w-36 bg-white/10 rounded" />{" "}
|
||||||
|
{/* Release date */}
|
||||||
|
<div className="h-4 w-20 bg-white/10 rounded" /> {/* Rating */}
|
||||||
|
<div className="h-4 w-40 bg-white/10 rounded" />{" "}
|
||||||
|
{/* External ratings */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Genres */}
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
<div className="h-6 w-20 bg-white/10 rounded-full" />
|
{/* Episodes Carousel Skeleton */}
|
||||||
<div className="h-6 w-24 bg-white/10 rounded-full" />
|
<div className="mt-8">
|
||||||
<div className="h-6 w-16 bg-white/10 rounded-full" />
|
<div className="h-6 w-48 bg-white/10 rounded mb-4" />{" "}
|
||||||
|
{/* Season selector */}
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
||||||
|
{episodeSkeletons.map((key) => (
|
||||||
|
<div key={key} className="aspect-video bg-white/10 rounded-lg" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Cast Carousel Skeleton */}
|
||||||
|
<div className="mt-8">
|
||||||
|
<div className="h-6 w-32 bg-white/10 rounded mb-4" />{" "}
|
||||||
|
{/* Cast title */}
|
||||||
|
<div className="flex gap-4 overflow-x-auto pb-4">
|
||||||
|
{castSkeletons.map((key) => (
|
||||||
|
<div key={key} className="flex-shrink-0 w-32">
|
||||||
|
<div className="aspect-[2/3] bg-white/10 rounded-lg mb-2" />{" "}
|
||||||
|
{/* Profile image */}
|
||||||
|
<div className="h-4 w-24 bg-white/10 rounded mx-auto" />{" "}
|
||||||
|
{/* Name */}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,10 @@ export interface DetailsHeaderProps {
|
||||||
voteCount?: number;
|
voteCount?: number;
|
||||||
releaseDate?: string;
|
releaseDate?: string;
|
||||||
seasons?: number;
|
seasons?: number;
|
||||||
|
imdbData?: {
|
||||||
|
rating: number;
|
||||||
|
votes: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DetailsInfoProps {
|
export interface DetailsInfoProps {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue