feat: implement responsive container utility and enhance layout styles across components; update Carousel and Gallery for improved structure and consistency
This commit is contained in:
parent
e891b37384
commit
fd1240252d
|
|
@ -16,22 +16,30 @@ export default async function Page({
|
||||||
const personDetails = await TMDB.getPersonDetails(actorId);
|
const personDetails = await TMDB.getPersonDetails(actorId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 pb-16">
|
<div className="bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 py-0.5">
|
||||||
<ActorHero personDetails={personDetails} />
|
<ActorHero personDetails={personDetails} />
|
||||||
<Gallery images={personDetails.images.profiles} heading="Galeria" />
|
<Gallery images={personDetails.images.profiles} heading="Galeria" />
|
||||||
<div className="container">
|
<section className="blocks">
|
||||||
<Carousel
|
<div className="container">
|
||||||
heading={`Filmy z udziałem ${personDetails.name}`}
|
<Carousel
|
||||||
icon={<FaStar />}
|
heading={`Filmy z udziałem ${personDetails.name}`}
|
||||||
colors="purple"
|
icon={<FaStar />}
|
||||||
>
|
colors="purple"
|
||||||
{personDetails.movie_credits.cast.map((movie) => {
|
>
|
||||||
const convertedMovie = convertToMovie(movie);
|
{personDetails.movie_credits.cast
|
||||||
if (!convertedMovie) return null;
|
.sort(
|
||||||
return <MovieCard key={movie.id} {...convertedMovie} />;
|
(a, b) =>
|
||||||
})}
|
new Date(b.release_date).getTime() -
|
||||||
</Carousel>
|
new Date(a.release_date).getTime()
|
||||||
</div>
|
)
|
||||||
|
.map((movie) => {
|
||||||
|
const convertedMovie = convertToMovie(movie);
|
||||||
|
if (!convertedMovie) return null;
|
||||||
|
return <MovieCard key={movie.id} {...convertedMovie} />;
|
||||||
|
})}
|
||||||
|
</Carousel>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ export default async function Page({
|
||||||
const movieDetails = await TMDB.getMovieDetails(movieId);
|
const movieDetails = await TMDB.getMovieDetails(movieId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen mt-16">
|
<>
|
||||||
<HeroMovie movieDetails={movieDetails} />
|
<HeroMovie movieDetails={movieDetails} />
|
||||||
<MovieCast movieDetails={movieDetails} />
|
<MovieCast movieDetails={movieDetails} />
|
||||||
<RecommendedMovies movies={movieDetails.recommendations} />
|
<RecommendedMovies movies={movieDetails.recommendations} />
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,18 +46,30 @@
|
||||||
|
|
||||||
@custom-variant hover-any (&:hover);
|
@custom-variant hover-any (&:hover);
|
||||||
|
|
||||||
|
@utility container {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 15px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
@variant sm {
|
||||||
|
max-width: 640px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@variant lg {
|
||||||
|
max-width: 860px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@variant xl {
|
||||||
|
max-width: 1280px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
body {
|
body {
|
||||||
@apply bg-hippie-blue-950 text-text;
|
@apply bg-hippie-blue-950 text-text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-fluid {
|
.container-fluid {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
@ -71,6 +83,22 @@
|
||||||
margin: 0 -15px;
|
margin: 0 -15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blocks {
|
||||||
|
margin: 32px 0;
|
||||||
|
|
||||||
|
@variant lg {
|
||||||
|
margin: 64px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.blockp {
|
||||||
|
padding: 32px 0;
|
||||||
|
|
||||||
|
@variant lg {
|
||||||
|
padding: 64px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@apply transition-colors;
|
@apply transition-colors;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,7 @@ export default async function RootLayout({
|
||||||
<GlobalStoreProvider>
|
<GlobalStoreProvider>
|
||||||
<AuroraBackground />
|
<AuroraBackground />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main className="relative pt-16 lg:pt-20 [&>:last-child]:mb-0">
|
<main className="relative">{children}</main>
|
||||||
{children}
|
|
||||||
</main>
|
|
||||||
</GlobalStoreProvider>
|
</GlobalStoreProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -47,63 +47,41 @@ export default async function Home() {
|
||||||
<>
|
<>
|
||||||
<Hero movies={heroMovies} autoRotate />
|
<Hero movies={heroMovies} autoRotate />
|
||||||
|
|
||||||
<div className="container py-16 space-y-16">
|
<section className="blocks">
|
||||||
<section>
|
<Carousel heading="Teraz w kinach" icon={<FaPlay />}>
|
||||||
<Carousel heading="Teraz w kinach" icon={<FaPlay />}>
|
{nowPlayingMovies.map((movie) => (
|
||||||
{nowPlayingMovies.map((movie) => (
|
<MovieCard key={movie.id} {...movie} simpleToggle layout="aurora" />
|
||||||
<MovieCard
|
))}
|
||||||
key={movie.id}
|
</Carousel>
|
||||||
{...movie}
|
</section>
|
||||||
simpleToggle
|
|
||||||
layout="aurora"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Carousel>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
<section className="blocks">
|
||||||
<Carousel
|
<Carousel
|
||||||
heading="Nadchodzące filmy"
|
heading="Nadchodzące filmy"
|
||||||
icon={<FaCalendar />}
|
icon={<FaCalendar />}
|
||||||
colors="blue"
|
colors="blue"
|
||||||
>
|
>
|
||||||
{upcomingMovies.map((movie) => (
|
{upcomingMovies.map((movie) => (
|
||||||
<MovieCard
|
<MovieCard key={movie.id} {...movie} simpleToggle layout="aurora" />
|
||||||
key={movie.id}
|
))}
|
||||||
{...movie}
|
</Carousel>
|
||||||
simpleToggle
|
</section>
|
||||||
layout="aurora"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Carousel>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
<section className="blocks">
|
||||||
<Carousel heading="Popularne filmy" icon={<FaFire />} colors="red">
|
<Carousel heading="Popularne filmy" icon={<FaFire />} colors="red">
|
||||||
{popularMovies.map((movie) => (
|
{popularMovies.map((movie) => (
|
||||||
<MovieCard
|
<MovieCard key={movie.id} {...movie} simpleToggle layout="aurora" />
|
||||||
key={movie.id}
|
))}
|
||||||
{...movie}
|
</Carousel>
|
||||||
simpleToggle
|
</section>
|
||||||
layout="aurora"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Carousel>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
<section className="blocks">
|
||||||
<Carousel heading="Trendy dnia" icon={<FaChartLine />} colors="green">
|
<Carousel heading="Trendy dnia" icon={<FaChartLine />} colors="green">
|
||||||
{trendingMovies.map((movie) => (
|
{trendingMovies.map((movie) => (
|
||||||
<MovieCard
|
<MovieCard key={movie.id} {...movie} simpleToggle layout="aurora" />
|
||||||
key={movie.id}
|
))}
|
||||||
{...movie}
|
</Carousel>
|
||||||
simpleToggle
|
</section>
|
||||||
layout="aurora"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Carousel>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="p-2 text-center text-xs text-gray-500">
|
<div className="p-2 text-center text-xs text-gray-500">
|
||||||
<p>Ostatnia aktualizacja: {lastModified}</p>
|
<p>Ostatnia aktualizacja: {lastModified}</p>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ type Props = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
theme?: Theme;
|
theme?: Theme;
|
||||||
size?: "small" | "medium" | "large";
|
size?: "small" | "medium" | "large" | "icon";
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
href?: string;
|
href?: string;
|
||||||
gradient?: {
|
gradient?: {
|
||||||
|
|
@ -31,7 +31,7 @@ export const Button: FC<Props> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
className={`flex items-center justify-center gap-2 cursor-pointer text-white rounded-xl font-semibold shadow-2xl transition-all duration-300 hover:scale-105
|
className={`flex items-center justify-center gap-2 cursor-pointer text-white rounded-xl font-semibold shadow-2xl transition-colors duration-300
|
||||||
bg-gradient-to-r ${buttonColor?.from} ${buttonColor?.to} cursor-pointer ${sizes[size]} ${className}`}
|
bg-gradient-to-r ${buttonColor?.from} ${buttonColor?.to} cursor-pointer ${sizes[size]} ${className}`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
{...(href && { href })}
|
{...(href && { href })}
|
||||||
|
|
@ -45,6 +45,7 @@ const sizes = {
|
||||||
small: "px-4 py-2 text-sm",
|
small: "px-4 py-2 text-sm",
|
||||||
medium: "px-8 py-4 text-lg",
|
medium: "px-8 py-4 text-lg",
|
||||||
large: "px-12 py-6 text-xl",
|
large: "px-12 py-6 text-xl",
|
||||||
|
icon: "p-3 [&>*]:w-5 [&>*]:h-5",
|
||||||
};
|
};
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
|
|
@ -57,7 +58,7 @@ const colors = {
|
||||||
to: "to-pink-600 hover:to-pink-500",
|
to: "to-pink-600 hover:to-pink-500",
|
||||||
},
|
},
|
||||||
glass: {
|
glass: {
|
||||||
from: "from-white/15 via-white/8 to-white/12",
|
from: "from-white/15 via-white/8 to-white/12 border border-white/20",
|
||||||
to: "to-white/15 hover:to-white/10",
|
to: "to-white/15 hover:to-white/10",
|
||||||
},
|
},
|
||||||
rose: {
|
rose: {
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
|
||||||
: "from-red-400 to-pink-400";
|
: "from-red-400 to-pink-400";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className="group relative w-full overflow-hidden rounded-2xl">
|
<article className="group relative w-full overflow-hidden rounded-2xl max-w-[300px] mx-auto">
|
||||||
{/* Aurora background effect */}
|
{/* Aurora background effect */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-br from-purple-900/20 via-blue-900/20 to-teal-900/20 opacity-60"></div>
|
<div className="absolute inset-0 bg-gradient-to-br from-purple-900/20 via-blue-900/20 to-teal-900/20 opacity-60"></div>
|
||||||
<div className="absolute inset-0 bg-gradient-to-tr from-pink-500/10 via-transparent to-cyan-500/10 opacity-0 group-hover:opacity-100 transition-opacity duration-1000"></div>
|
<div className="absolute inset-0 bg-gradient-to-tr from-pink-500/10 via-transparent to-cyan-500/10 opacity-0 group-hover:opacity-100 transition-opacity duration-1000"></div>
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export const ActorHero: FC<Props> = ({ personDetails }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="pt-16 pb-8">
|
<section className="blocks">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<div className="absolute top-0 left-0 right-0 z-20 px-6">
|
<div className="absolute top-0 left-0 right-0 z-20 px-6">
|
||||||
|
|
@ -63,161 +63,157 @@ export const ActorHero: FC<Props> = ({ personDetails }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main content */}
|
{/* Main content */}
|
||||||
<div className="relative z-10 px-6 lg:px-8 mt-16">
|
<div className="container">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
{/* Profile photo */}
|
||||||
{/* Profile photo */}
|
<div className="flex-shrink-0 text-center">
|
||||||
<div className="flex-shrink-0">
|
<div className="relative group inline-block">
|
||||||
<div className="relative group">
|
<img
|
||||||
<img
|
src={
|
||||||
src={
|
personDetails.profile_path
|
||||||
personDetails.profile_path
|
? `https://image.tmdb.org/t/p/w500${personDetails.profile_path}`
|
||||||
? `https://image.tmdb.org/t/p/w500${personDetails.profile_path}`
|
: "/api/placeholder/400/600"
|
||||||
: "/api/placeholder/400/600"
|
}
|
||||||
}
|
alt={personDetails.name}
|
||||||
alt={personDetails.name}
|
className="w-80 h-auto rounded-2xl shadow-2xl shadow-purple-500/20 group-hover:shadow-purple-500/40 transition-all duration-500"
|
||||||
className="w-80 h-auto rounded-2xl shadow-2xl shadow-purple-500/20 group-hover:shadow-purple-500/40 transition-all duration-500"
|
/>
|
||||||
/>
|
<div className="absolute inset-0 rounded-2xl bg-gradient-to-t from-purple-600/20 to-transparent opacity-100" />
|
||||||
<div className="absolute inset-0 rounded-2xl bg-gradient-to-t from-purple-600/20 to-transparent opacity-100" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Actor details */}
|
{/* Actor details */}
|
||||||
<div className="flex-1 text-white">
|
<div className="flex-1 text-white">
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Name and known for */}
|
{/* Name and known for */}
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-4xl lg:text-5xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
|
<h1 className="text-4xl lg:text-5xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
|
||||||
{personDetails.name}
|
{personDetails.name}
|
||||||
</h1>
|
</h1>
|
||||||
{personDetails.birthday && (
|
{personDetails.birthday && (
|
||||||
<span className="text-sm text-gray-400">
|
<span className="text-sm text-gray-400">
|
||||||
(
|
(
|
||||||
{calculateAge(
|
{calculateAge(
|
||||||
personDetails.birthday,
|
personDetails.birthday,
|
||||||
personDetails.deathday
|
personDetails.deathday
|
||||||
)}{" "}
|
)}{" "}
|
||||||
lat
|
lat
|
||||||
{personDetails.deathday && " w chwili śmierci"})
|
{personDetails.deathday && " w chwili śmierci"})
|
||||||
</span>
|
</span>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="flex items-center gap-4 mb-4 mt-4">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<FaTheaterMasks className="text-purple-400" />
|
|
||||||
<span className="text-xl text-gray-300 font-medium">
|
|
||||||
{personDetails.known_for_department}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<FaStar className="text-yellow-400" />
|
|
||||||
<span className="text-lg text-gray-300">
|
|
||||||
{Math.round(personDetails.popularity)} popularność
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Also known as */}
|
|
||||||
{personDetails.also_known_as.length > 0 && (
|
|
||||||
<div className="mb-4">
|
|
||||||
<p className="text-gray-400 text-sm">
|
|
||||||
Znany również jako:{" "}
|
|
||||||
{personDetails.also_known_as.slice(0, 3).join(", ")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Personal info */}
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
||||||
{/* Gender */}
|
|
||||||
<div className="flex items-center gap-2 text-gray-300">
|
|
||||||
<span className="text-purple-400">Płeć:</span>
|
|
||||||
<span>{getGenderText(personDetails.gender)}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Birthday */}
|
|
||||||
{personDetails.birthday && (
|
|
||||||
<div className="flex items-center gap-2 text-gray-300">
|
|
||||||
<FaCalendarAlt className="text-purple-400" />
|
|
||||||
<div className="flex">
|
|
||||||
<span>{formatDate(personDetails.birthday)}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Deathday */}
|
|
||||||
{personDetails.deathday && (
|
|
||||||
<div className="flex items-center gap-2 text-gray-300">
|
|
||||||
<FaCalendarAlt className="text-red-400" />
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<span className="text-red-300">Data śmierci:</span>
|
|
||||||
<span>{formatDate(personDetails.deathday)}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Place of birth */}
|
|
||||||
{personDetails.place_of_birth && (
|
|
||||||
<div className="flex items-center gap-2 text-gray-300">
|
|
||||||
<FaMapMarkerAlt className="text-purple-400" />
|
|
||||||
<span>{personDetails.place_of_birth}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Biography */}
|
|
||||||
{personDetails.biography && (
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold mb-3 text-purple-300">
|
|
||||||
Biografia
|
|
||||||
</h3>
|
|
||||||
<div className="text-gray-300 leading-relaxed text-lg space-y-4">
|
|
||||||
{personDetails.biography
|
|
||||||
.split("\n\n")
|
|
||||||
.map((paragraph, index) => (
|
|
||||||
<p key={index}>{paragraph}</p>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* External links */}
|
<div className="flex items-center gap-4 mb-4 mt-4">
|
||||||
{personDetails.external_ids && (
|
<div className="flex items-center gap-2">
|
||||||
<div>
|
<FaTheaterMasks className="text-purple-400" />
|
||||||
<h3 className="text-lg font-semibold mb-3 text-purple-300">
|
<span className="text-xl text-gray-300 font-medium">
|
||||||
Linki
|
{personDetails.known_for_department}
|
||||||
</h3>
|
</span>
|
||||||
<div className="flex gap-4">
|
</div>
|
||||||
{Object.entries(personDetails.external_ids).map(
|
|
||||||
([key, value]) => {
|
|
||||||
if (!(key in externalIdsMap) || !value) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { label, icon, url } =
|
<div className="flex items-center gap-2">
|
||||||
externalIdsMap[
|
<FaStar className="text-yellow-400" />
|
||||||
key as keyof typeof externalIdsMap
|
<span className="text-lg text-gray-300">
|
||||||
];
|
{Math.round(personDetails.popularity)} popularność
|
||||||
return (
|
</span>
|
||||||
<a
|
</div>
|
||||||
key={key}
|
</div>
|
||||||
href={url(value as string)}
|
|
||||||
target="_blank"
|
{/* Also known as */}
|
||||||
rel="noopener noreferrer"
|
{personDetails.also_known_as.length > 0 && (
|
||||||
className="flex items-center gap-2 bg-white/10 hover:bg-white/20 px-4 py-2 rounded-xl transition-all duration-300 border border-white/20"
|
<div className="mb-4">
|
||||||
>
|
<p className="text-gray-400 text-sm">
|
||||||
{icon}
|
Znany również jako:{" "}
|
||||||
{label}
|
{personDetails.also_known_as.slice(0, 3).join(", ")}
|
||||||
</a>
|
</p>
|
||||||
);
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Personal info */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
{/* Gender */}
|
||||||
|
<div className="flex items-center gap-2 text-gray-300">
|
||||||
|
<span className="text-purple-400">Płeć:</span>
|
||||||
|
<span>{getGenderText(personDetails.gender)}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Birthday */}
|
||||||
|
{personDetails.birthday && (
|
||||||
|
<div className="flex items-center gap-2 text-gray-300">
|
||||||
|
<FaCalendarAlt className="text-purple-400" />
|
||||||
|
<div className="flex">
|
||||||
|
<span>{formatDate(personDetails.birthday)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Deathday */}
|
||||||
|
{personDetails.deathday && (
|
||||||
|
<div className="flex items-center gap-2 text-gray-300">
|
||||||
|
<FaCalendarAlt className="text-red-400" />
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="text-red-300">Data śmierci:</span>
|
||||||
|
<span>{formatDate(personDetails.deathday)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Place of birth */}
|
||||||
|
{personDetails.place_of_birth && (
|
||||||
|
<div className="flex items-center gap-2 text-gray-300">
|
||||||
|
<FaMapMarkerAlt className="text-purple-400" />
|
||||||
|
<span>{personDetails.place_of_birth}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Biography */}
|
||||||
|
{personDetails.biography && (
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold mb-3 text-purple-300">
|
||||||
|
Biografia
|
||||||
|
</h3>
|
||||||
|
<div className="text-gray-300 leading-relaxed text-lg space-y-4">
|
||||||
|
{personDetails.biography
|
||||||
|
.split("\n\n")
|
||||||
|
.map((paragraph, index) => (
|
||||||
|
<p key={index}>{paragraph}</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* External links */}
|
||||||
|
{personDetails.external_ids && (
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold mb-3 text-purple-300">
|
||||||
|
Linki
|
||||||
|
</h3>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
{Object.entries(personDetails.external_ids).map(
|
||||||
|
([key, value]) => {
|
||||||
|
if (!(key in externalIdsMap) || !value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { label, icon, url } =
|
||||||
|
externalIdsMap[key as keyof typeof externalIdsMap];
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
key={key}
|
||||||
|
href={url(value as string)}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="flex items-center gap-2 bg-white/10 hover:bg-white/20 px-4 py-2 rounded-xl transition-all duration-300 border border-white/20"
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
{label}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ type Props = {
|
||||||
heading?: string;
|
heading?: string;
|
||||||
icon?: ReactNode;
|
icon?: ReactNode;
|
||||||
colors?: keyof typeof colorsMap;
|
colors?: keyof typeof colorsMap;
|
||||||
|
fluid?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Carousel: FC<Props> = ({
|
export const Carousel: FC<Props> = ({
|
||||||
|
|
@ -24,6 +25,7 @@ export const Carousel: FC<Props> = ({
|
||||||
heading,
|
heading,
|
||||||
icon,
|
icon,
|
||||||
colors = "yellow",
|
colors = "yellow",
|
||||||
|
fluid = false,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
itemsPerView = 4,
|
itemsPerView = 4,
|
||||||
|
|
@ -66,17 +68,19 @@ export const Carousel: FC<Props> = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={`${fluid ? "max-w-full px-4" : "container"}`}>
|
||||||
<div className="flex items-center justify-between mb-8">
|
<div className="flex items-center justify-between mb-8 flex-wrap">
|
||||||
{heading && (
|
{heading && (
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{icon && (
|
{icon && (
|
||||||
<div className={`p-2 rounded-lg ${colorsMap[colors]}`}>
|
<div
|
||||||
|
className={`hidden sm:block p-2 rounded-lg ${colorsMap[colors]}`}
|
||||||
|
>
|
||||||
{icon}
|
{icon}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<h2
|
<h2
|
||||||
className={`text-3xl font-bold ${colorsMap[colors]} bg-clip-text text-transparent`}
|
className={`text-3xl font-bold ${colorsMap[colors]} bg-clip-text text-transparent text-center sm:text-left`}
|
||||||
>
|
>
|
||||||
{heading}
|
{heading}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
@ -84,7 +88,7 @@ export const Carousel: FC<Props> = ({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{totalPages > 1 && (
|
{totalPages > 1 && (
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2 mx-auto mt-4 sm:mt-0 sm:mr-0 sm:ml-auto">
|
||||||
<button
|
<button
|
||||||
onClick={prevPage}
|
onClick={prevPage}
|
||||||
className={`cursor-pointer p-3 rounded-full ${colorsMap[colors]} text-white transition-all duration-300`}
|
className={`cursor-pointer p-3 rounded-full ${colorsMap[colors]} text-white transition-all duration-300`}
|
||||||
|
|
@ -116,7 +120,7 @@ export const Carousel: FC<Props> = ({
|
||||||
|
|
||||||
{totalPages > 1 && (
|
{totalPages > 1 && (
|
||||||
<div className="flex justify-center mt-8">
|
<div className="flex justify-center mt-8">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2 flex-wrap justify-center">
|
||||||
{Array.from({ length: totalPages }, (_, i) => (
|
{Array.from({ length: totalPages }, (_, i) => (
|
||||||
<button
|
<button
|
||||||
key={i}
|
key={i}
|
||||||
|
|
|
||||||
|
|
@ -43,71 +43,69 @@ export const Gallery: FC<Props> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="py-16">
|
<section className="blocks">
|
||||||
<div className="px-6 lg:px-8">
|
<div className="container">
|
||||||
<div className="max-w-7xl mx-auto">
|
{heading && (
|
||||||
{heading && (
|
<div className="flex items-center gap-3 mb-8">
|
||||||
<div className="flex items-center gap-3 mb-8">
|
<div className="p-2 rounded-lg bg-gradient-to-r from-purple-500 to-pink-500">
|
||||||
<div className="p-2 rounded-lg bg-gradient-to-r from-purple-500 to-pink-500">
|
<FaImages className="text-white" size={20} />
|
||||||
<FaImages className="text-white" size={20} />
|
|
||||||
</div>
|
|
||||||
<h2 className="text-3xl font-bold bg-gradient-to-r from-purple-400 to-pink-400 bg-clip-text text-transparent">
|
|
||||||
{heading}
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
<h2 className="text-3xl font-bold bg-gradient-to-r from-purple-400 to-pink-400 bg-clip-text text-transparent">
|
||||||
|
{heading}
|
||||||
{/* Category tabs */}
|
</h2>
|
||||||
{categories.length > 0 && (
|
|
||||||
<div className="flex gap-4 mb-8">
|
|
||||||
{Object.entries(images).map(([category, categoryImages]) => {
|
|
||||||
if (!categoryImages.length) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
key={category}
|
|
||||||
onClick={() =>
|
|
||||||
setSelectedCategory(category as keyof typeof images)
|
|
||||||
}
|
|
||||||
className={`px-6 py-3 rounded-xl font-medium transition-all duration-300 ${
|
|
||||||
selectedCategory === category
|
|
||||||
? "bg-gradient-to-r from-purple-600 to-pink-600 text-white shadow-lg"
|
|
||||||
: "bg-white/10 text-gray-300 hover:bg-white/20 hover:text-white"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{category} ({categoryImages.length})
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Image grid */}
|
|
||||||
<div className={`grid gap-4 grid-auto-cols-160 [&>div]:contents`}>
|
|
||||||
<LightGallery>
|
|
||||||
{currentImages.slice(0, limit).map((image, index) => (
|
|
||||||
<a
|
|
||||||
key={index}
|
|
||||||
href={getImageUrl(image.file_path)}
|
|
||||||
className="group relative overflow-hidden rounded-xl cursor-pointer bg-slate-800"
|
|
||||||
>
|
|
||||||
<img src={getImageUrl(image.file_path, "w185")} />
|
|
||||||
</a>
|
|
||||||
))}
|
|
||||||
</LightGallery>
|
|
||||||
</div>
|
</div>
|
||||||
{limit < currentImages.length && (
|
)}
|
||||||
<div className="flex justify-center mt-6">
|
|
||||||
<Button
|
{/* Category tabs */}
|
||||||
theme="teal"
|
{categories.length > 0 && (
|
||||||
size="small"
|
<div className="flex gap-4 mb-8">
|
||||||
onClick={() => setLimit(currentImages.length)}
|
{Object.entries(images).map(([category, categoryImages]) => {
|
||||||
|
if (!categoryImages.length) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={category}
|
||||||
|
onClick={() =>
|
||||||
|
setSelectedCategory(category as keyof typeof images)
|
||||||
|
}
|
||||||
|
className={`px-6 py-3 rounded-xl font-medium transition-all duration-300 ${
|
||||||
|
selectedCategory === category
|
||||||
|
? "bg-gradient-to-r from-purple-600 to-pink-600 text-white shadow-lg"
|
||||||
|
: "bg-white/10 text-gray-300 hover:bg-white/20 hover:text-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{category} ({categoryImages.length})
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Image grid */}
|
||||||
|
<div className={`grid gap-4 grid-auto-cols-160 [&>div]:contents`}>
|
||||||
|
<LightGallery>
|
||||||
|
{currentImages.slice(0, limit).map((image, index) => (
|
||||||
|
<a
|
||||||
|
key={index}
|
||||||
|
href={getImageUrl(image.file_path)}
|
||||||
|
className="group relative overflow-hidden rounded-xl cursor-pointer bg-slate-800"
|
||||||
>
|
>
|
||||||
Pokaż wszystkie ({currentImages.length - limit})
|
<img src={getImageUrl(image.file_path, "w185")} />
|
||||||
</Button>
|
</a>
|
||||||
</div>
|
))}
|
||||||
)}
|
</LightGallery>
|
||||||
</div>
|
</div>
|
||||||
|
{limit < currentImages.length && (
|
||||||
|
<div className="flex justify-center mt-6">
|
||||||
|
<Button
|
||||||
|
theme="teal"
|
||||||
|
size="small"
|
||||||
|
onClick={() => setLimit(currentImages.length)}
|
||||||
|
>
|
||||||
|
Pokaż wszystkie ({currentImages.length - limit})
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ export const HeroMovie: FC<Props> = ({ movieDetails }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="my-16">
|
<section className="blocks">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<div className="absolute top-0 left-0 right-0 z-20 px-6">
|
<div className="absolute top-0 left-0 right-0 z-20 px-6">
|
||||||
|
|
@ -83,8 +83,8 @@ export const HeroMovie: FC<Props> = ({ movieDetails }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main content */}
|
{/* Main content */}
|
||||||
<div className="relative z-10 px-6 lg:px-8">
|
<div className="relative z-10">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="container">
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
{/* Movie poster */}
|
{/* Movie poster */}
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ export const MovieCast: FC<Props> = ({ movieDetails }) => {
|
||||||
}).format(amount);
|
}).format(amount);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="px-6 lg:px-8 py-16">
|
<section className="blocks">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="container mx-auto">
|
||||||
<div className="grid lg:grid-cols-3 gap-12">
|
<div className="grid lg:grid-cols-3 gap-12">
|
||||||
{/* Cast */}
|
{/* Cast */}
|
||||||
{mainCast.length > 0 && (
|
{mainCast.length > 0 && (
|
||||||
<div className="lg:col-span-2">
|
<div className="lg:col-span-2">
|
||||||
<h2 className="text-2xl font-bold text-white mb-6">Obsada</h2>
|
<h2 className="text-2xl font-bold text-white mb-6">Obsada</h2>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-6">
|
||||||
{mainCast.map((actor) => (
|
{mainCast.map((actor) => (
|
||||||
<Link
|
<Link
|
||||||
key={actor.id}
|
key={actor.id}
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ export const MovieList: FC<Props> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="my-4 md:my-10">
|
<section className="blocks">
|
||||||
<div className={`${fluid ? "max-w-full" : "container"}`}>
|
<div className={`${fluid ? "max-w-full px-4" : "container"}`}>
|
||||||
{heading && (
|
{heading && (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12 md:col-10 flex gap-2 items-center">
|
<div className="col-12 md:col-10 flex gap-2 items-center">
|
||||||
|
|
@ -103,7 +103,7 @@ export const MovieList: FC<Props> = ({
|
||||||
)}
|
)}
|
||||||
{filteredMovies.length > 0 && (
|
{filteredMovies.length > 0 && (
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-y-6 gap-3 sm:gap-6 mt-8 justify-center"
|
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-y-6 gap-3 sm:gap-6 mt-8 justify-center"
|
||||||
ref={parent}
|
ref={parent}
|
||||||
>
|
>
|
||||||
{sortedMovies.map((movie) => (
|
{sortedMovies.map((movie) => (
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,20 @@ export const RecommendedMovies: FC<Props> = ({ movies }) => {
|
||||||
if (!movies.results.length) return null;
|
if (!movies.results.length) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="py-16 bg-gradient-to-br from-slate-900/50 to-slate-800/50">
|
<section className="blockp bg-gradient-to-br from-slate-900/50 to-slate-800/50">
|
||||||
<div className="px-6 lg:px-8">
|
<div className="container">
|
||||||
<div className="max-w-7xl mx-auto">
|
<Carousel
|
||||||
<Carousel
|
heading="Rekomendowane filmy"
|
||||||
heading="Rekomendowane filmy"
|
icon={<FaStar />}
|
||||||
icon={<FaStar />}
|
colors="yellow"
|
||||||
colors="yellow"
|
>
|
||||||
>
|
{movies.results
|
||||||
{movies.results.map((movie) => (
|
.sort(
|
||||||
|
(a, b) =>
|
||||||
|
new Date(b.release_date).getTime() -
|
||||||
|
new Date(a.release_date).getTime()
|
||||||
|
)
|
||||||
|
.map((movie) => (
|
||||||
<MovieCard
|
<MovieCard
|
||||||
key={movie.id}
|
key={movie.id}
|
||||||
layout="aurora"
|
layout="aurora"
|
||||||
|
|
@ -43,8 +48,7 @@ export const RecommendedMovies: FC<Props> = ({ movies }) => {
|
||||||
favorite={false}
|
favorite={false}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Carousel>
|
</Carousel>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export const SimilarMovies: FC<Props> = ({ movies }) => {
|
||||||
return (
|
return (
|
||||||
<section className="py-16">
|
<section className="py-16">
|
||||||
<div className="px-6 lg:px-8">
|
<div className="px-6 lg:px-8">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="container mx-auto">
|
||||||
<div className="flex items-center justify-between mb-8">
|
<div className="flex items-center justify-between mb-8">
|
||||||
<h2 className="text-3xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
|
<h2 className="text-3xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
|
||||||
Podobne filmy
|
Podobne filmy
|
||||||
|
|
|
||||||
|
|
@ -49,16 +49,12 @@ export const Search = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
theme="glass"
|
theme="secondary"
|
||||||
size="small"
|
size="icon"
|
||||||
className="group relative"
|
className="group relative"
|
||||||
onClick={() => setIsSearchOpen(!isSearchOpen)}
|
onClick={() => setIsSearchOpen(!isSearchOpen)}
|
||||||
>
|
>
|
||||||
<IoSearch
|
<IoSearch className="text-white" />
|
||||||
size={20}
|
|
||||||
className="text-white transition-transform duration-300 group-hover:scale-110"
|
|
||||||
/>
|
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-purple-500/30 to-cyan-500/30 rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{isSearchOpen && (
|
{isSearchOpen && (
|
||||||
|
|
@ -71,14 +67,11 @@ export const Search = () => {
|
||||||
{/* Close button */}
|
{/* Close button */}
|
||||||
<Button
|
<Button
|
||||||
theme="glass"
|
theme="glass"
|
||||||
size="small"
|
size="icon"
|
||||||
className="absolute top-6 right-6 z-10 group hover:!bg-red-500/50"
|
className="absolute top-6 right-6 z-10 group hover:!bg-red-500/50"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
<IoClose
|
<IoClose className="text-white transition-transform duration-300 group-hover:rotate-90" />
|
||||||
size={24}
|
|
||||||
className="text-white transition-transform duration-300 group-hover:rotate-90"
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className="relative min-h-full flex flex-col py-20" ref={ref}>
|
<div className="relative min-h-full flex flex-col py-20" ref={ref}>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { useEffect, useState } from "react";
|
||||||
import { HiMenuAlt3, HiX, HiSparkles } from "react-icons/hi";
|
import { HiMenuAlt3, HiX, HiSparkles } from "react-icons/hi";
|
||||||
import { Search } from "./components/Search";
|
import { Search } from "./components/Search";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
import { Button } from "@/components/atoms/Button";
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
{
|
{
|
||||||
|
|
@ -33,7 +34,7 @@ export const Navbar = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Main Navbar */}
|
{/* Main Navbar */}
|
||||||
<header className="fixed top-0 w-full z-50 transition-all duration-300">
|
<header className="sticky top-0 w-full z-50 transition-all duration-300">
|
||||||
{/* Aurora background effect */}
|
{/* Aurora background effect */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-slate-900/95 via-slate-800/98 to-slate-900/95"></div>
|
<div className="absolute inset-0 bg-gradient-to-r from-slate-900/95 via-slate-800/98 to-slate-900/95"></div>
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-purple-600/15 via-blue-600/10 to-teal-600/15"></div>
|
<div className="absolute inset-0 bg-gradient-to-r from-purple-600/15 via-blue-600/10 to-teal-600/15"></div>
|
||||||
|
|
@ -43,7 +44,7 @@ export const Navbar = () => {
|
||||||
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-purple-400/50 to-transparent"></div>
|
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-purple-400/50 to-transparent"></div>
|
||||||
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="container mx-auto px-4">
|
<div className=" mx-auto px-4 max-w-[1500px]">
|
||||||
<div className="flex items-center justify-between h-16 lg:h-20">
|
<div className="flex items-center justify-between h-16 lg:h-20">
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link
|
<Link
|
||||||
|
|
@ -95,19 +96,18 @@ export const Navbar = () => {
|
||||||
<Search />
|
<Search />
|
||||||
|
|
||||||
{/* Mobile Menu Button */}
|
{/* Mobile Menu Button */}
|
||||||
<button
|
<Button
|
||||||
|
theme="glass"
|
||||||
|
size="icon"
|
||||||
onClick={toggleMobileMenu}
|
onClick={toggleMobileMenu}
|
||||||
className="md:hidden relative p-3 rounded-xl bg-gradient-to-br from-white/15 to-white/5 border border-white/20 transition-all duration-300 hover:bg-gradient-to-br hover:from-white/25 hover:to-white/10 hover:scale-105 shadow-lg"
|
className="md:hidden"
|
||||||
>
|
>
|
||||||
<div className="w-6 h-6 flex items-center justify-center">
|
{isMobileMenuOpen ? (
|
||||||
{isMobileMenuOpen ? (
|
<HiX className="text-white" />
|
||||||
<HiX className="w-5 h-5 text-white" />
|
) : (
|
||||||
) : (
|
<HiMenuAlt3 className="text-white" />
|
||||||
<HiMenuAlt3 className="w-5 h-5 text-white" />
|
)}
|
||||||
)}
|
</Button>
|
||||||
</div>
|
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-purple-500/30 to-cyan-500/30 rounded-xl opacity-0 hover:opacity-100 transition-opacity duration-300"></div>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue