From b2a92d1a5b5340d49133d73724acf73e1c51772e Mon Sep 17 00:00:00 2001 From: Cleber Pereira Date: Sat, 30 May 2026 13:37:48 -0300 Subject: [PATCH 1/8] Commit V1.0.9 --- infra/releases/2026-05-30_13-37-47_HML.md | 52 ++++++++++ package-lock.json | 36 +++++++ package.json | 1 + src/components/SEO.tsx | 120 ++++++++++++++++++++++ src/main.tsx | 5 +- src/pages/Blog.tsx | 5 + src/pages/Cases.tsx | 5 + src/pages/Condominios.tsx | 5 + src/pages/Privacidade.tsx | 6 ++ src/pages/Sobre.tsx | 5 + src/pages/Tecnologias.tsx | 5 + src/pages/Termos.tsx | 6 ++ src/pages/nichos/Advocacia.tsx | 5 + src/pages/nichos/BackupCorporativo.tsx | 5 + src/pages/nichos/Contabilidade.tsx | 7 +- src/pages/nichos/FirewallPfSense.tsx | 5 + src/pages/nichos/Monitoramento.tsx | 5 + src/pages/nichos/VoipEmpresarial.tsx | 5 + src/pages/services/Backup.tsx | 5 + src/pages/services/CloudComputing.tsx | 5 + src/pages/services/Consultoria.tsx | 5 + src/pages/services/Noc.tsx | 5 + src/pages/services/Pabx.tsx | 5 + src/pages/services/Redes.tsx | 5 + src/pages/services/Seguranca.tsx | 5 + src/pages/services/Servidores.tsx | 5 + src/pages/services/Suporte.tsx | 5 + src/pages/services/TiGerenciada.tsx | 5 + src/pages/tech/Cisco.tsx | 5 + src/pages/tech/Linux.tsx | 5 + src/pages/tech/PfSense.tsx | 5 + src/pages/tech/Proxmox.tsx | 5 + src/pages/tech/Sharepoint.tsx | 5 + src/pages/tech/Vmware.tsx | 5 + src/pages/tech/WindowsServer.tsx | 5 + 35 files changed, 365 insertions(+), 3 deletions(-) create mode 100644 infra/releases/2026-05-30_13-37-47_HML.md create mode 100644 src/components/SEO.tsx diff --git a/infra/releases/2026-05-30_13-37-47_HML.md b/infra/releases/2026-05-30_13-37-47_HML.md new file mode 100644 index 00000000..66bfbd00 --- /dev/null +++ b/infra/releases/2026-05-30_13-37-47_HML.md @@ -0,0 +1,52 @@ +# Release HML + +Data: sáb 30 mai 2026 13:37:47 -03 + +Ambiente: +HML + +Descrição: +Commit V1.0.9 + +Branch: +develop + +Arquivos alterados antes do commit: + M package-lock.json + M package.json + M src/main.tsx + M src/pages/Blog.tsx + M src/pages/Cases.tsx + M src/pages/Condominios.tsx + M src/pages/Privacidade.tsx + M src/pages/Sobre.tsx + M src/pages/Tecnologias.tsx + M src/pages/Termos.tsx + M src/pages/nichos/Advocacia.tsx + M src/pages/nichos/BackupCorporativo.tsx + M src/pages/nichos/Contabilidade.tsx + M src/pages/nichos/FirewallPfSense.tsx + M src/pages/nichos/Monitoramento.tsx + M src/pages/nichos/VoipEmpresarial.tsx + M src/pages/services/Backup.tsx + M src/pages/services/CloudComputing.tsx + M src/pages/services/Consultoria.tsx + M src/pages/services/Noc.tsx + M src/pages/services/Pabx.tsx + M src/pages/services/Redes.tsx + M src/pages/services/Seguranca.tsx + M src/pages/services/Servidores.tsx + M src/pages/services/Suporte.tsx + M src/pages/services/TiGerenciada.tsx + M src/pages/tech/Cisco.tsx + M src/pages/tech/Linux.tsx + M src/pages/tech/PfSense.tsx + M src/pages/tech/Proxmox.tsx + M src/pages/tech/Sharepoint.tsx + M src/pages/tech/Vmware.tsx + M src/pages/tech/WindowsServer.tsx +?? infra/ +?? src/components/SEO.tsx + +Status: +Preparado para publicação diff --git a/package-lock.json b/package-lock.json index c0855b0d..58fc4421 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,7 @@ "react": "^19.2.0", "react-day-picker": "^9.13.0", "react-dom": "^19.2.0", + "react-helmet-async": "^3.0.0", "react-hook-form": "^7.70.0", "react-resizable-panels": "^4.2.2", "react-router-dom": "^7.14.0", @@ -6744,6 +6745,15 @@ "node": ">=12" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7668,6 +7678,26 @@ "react": "^19.2.3" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/react-helmet-async/-/react-helmet-async-3.0.0.tgz", + "integrity": "sha512-nA3IEZfXiclgrz4KLxAhqJqIfFDuvzQwlKwpdmzZIuC1KNSghDEIXmyU0TKtbM+NafnkICcwx8CECFrZ/sL/1w==", + "license": "Apache-2.0", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-hook-form": { "version": "7.70.0", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.70.0.tgz", @@ -8131,6 +8161,12 @@ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index d52ec2a7..c1b49c58 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "react": "^19.2.0", "react-day-picker": "^9.13.0", "react-dom": "^19.2.0", + "react-helmet-async": "^3.0.0", "react-hook-form": "^7.70.0", "react-resizable-panels": "^4.2.2", "react-router-dom": "^7.14.0", diff --git a/src/components/SEO.tsx b/src/components/SEO.tsx new file mode 100644 index 00000000..2b7626c8 --- /dev/null +++ b/src/components/SEO.tsx @@ -0,0 +1,120 @@ +// ============================================================================ +// SEO - Meta tags dinamicas por pagina +// ============================================================================ +// Uso: +// +// Cada pagina deve usar este componente com suas proprias tags. +// O canonical e gerado automaticamente a partir da URL atual. +// ============================================================================ + +import { Helmet } from 'react-helmet-async'; +import { useLocation } from 'react-router-dom'; + +interface SEOProps { + title?: string; + description?: string; + keywords?: string; + ogImage?: string; + ogType?: string; + noindex?: boolean; + schema?: Record; +} + +const SITE_URL = 'https://avanzato.com.br'; +const DEFAULT_TITLE = 'Avanzato Tecnologia | TI Gerenciada, Cloud e Seguranca'; +const DEFAULT_DESC = 'Solucoes em TI Gerenciada, Cloud Computing e Seguranca da Informacao. +23 anos de experiencia, +500 clientes atendidos. Suporte 24/7 em Guarulhos e regiao.'; +const DEFAULT_OG_IMAGE = 'https://avanzato.com.br/og-image.jpg'; + +export default function SEO({ + title, + description, + keywords, + ogImage, + ogType = 'website', + noindex = false, + schema, +}: SEOProps) { + const location = useLocation(); + const pathname = location.pathname; + const canonicalUrl = `${SITE_URL}${pathname}`; + const fullTitle = title ? `${title} | Avanzato` : DEFAULT_TITLE; + + return ( + + {/* Title */} + {fullTitle} + + + {/* Description */} + {description && } + {!description && } + + {/* Keywords */} + {keywords && } + + {/* Canonical - DINAMICO por pagina */} + + + {/* Robots */} + {noindex ? ( + + ) : ( + + )} + + {/* Open Graph */} + + + + + + + + + {/* Twitter */} + + + + + + + {/* Schema.org */} + {schema && ( + + )} + + ); +} + +// Schema helpers +export const createServiceSchema = (name: string, description: string, urlPath: string) => ({ + '@context': 'https://schema.org', + '@type': 'Service', + name, + description, + provider: { + '@type': 'Organization', + name: 'Avanzato Tecnologia', + url: SITE_URL, + }, + url: `${SITE_URL}${urlPath}`, + areaServed: { + '@type': 'City', + name: 'Guarulhos', + }, +}); + +export const createFAQSchema = (questions: Array<{q: string; a: string}>) => ({ + '@context': 'https://schema.org', + '@type': 'FAQPage', + mainEntity: questions.map(({q, a}) => ({ + '@type': 'Question', + name: q, + acceptedAnswer: { + '@type': 'Answer', + text: a, + }, + })), +}); diff --git a/src/main.tsx b/src/main.tsx index bef5202a..0a361e56 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,13 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' +import { HelmetProvider } from 'react-helmet-async' import './index.css' import App from './App.tsx' createRoot(document.getElementById('root')!).render( - + + + , ) diff --git a/src/pages/Blog.tsx b/src/pages/Blog.tsx index aedf2a22..5d399975 100644 --- a/src/pages/Blog.tsx +++ b/src/pages/Blog.tsx @@ -1,3 +1,4 @@ +import SEO from '../components/SEO'; import { useEffect, useRef } from 'react'; import { Link } from 'react-router-dom'; import { gsap } from 'gsap'; @@ -132,6 +133,10 @@ const Blog = () => { return (
+ {/* Hero */}
diff --git a/src/pages/Cases.tsx b/src/pages/Cases.tsx index 6fd4405b..f92d21a8 100644 --- a/src/pages/Cases.tsx +++ b/src/pages/Cases.tsx @@ -1,3 +1,4 @@ +import SEO from '../components/SEO'; import { useEffect, useRef } from 'react'; import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; @@ -199,6 +200,10 @@ const Cases = () => { return (
+ {/* Schema.org JSON-LD */}