feat(cases): cases de clientes, serviços ligados à prova e SEO por página
Cases da SEV Moda Íntima e da Lavação 047; case no formato cliente, problema, entrega, mídia e contato, com detalhes técnicos recolhidos; sem GitHub, ressalvas e fontes de commit. /cases separa clientes e Laboratório. Serviços mostram o case de cliente certo e o bloco de investimento e prazo só aparece preenchido. Metadata social própria por página, not-found com noindex, sitemap com /ia.
This commit is contained in:
1 parent
3756905a1b
commit
6e1022b58c
44 files changed
+2691
-1424
No files matched your search
@@ -40,6 +40,22 @@ it("preserves breadcrumb navigation and a breadcrumb-only JSON-LD graph", () =>
|
||||
]);
|
||||
});
|
||||
|
||||
it("mentions no GitHub link and no English jargon in the visible text", () => {
|
||||
const { container } = render(<PrivacyPage />);
|
||||
|
||||
expect(container.textContent).not.toMatch(/github/i);
|
||||
expect(container.textContent).not.toMatch(/\b(loader|endpoint)\b/i);
|
||||
for (const link of screen.getAllByRole("link")) {
|
||||
expect(link.getAttribute("href")).not.toMatch(/github/i);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the lime fill for contact actions only", () => {
|
||||
const { container } = render(<PrivacyPage />);
|
||||
|
||||
expect(container.querySelector(".ds-link-accent")).toBeNull();
|
||||
});
|
||||
|
||||
it("uses privacy-specific canonical metadata", () => {
|
||||
expect(metadata).toMatchObject({
|
||||
title: expect.stringMatching(/privacidade/i),
|
||||
|
||||
+24
-38
@@ -1,7 +1,9 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { Breadcrumb } from "@/app/components/Breadcrumb";
|
||||
import { pageTop } from "@/app/components/button-styles";
|
||||
import { safeJsonLd } from "@/lib/jsonld";
|
||||
import { buildBreadcrumbList } from "@/lib/seo";
|
||||
import { buildBreadcrumbList, buildPageSocialMetadata } from "@/lib/seo";
|
||||
import { siteName, siteUrl } from "@/lib/site-content";
|
||||
|
||||
const pageUrl = `${siteUrl}/privacidade`;
|
||||
@@ -10,16 +12,13 @@ export const metadata: Metadata = {
|
||||
title: "Privacidade e consentimento",
|
||||
description:
|
||||
"Como o portfólio trata dados de contato, consentimento de analytics, links externos e solicitações de privacidade.",
|
||||
alternates: { canonical: pageUrl },
|
||||
openGraph: {
|
||||
locale: "pt_BR",
|
||||
...buildPageSocialMetadata({
|
||||
url: pageUrl,
|
||||
title: `Privacidade e consentimento | ${siteName}`,
|
||||
description:
|
||||
"Informações factuais sobre contato, analytics e preferências de privacidade no portfólio.",
|
||||
url: pageUrl,
|
||||
siteName,
|
||||
type: "website",
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export default function PrivacyPage() {
|
||||
@@ -37,27 +36,14 @@ export default function PrivacyPage() {
|
||||
<main>
|
||||
<script type="application/ld+json">{safeJsonLd(jsonLd)}</script>
|
||||
|
||||
<section className="ds-section ds-section-dark">
|
||||
<section className={`ds-section ds-section-dark ${pageTop}`}>
|
||||
<div className="ds-section-shell max-w-[960px]">
|
||||
<nav aria-label="Breadcrumb" className="mb-sp-6">
|
||||
<ol className="flex flex-wrap items-center gap-sp-2 text-sm">
|
||||
<li>
|
||||
<Link className="ds-link ds-link-muted" href="/">
|
||||
Início
|
||||
</Link>
|
||||
</li>
|
||||
<li className="flex items-center gap-sp-2">
|
||||
<span aria-hidden="true">/</span>
|
||||
<Link
|
||||
aria-current="page"
|
||||
className="ds-link ds-link-muted"
|
||||
href="/privacidade"
|
||||
>
|
||||
Privacidade
|
||||
</Link>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{ label: "Início", href: "/" },
|
||||
{ label: "Privacidade", href: "/privacidade" },
|
||||
]}
|
||||
/>
|
||||
<p className="ds-eyebrow">Privacidade e consentimento</p>
|
||||
<h1 className="ds-section-title text-white">
|
||||
Privacidade e consentimento
|
||||
@@ -71,7 +57,7 @@ export default function PrivacyPage() {
|
||||
|
||||
<section className="ds-section">
|
||||
<div className="ds-section-shell">
|
||||
<div className="ds-grid-2">
|
||||
<div className="ds-grid-2 items-start">
|
||||
<article className="ds-card">
|
||||
<p className="ds-kicker">Responsável e contato</p>
|
||||
<h2 className="ds-card-title">Evandro Fonseca Junior</h2>
|
||||
@@ -79,7 +65,7 @@ export default function PrivacyPage() {
|
||||
O responsável pelo site é Evandro Fonseca Junior. Para contato
|
||||
ou solicitações relacionadas a esta página, escreva para{" "}
|
||||
<a
|
||||
className="ds-link ds-link-accent"
|
||||
className="font-medium underline underline-offset-4"
|
||||
href="mailto:[email protected]"
|
||||
>
|
||||
evandrofonsecajunior@gmail.com
|
||||
@@ -93,8 +79,8 @@ export default function PrivacyPage() {
|
||||
<h2 className="ds-card-title">Mensagem pelo WhatsApp</h2>
|
||||
<p className="ds-copy">
|
||||
Os dados digitados no formulário são transformados em uma
|
||||
mensagem e abrem o WhatsApp. O site não possui endpoint próprio
|
||||
de armazenamento desse formulário.
|
||||
mensagem e abrem o WhatsApp. O site não guarda esse formulário
|
||||
em nenhum servidor próprio.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
@@ -111,8 +97,8 @@ export default function PrivacyPage() {
|
||||
Cookies de publicidade e personalização permanecem negados. Ao
|
||||
conceder analytics, o Google pode criar cookies{" "}
|
||||
<code>_ga*</code>. Ao revogar, o consentimento é atualizado para
|
||||
negado, o loader é removido e os cookies de analytics acessíveis
|
||||
são expirados.
|
||||
negado, o carregador da tag é removido e os cookies de analytics
|
||||
acessíveis são expirados.
|
||||
</p>
|
||||
<p className="ds-copy mt-sp-4">
|
||||
A tag compartilhada conecta Google Analytics e Google Ads. O
|
||||
@@ -137,16 +123,16 @@ export default function PrivacyPage() {
|
||||
<p className="ds-copy">
|
||||
Para alterar a preferência, use o controle existente{" "}
|
||||
<strong>“Preferências de analytics”</strong> para acessar suas
|
||||
preferências de privacidade. Links externos para GitHub,
|
||||
LinkedIn, Instagram, demos e WhatsApp seguem as políticas
|
||||
próprias de cada serviço.
|
||||
preferências de privacidade. Links externos para LinkedIn,
|
||||
Instagram, demonstrações e WhatsApp seguem as políticas próprias
|
||||
de cada serviço.
|
||||
</p>
|
||||
<p className="ds-copy mt-sp-4">
|
||||
Solicitações relacionadas aos seus direitos devem ser
|
||||
encaminhadas ao e-mail publicado acima.
|
||||
</p>
|
||||
<Link
|
||||
className="ds-link ds-link-accent mt-sp-5 inline-block"
|
||||
className="ds-link ds-link-muted mt-sp-5 self-start"
|
||||
href="/"
|
||||
>
|
||||
Voltar ao início
|
||||
@@ -158,7 +144,7 @@ export default function PrivacyPage() {
|
||||
<p className="ds-kicker">Vigência</p>
|
||||
<p className="ds-copy mt-sp-2">
|
||||
Esta versão está vigente desde{" "}
|
||||
<time dateTime="2026-09-13">2026-09-13</time>.
|
||||
<time dateTime="2026-09-13">13 de setembro de 2026</time>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user