208 lines
8.0 KiB
TypeScript
208 lines
8.0 KiB
TypeScript
"use client";
|
|
import { FC, useState } from "react";
|
|
import { MdFavorite } from "react-icons/md";
|
|
import { RxEyeOpen } from "react-icons/rx";
|
|
import { FaFire, FaTrash, FaPlusCircle } from "react-icons/fa";
|
|
import { RiCalendarCheckLine, RiCalendarScheduleLine } from "react-icons/ri";
|
|
import { Movie } from "@/types/global";
|
|
import Link from "next/link";
|
|
|
|
interface AuroraLayoutProps extends Movie {
|
|
showDayCounter?: boolean;
|
|
simpleToggle?: boolean;
|
|
alreadyInStore?: Movie | undefined;
|
|
isReleased: boolean;
|
|
handleAdd: () => void;
|
|
handleRemove: () => void;
|
|
handleSeen: () => void;
|
|
handleFavorite: () => void;
|
|
daysSinceRelease: number;
|
|
releaseDate: Date;
|
|
}
|
|
|
|
export const AuroraLayout: FC<AuroraLayoutProps> = ({
|
|
id,
|
|
title,
|
|
overview,
|
|
popularity,
|
|
release_date,
|
|
poster_path,
|
|
vote_average,
|
|
seen,
|
|
favorite,
|
|
alreadyInStore,
|
|
isReleased,
|
|
handleAdd,
|
|
handleRemove,
|
|
handleSeen,
|
|
handleFavorite,
|
|
daysSinceRelease,
|
|
releaseDate,
|
|
simpleToggle,
|
|
}) => {
|
|
const scoreColor =
|
|
vote_average >= 8
|
|
? "from-emerald-400 to-teal-400"
|
|
: vote_average >= 6
|
|
? "from-yellow-400 to-orange-400"
|
|
: "from-red-400 to-pink-400";
|
|
|
|
return (
|
|
<article className="group relative w-full overflow-hidden rounded-2xl max-w-[300px] mx-auto">
|
|
{/* Main card container */}
|
|
<div className="grid relative h-full bg-gradient-to-br from-slate-800/95 via-slate-850/97 to-slate-900/95 border border-slate-700/50 shadow-2xl shadow-purple-500/10 group-hover:shadow-purple-500/20 transition-all duration-500">
|
|
{/* Image section with sophisticated overlay */}
|
|
<figure className="relative overflow-hidden aspect-[4/3] lg:aspect-[342/513]">
|
|
<Link href={`/film/${id}`}>
|
|
<img
|
|
className="w-full h-full object-cover transition-all duration-700 hover:scale-110 hover:brightness-110 bg-gradient-to-b from-purple-600/50 to-emerald-600"
|
|
src={`http://image.tmdb.org/t/p/w342${poster_path}`}
|
|
alt={title}
|
|
/>
|
|
</Link>
|
|
|
|
{/* Gradient overlays for depth */}
|
|
<div className="absolute inset-0 bg-gradient-to-t from-slate-900 via-slate-900/20 to-transparent pointer-events-none" />
|
|
|
|
{/* Floating rating badge */}
|
|
{!!vote_average && (
|
|
<div className="absolute top-4 right-4 transform rotate-3 group-hover:rotate-0 transition-transform duration-300">
|
|
<div
|
|
className={`bg-gradient-to-r ${scoreColor} p-2 rounded-xl shadow-lg border border-white/10`}
|
|
>
|
|
<div className="flex items-center gap-2 text-white font-bold">
|
|
<span className="text-xl">★</span>
|
|
<span className="text-lg">{vote_average.toFixed(1)}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Popularity indicator */}
|
|
<div className="absolute top-4 left-4 bg-gradient-to-br from-black/80 to-slate-900/85 px-3 py-2 rounded-xl border border-white/20 shadow-lg">
|
|
<div className="flex items-center gap-2 text-orange-400">
|
|
<FaFire className="animate-pulse" />
|
|
<span className="text-sm font-medium">
|
|
{Math.round(popularity)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Days left to release */}
|
|
{(!isReleased || daysSinceRelease < 35) && (
|
|
<div className="absolute bottom-4 left-4 flex justify-center">
|
|
<p className="text-white bg-gradient-to-r from-black/75 to-slate-900/80 px-2.5 leading-[2] rounded-xl border border-white/20 text-xs shadow-lg">
|
|
{isReleased &&
|
|
daysSinceRelease < 35 &&
|
|
`od ${daysSinceRelease} dni`}
|
|
{!isReleased && `za ${daysSinceRelease} dni`}
|
|
</p>
|
|
</div>
|
|
)}
|
|
|
|
{/* Status indicators */}
|
|
<div className="absolute bottom-4 right-4 flex gap-2">
|
|
{alreadyInStore && !simpleToggle && (
|
|
<>
|
|
<div
|
|
className={`${
|
|
seen
|
|
? "bg-gradient-to-r from-emerald-500/95 to-emerald-600/90"
|
|
: "bg-gradient-to-r from-white/25 to-white/15"
|
|
} p-2 rounded-full cursor-pointer hover:bg-emerald-400 transition-colors border border-white/10 shadow-lg`}
|
|
onClick={handleSeen}
|
|
>
|
|
<RxEyeOpen size={16} className="text-white" />
|
|
</div>
|
|
<div
|
|
className={`${
|
|
favorite
|
|
? "bg-gradient-to-r from-rose-500/95 to-rose-600/90"
|
|
: "bg-gradient-to-r from-white/25 to-white/15"
|
|
} p-2 rounded-full cursor-pointer hover:bg-rose-400 transition-colors border border-white/10 shadow-lg`}
|
|
onClick={handleFavorite}
|
|
>
|
|
<MdFavorite size={16} className="text-white" />
|
|
</div>
|
|
</>
|
|
)}
|
|
{!alreadyInStore && (
|
|
<div
|
|
className={`bg-gradient-to-r from-emerald-500/50 to-emerald-600/50 p-2 rounded-full cursor-pointer hover:bg-emerald-400 transition-colors border border-white/10 shadow-lg`}
|
|
onClick={handleAdd}
|
|
>
|
|
<FaPlusCircle size={16} className="text-white" />
|
|
</div>
|
|
)}
|
|
{alreadyInStore && (
|
|
<div
|
|
className={`bg-gradient-to-r from-red-400/25 to-red-400/15 p-2 rounded-full cursor-pointer hover:bg-red-400 transition-colors border border-white/10 shadow-lg`}
|
|
onClick={handleRemove}
|
|
>
|
|
<FaTrash size={16} className="text-white" />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</figure>
|
|
|
|
{/* Content section with glowing effects */}
|
|
<div className="relative p-6 flex flex-col justify-between">
|
|
<div className="relative z-10">
|
|
<Link href={`/film/${id}`}>
|
|
<h3 className="font-bold text-xl leading-tight mb-3 transition-colors duration-500 hover:text-secondary flex items-center gap-2">
|
|
{title}
|
|
</h3>
|
|
<p className="text-sm text-gray-400 line-clamp-2 leading-relaxed opacity-80 transition-colors duration-300 hover:text-secondary">
|
|
{overview}
|
|
</p>
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Bottom section with enhanced styling */}
|
|
<div className="relative z-10 flex items-center justify-between pt-4 mt-4 border-t border-gradient-to-r border-slate-700/50">
|
|
<div className="flex items-center gap-3">
|
|
<div
|
|
className={`flex items-center gap-1 text-sm ${
|
|
isReleased ? "text-emerald-400" : "text-amber-400"
|
|
}`}
|
|
>
|
|
{isReleased ? (
|
|
<RiCalendarCheckLine />
|
|
) : (
|
|
<RiCalendarScheduleLine />
|
|
)}
|
|
<span className="font-medium">
|
|
{releaseDate.toLocaleDateString("pl-PL", {
|
|
day: "numeric",
|
|
month: "short",
|
|
year: "numeric",
|
|
})}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3">
|
|
{alreadyInStore && (
|
|
<div className="flex gap-2">
|
|
{seen && (
|
|
<div
|
|
className="w-3 h-3 bg-gradient-to-r from-emerald-400 to-teal-400 rounded-full shadow-lg shadow-emerald-400/50 animate-pulse"
|
|
title="Watched"
|
|
/>
|
|
)}
|
|
{favorite && (
|
|
<div
|
|
className="w-3 h-3 bg-gradient-to-r from-rose-400 to-pink-400 rounded-full shadow-lg shadow-rose-400/50 animate-pulse"
|
|
title="Favorite"
|
|
/>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
);
|
|
};
|