Landing del cliente: galería apaisada con lightbox y quita "Entrar"
La galería de trabajos (GaleriaTrabajos) en la landing personalizada del cliente pasa a formato apaisado (3/2) y, al pulsar una foto, se amplía en un lightbox con navegación ‹ ›, Esc y clic fuera para cerrar. Se quita el botón "Entrar" del header de esa landing (TenantBrand sin showLogin): el cliente final no entra al panel. Revierte el cambio anterior en public/b2b.html (era la landing equivocada). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import type { PublicGaleriaFoto } from '@/lib/funnel/public-queries';
|
||||
|
||||
type GaleriaTrabajosProps = {
|
||||
@@ -5,11 +8,37 @@ type GaleriaTrabajosProps = {
|
||||
nombreEmpresa: string;
|
||||
};
|
||||
|
||||
// Galería de trabajos del reformista en su landing pública. Solo se muestra si
|
||||
// el reformista ha subido fotos desde su panel.
|
||||
// Galería de trabajos del reformista en su landing pública. Solo se muestra si el reformista ha
|
||||
// subido fotos desde su panel. Formato apaisado y, al pulsar una foto, se amplía en un lightbox
|
||||
// con navegación entre todas las imágenes.
|
||||
export default function GaleriaTrabajos({ fotos, nombreEmpresa }: GaleriaTrabajosProps) {
|
||||
const [idx, setIdx] = useState<number | null>(null);
|
||||
|
||||
const cerrar = useCallback(() => setIdx(null), []);
|
||||
const mover = useCallback(
|
||||
(d: number) => setIdx((cur) => (cur === null ? cur : (cur + d + fotos.length) % fotos.length)),
|
||||
[fotos.length],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (idx === null) return;
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') cerrar();
|
||||
else if (e.key === 'ArrowRight') mover(1);
|
||||
else if (e.key === 'ArrowLeft') mover(-1);
|
||||
};
|
||||
document.addEventListener('keydown', onKey);
|
||||
document.body.style.overflow = 'hidden';
|
||||
return () => {
|
||||
document.removeEventListener('keydown', onKey);
|
||||
document.body.style.overflow = '';
|
||||
};
|
||||
}, [idx, cerrar, mover]);
|
||||
|
||||
if (fotos.length === 0) return null;
|
||||
|
||||
const actual = idx !== null ? fotos[idx] : null;
|
||||
|
||||
return (
|
||||
<section id="galeria" className="bg-gray-50 section" aria-label="Galería de trabajos">
|
||||
<div className="container">
|
||||
@@ -24,24 +53,31 @@ export default function GaleriaTrabajos({ fotos, nombreEmpresa }: GaleriaTrabajo
|
||||
Reformas que ya hemos hecho
|
||||
</h2>
|
||||
<p className="text-gray-500 mt-3 leading-relaxed">
|
||||
Una muestra real del trabajo de {nombreEmpresa}. Calidad de acabados, plazos cumplidos.
|
||||
Una muestra real del trabajo de {nombreEmpresa}. Toca cualquier imagen para verla en grande.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-3 md:gap-4">
|
||||
{fotos.map((f) => (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 md:gap-4">
|
||||
{fotos.map((f, i) => (
|
||||
<figure
|
||||
key={f.id}
|
||||
className="group relative aspect-[4/3] overflow-hidden rounded-xl bg-gray-100 border border-gray-200"
|
||||
className="group relative aspect-[3/2] overflow-hidden rounded-xl bg-gray-100 border border-gray-200"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={f.url}
|
||||
alt={f.titulo ?? `Reforma de ${nombreEmpresa}`}
|
||||
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIdx(i)}
|
||||
className="block h-full w-full cursor-zoom-in"
|
||||
aria-label={`Ampliar ${f.titulo ?? `reforma de ${nombreEmpresa}`}`}
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={f.url}
|
||||
alt={f.titulo ?? `Reforma de ${nombreEmpresa}`}
|
||||
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
|
||||
/>
|
||||
</button>
|
||||
{f.titulo && (
|
||||
<figcaption className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 to-transparent p-3 text-white text-sm font-semibold opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||
<figcaption className="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 to-transparent p-3 text-white text-sm font-semibold opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||
{f.titulo}
|
||||
</figcaption>
|
||||
)}
|
||||
@@ -49,6 +85,67 @@ export default function GaleriaTrabajos({ fotos, nombreEmpresa }: GaleriaTrabajo
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{actual && (
|
||||
<div
|
||||
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/90 p-4 sm:p-8"
|
||||
onClick={cerrar}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Imagen ampliada"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={cerrar}
|
||||
aria-label="Cerrar"
|
||||
className="absolute right-4 top-4 flex h-10 w-10 items-center justify-center rounded-full bg-white/15 text-2xl leading-none text-white hover:bg-white/30"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
|
||||
{fotos.length > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
mover(-1);
|
||||
}}
|
||||
aria-label="Anterior"
|
||||
className="absolute left-3 top-1/2 flex h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full bg-white/15 text-3xl leading-none text-white hover:bg-white/30 sm:left-6"
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={actual.url}
|
||||
alt={actual.titulo ?? `Reforma de ${nombreEmpresa}`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="max-h-[86vh] max-w-[94vw] w-auto rounded-lg shadow-2xl"
|
||||
/>
|
||||
|
||||
{fotos.length > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
mover(1);
|
||||
}}
|
||||
aria-label="Siguiente"
|
||||
className="absolute right-3 top-1/2 flex h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full bg-white/15 text-3xl leading-none text-white hover:bg-white/30 sm:right-6"
|
||||
>
|
||||
›
|
||||
</button>
|
||||
)}
|
||||
|
||||
{actual.titulo && (
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-5 text-center text-sm font-medium text-white/85">
|
||||
{actual.titulo}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user