Três ofertas (site que traz pedidos pelo WhatsApp, sistema para tirar a operação da planilha, revisão de sistema existente) com miniatura e formulário com o tipo escolhido; botão principal do hero abre o WhatsApp; moldura da SEV no hero do celular; menu fecha ao navegar, Esc, foco preso incluindo a barra de cookies e espaço para ela; CinematicHome como componente de servidor com ilha cliente; /ia com H1 de oferta e cartão do que você recebe; botão flutuante em aside com transform; AVIF antes de WebP; copy sem repetir contato direto.
47 lines
2.0 KiB
TypeScript
47 lines
2.0 KiB
TypeScript
/**
|
|
* Tipos de projeto do formulário de contato (Contact.tsx) e o jeito de as ofertas da home escolherem um deles.
|
|
* Uma oferta abre o formulário com o tipo já marcado de dois jeitos: o endereço `/?tipo=<tipo>#contact` (vale ao
|
|
* chegar de outra página ou em um link copiado) e o evento CONTACT_KIND_EVENT (vale na própria home, onde o
|
|
* gerenciador de âncoras rola até o formulário sem recarregar a página nem mudar a busca do endereço).
|
|
* O tipo vai na busca, antes do `#`: um `/#contact?tipo=...` faria o fragmento virar "contact?tipo=...",
|
|
* que não é o id de nenhum elemento, e a página não rolaria até o formulário.
|
|
*/
|
|
|
|
/** Primeiro e padrão: quem chega sem saber o que pedir não é empurrado para um tipo. */
|
|
export const DEFAULT_CONTACT_SUBJECT = "Ainda preciso definir";
|
|
|
|
export const CONTACT_SUBJECT_OPTIONS = [
|
|
DEFAULT_CONTACT_SUBJECT,
|
|
"Site para empresa",
|
|
"Sistemas web sob medida",
|
|
"Aplicativos",
|
|
"Integrações e automações",
|
|
"Evolução de um sistema existente",
|
|
"Revisão ou diagnóstico de sistema",
|
|
] as const;
|
|
|
|
/** Tipo que uma oferta pede -> opção do formulário. */
|
|
export const CONTACT_KINDS = {
|
|
site: "Site para empresa",
|
|
sistema: "Sistemas web sob medida",
|
|
revisao: "Revisão ou diagnóstico de sistema",
|
|
} as const satisfies Record<string, (typeof CONTACT_SUBJECT_OPTIONS)[number]>;
|
|
|
|
export type ContactKind = keyof typeof CONTACT_KINDS;
|
|
|
|
/** Parâmetro de busca do endereço: `/?tipo=site#contact`. */
|
|
export const CONTACT_KIND_PARAM = "tipo";
|
|
/** Evento da janela com o tipo escolhido em `detail`. */
|
|
export const CONTACT_KIND_EVENT = "contact:kind";
|
|
|
|
/** Opção do formulário para um tipo; `undefined` para um tipo desconhecido (inclusive nomes herdados, como "constructor"). */
|
|
export function contactSubjectForKind(kind: string | null | undefined) {
|
|
return kind && Object.hasOwn(CONTACT_KINDS, kind)
|
|
? CONTACT_KINDS[kind as ContactKind]
|
|
: undefined;
|
|
}
|
|
|
|
export function contactKindHref(kind: ContactKind) {
|
|
return `/?${CONTACT_KIND_PARAM}=${kind}#contact`;
|
|
}
|