Обновить дизайн и функциональность страниц каталога, коллекций и категорий с использованием новой цветовой палитры
@ -3,39 +3,39 @@ import { Facebook, Instagram, Twitter, Youtube } from "lucide-react";
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="bg-gray-100 text-gray-800 py-12">
|
||||
<footer className="bg-[#2B5F47] text-white py-12">
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<div>
|
||||
<h4 className="text-lg font-medium mb-4">Помощь</h4>
|
||||
<ul className="space-y-2">
|
||||
<li><Link href="/contact" className="text-sm hover:underline">Связаться с нами</Link></li>
|
||||
<li><Link href="/faq" className="text-sm hover:underline">Часто задаваемые вопросы</Link></li>
|
||||
<li><Link href="/shipping" className="text-sm hover:underline">Доставка и возврат</Link></li>
|
||||
<li><Link href="/track-order" className="text-sm hover:underline">Отследить заказ</Link></li>
|
||||
<li><Link href="/size-guide" className="text-sm hover:underline">Руководство по размерам</Link></li>
|
||||
<li><Link href="/contact" className="text-sm hover:text-[#E2E2C1] transition-colors">Связаться с нами</Link></li>
|
||||
<li><Link href="/faq" className="text-sm hover:text-[#E2E2C1] transition-colors">Часто задаваемые вопросы</Link></li>
|
||||
<li><Link href="/shipping" className="text-sm hover:text-[#E2E2C1] transition-colors">Доставка и возврат</Link></li>
|
||||
<li><Link href="/track-order" className="text-sm hover:text-[#E2E2C1] transition-colors">Отследить заказ</Link></li>
|
||||
<li><Link href="/size-guide" className="text-sm hover:text-[#E2E2C1] transition-colors">Руководство по размерам</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-lg font-medium mb-4">Магазин</h4>
|
||||
<ul className="space-y-2">
|
||||
<li><Link href="/women" className="text-sm hover:underline">Женщинам</Link></li>
|
||||
<li><Link href="/men" className="text-sm hover:underline">Мужчинам</Link></li>
|
||||
<li><Link href="/accessories" className="text-sm hover:underline">Аксессуары</Link></li>
|
||||
<li><Link href="/collections" className="text-sm hover:underline">Коллекции</Link></li>
|
||||
<li><Link href="/sale" className="text-sm hover:underline">Распродажа</Link></li>
|
||||
<li><Link href="/women" className="text-sm hover:text-[#E2E2C1] transition-colors">Женщинам</Link></li>
|
||||
<li><Link href="/men" className="text-sm hover:text-[#E2E2C1] transition-colors">Мужчинам</Link></li>
|
||||
<li><Link href="/accessories" className="text-sm hover:text-[#E2E2C1] transition-colors">Аксессуары</Link></li>
|
||||
<li><Link href="/collections" className="text-sm hover:text-[#E2E2C1] transition-colors">Коллекции</Link></li>
|
||||
<li><Link href="/sale" className="text-sm hover:text-[#E2E2C1] transition-colors">Распродажа</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-lg font-medium mb-4">О компании</h4>
|
||||
<ul className="space-y-2">
|
||||
<li><Link href="/about" className="text-sm hover:underline">О нас</Link></li>
|
||||
<li><Link href="/careers" className="text-sm hover:underline">Карьера</Link></li>
|
||||
<li><Link href="/sustainability" className="text-sm hover:underline">Устойчивое развитие</Link></li>
|
||||
<li><Link href="/press" className="text-sm hover:underline">Пресса</Link></li>
|
||||
<li><Link href="/affiliates" className="text-sm hover:underline">Партнерская программа</Link></li>
|
||||
<li><Link href="/about" className="text-sm hover:text-[#E2E2C1] transition-colors">О нас</Link></li>
|
||||
<li><Link href="/careers" className="text-sm hover:text-[#E2E2C1] transition-colors">Карьера</Link></li>
|
||||
<li><Link href="/sustainability" className="text-sm hover:text-[#E2E2C1] transition-colors">Устойчивое развитие</Link></li>
|
||||
<li><Link href="/press" className="text-sm hover:text-[#E2E2C1] transition-colors">Пресса</Link></li>
|
||||
<li><Link href="/affiliates" className="text-sm hover:text-[#E2E2C1] transition-colors">Партнерская программа</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -46,35 +46,35 @@ export default function Footer() {
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Ваш email"
|
||||
className="bg-white px-4 py-2 text-sm border border-gray-300 rounded-l focus:outline-none flex-grow"
|
||||
className="bg-white px-4 py-2 text-sm border border-[#63823B] rounded-l focus:outline-none focus:border-[#E2E2C1] text-[#2B5F47] flex-grow"
|
||||
/>
|
||||
<button className="bg-black text-white px-4 py-2 text-sm rounded-r hover:bg-gray-800 transition-colors">
|
||||
<button className="bg-[#63823B] text-white px-4 py-2 text-sm rounded-r hover:bg-[#63823B]/80 transition-colors">
|
||||
→
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<a href="#" className="text-gray-600 hover:text-black transition-colors">
|
||||
<a href="#" className="text-white hover:text-[#E2E2C1] transition-colors">
|
||||
<Facebook size={20} />
|
||||
</a>
|
||||
<a href="#" className="text-gray-600 hover:text-black transition-colors">
|
||||
<a href="#" className="text-white hover:text-[#E2E2C1] transition-colors">
|
||||
<Instagram size={20} />
|
||||
</a>
|
||||
<a href="#" className="text-gray-600 hover:text-black transition-colors">
|
||||
<a href="#" className="text-white hover:text-[#E2E2C1] transition-colors">
|
||||
<Twitter size={20} />
|
||||
</a>
|
||||
<a href="#" className="text-gray-600 hover:text-black transition-colors">
|
||||
<a href="#" className="text-white hover:text-[#E2E2C1] transition-colors">
|
||||
<Youtube size={20} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-200 mt-8 pt-8 flex flex-col md:flex-row justify-between items-center">
|
||||
<p className="text-xs text-gray-500 mb-4 md:mb-0">© {new Date().getFullYear()} Brand Store. Все права защищены.</p>
|
||||
<div className="border-t border-[#63823B] mt-8 pt-8 flex flex-col md:flex-row justify-between items-center">
|
||||
<p className="text-xs text-[#E2E2C1]/80 mb-4 md:mb-0">© {new Date().getFullYear()} Brand Store. Все права защищены.</p>
|
||||
<div className="flex space-x-4">
|
||||
<Link href="/privacy" className="text-xs text-gray-500 hover:underline">Политика конфиденциальности</Link>
|
||||
<Link href="/terms" className="text-xs text-gray-500 hover:underline">Условия использования</Link>
|
||||
<Link href="/cookies" className="text-xs text-gray-500 hover:underline">Политика использования файлов cookie</Link>
|
||||
<Link href="/privacy" className="text-xs text-[#E2E2C1]/80 hover:text-[#E2E2C1] transition-colors">Политика конфиденциальности</Link>
|
||||
<Link href="/terms" className="text-xs text-[#E2E2C1]/80 hover:text-[#E2E2C1] transition-colors">Условия использования</Link>
|
||||
<Link href="/cookies" className="text-xs text-[#E2E2C1]/80 hover:text-[#E2E2C1] transition-colors">Политика использования файлов cookie</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -56,13 +56,13 @@ export default function TabSelector({ onTabChange }: TabSelectorProps) {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex justify-center items-center w-full py-8 bg-white">
|
||||
<div className="flex justify-center items-center w-full py-8 bg-[#E2E2C1]">
|
||||
<div className="w-full max-w-[1200px] h-[60px] relative flex items-center justify-center">
|
||||
<div className="p-0">
|
||||
<div className="relative">
|
||||
{/* Hover Highlight */}
|
||||
<div
|
||||
className="absolute h-[30px] transition-all duration-300 ease-out bg-[#0e0f1114] rounded-[6px] flex items-center"
|
||||
className="absolute h-[30px] transition-all duration-300 ease-out bg-[#63823B]/20 rounded-[6px] flex items-center"
|
||||
style={{
|
||||
...hoverStyle,
|
||||
opacity: hoveredIndex !== null ? 1 : 0,
|
||||
@ -71,7 +71,7 @@ export default function TabSelector({ onTabChange }: TabSelectorProps) {
|
||||
|
||||
{/* Active Indicator */}
|
||||
<div
|
||||
className="absolute bottom-[-6px] h-[2px] bg-black transition-all duration-300 ease-out"
|
||||
className="absolute bottom-[-6px] h-[2px] bg-[#2B5F47] transition-all duration-300 ease-out"
|
||||
style={activeStyle}
|
||||
/>
|
||||
|
||||
@ -82,7 +82,7 @@ export default function TabSelector({ onTabChange }: TabSelectorProps) {
|
||||
key={index}
|
||||
ref={(el) => (tabRefs.current[index] = el)}
|
||||
className={`px-3 py-2 cursor-pointer transition-colors duration-300 h-[30px] ${
|
||||
index === activeIndex ? "text-black font-medium" : "text-gray-500"
|
||||
index === activeIndex ? "text-[#2B5F47] font-medium" : "text-[#2B5F47]/70"
|
||||
}`}
|
||||
onMouseEnter={() => setHoveredIndex(index)}
|
||||
onMouseLeave={() => setHoveredIndex(null)}
|
||||
|
||||
@ -21,7 +21,7 @@ export const collections: Collection[] = [
|
||||
{
|
||||
id: 2,
|
||||
name: 'Осень-Зима 2023',
|
||||
image: '/photos/photo2.jpg',
|
||||
image: '/photos/autumn_winter.jpg',
|
||||
description: 'Теплые и уютные модели для холодного времени года. Коллекция сочетает в себе комфорт и стиль, предлагая элегантные решения для зимнего гардероба.',
|
||||
url: '/collections/autumn-winter-2023',
|
||||
slug: 'autumn-winter-2023'
|
||||
@ -29,7 +29,7 @@ export const collections: Collection[] = [
|
||||
{
|
||||
id: 3,
|
||||
name: 'Базовый гардероб',
|
||||
image: '/photos/head_photo.png',
|
||||
image: '/photos/based_outfit.jpg',
|
||||
description: 'Классические модели, которые никогда не выходят из моды. Эта коллекция представляет собой основу любого гардероба, включая вневременные предметы одежды высокого качества.',
|
||||
url: '/collections/basic',
|
||||
slug: 'basic'
|
||||
@ -37,7 +37,7 @@ export const collections: Collection[] = [
|
||||
{
|
||||
id: 4,
|
||||
name: 'Вечерняя коллекция',
|
||||
image: '/photos/evening.jpg',
|
||||
image: '/photos/night_dress.jpg',
|
||||
description: 'Элегантные наряды для особых случаев. Изысканные ткани и утонченный дизайн создают неповторимые образы для вечерних мероприятий и торжественных событий.',
|
||||
url: '/collections/evening',
|
||||
slug: 'evening'
|
||||
@ -45,7 +45,7 @@ export const collections: Collection[] = [
|
||||
{
|
||||
id: 5,
|
||||
name: 'Деловой стиль',
|
||||
image: '/photos/business.jpg',
|
||||
image: '/photos/business_outfit.jpg',
|
||||
description: 'Стильная и функциональная одежда для работы и деловых встреч. Коллекция сочетает в себе профессионализм и элегантность, подчеркивая ваш статус и вкус.',
|
||||
url: '/collections/business',
|
||||
slug: 'business'
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// Тип для товара
|
||||
export interface Product {
|
||||
inStock: any;
|
||||
id: number;
|
||||
name: string;
|
||||
price: number;
|
||||
@ -20,7 +21,8 @@ export const products: Product[] = [
|
||||
description: 'Элегантное пальто оверсайз высокого качества. Изготовлено из премиальных материалов, обеспечивающих комфорт и тепло. Идеально подходит для холодного сезона и создания стильного образа.',
|
||||
isNew: true,
|
||||
categoryId: 6,
|
||||
slug: 'palto-oversaiz'
|
||||
slug: 'palto-oversaiz',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
@ -30,7 +32,8 @@ export const products: Product[] = [
|
||||
description: 'Стильный костюм для особых случаев. Выполнен из высококачественного хлопка, обеспечивающего комфорт и элегантный внешний вид. Идеально подходит для деловых встреч и официальных мероприятий.',
|
||||
isNew: true,
|
||||
categoryId: 6,
|
||||
slug: 'kostyum-hlopok'
|
||||
slug: 'kostyum-hlopok',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
@ -40,7 +43,8 @@ export const products: Product[] = [
|
||||
description: 'Классическая блузка в коричневом цвете. Изготовлена из мягкой и приятной к телу ткани. Универсальная модель, которая подойдет как для офиса, так и для повседневного образа.',
|
||||
isNew: true,
|
||||
categoryId: 7,
|
||||
slug: 'bluzka'
|
||||
slug: 'bluzka',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
@ -50,57 +54,63 @@ export const products: Product[] = [
|
||||
description: 'Элегантное платье высокого качества со сборкой. Подчеркивает фигуру и создает женственный силуэт. Идеально подходит для особых случаев и вечерних мероприятий.',
|
||||
isNew: true,
|
||||
categoryId: 5,
|
||||
slug: 'plate-so-sborkoy'
|
||||
slug: 'plate-so-sborkoy',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'Кожаные туфли',
|
||||
name: 'Кожаные ботинки',
|
||||
price: 15600,
|
||||
images: ['/wear/shoes1.jpg', '/wear/shoes2.jpg'],
|
||||
description: 'Элегантные кожаные туфли ручной работы. Изготовлены из натуральной кожи высшего качества. Комфортная колодка и стильный дизайн делают эту модель незаменимой в гардеробе.',
|
||||
isNew: false,
|
||||
images: ['/wear/kozh_boots1.jpg', '/wear/kozh_boots2.jpg'],
|
||||
description: 'Элегантные кожаные ботинки ручной работы. Изготовлены из натуральной кожи высшего качества. Комфортная колодка и стильный дизайн делают эту модель незаменимой в гардеробе.',
|
||||
isNew: true,
|
||||
categoryId: 1,
|
||||
slug: 'kozhanye-tufli'
|
||||
slug: 'kozhanye-botinki',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'Шелковый шарф',
|
||||
price: 5900,
|
||||
images: ['/wear/scarf1.jpg', '/wear/scarf2.jpg'],
|
||||
images: ['/wear/silk_scarf1.jpg', '/wear/silk_scarf2.jpg'],
|
||||
description: 'Роскошный шелковый шарф с уникальным принтом. Изготовлен из 100% натурального шелка. Добавит элегантности и шарма любому образу.',
|
||||
isNew: false,
|
||||
categoryId: 8,
|
||||
slug: 'shelkovyj-sharf'
|
||||
slug: 'shelkovyj-sharf',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: 'Шерстяной свитер',
|
||||
price: 8700,
|
||||
images: ['/wear/sweater1.jpg', '/wear/sweater2.jpg'],
|
||||
images: ['/wear/sherst_sweater1.jpg', '/wear/sherst_sweater2.jpg'],
|
||||
description: 'Теплый шерстяной свитер крупной вязки. Изготовлен из мягкой шерсти мериноса. Идеально подходит для холодного времени года.',
|
||||
isNew: false,
|
||||
categoryId: 4,
|
||||
slug: 'sherstyanoj-sviter'
|
||||
slug: 'sherstyanoj-sviter',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: 'Классические брюки',
|
||||
price: 7500,
|
||||
images: ['/wear/pants1.jpg', '/wear/pants2.jpg'],
|
||||
images: ['/wear/classic_bruk1.jpg', '/wear/classic_bruk2.jpg'],
|
||||
description: 'Классические брюки прямого кроя. Выполнены из высококачественной ткани с добавлением эластана для комфортной посадки. Универсальная модель для офиса и повседневной носки.',
|
||||
isNew: false,
|
||||
categoryId: 3,
|
||||
slug: 'klassicheskie-bryuki'
|
||||
slug: 'klassicheskie-bryuki',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: 'Фетровая шляпа',
|
||||
price: 6200,
|
||||
images: ['/wear/hat1.jpg', '/wear/hat2.jpg'],
|
||||
images: ['/wear/hat1.jpg'],
|
||||
description: 'Элегантная фетровая шляпа ручной работы. Изготовлена из высококачественного фетра. Дополнит любой образ и защитит от непогоды.',
|
||||
isNew: false,
|
||||
categoryId: 2,
|
||||
slug: 'fetrovaya-shlyapa'
|
||||
slug: 'fetrovaya-shlyapa',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
@ -110,7 +120,8 @@ export const products: Product[] = [
|
||||
description: 'Роскошная шелковая блузка с элегантным дизайном. Изготовлена из 100% натурального шелка. Идеально подходит для создания изысканного образа.',
|
||||
isNew: true,
|
||||
categoryId: 7,
|
||||
slug: 'shelkovaya-bluzka'
|
||||
slug: 'shelkovaya-bluzka',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
@ -120,7 +131,8 @@ export const products: Product[] = [
|
||||
description: 'Стильная кожаная сумка ручной работы. Изготовлена из натуральной кожи высшего качества. Вместительная и функциональная модель для повседневного использования.',
|
||||
isNew: false,
|
||||
categoryId: 8,
|
||||
slug: 'kozhanaya-sumka'
|
||||
slug: 'kozhanaya-sumka',
|
||||
inStock: true
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
@ -130,7 +142,8 @@ export const products: Product[] = [
|
||||
description: 'Роскошное кашемировое пальто классического кроя. Изготовлено из 100% кашемира высшего качества. Элегантная модель, которая прослужит долгие годы.',
|
||||
isNew: true,
|
||||
categoryId: 6,
|
||||
slug: 'kashemirovoe-palto'
|
||||
slug: 'kashemirovoe-palto',
|
||||
inStock: true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -31,105 +31,122 @@ export default function CategoryPage({ category, products }: CategoryPageProps)
|
||||
// Если страница еще загружается, показываем заглушку
|
||||
if (router.isFallback) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900"></div>
|
||||
<div className="min-h-screen bg-[#E2E2C1] font-['Arimo'] flex items-center justify-center">
|
||||
<div className="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-[#2B5F47]"></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Функция для добавления/удаления товара из избранного
|
||||
const toggleFavorite = (id: number, e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setFavorites((prev) => (prev.includes(id) ? prev.filter((itemId) => itemId !== id) : [...prev, id]))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white font-['Arimo']">
|
||||
<div className="min-h-screen bg-[#E2E2C1] font-['Arimo']">
|
||||
<Head>
|
||||
<title>{category.name} | Brand Store</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</Head>
|
||||
|
||||
<Header />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 py-12 md:px-8">
|
||||
<div className="mb-12">
|
||||
<Link href="/category" className="text-gray-600 hover:text-black transition-colors">
|
||||
← Все категории
|
||||
</Link>
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-3xl md:text-4xl font-bold mt-4 font-['Playfair_Display']"
|
||||
>
|
||||
{category.name}
|
||||
</motion.h1>
|
||||
<p className="mt-2 text-gray-600 max-w-3xl">{category.description}</p>
|
||||
</div>
|
||||
<main className="pt-24 pb-16 px-4 md:px-8">
|
||||
<div className="container mx-auto">
|
||||
<div className="relative mb-12 rounded-lg overflow-hidden h-64 md:h-80">
|
||||
<Image
|
||||
src={category.image}
|
||||
alt={category.name}
|
||||
fill
|
||||
className="object-cover"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-[#2B5F47]/50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-3xl md:text-5xl font-bold mb-4 text-white"
|
||||
>
|
||||
{category.name}
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
className="text-white/90 max-w-2xl mx-auto px-4"
|
||||
>
|
||||
{category.description}
|
||||
</motion.p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{products.length > 0 ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
|
||||
{products.map((product) => (
|
||||
<motion.div
|
||||
key={product.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: product.id * 0.05 }}
|
||||
whileHover={{ y: -5, transition: { duration: 0.2 } }}
|
||||
>
|
||||
<Link
|
||||
href={`/product/${product.slug}`}
|
||||
className="block h-full"
|
||||
{products.length > 0 ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.3 }}
|
||||
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
|
||||
>
|
||||
{products.map((product, index) => (
|
||||
<motion.div
|
||||
key={product.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.1 * index }}
|
||||
className="bg-white rounded-lg overflow-hidden shadow-md hover:shadow-lg transition-shadow"
|
||||
onMouseEnter={() => setHoveredProduct(product.id)}
|
||||
onMouseLeave={() => setHoveredProduct(null)}
|
||||
>
|
||||
<div className="relative overflow-hidden rounded-xl">
|
||||
<div className="aspect-[3/4] relative overflow-hidden rounded-xl">
|
||||
<Link href={`/product/${product.slug}`}>
|
||||
<div className="relative h-64 w-full overflow-hidden">
|
||||
<Image
|
||||
src={
|
||||
hoveredProduct === product.id && product.images.length > 1
|
||||
? product.images[1]
|
||||
: product.images[0]
|
||||
}
|
||||
src={product.images[0]}
|
||||
alt={product.name}
|
||||
fill
|
||||
sizes="(max-width: 640px) 100vw, (max-width: 768px) 50vw, (max-width: 1024px) 33vw, 25vw"
|
||||
className="object-cover transition-all duration-500 group-hover:scale-105"
|
||||
className="object-cover transition-transform duration-500 ease-in-out"
|
||||
style={{
|
||||
transform: hoveredProduct === product.id && product.images.length > 1
|
||||
? 'scale(1.1)'
|
||||
: 'scale(1)'
|
||||
}}
|
||||
/>
|
||||
{product.isNew && (
|
||||
<span className="absolute top-4 left-4 bg-black text-white text-sm py-1 px-3 rounded">
|
||||
Новинка
|
||||
</span>
|
||||
)}
|
||||
<button
|
||||
onClick={(e) => toggleFavorite(product.id, e)}
|
||||
className="absolute top-4 right-4 bg-white/80 hover:bg-white rounded-full p-2 transition-all"
|
||||
aria-label={favorites.includes(product.id) ? "Удалить из избранного" : "Добавить в избранное"}
|
||||
className="absolute top-3 right-3 p-2 rounded-full bg-white/80 hover:bg-white transition-colors z-10"
|
||||
>
|
||||
<Heart
|
||||
className={`w-5 h-5 ${favorites.includes(product.id) ? "fill-red-500 text-red-500" : "text-gray-700"}`}
|
||||
<Heart
|
||||
className={`w-5 h-5 ${favorites.includes(product.id) ? 'fill-[#63823B] text-[#63823B]' : 'text-gray-600'}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<h3 className="text-lg font-medium">{product.name}</h3>
|
||||
<p className="mt-1 text-lg font-bold">{formatPrice(product.price)} ₽</p>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-xl text-gray-600">В этой категории пока нет товаров</p>
|
||||
<Link href="/" className="mt-4 inline-block bg-black text-white px-6 py-2 rounded-md hover:bg-gray-800 transition-colors">
|
||||
Вернуться на главную
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
<div className="p-4">
|
||||
<h3 className="text-lg font-medium text-[#2B5F47] mb-1">{product.name}</h3>
|
||||
<p className="text-sm text-gray-600 mb-2 line-clamp-2">{product.description}</p>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="font-bold text-[#2B5F47]">{formatPrice(product.price)} ₽</span>
|
||||
<span className="text-sm text-[#63823B]">
|
||||
{product.inStock ? 'В наличии' : 'Нет в наличии'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-xl text-[#2B5F47] mb-4">В этой категории пока нет товаров</p>
|
||||
<Link href="/category" className="inline-block px-6 py-3 bg-[#63823B] text-white rounded-md hover:bg-[#2B5F47] transition-colors">
|
||||
Вернуться к категориям
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@ -1 +1,81 @@
|
||||
|
||||
import { useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { motion } from 'framer-motion';
|
||||
import Header from '../../components/Header';
|
||||
import Footer from '../../components/Footer';
|
||||
import { Category, categories } from '../../data/categories';
|
||||
|
||||
export default function Categories() {
|
||||
const [hoveredCategory, setHoveredCategory] = useState<number | null>(null);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#E2E2C1] font-['Arimo']">
|
||||
<Head>
|
||||
<title>Каталог категорий | Brand Store</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</Head>
|
||||
|
||||
<Header />
|
||||
|
||||
<main className="pt-24 pb-16 px-4 md:px-8">
|
||||
<div className="container mx-auto">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-3xl md:text-4xl font-bold mb-8 text-[#2B5F47] text-center"
|
||||
>
|
||||
Каталог категорий
|
||||
</motion.h1>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8"
|
||||
>
|
||||
{categories.map((category, index) => (
|
||||
<motion.div
|
||||
key={category.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.1 * index }}
|
||||
className="relative overflow-hidden rounded-lg shadow-md bg-white"
|
||||
onMouseEnter={() => setHoveredCategory(category.id)}
|
||||
onMouseLeave={() => setHoveredCategory(null)}
|
||||
>
|
||||
<Link href={`/category/${category.slug}`}>
|
||||
<div className="relative h-80 w-full overflow-hidden">
|
||||
<Image
|
||||
src={category.image}
|
||||
alt={category.name}
|
||||
fill
|
||||
className={`object-cover transition-transform duration-500 ${
|
||||
hoveredCategory === category.id ? 'scale-110' : 'scale-100'
|
||||
}`}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#2B5F47]/70 to-transparent"></div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 right-0 p-6">
|
||||
<h2 className="text-xl font-semibold text-white mb-2">{category.name}</h2>
|
||||
<p className="text-white/80 text-sm mb-4 line-clamp-2">{category.description}</p>
|
||||
<div className={`inline-block px-4 py-2 bg-[#63823B] text-white rounded-md transition-transform duration-300 ${
|
||||
hoveredCategory === category.id ? 'translate-y-0' : 'translate-y-8 opacity-0'
|
||||
}`}>
|
||||
Смотреть товары
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,69 +1,77 @@
|
||||
import { useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { motion } from 'framer-motion';
|
||||
import Header from '../../components/Header';
|
||||
import Footer from '../../components/Footer';
|
||||
import { Collection, collections } from '../../data/collections';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export default function Collections() {
|
||||
const [hoveredCollection, setHoveredCollection] = useState<number | null>(null);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white font-['Arimo']">
|
||||
<div className="min-h-screen bg-[#E2E2C1] font-['Arimo']">
|
||||
<Head>
|
||||
<title>Коллекции | Brand Store</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</Head>
|
||||
|
||||
<Header />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 py-12 md:px-8">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-3xl md:text-4xl font-bold mb-8 font-['Playfair_Display']"
|
||||
>
|
||||
Коллекции
|
||||
</motion.h1>
|
||||
<main className="pt-24 pb-16 px-4 md:px-8">
|
||||
<div className="container mx-auto">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-3xl md:text-4xl font-bold mb-8 text-[#2B5F47] text-center"
|
||||
>
|
||||
Наши коллекции
|
||||
</motion.h1>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{collections.map((collection) => (
|
||||
<motion.div
|
||||
key={collection.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: collection.id * 0.1 }}
|
||||
whileHover={{ y: -5, transition: { duration: 0.2 } }}
|
||||
>
|
||||
<Link
|
||||
href={`/collections/${collection.slug}`}
|
||||
className="block h-full"
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
className="grid grid-cols-1 md:grid-cols-2 gap-8"
|
||||
>
|
||||
{collections.map((collection, index) => (
|
||||
<motion.div
|
||||
key={collection.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.1 * index }}
|
||||
className="relative overflow-hidden rounded-lg shadow-md bg-white"
|
||||
onMouseEnter={() => setHoveredCollection(collection.id)}
|
||||
onMouseLeave={() => setHoveredCollection(null)}
|
||||
>
|
||||
<div className="relative overflow-hidden rounded-xl aspect-[16/9]">
|
||||
<Image
|
||||
src={collection.image}
|
||||
alt={collection.name}
|
||||
fill
|
||||
className={`object-cover transition-all duration-500 ${
|
||||
hoveredCollection === collection.id ? 'scale-110' : 'scale-100'
|
||||
}`}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-black bg-opacity-30 transition-opacity duration-300"></div>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<h2 className="text-white text-xl md:text-2xl font-bold text-center px-4 font-['Playfair_Display']">
|
||||
{collection.name}
|
||||
</h2>
|
||||
<Link href={`/collections/${collection.slug}`}>
|
||||
<div className="relative h-96 w-full overflow-hidden">
|
||||
<Image
|
||||
src={collection.image}
|
||||
alt={collection.name}
|
||||
fill
|
||||
className={`object-cover transition-transform duration-500 ${
|
||||
hoveredCollection === collection.id ? 'scale-110' : 'scale-100'
|
||||
}`}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#2B5F47]/80 to-transparent"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-4 text-gray-600 line-clamp-3">{collection.description}</p>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
<div className="absolute bottom-0 left-0 right-0 p-8">
|
||||
<h2 className="text-2xl font-semibold text-white mb-3">{collection.name}</h2>
|
||||
<p className="text-white/90 text-sm mb-6 line-clamp-3">{collection.description}</p>
|
||||
<div className={`inline-block px-5 py-2 bg-[#63823B] text-white rounded-md transition-transform duration-300 ${
|
||||
hoveredCollection === collection.id ? 'translate-y-0' : 'translate-y-8 opacity-0'
|
||||
}`}>
|
||||
Смотреть коллекцию
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ export default function Home({ heroImages, products, collections, categories }:
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white font-['Arimo']">
|
||||
<div className="min-h-screen bg-[#E2E2C1] font-['Arimo']">
|
||||
<Head>
|
||||
<title>Brand Store | Элегантная мода</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
|
||||
117
pages/new-arrivals/index.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import { useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Heart } from 'lucide-react';
|
||||
import Header from '../../components/Header';
|
||||
import Footer from '../../components/Footer';
|
||||
import { Product, products } from '../../data/products';
|
||||
|
||||
export default function NewArrivals() {
|
||||
const [hoveredProduct, setHoveredProduct] = useState<number | null>(null);
|
||||
const [favorites, setFavorites] = useState<number[]>([]);
|
||||
|
||||
// Фильтруем только новые товары
|
||||
const newProducts = products.filter(product => product.isNew);
|
||||
|
||||
// Функция для добавления/удаления товара из избранного
|
||||
const toggleFavorite = (id: number, e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setFavorites(prev =>
|
||||
prev.includes(id)
|
||||
? prev.filter(itemId => itemId !== id)
|
||||
: [...prev, id]
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#E2E2C1] font-['Arimo']">
|
||||
<Head>
|
||||
<title>Новинки | Brand Store</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</Head>
|
||||
|
||||
<Header />
|
||||
|
||||
<main className="pt-24 pb-16 px-4 md:px-8">
|
||||
<div className="container mx-auto">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-3xl md:text-4xl font-bold mb-8 text-[#2B5F47] text-center"
|
||||
>
|
||||
Новые поступления
|
||||
</motion.h1>
|
||||
|
||||
{newProducts.length > 0 ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
|
||||
>
|
||||
{newProducts.map((product, index) => (
|
||||
<motion.div
|
||||
key={product.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.1 * index }}
|
||||
className="bg-white rounded-lg overflow-hidden shadow-md hover:shadow-lg transition-shadow"
|
||||
onMouseEnter={() => setHoveredProduct(product.id)}
|
||||
onMouseLeave={() => setHoveredProduct(null)}
|
||||
>
|
||||
<Link href={`/product/${product.slug}`}>
|
||||
<div className="relative h-64 w-full overflow-hidden">
|
||||
<Image
|
||||
src={hoveredProduct === product.id && product.images.length > 1
|
||||
? product.images[1]
|
||||
: product.images[0]}
|
||||
alt={product.name}
|
||||
fill
|
||||
className="object-cover transition-transform duration-500 ease-in-out"
|
||||
/>
|
||||
<div className="absolute top-3 left-3 bg-[#63823B] text-white text-xs py-1 px-3 rounded-md">
|
||||
Новинка
|
||||
</div>
|
||||
<button
|
||||
onClick={(e) => toggleFavorite(product.id, e)}
|
||||
className="absolute top-3 right-3 p-2 rounded-full bg-white/80 hover:bg-white transition-colors z-10"
|
||||
>
|
||||
<Heart
|
||||
className={`w-5 h-5 ${favorites.includes(product.id) ? 'fill-[#63823B] text-[#63823B]' : 'text-gray-600'}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<h3 className="text-lg font-medium text-[#2B5F47] mb-1">{product.name}</h3>
|
||||
<p className="text-sm text-gray-600 mb-2 line-clamp-2">{product.description}</p>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="font-bold text-[#2B5F47]">{product.price} ₽</span>
|
||||
<span className="text-sm text-[#63823B]">
|
||||
{product.inStock ? 'В наличии' : 'Нет в наличии'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-xl text-[#2B5F47] mb-4">Новинок пока нет</p>
|
||||
<Link href="/" className="inline-block px-6 py-3 bg-[#63823B] text-white rounded-md hover:bg-[#2B5F47] transition-colors">
|
||||
Вернуться на главную
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
BIN
public/photos/autumn_winter.jpg
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
public/photos/based_outfit.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
public/photos/business_outfit.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
public/photos/night_dress.jpg
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
public/wear/bag1.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
public/wear/bag2.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
public/wear/classic_bruk1.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/wear/classic_bruk2.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/wear/coat1.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/wear/coat2.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/wear/hat1.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
public/wear/kozh_boots1.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/wear/kozh_boots2.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/wear/sherst_sweater1.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/wear/sherst_sweater2.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/wear/silk1.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
public/wear/silk2.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
public/wear/silk_scarf1.jpg
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
public/wear/silk_scarf2.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |