Rediseña panel y auth con la identidad de la landing B2C
- Vista de leads en tarjetas + tabla con toggle (tarjetas por defecto, preferencia persistida) - Galería de trabajos: gestión en /panel/galeria y bloque público en el funnel - Selector de tema por reformista (presets + color de marca opcional) aplicado a la landing - Login y registro rediseñados a pantalla partida 50/50 con foto de reforma - Enlace "Entrar" funcional en la cabecera del funnel; elimina Navbar muerto - Unifica tipografía y botones del panel con los tokens de la landing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
73
mvp/b2c/src/app/panel/galeria/page.tsx
Normal file
73
mvp/b2c/src/app/panel/galeria/page.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import { getGaleriaPanel } from '@/db/tenant-queries';
|
||||
import { eliminarFotoGaleria } from './actions';
|
||||
import { GALERIA_MAX_FOTOS } from '@/lib/galeria';
|
||||
import GaleriaUploader from '@/components/panel/GaleriaUploader';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export default async function GaleriaPage() {
|
||||
const fotos = await getGaleriaPanel();
|
||||
|
||||
return (
|
||||
<div className="space-y-8 max-w-3xl">
|
||||
<div>
|
||||
<h1 className="text-2xl font-black tracking-tight text-black">Galería de trabajos</h1>
|
||||
<p className="text-sm text-gray-500 mt-1">
|
||||
Sube fotos de reformas que ya has hecho. Aparecen en tu funnel para dar confianza al
|
||||
cliente antes de pedir presupuesto.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<GaleriaUploader total={fotos.length} max={GALERIA_MAX_FOTOS} />
|
||||
|
||||
{fotos.length === 0 ? (
|
||||
<p className="text-sm text-gray-400">
|
||||
Aún no has subido ninguna foto. La galería no se mostrará en tu funnel hasta que añadas la
|
||||
primera.
|
||||
</p>
|
||||
) : (
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 gap-4">
|
||||
{fotos.map((foto) => (
|
||||
<figure
|
||||
key={foto.id}
|
||||
className="group relative overflow-hidden rounded-xl border border-gray-200 bg-white"
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={foto.url}
|
||||
alt={foto.titulo ?? 'Reforma'}
|
||||
className="aspect-[4/3] w-full object-cover"
|
||||
/>
|
||||
{foto.titulo && (
|
||||
<figcaption className="px-3 py-2 text-xs font-medium text-gray-700 truncate">
|
||||
{foto.titulo}
|
||||
</figcaption>
|
||||
)}
|
||||
<form action={eliminarFotoGaleria.bind(null, foto.id)} className="absolute top-2 right-2">
|
||||
<button
|
||||
type="submit"
|
||||
aria-label="Eliminar foto"
|
||||
className="flex h-8 w-8 items-center justify-center rounded-full bg-white/90 text-gray-600 shadow-sm transition hover:bg-red-500 hover:text-white"
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</figure>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user