feat(home): prova no topo, contato sem atrito e conversão medida
Home mais curta (hero, vitrine de clientes, sobre, serviços, IA resumida, depoimentos e contato), faixa de clientes e telas reais no hero, sem números do GitHub. Barra de cookies fina, WhatsApp fixo no celular, formulário com e-mail opcional e alternativa por e-mail, página /ia, eventos de e-mail, redes e currículo e conversão do Ads opcional por variável. Rodapé em 3 colunas. Remove componentes órfãos (LighthouseMetrics, Skills, Experience, contagem do GitHub).
This commit is contained in:
1 parent
6e1022b58c
commit
8d07b8c6bb
60 files changed
+4392
-2124
No files matched your search
@@ -0,0 +1,103 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import ts from "typescript";
|
||||
|
||||
/**
|
||||
* Caminhos de lib/analytics.ts quando não existe `window` (renderização no servidor): nenhum rastreio,
|
||||
* nenhuma conversão e nenhum erro. O setup do projeto exige o jsdom e o `window` dele não pode ser
|
||||
* escondido, então o próprio fonte é transpilado e executado com `window` e `localStorage` indefinidos.
|
||||
*/
|
||||
|
||||
type AnalyticsModule = typeof import("./analytics");
|
||||
|
||||
const ADS_LABEL = "NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_LABEL";
|
||||
|
||||
function loadWithoutWindow(storage?: Storage): AnalyticsModule {
|
||||
const source = readFileSync(join(process.cwd(), "lib/analytics.ts"), "utf8");
|
||||
const { outputText } = ts.transpileModule(source, {
|
||||
compilerOptions: {
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES2020,
|
||||
},
|
||||
});
|
||||
const loaded = { exports: {} as AnalyticsModule };
|
||||
new Function("module", "exports", "window", "localStorage", outputText)(
|
||||
loaded,
|
||||
loaded.exports,
|
||||
undefined,
|
||||
storage,
|
||||
);
|
||||
return loaded.exports;
|
||||
}
|
||||
|
||||
let gtag: jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.replaceProperty(process.env, "NODE_ENV", "production");
|
||||
process.env[ADS_LABEL] = "abc123";
|
||||
localStorage.setItem("evandro.analytics-consent.v1", "granted");
|
||||
gtag = jest.fn();
|
||||
window.gtag = gtag;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
localStorage.clear();
|
||||
delete window.gtag;
|
||||
delete process.env[ADS_LABEL];
|
||||
});
|
||||
|
||||
describe("analytics without a window", () => {
|
||||
it("path: every tracker is silent and never throws, even with granted consent and a conversion label", () => {
|
||||
// o consentimento está "granted" no storage real: só a ausência de `window` impede o envio
|
||||
const analytics = loadWithoutWindow(localStorage);
|
||||
|
||||
expect(() => {
|
||||
analytics.trackWhatsAppOpen({
|
||||
service: "Contato",
|
||||
placement: "floating",
|
||||
});
|
||||
analytics.trackEmailClick({ placement: "footer" });
|
||||
analytics.trackSocialClick({ network: "linkedin" });
|
||||
analytics.trackCvDownload({ placement: "curriculo" });
|
||||
}).not.toThrow();
|
||||
expect(gtag).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("path: readConsent finds no storage -> null", () => {
|
||||
expect(loadWithoutWindow().readConsent()).toBeNull();
|
||||
});
|
||||
|
||||
it("path: openCookiePreferences has no window to notify -> returns without error", () => {
|
||||
const listener = jest.fn();
|
||||
window.addEventListener("evandro:open-cookie-preferences", listener);
|
||||
|
||||
expect(() => loadWithoutWindow().openCookiePreferences()).not.toThrow();
|
||||
|
||||
window.removeEventListener("evandro:open-cookie-preferences", listener);
|
||||
expect(listener).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("control: the same source with a window does dispatch the reopen event", () => {
|
||||
const listener = jest.fn();
|
||||
window.addEventListener("evandro:open-cookie-preferences", listener);
|
||||
const source = readFileSync(
|
||||
join(process.cwd(), "lib/analytics.ts"),
|
||||
"utf8",
|
||||
);
|
||||
const { outputText } = ts.transpileModule(source, {
|
||||
compilerOptions: { module: ts.ModuleKind.CommonJS },
|
||||
});
|
||||
const loaded = { exports: {} as AnalyticsModule };
|
||||
new Function("module", "exports", "window", outputText)(
|
||||
loaded,
|
||||
loaded.exports,
|
||||
window,
|
||||
);
|
||||
|
||||
loaded.exports.openCookiePreferences();
|
||||
|
||||
window.removeEventListener("evandro:open-cookie-preferences", listener);
|
||||
expect(listener).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user