diff --git a/app/tienda/[slug]/producto/[productId]/page.tsx b/app/tienda/[slug]/producto/[productId]/page.tsx index 7b33604..17c5a8f 100644 --- a/app/tienda/[slug]/producto/[productId]/page.tsx +++ b/app/tienda/[slug]/producto/[productId]/page.tsx @@ -48,6 +48,32 @@ export default async function ProductoDetallePage(props: { })), } + const recommended = await prisma.product.findMany({ + where: { + companyId: company.id, + id: { not: productId }, + deletedAt: null, + isActive: true, + isPublic: true, + }, + include: { + images: { + where: { deletedAt: null }, + orderBy: { order: 'asc' }, + }, + }, + take: 8, + orderBy: { name: 'asc' }, + }) + + const serializedRecommended = recommended.map((p) => ({ + id: p.id, + name: p.name, + salePrice: Number(p.salePrice), + currentStock: Number(p.currentStock), + images: (p.images || []).map((i) => ({ url: i.url, publicId: i.publicId })), + })) + const companyInfo = { name: company.name, slug: company.slug, @@ -55,5 +81,5 @@ export default async function ProductoDetallePage(props: { whatsapp: company.whatsapp, } - return + return } diff --git a/app/tienda/[slug]/producto/[productId]/producto-detalle-client.tsx b/app/tienda/[slug]/producto/[productId]/producto-detalle-client.tsx index 4be285c..c3dbbb1 100644 --- a/app/tienda/[slug]/producto/[productId]/producto-detalle-client.tsx +++ b/app/tienda/[slug]/producto/[productId]/producto-detalle-client.tsx @@ -3,7 +3,7 @@ import { useState, useRef, useCallback, useEffect } from 'react' import { Button } from '@/components/ui/button' import { formatCurrency } from '@/lib/utils' -import { ArrowLeft, Plus, ShoppingCart, Minus, Check } from 'lucide-react' +import { ArrowLeft, Plus, ShoppingCart, Minus, Check, ChevronRight } from 'lucide-react' import Link from 'next/link' interface Product { @@ -15,6 +15,14 @@ interface Product { ingredients: { name: string; quantity: number; unit: string }[] } +interface RecommendedProduct { + id: string + name: string + salePrice: number + currentStock: number + images: { url: string; publicId: string }[] +} + interface Company { name: string slug: string @@ -24,7 +32,7 @@ interface Company { const ZOOM = 4 -export function ProductoDetalleClient({ product, company }: { product: Product; company: Company }) { +export function ProductoDetalleClient({ product, company, recommended = [] }: { product: Product; company: Company; recommended?: RecommendedProduct[] }) { const [selectedImage, setSelectedImage] = useState(0) const [qty, setQty] = useState(1) const [added, setAdded] = useState(false) @@ -87,29 +95,39 @@ export function ProductoDetalleClient({ product, company }: { product: Product; const imgY = px.y - imgOffset.y return ( -
-
-
-
- {company.logo && } - - - {company.name} +
+ {/* Header */} +
+
+
+ {company.logo && ( + + )} + + + {company.name}
- - Volver a tienda + + + Volver
-
+
{/* Gallery */}
setShowZoom(true)} onMouseLeave={() => setShowZoom(false)} @@ -132,10 +150,10 @@ export function ProductoDetalleClient({ product, company }: { product: Product; }} />
{product.images.length > 1 && ( -
+
{product.images.map((img, i) => ( ))} @@ -166,8 +184,8 @@ export function ProductoDetalleClient({ product, company }: { product: Product; )}
{outOfStock && Sin stock} -

{product.name}

-

{formatCurrency(product.salePrice)}

+

{product.name}

+

{formatCurrency(product.salePrice)}

{product.ingredients.length > 0 && ( @@ -200,6 +218,50 @@ export function ProductoDetalleClient({ product, company }: { product: Product;
+ + {/* Recommended Products */} + {recommended.length > 0 && ( +
+
+

También te puede gustar

+ + Ver todo + +
+
+ {recommended.map((rp) => { + const storeUrl = `/tienda/${company.slug}/producto/${rp.id}` + return ( + +
+ {rp.images[0] ? ( + {rp.name} + ) : ( +
🛍️
+ )} + {rp.currentStock <= 0 && ( + + Sin stock + + )} +
+
+

{rp.name}

+

{formatCurrency(rp.salePrice)}

+
+ + ) + })} +
+
+ )}
) diff --git a/app/tienda/[slug]/tienda-client.tsx b/app/tienda/[slug]/tienda-client.tsx index 97825a1..adc45e2 100644 --- a/app/tienda/[slug]/tienda-client.tsx +++ b/app/tienda/[slug]/tienda-client.tsx @@ -4,7 +4,7 @@ import { useState, useEffect } from 'react' import { Button } from '@/components/ui/button' import { formatCurrency } from '@/lib/utils' import Link from 'next/link' -import { ShoppingCart, Plus, Minus, X, Send, Loader2, CheckCircle } from 'lucide-react' +import { ShoppingCart, Plus, Minus, X, Send, Loader2, CheckCircle, Store } from 'lucide-react' interface Product { id: string @@ -97,21 +97,32 @@ export function TiendaClient({ company, products }: { company: Company; products } return ( -
+
{/* Header */} -
-
-
- {company.logo && } -
-

{company.name}

- {company.description &&

{company.description}

} +
+
+
+ {company.logo ? ( + + ) : ( +
+ +
+ )} +
+

{company.name}

+ {company.description && ( +

{company.description}

+ )}
-
-
+
{products.length === 0 ? (

No hay productos en la tienda aún

@@ -132,17 +143,17 @@ export function TiendaClient({ company, products }: { company: Company; products return (
-
+
{p.images[0] ? ( - {p.name} + {p.name} ) : ( -
🛍️
+
🛍️
)} {p.currentStock <= 0 && ( - + Sin stock )} @@ -150,11 +161,11 @@ export function TiendaClient({ company, products }: { company: Company; products

{p.name}

{p.ingredients.length > 0 && ( -

+

{p.ingredients.map((ig) => `${ig.name}`).join(', ')}

)} -
+
{formatCurrency(p.salePrice)} +
setShowCart(false)} /> +
+
+

Carrito ({cartCount})

+
{cart.length === 0 &&

Carrito vacío

} @@ -202,7 +213,7 @@ export function TiendaClient({ company, products }: { company: Company; products ))}
{cart.length > 0 && ( -
+
Total {formatCurrency(cartTotal)} @@ -218,21 +229,21 @@ export function TiendaClient({ company, products }: { company: Company; products {/* Checkout Modal */} {showCheckout && ( -
!submitting && setShowCheckout(false)}> -
e.stopPropagation()}> +
!submitting && setShowCheckout(false)}> +
e.stopPropagation()}>

Confirmar Pedido

- setCustomerName(e.target.value)} className="mt-1 w-full h-12 px-4 rounded-lg border border-border/50 bg-background/50" placeholder="Tu nombre" /> + setCustomerName(e.target.value)} className="mt-1 w-full h-12 px-4 rounded-lg border border-border/50 bg-background/50 focus:border-primary/50 focus:ring-2 focus:ring-primary/10 transition-all outline-none" placeholder="Tu nombre" />
- setCustomerPhone(e.target.value)} className="mt-1 w-full h-12 px-4 rounded-lg border border-border/50 bg-background/50" placeholder="+573001234567" /> + setCustomerPhone(e.target.value)} className="mt-1 w-full h-12 px-4 rounded-lg border border-border/50 bg-background/50 focus:border-primary/50 focus:ring-2 focus:ring-primary/10 transition-all outline-none" placeholder="+573001234567" />
-