2026-02-28 19:37:33 +00:00

280 lines
16 KiB
TypeScript

import React, { useEffect } from 'react';
import type { ReactElement } from 'react';
import Head from 'next/head';
import Link from 'next/link';
import BaseButton from '../components/BaseButton';
import LayoutGuest from '../layouts/Guest';
import { getPageTitle } from '../config';
import { useAppSelector, useAppDispatch } from '../stores/hooks';
import { fetch as fetchProducts } from '../stores/products/productsSlice';
import { fetch as fetchCategories } from '../stores/product_categories/product_categoriesSlice';
import ImageField from '../components/ImageField';
import { mdiCartOutline, mdiArrowRight } from '@mdi/js';
import BaseIcon from '../components/BaseIcon';
import LoadingSpinner from '../components/LoadingSpinner';
import CartDrawer from '../components/CartDrawer';
import { addToCart, toggleCart } from '../stores/localCartSlice';
export default function Home() {
const dispatch = useAppDispatch();
const { products, loading: productsLoading } = useAppSelector((state) => state.products);
const { product_categories, loading: categoriesLoading } = useAppSelector((state) => state.product_categories);
const { currentUser } = useAppSelector((state) => state.auth);
const darkMode = useAppSelector((state) => state.style.darkMode);
const { items: cartItems } = useAppSelector((state) => state.localCart);
const cartCount = cartItems.reduce((sum, item) => sum + item.quantity, 0);
useEffect(() => {
dispatch(fetchProducts({ query: '?limit=8' }));
dispatch(fetchCategories({ query: '' }));
}, [dispatch]);
const handleAddToCart = (product: any) => {
dispatch(addToCart({
id: product.id,
name: product.name,
price: product.price,
quantity: 1,
image: product.images ? product.images[0]?.url : null
}));
dispatch(toggleCart());
};
const heroImage = "https://images.pexels.com/photos/958545/pexels-photo-958545.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1";
return (
<div className={`min-h-screen ${darkMode ? 'bg-dark-900 text-white' : 'bg-gray-50 text-gray-900'}`}>
<Head>
<title>{getPageTitle('El Calentico - Tu Tienda Virtual')}</title>
</Head>
<CartDrawer />
{/* Navigation / Header */}
<nav className={`sticky top-0 z-40 w-full border-b ${darkMode ? 'bg-dark-800 border-dark-700' : 'bg-white border-gray-200'} px-4 py-3 shadow-sm`}>
<div className="container mx-auto flex items-center justify-between">
<Link href="/" className="flex items-center gap-2">
<span className="text-2xl font-bold text-orange-600">El Calentico</span>
</Link>
<div className="flex items-center gap-4">
<Link href="/search" className="hidden md:block text-sm font-medium hover:text-orange-600 transition-colors">
Buscar
</Link>
{/* Cart Toggle Button */}
<button
onClick={() => dispatch(toggleCart())}
className="relative p-2 text-gray-600 hover:text-orange-600 transition-colors"
>
<BaseIcon path={mdiCartOutline} size={28} />
{cartCount > 0 && (
<span className="absolute top-0 right-0 bg-orange-600 text-white text-[10px] font-bold w-5 h-5 flex items-center justify-center rounded-full border-2 border-white">
{cartCount}
</span>
)}
</button>
{currentUser ? (
<Link href="/dashboard" className="text-sm font-medium px-4 py-2 rounded-full bg-orange-600 text-white hover:bg-orange-700 transition-colors">
Dashboard
</Link>
) : (
<div className="flex items-center gap-2">
<Link href="/login" className="hidden sm:block text-sm font-medium hover:text-orange-600 transition-colors">
Iniciar Sesión
</Link>
<Link href="/register" className="text-sm font-medium px-4 py-2 rounded-full bg-orange-600 text-white hover:bg-orange-700 transition-colors">
Registrarse
</Link>
</div>
)}
</div>
</div>
</nav>
{/* Hero Section */}
<section className="relative h-[500px] w-full overflow-hidden flex items-center">
<div className="absolute inset-0 z-0">
<img src={heroImage} alt="Food hero" className="w-full h-full object-cover" />
<div className="absolute inset-0 bg-black/40"></div>
</div>
<div className="container mx-auto relative z-10 px-4">
<div className="max-w-2xl text-white">
<h1 className="text-5xl md:text-6xl font-extrabold mb-6 leading-tight">
Sabor y Frescura <br />
<span className="text-orange-400">Directo a tu Mesa</span>
</h1>
<p className="text-xl mb-8 text-gray-100">
Descubre la mejor selección de alimentos, bebidas y productos locales en El Calentico. Calidad garantizada en cada pedido.
</p>
<div className="flex gap-4">
<BaseButton
label="Comprar Ahora"
color="warning"
roundedFull
className="px-8 py-3 text-lg font-bold"
href="#products"
/>
<BaseButton
label="Ver Categorías"
color="white"
outline
roundedFull
className="px-8 py-3 text-lg font-bold"
href="#categories"
/>
</div>
</div>
</div>
</section>
{/* Categories Section */}
<section id="categories" className="py-16 bg-white dark:bg-dark-800">
<div className="container mx-auto px-4">
<div className="flex justify-between items-end mb-10">
<div>
<h2 className="text-3xl font-bold mb-2">Categorías</h2>
<p className="text-gray-500">Explora nuestra variedad de productos</p>
</div>
</div>
{categoriesLoading ? (
<div className="flex justify-center py-10"><LoadingSpinner /></div>
) : (
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
{product_categories?.map((cat: any) => (
<Link
key={cat.id}
href={`/search?category=${cat.id}`}
className={`group flex flex-col items-center p-6 rounded-2xl transition-all hover:shadow-lg ${darkMode ? 'bg-dark-700 border-dark-600 hover:bg-dark-600' : 'bg-gray-50 border-gray-100 hover:bg-orange-50 hover:border-orange-200'} border`}
>
<div className="w-16 h-16 bg-orange-100 rounded-full flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
<span className="text-2xl font-bold text-orange-600">{cat.name.charAt(0)}</span>
</div>
<span className="font-semibold text-center group-hover:text-orange-600">{cat.name}</span>
</Link>
))}
</div>
)}
</div>
</section>
{/* Featured Products */}
<section id="products" className="py-16">
<div className="container mx-auto px-4">
<div className="flex justify-between items-end mb-10">
<div>
<h2 className="text-3xl font-bold mb-2">Productos Destacados</h2>
<p className="text-gray-500">Lo más buscado de esta semana</p>
</div>
<Link href="/search" className="text-orange-600 font-bold flex items-center gap-1 hover:underline">
Ver todos <BaseIcon path={mdiArrowRight} size={20} />
</Link>
</div>
{productsLoading ? (
<div className="flex justify-center py-10"><LoadingSpinner /></div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8">
{products?.map((product: any) => (
<div key={product.id} className={`group flex flex-col overflow-hidden rounded-2xl shadow-sm border transition-all hover:shadow-xl ${darkMode ? 'bg-dark-800 border-dark-700' : 'bg-white border-gray-200'}`}>
<Link href={`/products/products-view/?id=${product.id}`} className="relative h-64 overflow-hidden">
<ImageField
image={product.images}
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
/>
{product.price < product.compare_at_price && (
<div className="absolute top-4 left-4 bg-red-600 text-white text-xs font-bold px-3 py-1 rounded-full">
OFERTA
</div>
)}
</Link>
<div className="p-6 flex flex-col flex-grow">
<div className="text-xs text-gray-500 mb-2 uppercase tracking-wider font-semibold">
{product.category?.name || 'Producto'}
</div>
<Link href={`/products/products-view/?id=${product.id}`}>
<h3 className="text-lg font-bold mb-2 group-hover:text-orange-600 transition-colors line-clamp-2">{product.name}</h3>
</Link>
<div className="mt-auto flex items-center justify-between">
<div className="flex flex-col">
{product.compare_at_price > 0 && (
<span className="text-sm text-gray-400 line-through">${product.compare_at_price}</span>
)}
<span className="text-2xl font-extrabold text-orange-600">${product.price}</span>
</div>
<button
onClick={() => handleAddToCart(product)}
className="p-3 bg-gray-100 hover:bg-orange-600 hover:text-white rounded-full transition-all duration-300 group/cart"
title="Añadir al carrito"
>
<BaseIcon path={mdiCartOutline} size={24} />
</button>
</div>
</div>
</div>
))}
</div>
)}
</div>
</section>
{/* CTA Section */}
<section className="py-20 bg-orange-600 text-white">
<div className="container mx-auto px-4 text-center">
<h2 className="text-4xl font-bold mb-6">¿Listo para hacer tu primer pedido?</h2>
<p className="text-xl mb-10 max-w-2xl mx-auto opacity-90">
Únete a miles de clientes satisfechos que ya disfrutan de la frescura de El Calentico en sus hogares.
</p>
<BaseButton
label="Crear una Cuenta Gratis"
color="white"
roundedFull
className="px-10 py-4 text-lg font-bold text-orange-600"
href="/register"
/>
</div>
</section>
{/* Footer */}
<footer className={`py-12 ${darkMode ? 'bg-dark-800 text-gray-400' : 'bg-gray-100 text-gray-600'}`}>
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-12">
<div className="col-span-1 md:col-span-2">
<h3 className="text-2xl font-bold text-orange-600 mb-6">El Calentico</h3>
<p className="mb-6 max-w-md">
Tu tienda virtual de confianza para alimentos, bebidas y productos del día a día. Llevamos la mejor calidad directamente a tu puerta.
</p>
</div>
<div>
<h4 className="text-lg font-bold mb-6 text-gray-900 dark:text-white">Enlaces Rápidos</h4>
<ul className="space-y-4">
<li><Link href="/search" className="hover:text-orange-600 transition-colors">Productos</Link></li>
<li><Link href="#categories" className="hover:text-orange-600 transition-colors">Categorías</Link></li>
<li><Link href="/login" className="hover:text-orange-600 transition-colors">Mi Cuenta</Link></li>
</ul>
</div>
<div>
<h4 className="text-lg font-bold mb-6 text-gray-900 dark:text-white">Legal</h4>
<ul className="space-y-4">
<li><Link href="/privacy-policy" className="hover:text-orange-600 transition-colors">Privacidad</Link></li>
<li><Link href="/terms-of-use" className="hover:text-orange-600 transition-colors">Términos</Link></li>
</ul>
</div>
</div>
<div className="border-t border-gray-200 dark:border-dark-700 pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
<p className="text-sm">© 2026 El Calentico. Todos los derechos reservados.</p>
<div className="flex gap-6">
{/* Social icons could go here */}
</div>
</div>
</div>
</footer>
</div>
);
}
Home.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};