dressed_for_succes_store/pages/index.tsx

222 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { motion } from 'framer-motion';
import Head from 'next/head';
import Image from 'next/image';
import { useState, useEffect } from 'react';
import Header from '../components/Header';
import Hero from '../components/Hero';
import CookieNotification from '../components/CookieNotification';
import fs from 'fs';
import path from 'path';
import { Heart } from 'lucide-react';
import Footer from '../components/Footer';
// Типы для свойств компонента
interface HomeProps {
heroImages: string[];
products: Product[];
}
// Тип для товара
interface Product {
id: number;
name: string;
price: number;
images: string[];
description: string;
isNew?: boolean;
}
export default function Home({ heroImages, products }: HomeProps) {
// Состояние для отслеживания наведения на карточки товаров
const [hoveredProduct, setHoveredProduct] = useState<number | null>(null);
// Состояние для отслеживания избранных товаров
const [favorites, setFavorites] = useState<number[]>([]);
// Состояние для отслеживания прокрутки страницы
const [scrolled, setScrolled] = useState(false);
// Эффект для отслеживания прокрутки
useEffect(() => {
const handleScroll = () => {
const isScrolled = window.scrollY > 50;
if (isScrolled !== scrolled) {
setScrolled(isScrolled);
}
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [scrolled]);
// Функция для добавления/удаления товара из избранного
const toggleFavorite = (id: number, e: React.MouseEvent) => {
e.stopPropagation();
setFavorites(prev =>
prev.includes(id)
? prev.filter(itemId => itemId !== id)
: [...prev, id]
);
};
return (
<div className="min-h-screen bg-white 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" />
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&display=swap" rel="stylesheet" />
</Head>
<Header />
<main>
{/* Секция с HERO элементом */}
<Hero images={heroImages} />
{/* Секция с товарами */}
<section className="py-16 bg-white">
<div className="container mx-auto px-6">
<motion.h2
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 }}
className="text-3xl text-center font-medium mb-12"
>
Коллекция
</motion.h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-6 gap-y-12">
{products.map((product, index) => (
<motion.div
key={product.id}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.1 }}
className="group relative"
onMouseEnter={() => setHoveredProduct(product.id)}
onMouseLeave={() => setHoveredProduct(null)}
>
{/* Метка "New" */}
{product.isNew && (
<div className="absolute top-4 left-4 z-10 bg-gray-100 text-gray-700 text-xs px-3 py-1 rounded-full">
New
</div>
)}
{/* Кнопка избранного */}
<button
onClick={(e) => toggleFavorite(product.id, e)}
className="absolute top-4 right-4 z-10 p-1"
>
<Heart
className={`w-6 h-6 transition-colors ${
favorites.includes(product.id)
? 'fill-black text-black'
: 'text-gray-400 hover:text-black'
}`}
/>
</button>
{/* Изображение товара */}
<div className="relative aspect-[3/4] w-full overflow-hidden mb-4">
<Image
src={hoveredProduct === product.id && product.images.length > 1 ? product.images[1] : product.images[0]}
alt={product.name}
layout="fill"
objectFit="cover"
className="transition-all duration-500 hover:scale-105"
/>
</div>
{/* Информация о товаре */}
<div className="px-1">
<h3 className="text-sm text-gray-700 mb-2 line-clamp-2">{product.name}</h3>
<p className="text-base font-medium">{product.price.toLocaleString()} </p>
</div>
</motion.div>
))}
</div>
</div>
</section>
</main>
<Footer />
<CookieNotification />
</div>
);
}
// Функция для получения данных на стороне сервера
export async function getStaticProps() {
// Данные о товарах
const products = [
{
id: 1,
name: 'Пальто оверсайз',
price: 43800,
images: ['/wear/palto1.jpg', '/wear/palto2.jpg'],
description: 'Элегантное пальто оверсайз высокого качества',
isNew: true
},
{
id: 2,
name: 'Костюм хлопок',
price: 12800,
images: ['/wear/pidzak2.jpg', '/wear/pidzak1.jpg'],
description: 'Стильный костюм для особых случаев',
isNew: true
},
{
id: 3,
name: 'Блузка',
price: 3500,
images: ['/wear/sorochka1.jpg', '/wear/sorochka2.jpg'],
description: 'Классическая блузка в коричневом цвете',
isNew: true
},
{
id: 4,
name: 'Платье со сборкой',
price: 28800,
images: ['/wear/jumpsuit_1.jpg', '/wear/jumpsuit_2.jpg'],
description: 'Элегантное платье высокого качества',
isNew: true
}
];
// Получение изображений для слайдера из папки hero_photos
const heroImagesDirectory = path.join(process.cwd(), 'public/hero_photos');
let heroImages = [];
try {
const fileNames = fs.readdirSync(heroImagesDirectory);
// Фильтруем только изображения
const imageExtensions = ['.jpg', '.jpeg', '.png', '.webp', '.gif'];
const imageFiles = fileNames.filter(file =>
imageExtensions.some(ext => file.toLowerCase().endsWith(ext))
);
if (imageFiles.length > 0) {
heroImages = imageFiles.map(fileName => `/hero_photos/${fileName}`);
} else {
// Если нет изображений, используем изображения из папки photos
heroImages = ['/photos/head_photo.png'];
}
} catch (error) {
console.error('Error reading hero_photos directory:', error);
// Если папка не существует или пуста, используем изображение из папки photos
heroImages = ['/photos/head_photo.png'];
}
return {
props: {
heroImages,
products,
},
// Перегенерация страницы каждые 10 минут
revalidate: 600,
};
}