Añade personalización SEO/Quiénes somos y testimonios gestionables por reformista
- Panel/empresa: title y meta description SEO personalizables; foto, texto y años de experiencia para el bloque "Quiénes somos" (toggle on/off). - Funnel por slug: metadata SEO desde el tenant, bloque "Quiénes somos" y testimonios servidos desde DB (sustituye los hardcodeados). - Flujo de opiniones: el reformista solicita la opinión desde la ficha de un lead ganado; el cliente la deja en un funnel dedicado /opinion/[id] con estrellas + texto + fotos; entra como pendiente y el reformista la modera (publicar/ocultar/eliminar) en /panel/opiniones antes de mostrarla. - Schema: columnas SEO/about en tenants, testimonioSolicitadoAt en leads, enum testimonio_estado, tablas testimonios + testimonio_fotos (migración 0006). - Seed: opiniones demo (2 publicadas, 1 pendiente) y contenido "Quiénes somos". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
50
mvp/b2c/src/app/opinion/[id]/page.tsx
Normal file
50
mvp/b2c/src/app/opinion/[id]/page.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { notFound } from 'next/navigation';
|
||||
import { getLeadForReview } from '@/lib/funnel/public-queries';
|
||||
import { enviarOpinion } from '../actions';
|
||||
import OpinionForm from '@/components/funnel/OpinionForm';
|
||||
import TenantBrand from '@/components/funnel/TenantBrand';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export default async function OpinionPage({ params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await params;
|
||||
const data = await getLeadForReview(id);
|
||||
if (!data || !data.tenant) notFound();
|
||||
|
||||
const { lead, tenant, yaEnviado } = data;
|
||||
|
||||
return (
|
||||
<>
|
||||
<TenantBrand
|
||||
nombreEmpresa={tenant.nombreEmpresa}
|
||||
logoUrl={tenant.logoUrl}
|
||||
subtitle="Tu opinión"
|
||||
/>
|
||||
<div className="container py-10 max-w-2xl flex flex-col gap-6">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="text-2xl font-black tracking-tight text-black">
|
||||
{lead.nombre.split(' ')[0]}, ¿qué tal fue tu reforma con {tenant.nombreEmpresa}?
|
||||
</h1>
|
||||
<p className="text-sm text-gray-500 leading-relaxed">
|
||||
Tu opinión nos ayuda muchísimo. Cuéntanos cómo fue y, si quieres, sube alguna foto del
|
||||
resultado.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{yaEnviado ? (
|
||||
<div className="bg-white border border-gray-200 rounded-xl p-8 text-center flex flex-col gap-3">
|
||||
<span className="text-4xl" aria-hidden="true">
|
||||
✅
|
||||
</span>
|
||||
<h2 className="text-xl font-black text-black">Ya hemos recibido tu opinión</h2>
|
||||
<p className="text-sm text-gray-500">¡Gracias por tomarte el tiempo!</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-white border border-gray-200 rounded-xl p-6 md:p-8 shadow-sm">
|
||||
<OpinionForm action={enviarOpinion.bind(null, id)} nombreCliente={lead.nombre} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user