Enhance UI components with gradient backgrounds and improved interactions: update Button, Dropdown, MovieCard layouts (Aurora, Minimal, Zeus), Pagination, Navbar, and Search components to utilize gradient styles for a more visually appealing design. Refactor Pagination to use the new Button component for consistency.

This commit is contained in:
Norbert Maciaszek 2025-08-17 18:53:15 +02:00
parent d386c8f703
commit b577a79278
9 changed files with 54 additions and 34 deletions

View File

@ -33,5 +33,5 @@ const styles = {
primary: primary:
"block relative bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white px-8 py-4 rounded-xl font-semibold text-lg shadow-2xl transition-all duration-300 hover:scale-105", "block relative bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white px-8 py-4 rounded-xl font-semibold text-lg shadow-2xl transition-all duration-300 hover:scale-105",
glass: glass:
"p-3 rounded-xl bg-white/10 backdrop-blur-sm border border-white/20 transition-all duration-300 hover:bg-white/20 hover:scale-105", "p-3 rounded-xl bg-gradient-to-br from-white/15 via-white/8 to-white/12 border border-white/20 transition-all duration-300 hover:bg-gradient-to-br hover:from-white/25 hover:to-white/15 hover:scale-105 shadow-lg shadow-black/20",
}; };

View File

@ -36,6 +36,7 @@ export const Dropdown: FC<Props> = ({ items, defaultValue, callback }) => {
className="absolute left-0 z-20 w-48 py-2 mt-2 origin-top-right bg-white rounded-md shadow-xl dark:bg-gray-800" className="absolute left-0 z-20 w-48 py-2 mt-2 origin-top-right bg-white rounded-md shadow-xl dark:bg-gray-800"
style={{ style={{
opacity: isOpen ? 1 : 0, opacity: isOpen ? 1 : 0,
pointerEvents: isOpen ? "auto" : "none",
}} }}
> >
{items.map((item) => ( {items.map((item) => (

View File

@ -57,7 +57,8 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
<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>
{/* Main card container */} {/* Main card container */}
<div className="grid relative h-full bg-gradient-to-br from-slate-800/90 to-slate-900/90 backdrop-blur-xl border border-slate-700/50 shadow-2xl shadow-purple-500/10 group-hover:shadow-purple-500/20 transition-all duration-500"> <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">
<div className="absolute inset-0 bg-gradient-to-br from-purple-500/5 via-transparent to-cyan-500/5 opacity-80"></div>
{/* Image section with sophisticated overlay */} {/* Image section with sophisticated overlay */}
<figure <figure
className="relative overflow-hidden" className="relative overflow-hidden"
@ -79,7 +80,7 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
{!!vote_average && ( {!!vote_average && (
<div className="absolute top-4 right-4 transform rotate-3 group-hover:rotate-0 transition-transform duration-300"> <div className="absolute top-4 right-4 transform rotate-3 group-hover:rotate-0 transition-transform duration-300">
<div <div
className={`bg-gradient-to-r ${scoreColor} p-2 rounded-xl shadow-lg backdrop-blur-sm`} 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"> <div className="flex items-center gap-2 text-white font-bold">
<span className="text-xl"></span> <span className="text-xl"></span>
@ -90,7 +91,7 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
)} )}
{/* Popularity indicator */} {/* Popularity indicator */}
<div className="absolute top-4 left-4 bg-black/60 backdrop-blur-sm px-3 py-2 rounded-xl border border-white/20"> <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"> <div className="flex items-center gap-2 text-orange-400">
<FaFire className="animate-pulse" /> <FaFire className="animate-pulse" />
<span className="text-sm font-medium"> <span className="text-sm font-medium">
@ -102,7 +103,7 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
{/* Days left to release */} {/* Days left to release */}
{(!isReleased || daysSinceRelease < 35) && ( {(!isReleased || daysSinceRelease < 35) && (
<div className="absolute bottom-4 left-4 flex justify-center"> <div className="absolute bottom-4 left-4 flex justify-center">
<p className="text-white bg-black/60 backdrop-blur-sm px-2.5 leading-[2] rounded-xl border border-white/20 text-xs"> <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 && {isReleased &&
daysSinceRelease < 35 && daysSinceRelease < 35 &&
`od ${daysSinceRelease} dni`} `od ${daysSinceRelease} dni`}
@ -118,16 +119,20 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
<> <>
<div <div
className={`${ className={`${
seen ? "bg-emerald-500/90" : "bg-white/20" seen
} backdrop-blur-sm p-2 rounded-full animate-pulse cursor-pointer hover:bg-emerald-400 transition-colors`} ? "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} onClick={handleSeen}
> >
<RxEyeOpen size={16} className="text-white" /> <RxEyeOpen size={16} className="text-white" />
</div> </div>
<div <div
className={`${ className={`${
favorite ? "bg-rose-500/90" : "bg-white/20" favorite
} backdrop-blur-sm p-2 rounded-full animate-pulse cursor-pointer hover:bg-rose-400 transition-colors`} ? "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} onClick={handleFavorite}
> >
<MdFavorite size={16} className="text-white" /> <MdFavorite size={16} className="text-white" />
@ -135,7 +140,7 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
</> </>
)} )}
<div <div
className={`bg-white/20 backdrop-blur-sm p-2 rounded-full animate-pulse cursor-pointer hover:bg-red-400 transition-colors`} className={`bg-gradient-to-r from-white/25 to-white/15 p-2 rounded-full cursor-pointer hover:bg-red-400 transition-colors border border-white/10 shadow-lg`}
onClick={handleRemove} onClick={handleRemove}
> >
<FaTrash size={16} className="text-white" /> <FaTrash size={16} className="text-white" />
@ -222,10 +227,20 @@ export const AuroraLayout: FC<AuroraLayoutProps> = ({
{isExpanded && ( {isExpanded && (
<div <div
className="absolute inset-0 p-4 bg-black bg-gradient-to-t from-purple-500/30 to-secondary/30 cursor-pointer" className="absolute inset-0 p-4 bg-black bg-gradient-to-t from-purple-500/30 to-secondary/30 cursor-pointer z-10"
style={{
animation: "fadeIn 0.3s ease-in-out",
}}
onClick={() => setIsExpanded(false)} onClick={() => setIsExpanded(false)}
> >
<p>{overview}</p> <p>{overview}</p>
<style jsx>{`
@keyframes fadeIn {
from {
opacity: 0;
}
}
`}</style>
</div> </div>
)} )}
</article> </article>

View File

@ -34,7 +34,7 @@ export const MinimalLayout: FC<MinimalLayoutProps> = ({
releaseDate, releaseDate,
}) => { }) => {
return ( return (
<article className="group relative w-full h-[420px] bg-white/5 border border-white/10 rounded-xl overflow-hidden backdrop-blur-sm transition-all duration-300 hover:bg-white/10 hover:border-white/20 hover:shadow-lg hover:shadow-black/20"> <article className="group relative w-full h-[420px] bg-gradient-to-br from-white/8 via-slate-800/5 to-white/5 border border-white/10 rounded-xl overflow-hidden transition-all duration-300 hover:bg-gradient-to-br hover:from-white/15 hover:to-white/8 hover:border-white/20 hover:shadow-lg hover:shadow-black/20">
<figure className="relative h-[280px] overflow-hidden"> <figure className="relative h-[280px] overflow-hidden">
<img <img
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
@ -44,7 +44,7 @@ export const MinimalLayout: FC<MinimalLayoutProps> = ({
{/* Rating badge */} {/* Rating badge */}
{!!vote_average && ( {!!vote_average && (
<div className="absolute top-3 right-3 bg-black/60 backdrop-blur-sm px-2 pr-3 pb-1 rounded-full"> <div className="absolute top-3 right-3 bg-gradient-to-br from-black/75 to-slate-900/80 px-2 pr-3 pb-1 rounded-full border border-white/10 shadow-lg">
<span className="text-xs font-medium text-yellow-400"> <span className="text-xs font-medium text-yellow-400">
{vote_average.toFixed(1)} {vote_average.toFixed(1)}
</span> </span>
@ -52,7 +52,7 @@ export const MinimalLayout: FC<MinimalLayoutProps> = ({
)} )}
{/* Action overlay */} {/* Action overlay */}
<div className="absolute inset-0 bg-black/70 backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center"> <div className="absolute inset-0 bg-gradient-to-t from-black/85 via-slate-900/75 to-black/60 opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center">
{!alreadyInStore ? ( {!alreadyInStore ? (
<button <button
onClick={handleAdd} onClick={handleAdd}

View File

@ -54,7 +54,7 @@ export const ZeusLayout: FC<ZeusLayoutProps> = ({
className="w-full object-cover" className="w-full object-cover"
src={`http://image.tmdb.org/t/p/w342${poster_path}`} src={`http://image.tmdb.org/t/p/w342${poster_path}`}
/> />
<span className="absolute inset-0 bg-black/30 backdrop-blur-md opacity-0 hover-any:opacity-100 transition-opacity duration-300 flex items-center justify-center cursor-pointer"> <span className="absolute inset-0 bg-gradient-to-t from-black/60 via-slate-900/40 to-black/30 opacity-0 hover-any:opacity-100 transition-opacity duration-300 flex items-center justify-center cursor-pointer">
{!alreadyInStore && ( {!alreadyInStore && (
<button className={buttonClass} onClick={handleAdd}> <button className={buttonClass} onClick={handleAdd}>
<MdOutlinePostAdd size={64} color="white" /> <MdOutlinePostAdd size={64} color="white" />

View File

@ -1,4 +1,5 @@
import { FC } from "react"; import { FC } from "react";
import { Button } from "../Button";
type Props = { type Props = {
totalPages: number; totalPages: number;
@ -15,8 +16,8 @@ export const Pagination: FC<Props> = ({
<ul className="flex justify-center gap-3 my-10"> <ul className="flex justify-center gap-3 my-10">
{currentPage > 1 && ( {currentPage > 1 && (
<li> <li>
<button <Button
className="grid size-8 place-content-center rounded border bg-white text-black border-primary transition-colors hover:bg-primary hover:text-white cursor-pointer" theme="glass"
aria-label="Previous page" aria-label="Previous page"
onClick={() => onPageChange(currentPage - 1)} onClick={() => onPageChange(currentPage - 1)}
> >
@ -32,18 +33,18 @@ export const Pagination: FC<Props> = ({
clipRule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
</button> </Button>
</li> </li>
)} )}
<li className="text-sm/8 font-medium tracking-widest"> <li className="text-sm/8 font-medium tracking-widest leading-[2.8]">
{currentPage}/{totalPages} {currentPage}/{totalPages}
</li> </li>
{currentPage < totalPages && ( {currentPage < totalPages && (
<li> <li>
<button <Button
className="grid size-8 place-content-center rounded border bg-white text-black border-primary transition-colors hover:bg-primary hover:text-white cursor-pointer" theme="glass"
aria-label="Next page" aria-label="Next page"
onClick={() => onPageChange(currentPage + 1)} onClick={() => onPageChange(currentPage + 1)}
> >
@ -59,7 +60,7 @@ export const Pagination: FC<Props> = ({
clipRule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
</button> </Button>
</li> </li>
)} )}
</ul> </ul>

View File

@ -53,7 +53,7 @@ export const SearchList: FC<Props> = ({ query }) => {
<div className="relative"> <div className="relative">
{isLoading && ( {isLoading && (
<div className="absolute -inset-10 flex pt-60 justify-center backdrop-blur-xs z-10"> <div className="absolute -inset-10 flex pt-60 justify-center bg-gradient-to-t from-slate-900/90 via-slate-800/50 to-transparent z-10">
<Spinner /> <Spinner />
</div> </div>
)} )}

View File

@ -57,8 +57,9 @@ export const Search = () => {
{isSearchOpen && ( {isSearchOpen && (
<div className="fixed inset-0 z-[60] overflow-y-auto"> <div className="fixed inset-0 z-[60] overflow-y-auto">
{/* Aurora Background */} {/* Aurora Background */}
<div className="absolute inset-0 bg-gradient-to-br from-purple-900/95 via-blue-900/95 to-teal-900/95 backdrop-blur-2xl"></div> <div className="fixed inset-0 bg-gradient-to-br from-purple-900/98 via-blue-900/98 to-teal-900/98"></div>
<div className="absolute inset-0 bg-gradient-to-tr from-pink-500/20 via-transparent to-cyan-500/20 animate-pulse"></div> <div className="fixed inset-0 bg-gradient-to-tr from-slate-900/95 via-slate-800/90 to-slate-900/95"></div>
<div className="fixed inset-0 bg-gradient-to-tr from-pink-500/20 via-transparent to-cyan-500/20 animate-pulse"></div>
{/* Close button */} {/* Close button */}
<Button <Button
@ -86,7 +87,7 @@ export const Search = () => {
{/* Enhanced Search Input */} {/* Enhanced Search Input */}
<div className="relative max-w-2xl mx-auto"> <div className="relative max-w-2xl mx-auto">
<div className="absolute inset-0 bg-gradient-to-r from-purple-500/30 to-cyan-500/30 rounded-2xl blur-xl"></div> <div className="absolute inset-0 bg-gradient-to-r from-purple-500/30 to-cyan-500/30 rounded-2xl blur-xl"></div>
<div className="relative bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-2"> <div className="relative bg-gradient-to-br from-white/15 via-white/8 to-white/12 border border-white/20 rounded-2xl p-2 shadow-2xl shadow-purple-500/10">
<SearchInput <SearchInput
className="w-full px-3 bg-transparent border-none text-lg lg:text-xl placeholder-gray-400 text-white focus:outline-none" className="w-full px-3 bg-transparent border-none text-lg lg:text-xl placeholder-gray-400 text-white focus:outline-none"
onChange={handleSearch} onChange={handleSearch}
@ -122,7 +123,7 @@ export const Search = () => {
{results && ( {results && (
<div className="mb-12"> <div className="mb-12">
<MovieList <MovieList
overrideMovies={results.slice(0, 5).map((m) => ({ overrideMovies={results.slice(0, 4).map((m) => ({
...m, ...m,
favorite: false, favorite: false,
seen: false, seen: false,
@ -134,7 +135,7 @@ export const Search = () => {
)} )}
{/* Show More Button */} {/* Show More Button */}
{total_results > 5 && ( {total_results > 4 && (
<div className="text-center"> <div className="text-center">
<div className="relative inline-block"> <div className="relative inline-block">
<div className="absolute inset-0 bg-gradient-to-r from-purple-500 to-cyan-500 rounded-xl blur-lg opacity-50"></div> <div className="absolute inset-0 bg-gradient-to-r from-purple-500 to-cyan-500 rounded-xl blur-lg opacity-50"></div>

View File

@ -29,7 +29,8 @@ export const Navbar = () => {
{/* Main Navbar */} {/* Main Navbar */}
<header className="fixed top-0 w-full z-50 transition-all duration-300"> <header className="fixed 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-purple-900/80 via-blue-900/80 to-teal-900/80 backdrop-blur-xl"></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-500/10 via-transparent to-cyan-500/10"></div> <div className="absolute inset-0 bg-gradient-to-r from-purple-500/10 via-transparent to-cyan-500/10"></div>
{/* Border glow */} {/* Border glow */}
@ -70,7 +71,7 @@ export const Navbar = () => {
<Link <Link
key={link.href} key={link.href}
href={link.href} href={link.href}
className="group relative px-4 py-2 rounded-xl transition-all duration-300 hover:bg-white/10 backdrop-blur-sm" className="group relative px-4 py-2 rounded-xl transition-all duration-300 hover:bg-gradient-to-r hover:from-white/10 hover:to-white/5 border border-transparent hover:border-white/10"
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<span className="text-lg">{link.icon}</span> <span className="text-lg">{link.icon}</span>
@ -90,7 +91,7 @@ export const Navbar = () => {
{/* Mobile Menu Button */} {/* Mobile Menu Button */}
<button <button
onClick={toggleMobileMenu} onClick={toggleMobileMenu}
className="md:hidden relative p-3 rounded-xl bg-white/10 backdrop-blur-sm border border-white/20 transition-all duration-300 hover:bg-white/20 hover:scale-105" 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"
> >
<div className="w-6 h-6 flex items-center justify-center"> <div className="w-6 h-6 flex items-center justify-center">
{isMobileMenuOpen ? ( {isMobileMenuOpen ? (
@ -112,14 +113,15 @@ export const Navbar = () => {
<div className="fixed inset-0 z-40 md:hidden"> <div className="fixed inset-0 z-40 md:hidden">
{/* Backdrop */} {/* Backdrop */}
<div <div
className="absolute inset-0 bg-black/70 backdrop-blur-sm transition-opacity duration-300" className="absolute inset-0 bg-gradient-to-br from-black/85 via-slate-900/90 to-black/85 transition-opacity duration-300"
onClick={toggleMobileMenu} onClick={toggleMobileMenu}
/> />
{/* Menu Panel */} {/* Menu Panel */}
<div className="absolute top-0 right-0 w-80 max-w-[85vw] h-full"> <div className="absolute top-0 right-0 w-80 max-w-[85vw] h-full">
{/* Aurora background */} {/* Aurora background */}
<div className="absolute inset-0 bg-gradient-to-br from-slate-800/95 to-slate-900/95 backdrop-blur-xl"></div> <div className="absolute inset-0 bg-gradient-to-br from-slate-800/98 via-slate-850/99 to-slate-900/98"></div>
<div className="absolute inset-0 bg-gradient-to-br from-purple-500/8 via-transparent to-cyan-500/8"></div>
<div className="absolute inset-0 bg-gradient-to-br from-purple-500/10 via-transparent to-cyan-500/10"></div> <div className="absolute inset-0 bg-gradient-to-br from-purple-500/10 via-transparent to-cyan-500/10"></div>
<div className="relative h-full flex flex-col p-6 pt-24"> <div className="relative h-full flex flex-col p-6 pt-24">
@ -138,7 +140,7 @@ export const Navbar = () => {
}} }}
> >
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-xl bg-gradient-to-r from-purple-500/20 to-cyan-500/20 flex items-center justify-center text-2xl backdrop-blur-sm"> <div className="w-12 h-12 rounded-xl bg-gradient-to-r from-purple-500/25 via-purple-400/15 to-cyan-500/25 flex items-center justify-center text-2xl border border-white/10 shadow-lg shadow-purple-500/10">
{link.icon} {link.icon}
</div> </div>
<div> <div>