feat(home): ofertas que vendem o título, WhatsApp no hero e menu do celular acessível
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.
This commit is contained in:
1 parent
de6af74a0c
commit
f8545cd442
44 files changed
+2286
-571
No files matched your search
+49
-6
@@ -1,7 +1,13 @@
|
||||
import {
|
||||
AI_REVIEW_SUBJECT,
|
||||
buildWhatsAppUrl,
|
||||
CASES_SUBJECT,
|
||||
HOME_SUBJECT,
|
||||
headerOpensWhatsApp,
|
||||
isServiceOrCasePath,
|
||||
RESUME_SUBJECT,
|
||||
SERVICES_SUBJECT,
|
||||
similarProjectSubject,
|
||||
type WhatsAppContexts,
|
||||
whatsAppSubjectForPath,
|
||||
} from "./whatsapp";
|
||||
@@ -18,10 +24,27 @@ describe("whatsAppSubjectForPath", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("cites the case on /cases/<slug>", () => {
|
||||
it("cites the case on /cases/<slug>, with the phrase every page uses for a similar project", () => {
|
||||
expect(whatsAppSubjectForPath("/cases/sev-modaintima", contexts)).toBe(
|
||||
"um projeto parecido com o da SEV Moda Íntima",
|
||||
"um projeto parecido com o SEV Moda Íntima",
|
||||
);
|
||||
expect(similarProjectSubject("Lavação 047")).toBe(
|
||||
"um projeto parecido com o Lavação 047",
|
||||
);
|
||||
});
|
||||
|
||||
it("speaks of the page itself on the home and the index pages, the same as the body buttons of /cases and /servicos", () => {
|
||||
expect(whatsAppSubjectForPath("/", contexts)).toBe(HOME_SUBJECT);
|
||||
expect(whatsAppSubjectForPath("/cases", contexts)).toBe(CASES_SUBJECT);
|
||||
expect(CASES_SUBJECT).toBe("um projeto parecido com os cases do portfólio");
|
||||
expect(whatsAppSubjectForPath("/servicos", contexts)).toBe(
|
||||
SERVICES_SUBJECT,
|
||||
);
|
||||
expect(SERVICES_SUBJECT).toBe("Sites, sistemas e aplicativos");
|
||||
expect(whatsAppSubjectForPath("/curriculo", contexts)).toBe(RESUME_SUBJECT);
|
||||
// sem contextos, a página-índice continua falando de si
|
||||
expect(whatsAppSubjectForPath("/cases/")).toBe(CASES_SUBJECT);
|
||||
expect(whatsAppSubjectForPath("/curriculo/")).toBe(RESUME_SUBJECT);
|
||||
});
|
||||
|
||||
it("cites the AI review on /ia", () => {
|
||||
@@ -36,11 +59,8 @@ describe("whatsAppSubjectForPath", () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
"/",
|
||||
"/servicos",
|
||||
"/cases",
|
||||
"/curriculo",
|
||||
"/privacidade",
|
||||
"/notebook-smoke",
|
||||
"/servicos/inexistente",
|
||||
"/cases/inexistente",
|
||||
"/servicos/criacao-de-sites/extra",
|
||||
@@ -93,6 +113,29 @@ describe("isServiceOrCasePath", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("headerOpensWhatsApp", () => {
|
||||
it.each([
|
||||
["/servicos/criacao-de-sites", true],
|
||||
["/servicos/inexistente", true],
|
||||
["/cases/sev-modaintima", true],
|
||||
["/ia", true],
|
||||
["/ia/", true],
|
||||
["/cases", true],
|
||||
["/servicos", true],
|
||||
["/curriculo", true],
|
||||
["/curriculo/", true],
|
||||
// a home já tem o formulário na própria página; as demais rotas não têm assunto
|
||||
["/", false],
|
||||
["/privacidade", false],
|
||||
["/cases/a/b", false],
|
||||
["/ia/extra", false],
|
||||
[null, false],
|
||||
[undefined, false],
|
||||
])("%s -> %s", (pathname, expected) => {
|
||||
expect(headerOpensWhatsApp(pathname)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildWhatsAppUrl", () => {
|
||||
it("encodes the message in the text parameter of a wa.me link", () => {
|
||||
const url = new URL(buildWhatsAppUrl("Olá & tudo? #1"));
|
||||
|
||||
Reference in new issue
Block a user