Reestructuración pedida por el cliente tras revisar la primera versión. Conversión: - Formulario de 14 campos a 4: nombre, correo, teléfono y mensaje. La clasificación de riesgo ya no se pregunta, se deduce del contexto de la página y viaja oculta. Menos fricción, misma riqueza para el análisis. - El inicio deja de bifurcar y empuja al catálogo: 36 llamados desembocan ahí, y las rutas por industria y escenario pasan a ser la forma de entrar al catálogo ya filtrado, en lugar de competir como destino. - Catálogo rehecho como tienda: barra lateral con filtros, búsqueda que acepta expresiones regulares, títulos que abren la ficha, un solo botón primario por tarjeta y el comparador detrás de un desplegable. - Ficha de producto orientada al cierre: bloque en lenguaje llano sobre si el equipo corresponde al caso, y "Cotizar este equipo" con el formulario precargado. Se retiraron los enlaces que sacaban del embudo a leer normas. - Todos los llamados se unifican en "Recibir cotización". - Widget de WhatsApp: nombre, teléfono, correo y mensaje libre. El texto que escribe la persona es el que viaja a la conversación. Doble audiencia: - 13 escenarios con la iconografía original de FSPM traducen un lugar reconocible a clases de fuego y productos, para quien no domina la terminología. La capa técnica se conserva para búsqueda. - Héroe con fotografía en todas las landings. Correcciones: - El contenedor moría al arrancar porque el CLI de Prisma no podía escribir sus motores; el chown ahora incluye /app/prisma-cli. - Iconos repetidos entre escenarios. El set original no tiene icono de cocina, así que ese escenario usa un marcador tipográfico explícito. - FIREMIKS no aparecía en ningún escenario. - Los ids de campo del formulario colisionaban con dos instancias por página. - Se documentó el despliegue, que faltaba por completo. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
264 lines
12 KiB
TypeScript
264 lines
12 KiB
TypeScript
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
import { FormularioContacto } from "@/components/formulario/FormularioContacto";
|
|
import { Migas } from "@/components/site/contenido/Migas";
|
|
import { FOTOS, HeroeLanding } from "@/components/site/HeroeLanding";
|
|
import { Revelar } from "@/components/site/Revelar";
|
|
import { EMPRESA, SITIO_URL, WHATSAPP } from "@/data/empresa";
|
|
|
|
/**
|
|
* /contacto
|
|
*
|
|
* Solo datos verificados: teléfono, correo, ciudad y colonia. No hay horario de
|
|
* atención, ni domicilio con número, ni mapa: nada de eso está confirmado, y
|
|
* una dirección equivocada en un sitio de protección contra incendios es un
|
|
* problema real, no un detalle.
|
|
*
|
|
* El formulario pide cuatro campos, así que la página no puede prometer que la
|
|
* respuesta llega con la clase de fuego y la superficie ya declaradas: lo que
|
|
* promete es que preguntamos nosotros lo que falte.
|
|
*/
|
|
|
|
const TITULO = "Contacto: habla con un especialista de FSPM";
|
|
const DESCRIPCION = `Teléfono, correo y WhatsApp de ${EMPRESA.nombre}, en ${EMPRESA.ciudad}. Solicita un diagnóstico de protección contra incendios con cuatro campos y te contesta una persona con nombre, no un buzón compartido.`;
|
|
|
|
export const metadata: Metadata = {
|
|
title: TITULO,
|
|
description: DESCRIPCION,
|
|
alternates: { canonical: `${SITIO_URL}/contacto` },
|
|
openGraph: {
|
|
title: `${TITULO} | ${EMPRESA.nombreCorto}`,
|
|
description: DESCRIPCION,
|
|
url: `${SITIO_URL}/contacto`,
|
|
},
|
|
};
|
|
|
|
const MENSAJE_WHATSAPP = encodeURIComponent(
|
|
"Hola, me gustaría información sobre protección contra incendios.",
|
|
);
|
|
|
|
const MENSAJE_INICIAL = "Necesito proteger ";
|
|
|
|
export default function PaginaContacto() {
|
|
return (
|
|
<>
|
|
<HeroeLanding
|
|
antes={<Migas actual="Contacto" />}
|
|
eyebrow="Contacto"
|
|
titulo="Si tu situación no puede esperar, marca"
|
|
entrada="Para todo lo demás, el formulario funciona mejor: son cuatro campos, queda con folio y lo recibe una persona con nombre. Lo que falte lo preguntamos nosotros."
|
|
foto={FOTOS.contacto}
|
|
enfoque="50% 38%"
|
|
altura="alto"
|
|
prioridad
|
|
>
|
|
<div className="flex flex-col gap-4 sm:flex-row sm:items-center">
|
|
<a href={`tel:${EMPRESA.telefonoTel}`} className="btn btn-signal w-full sm:w-auto">
|
|
Marcar {EMPRESA.telefono}
|
|
</a>
|
|
<Link
|
|
href="#formulario"
|
|
className="font-mono text-[0.6875rem] uppercase tracking-[0.12em] text-bright underline decoration-rule-2 underline-offset-4 hover:decoration-signal [-webkit-tap-highlight-color:transparent]"
|
|
>
|
|
O envía el formulario
|
|
</Link>
|
|
</div>
|
|
</HeroeLanding>
|
|
|
|
{/* ---------- datos verificados ---------- */}
|
|
<section className="border-t border-rule bg-ink-2 py-12 sm:py-14" aria-labelledby="datos-titulo">
|
|
<div className="shell">
|
|
<h2 id="datos-titulo" className="sr-only">
|
|
Datos de contacto
|
|
</h2>
|
|
|
|
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
<a
|
|
href={`tel:${EMPRESA.telefonoTel}`}
|
|
className="group flex flex-col rounded-[6px] border border-signal/60 bg-ink p-5 transition-colors duration-200 hover:border-signal [-webkit-tap-highlight-color:transparent]"
|
|
>
|
|
<span className="font-mono text-[0.625rem] uppercase tracking-[0.14em] text-signal">
|
|
Teléfono
|
|
</span>
|
|
<span className="mt-2.5 font-mono text-lg font-semibold text-bright transition-colors group-hover:text-signal-hi">
|
|
{EMPRESA.telefono}
|
|
</span>
|
|
<span className="mt-2 text-xs leading-relaxed text-muted">
|
|
La vía más rápida. Marca directo desde el móvil.
|
|
</span>
|
|
</a>
|
|
|
|
<a
|
|
href={`mailto:${EMPRESA.correo}`}
|
|
className="group flex flex-col rounded-[6px] border border-rule bg-ink p-5 transition-colors duration-200 hover:border-signal [-webkit-tap-highlight-color:transparent]"
|
|
>
|
|
<span className="font-mono text-[0.625rem] uppercase tracking-[0.14em] text-faint">
|
|
Correo
|
|
</span>
|
|
<span className="mt-2.5 break-all font-mono text-sm font-semibold text-bright transition-colors group-hover:text-signal-hi">
|
|
{EMPRESA.correo}
|
|
</span>
|
|
<span className="mt-2 text-xs leading-relaxed text-muted">
|
|
Útil si necesitas adjuntar planos o el requerimiento de tu auditoría.
|
|
</span>
|
|
</a>
|
|
|
|
<a
|
|
href={`https://api.whatsapp.com/send?phone=${WHATSAPP}&text=${MENSAJE_WHATSAPP}`}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="group flex flex-col rounded-[6px] border border-rule bg-ink p-5 transition-colors duration-200 hover:border-signal [-webkit-tap-highlight-color:transparent]"
|
|
>
|
|
<span className="font-mono text-[0.625rem] uppercase tracking-[0.14em] text-faint">
|
|
WhatsApp
|
|
</span>
|
|
<span className="mt-2.5 font-mono text-sm font-semibold text-bright transition-colors group-hover:text-signal-hi">
|
|
Abrir conversación
|
|
</span>
|
|
<span className="mt-2 text-xs leading-relaxed text-muted">
|
|
El mismo número, si prefieres escribir antes de llamar.
|
|
</span>
|
|
</a>
|
|
|
|
<div className="flex flex-col rounded-[6px] border border-rule bg-ink p-5">
|
|
<span className="font-mono text-[0.625rem] uppercase tracking-[0.14em] text-faint">
|
|
Ubicación
|
|
</span>
|
|
<span className="mt-2.5 font-mono text-sm font-semibold text-bright">
|
|
{EMPRESA.colonia}
|
|
</span>
|
|
<span className="mt-1 font-mono text-sm text-muted">
|
|
{EMPRESA.ciudad}, {EMPRESA.pais}
|
|
</span>
|
|
<span className="mt-2 text-xs leading-relaxed text-muted">
|
|
Dinos en el formulario dónde está la instalación y te confirmamos cómo podemos
|
|
atenderla.
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<p className="mt-6 max-w-3xl text-xs leading-relaxed text-faint">
|
|
Publicamos únicamente los datos que pudimos verificar en la información pública de la
|
|
empresa. Si necesitas domicilio fiscal, horario de atención o una visita presencial,
|
|
pídelos por cualquiera de estos medios y te los confirmamos por escrito.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ---------- formulario completo ---------- */}
|
|
<section
|
|
id="formulario"
|
|
className="grid-bg-lite border-t border-rule bg-paper py-14 sm:py-20"
|
|
aria-labelledby="solicitud-titulo"
|
|
>
|
|
<div className="shell">
|
|
<div className="grid gap-10 lg:grid-cols-[1fr_1.1fr] lg:items-start lg:gap-16">
|
|
<div>
|
|
<Revelar>
|
|
<p className="eyebrow mb-4">Solicitud</p>
|
|
<h2
|
|
id="solicitud-titulo"
|
|
className="font-display text-2xl font-extrabold text-deep sm:text-3xl"
|
|
>
|
|
Qué pasa cuando envías el formulario
|
|
</h2>
|
|
<p className="mt-4 text-sm leading-relaxed text-deep-muted sm:text-base">
|
|
Nombre, correo, teléfono y una línea de contexto. Nada más: los cuestionarios
|
|
técnicos de catorce campos son la razón por la que la gente cierra la pestaña.
|
|
</p>
|
|
</Revelar>
|
|
|
|
<ol className="mt-8 space-y-6">
|
|
{[
|
|
{
|
|
n: "01",
|
|
t: "Se registra con folio",
|
|
d: "Recibes un folio en pantalla. Tu solicitud queda asignada a una persona, no a un buzón compartido.",
|
|
},
|
|
{
|
|
n: "02",
|
|
t: "Preguntamos lo que falta",
|
|
d: "Con la página desde la que escribiste y lo que dejaste en el mensaje ya se intuye el escenario. Lo que no se intuye —qué se puede quemar, quién opera, qué superficie— lo preguntamos nosotros en la primera respuesta.",
|
|
},
|
|
{
|
|
n: "03",
|
|
t: "Respondemos con documentación, no con folleto",
|
|
d: "La respuesta incluye la selección propuesta y el índice de documentos que debería acompañarla. Si algo no podemos sostener por escrito, va dicho ahí.",
|
|
},
|
|
].map((paso) => (
|
|
<li key={paso.n} className="flex gap-4">
|
|
<span className="font-mono text-[0.625rem] font-semibold tracking-[0.08em] text-signal">
|
|
{paso.n}
|
|
</span>
|
|
<div>
|
|
<h3 className="font-display text-sm font-bold uppercase tracking-wide text-deep">
|
|
{paso.t}
|
|
</h3>
|
|
<p className="mt-1.5 text-sm leading-relaxed text-deep-muted">{paso.d}</p>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ol>
|
|
|
|
<hr className="hair-lite my-8" />
|
|
|
|
<h3 className="font-mono text-[0.6875rem] uppercase tracking-[0.16em] text-deep-muted">
|
|
Antes de escribir, quizá ya está respondido
|
|
</h3>
|
|
<ul className="mt-4 flex flex-wrap gap-2">
|
|
{[
|
|
{ href: "/preguntas-frecuentes", label: "Preguntas frecuentes" },
|
|
{ href: "/cumplimiento-nom-002", label: "Cumplimiento NOM-002" },
|
|
{ href: "/evidencia", label: "Documentación técnica" },
|
|
{ href: "/catalogo", label: "Catálogo" },
|
|
].map((enlace) => (
|
|
<li key={enlace.href}>
|
|
<Link
|
|
href={enlace.href}
|
|
className="badge !border-rule-lite !text-deep-muted hover:!border-signal hover:!text-deep [-webkit-tap-highlight-color:transparent]"
|
|
>
|
|
{enlace.label}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
|
|
<h3 className="mt-8 font-mono text-[0.6875rem] uppercase tracking-[0.16em] text-deep-muted">
|
|
Redes
|
|
</h3>
|
|
<ul className="mt-4 flex flex-wrap gap-4">
|
|
{[
|
|
{ url: EMPRESA.redes.linkedin, label: "LinkedIn" },
|
|
{ url: EMPRESA.redes.facebook, label: "Facebook" },
|
|
{ url: EMPRESA.redes.youtube, label: "YouTube" },
|
|
].map((red) => (
|
|
<li key={red.label}>
|
|
<a
|
|
href={red.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="font-mono text-[0.6875rem] uppercase tracking-[0.12em] text-deep underline decoration-rule-lite underline-offset-4 hover:decoration-signal"
|
|
>
|
|
{red.label}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
|
|
<FormularioContacto
|
|
id="formulario-contacto"
|
|
canal="contacto"
|
|
variante="claro"
|
|
titulo="Recibir cotización"
|
|
descripcion="Completa la frase del mensaje con lo que hay que proteger. Te respondemos con el escenario, el equipo que aplica y qué documentación te corresponde."
|
|
mensajeInicial={MENSAJE_INICIAL}
|
|
textoBoton="Recibir cotización"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|