feat: update Button component styles and themes; introduce new slate theme for consistent UI across Dropdown, SearchInput, and Navbar components, and enhance MovieList display type toggle functionality
This commit is contained in:
parent
9079a52778
commit
3ed7b14f1b
|
|
@ -29,10 +29,14 @@ export const Button: FC<Props> = ({
|
||||||
|
|
||||||
const buttonColor = gradient ?? colors[theme];
|
const buttonColor = gradient ?? colors[theme];
|
||||||
|
|
||||||
|
if (theme === "slate" && !className.includes("shadow-")) {
|
||||||
|
className += " shadow-cyan-500/20 hover:shadow-cyan-500/40";
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
className={`flex items-center justify-center gap-2 cursor-pointer text-white rounded-xl font-semibold shadow-2xl transition-colors duration-300
|
className={`flex items-center justify-center gap-2 cursor-pointer text-white rounded-xl font-semibold shadow-2xl transition-all duration-300
|
||||||
bg-gradient-to-r ${buttonColor?.from} ${buttonColor?.to} cursor-pointer ${sizes[size]} ${className}`}
|
bg-gradient-to-br ${buttonColor?.from} ${buttonColor?.to} cursor-pointer ${sizes[size]} ${className}`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
{...(href && { href })}
|
{...(href && { href })}
|
||||||
>
|
>
|
||||||
|
|
@ -45,7 +49,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",
|
icon: "w-12 h-12 !rounded-full border border-white/20 hover:scale-105 [&>svg]:w-5 [&>svg]:h-5 shadow-lg ",
|
||||||
};
|
};
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
|
|
@ -55,30 +59,38 @@ const colors = {
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
from: "from-purple-600 hover:from-purple-500",
|
from: "from-purple-600 hover:from-purple-500",
|
||||||
to: "to-pink-600 hover:to-pink-500",
|
to: "to-cyan-600 hover:to-cyan-500",
|
||||||
},
|
},
|
||||||
glass: {
|
glass: {
|
||||||
from: "from-white/15 via-white/8 to-white/12 border border-white/20",
|
from: "from-white/15 border border-white/20",
|
||||||
to: "to-white/15 hover:to-white/10",
|
to: "to-white/5 hover:to-white/10",
|
||||||
},
|
},
|
||||||
rose: {
|
rosePink: {
|
||||||
from: "from-rose-600/90 hover:from-rose-500/90",
|
from: "from-rose-600/90 hover:from-rose-500/90",
|
||||||
to: "to-pink-600/90 hover:to-pink-500/90",
|
to: "to-pink-600/90 hover:to-pink-500/90",
|
||||||
},
|
},
|
||||||
emerald: {
|
emeraldTeal: {
|
||||||
from: "from-emerald-600/90 hover:from-emerald-500/90",
|
from: "from-emerald-600/90 hover:from-emerald-500/90",
|
||||||
to: "to-teal-600/90 hover:to-teal-500/90",
|
to: "to-teal-600/90 hover:to-teal-500/90",
|
||||||
},
|
},
|
||||||
purple: {
|
purplePink: {
|
||||||
from: "from-purple-600/90 hover:from-purple-500/90",
|
from: "from-purple-600/90 hover:from-purple-500/90",
|
||||||
to: "to-pink-600/90 hover:to-pink-500/90",
|
to: "to-pink-600/90 hover:to-pink-500/90",
|
||||||
},
|
},
|
||||||
pink: {
|
pinkEmerald: {
|
||||||
from: "from-pink-600/90 hover:from-pink-500/90",
|
from: "from-pink-600/90 hover:from-pink-500/90",
|
||||||
to: "to-emerald-600/90 hover:to-emerald-500/90",
|
to: "to-emerald-600/90 hover:to-emerald-500/90",
|
||||||
},
|
},
|
||||||
teal: {
|
tealEmerald: {
|
||||||
from: "from-teal-600/90 hover:from-teal-500/90",
|
from: "from-teal-600/90 hover:from-teal-500/90",
|
||||||
to: "to-emerald-600/90 hover:to-emerald-500/90",
|
to: "to-emerald-600/90 hover:to-emerald-500/90",
|
||||||
},
|
},
|
||||||
|
cyanPurple: {
|
||||||
|
from: "from-cyan-600/90 hover:from-cyan-500/90",
|
||||||
|
to: "to-purple-600/90 hover:to-purple-500/90",
|
||||||
|
},
|
||||||
|
slate: {
|
||||||
|
from: "from-slate-800/95",
|
||||||
|
to: "to-slate-900/95",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export const Dropdown: FC<Props> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className="relative inline-block">
|
<div ref={ref} className="relative inline-block">
|
||||||
<Button theme="glass" size="icon" onClick={() => setIsOpen(!isOpen)}>
|
<Button theme="slate" size="icon" onClick={() => setIsOpen(!isOpen)}>
|
||||||
{icon || <FaFilter />}
|
{icon || <FaFilter />}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ export const MovieRow: FC<Props> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative overflow-hidden">
|
<div className="relative overflow-hidden rounded-xl">
|
||||||
{/* Background actions */}
|
{/* Background actions */}
|
||||||
<div className="absolute inset-0 flex">
|
<div className="absolute inset-0 flex">
|
||||||
<div className="absolute right-0 h-full w-24 bg-green-500/20 flex items-center justify-center cursor-pointer">
|
<div className="absolute right-0 h-full w-24 bg-green-500/20 flex items-center justify-center cursor-pointer">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { FC, useEffect, useState } from "react";
|
import { FC, useEffect, useState } from "react";
|
||||||
import { IoSearch } from "react-icons/io5";
|
import { IoSearch } from "react-icons/io5";
|
||||||
|
import { Button } from "../Button";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
@ -30,19 +31,21 @@ export const SearchInput: FC<Props> = ({
|
||||||
}, [value]);
|
}, [value]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="relative flex items-center gap-4">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
name="search"
|
name="search"
|
||||||
value={value}
|
value={value}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
className={className}
|
className={
|
||||||
|
"w-full bg-gradient-to-br from-slate-800/95 to-slate-900/90 border border-white/20 rounded-full h-12 px-6 shadow-lg shadow-purple-500/15 outline-none focus:shadow-purple-500/20"
|
||||||
|
}
|
||||||
onChange={(e) => setValue(e.target.value)}
|
onChange={(e) => setValue(e.target.value)}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
/>
|
/>
|
||||||
<button type="submit" className="absolute right-0 top-1 mt-3 mr-4">
|
<Button theme="slate" size="icon" className="shrink-0">
|
||||||
<IoSearch />
|
<IoSearch />
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -211,8 +211,8 @@ export const MovieList: FC<Props> = ({
|
||||||
/>
|
/>
|
||||||
{!overrideDisplayType && (
|
{!overrideDisplayType && (
|
||||||
<Button
|
<Button
|
||||||
theme="glass"
|
|
||||||
size="icon"
|
size="icon"
|
||||||
|
theme="slate"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setDisplayType(displayType === "grid" ? "list" : "grid")
|
setDisplayType(displayType === "grid" ? "list" : "grid")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,9 @@ export const Search: FC<Props> = ({ onClose }) => {
|
||||||
<div className="fixed inset-0 z-[60] overflow-y-auto">
|
<div className="fixed inset-0 z-[60] overflow-y-auto">
|
||||||
{/* Close button */}
|
{/* Close button */}
|
||||||
<Button
|
<Button
|
||||||
theme="glass"
|
theme="slate"
|
||||||
size="icon"
|
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 shadow-lg shadow-red-500/20 hover:shadow-red-500/40"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
<IoClose className="text-white transition-transform duration-300 group-hover:rotate-90" />
|
<IoClose className="text-white transition-transform duration-300 group-hover:rotate-90" />
|
||||||
|
|
@ -71,15 +71,11 @@ export const Search: FC<Props> = ({ onClose }) => {
|
||||||
|
|
||||||
{/* 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"></div>
|
<SearchInput
|
||||||
<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">
|
onChange={handleSearch}
|
||||||
<SearchInput
|
placeholder="Wpisz tytuł filmu..."
|
||||||
className="w-full px-3 bg-transparent border-none text-lg lg:text-xl placeholder-gray-400 text-white focus:outline-none"
|
autoFocus={true}
|
||||||
onChange={handleSearch}
|
/>
|
||||||
placeholder="Wpisz tytuł filmu..."
|
|
||||||
autoFocus={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,9 @@ import { useState } from "react";
|
||||||
import { HiSearch, HiHome, HiSparkles } from "react-icons/hi";
|
import { HiSearch, HiHome, 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 navigationItems = [
|
const navigationItems = [
|
||||||
{
|
|
||||||
label: "Strona Główna",
|
|
||||||
href: "/",
|
|
||||||
icon: HiHome,
|
|
||||||
emoji: "🏠",
|
|
||||||
color: "from-blue-500 to-purple-600",
|
|
||||||
description: "Twoja lista filmów",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "Odkrywaj",
|
label: "Odkrywaj",
|
||||||
href: "/odkrywaj",
|
href: "/odkrywaj",
|
||||||
|
|
@ -22,6 +15,14 @@ const navigationItems = [
|
||||||
color: "from-purple-500 to-pink-600",
|
color: "from-purple-500 to-pink-600",
|
||||||
description: "Znajdź nowe filmy",
|
description: "Znajdź nowe filmy",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Strona Główna",
|
||||||
|
href: "/",
|
||||||
|
icon: HiHome,
|
||||||
|
emoji: "🏠",
|
||||||
|
color: "from-blue-500 to-purple-600",
|
||||||
|
description: "Twoja lista filmów",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const Navbar = () => {
|
export const Navbar = () => {
|
||||||
|
|
@ -31,82 +32,36 @@ export const Navbar = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Elegant Floating Navigation */}
|
{/* Elegant Floating Navigation */}
|
||||||
<nav className="fixed bottom-0 left-0 right-0 z-50 pointer-events-none bg-black/90 lg:bg-transparent">
|
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-gradient-to-t from-black to-transparent">
|
||||||
<div className="relative h-24 flex items-center justify-between px-6">
|
<div className="relative flex items-center justify-center px-6 py-4 gap-3">
|
||||||
{/* Brand Name - Floating Left */}
|
{/* Desktop Navigation Orbs */}
|
||||||
<div className="pointer-events-auto">
|
{navigationItems.map((item, index) => {
|
||||||
<Link href="/" className="group flex items-center gap-3">
|
const isActive = pathname === item.href;
|
||||||
<div className="relative">
|
return (
|
||||||
<h1 className="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-white via-purple-200 to-cyan-200 group-hover:from-purple-300 group-hover:to-cyan-300 transition-all duration-500">
|
<Link
|
||||||
MovieBox
|
key={item.href}
|
||||||
</h1>
|
href={item.href}
|
||||||
</div>
|
className="relative group cursor-pointer"
|
||||||
</Link>
|
>
|
||||||
</div>
|
{/* Main orb */}
|
||||||
|
<Button theme={isActive ? "secondary" : "slate"} size="icon">
|
||||||
{/* Navigation & Action Orbs - Right Side */}
|
{/* Icon */}
|
||||||
<div className="flex items-center gap-3 pointer-events-auto">
|
<item.icon
|
||||||
{/* Desktop Navigation Orbs */}
|
className={`transition-colors duration-300
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
{navigationItems.map((item, index) => {
|
|
||||||
const isActive = pathname === item.href;
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
key={item.href}
|
|
||||||
href={item.href}
|
|
||||||
className="relative group cursor-pointer"
|
|
||||||
>
|
|
||||||
{/* Main orb */}
|
|
||||||
<div
|
|
||||||
className={`relative w-12 h-12 rounded-full border border-white/20 shadow-lg transition-all duration-300 hover:scale-105
|
|
||||||
${
|
|
||||||
isActive
|
|
||||||
? "bg-gradient-to-br from-purple-500/80 to-cyan-500/80 shadow-purple-500/40"
|
|
||||||
: "bg-gradient-to-br from-slate-800/95 to-slate-900/95 shadow-slate-500/20"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{/* Icon */}
|
|
||||||
<div className="w-full h-full flex items-center justify-center">
|
|
||||||
<item.icon
|
|
||||||
className={`w-5 h-5 transition-colors duration-300
|
|
||||||
${
|
${
|
||||||
isActive
|
isActive
|
||||||
? "text-white"
|
? "text-white"
|
||||||
: "text-gray-300 group-hover:text-white"
|
: "text-gray-300 group-hover:text-white"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Button>
|
||||||
</div>
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
{/* Tooltip */}
|
<Button theme="slate" size="icon" onClick={() => setSearchOpen(true)}>
|
||||||
<div className="absolute -bottom-12 left-1/2 transform -translate-x-1/2 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none">
|
<HiSearch className="text-cyan-400 mx-auto" />
|
||||||
<div className="bg-black/90 text-white text-xs px-3 py-1 rounded-lg whitespace-nowrap border border-white/10">
|
</Button>
|
||||||
{item.label}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Search Orb */}
|
|
||||||
<div className="relative group">
|
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-cyan-500/30 to-purple-500/30 rounded-full transition-all duration-300"></div>
|
|
||||||
<button
|
|
||||||
onClick={() => setSearchOpen(true)}
|
|
||||||
className="relative w-12 h-12 rounded-full bg-gradient-to-br from-slate-800/95 to-slate-900/95 border border-white/20 shadow-lg shadow-cyan-500/20 hover:shadow-cyan-500/40 transition-all duration-300 hover:scale-105"
|
|
||||||
>
|
|
||||||
<HiSearch className="w-5 h-5 text-cyan-400 mx-auto" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Tooltip */}
|
|
||||||
<div className="absolute -bottom-12 left-1/2 transform -translate-x-1/2 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none">
|
|
||||||
<div className="bg-black/90 text-white text-xs px-3 py-1 rounded-lg whitespace-nowrap border border-white/10">
|
|
||||||
Szukaj filmów
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue