feat(config, layout, components): enhance security headers, improve SEO, and update project descriptions
- Added security headers in the Next.js configuration to enhance application security. - Updated metadata in the layout component for improved SEO, including new titles, descriptions, and keywords. - Introduced JSON-LD schema for projects to enhance search engine visibility. - Enhanced project descriptions in the portfolio data for clarity and detail. - Improved header component with logo integration and refined social media links for better accessibility.
This commit is contained in:
1 parent
3f3fca11ab
commit
ad6a76efdd
14 files changed
+467
-57
No files matched your search
@@ -138,6 +138,16 @@ export default function About() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* SEO Semantic Content - Visible but subtle */}
|
||||
<div className="mt-16 pt-8 border-t border-slate-800">
|
||||
<p className="text-xs text-slate-600 text-center max-w-2xl mx-auto leading-relaxed">
|
||||
Evandro Fonseca Junior é Engenheiro Full-Stack especializado em Next.js,
|
||||
React, Angular e Node.js. Desenvolvedor de aplicações desktop com Tauri,
|
||||
sistemas web escaláveis e automação de processos. Experiência em PostgreSQL,
|
||||
MySQL, computação em nuvem e IoT. Localizado em Garuva, Santa Catarina, Brasil.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { MenuIcon, XIcon, Layers } from "lucide-react";
|
||||
import { MenuIcon, XIcon } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
// Definição de Tipos para consistência de dados
|
||||
@@ -59,8 +60,15 @@ export function Header() {
|
||||
whileHover={{ scale: 1.05 }}
|
||||
className="flex items-center gap-2 cursor-pointer"
|
||||
>
|
||||
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center shadow-[0_0_15px_rgba(37,99,235,0.4)]">
|
||||
<Layers className="w-5 h-5 text-white" />
|
||||
<div className="w-8 h-8 flex items-center justify-center">
|
||||
<Image
|
||||
src="/edev_logo.svg"
|
||||
alt="Evandro.dev Logo"
|
||||
width={32}
|
||||
height={32}
|
||||
className="w-8 h-8"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xl font-black tracking-tighter text-white">
|
||||
EVANDRO<span className="text-blue-500">.DEV</span>
|
||||
|
||||
+13
-6
@@ -21,7 +21,7 @@ export default function Hero() {
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="home" className="relative min-h-screen flex items-center justify-center overflow-hidden bg-[#030712]">
|
||||
<section id="home" className="relative min-h-screen flex items-center justify-center overflow-hidden bg-[#030712] pt-28 md:pt-20">
|
||||
{/* 1. Background Engineering: Grid Pattern & Radial Shading */}
|
||||
<div className="absolute inset-0 z-0">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(to_right,#1f2937_1px,transparent_1px),linear-gradient(to_bottom,#1f2937_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_0%,#000_70%,transparent_100%)] opacity-20" />
|
||||
@@ -79,11 +79,17 @@ export default function Hero() {
|
||||
|
||||
<div className="flex gap-4 px-4">
|
||||
{[
|
||||
{ icon: Github, link: "https://github.com/evandrodevbr" },
|
||||
{ icon: Linkedin, link: "https://linkedin.com/..." },
|
||||
{ icon: Mail, link: "mailto:..." }
|
||||
{ icon: Github, link: "https://github.com/evandrodevbr", rel: "me" },
|
||||
{ icon: Linkedin, link: "https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/", rel: "me" },
|
||||
{ icon: Mail, link: "mailto:[email protected]" }
|
||||
].map((social, i) => (
|
||||
<a key={i} href={social.link} className="p-3 rounded-lg border border-slate-800 text-slate-400 hover:text-white hover:border-slate-600 transition-all">
|
||||
<a
|
||||
key={i}
|
||||
href={social.link}
|
||||
rel={social.rel ? `${social.rel} noopener noreferrer` : "noopener noreferrer"}
|
||||
target={social.link.startsWith("mailto:") ? undefined : "_blank"}
|
||||
className="p-3 rounded-lg border border-slate-800 text-slate-400 hover:text-white hover:border-slate-600 transition-all"
|
||||
>
|
||||
<social.icon className="w-5 h-5" />
|
||||
</a>
|
||||
))}
|
||||
@@ -118,13 +124,14 @@ export default function Hero() {
|
||||
fill
|
||||
className="object-cover grayscale hover:grayscale-0 transition-all duration-700 scale-105 hover:scale-100"
|
||||
priority
|
||||
fetchPriority="high"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Floating Stats Badge */}
|
||||
<div className="absolute -bottom-6 -right-6 bg-slate-900 border border-slate-800 p-4 rounded-2xl shadow-2xl z-20 backdrop-blur-xl">
|
||||
<p className="text-xs text-slate-500 uppercase font-bold tracking-tighter">Exp. Level</p>
|
||||
<p className="text-xl font-mono text-blue-400">Senior Dev</p>
|
||||
<p className="text-xl font-mono text-blue-400">Mid-Level Engineer</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
@@ -24,6 +24,23 @@ const CATEGORY_THEMES: Record<string, any> = {
|
||||
desktop: { color: "text-emerald-400", bg: "bg-emerald-500/10", border: "border-emerald-500/20", icon: Terminal },
|
||||
};
|
||||
|
||||
// Funções auxiliares para Schema
|
||||
function getApplicationCategory(category: string): string {
|
||||
const map: Record<string, string> = {
|
||||
"full-stack": "WebApplication",
|
||||
"iot": "DesktopApplication",
|
||||
"api": "WebApplication",
|
||||
"web": "WebApplication",
|
||||
"desktop": "DesktopApplication"
|
||||
};
|
||||
return map[category.toLowerCase()] || "WebApplication";
|
||||
}
|
||||
|
||||
function getOperatingSystem(category: string): string {
|
||||
if (category.toLowerCase() === "desktop") return "Windows, Linux";
|
||||
return "Web Browser";
|
||||
}
|
||||
|
||||
export default function Projects() {
|
||||
const { data, loading, error } = usePortfolioData();
|
||||
|
||||
@@ -31,6 +48,38 @@ export default function Projects() {
|
||||
data?.projects.filter((p) => p.featured) || [],
|
||||
[data]);
|
||||
|
||||
const projectsJsonLd = useMemo(() => {
|
||||
if (!projects || projects.length === 0) return null;
|
||||
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "ItemList",
|
||||
"itemListElement": projects.map((project, index) => ({
|
||||
"@type": "ListItem",
|
||||
"position": index + 1,
|
||||
"item": {
|
||||
"@type": "SoftwareApplication",
|
||||
"name": project.title,
|
||||
"description": project.description,
|
||||
"applicationCategory": getApplicationCategory(project.category),
|
||||
"operatingSystem": getOperatingSystem(project.category),
|
||||
"url": project.demoUrl || project.githubUrl || `https://evandro.dev.br/#projects`,
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"price": "0",
|
||||
"priceCurrency": "BRL"
|
||||
},
|
||||
"softwareVersion": "1.0.0",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Evandro Fonseca Junior",
|
||||
"url": "https://evandro.dev.br"
|
||||
}
|
||||
}
|
||||
}))
|
||||
};
|
||||
}, [projects]);
|
||||
|
||||
if (loading) return <div className="py-20 text-center animate-pulse text-slate-500 font-mono">Loading_Assets...</div>;
|
||||
if (error) return <div className="py-20 text-center text-red-500">System_Error: Failed to sync projects.</div>;
|
||||
|
||||
@@ -118,6 +167,14 @@ export default function Projects() {
|
||||
);
|
||||
})}
|
||||
</BentoGrid>
|
||||
|
||||
{/* JSON-LD Schema for Projects */}
|
||||
{projectsJsonLd && (
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(projectsJsonLd) }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024">
|
||||
<defs>
|
||||
<image width="978" height="981" id="img1" href="data:image/png;base64,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 truncated
|
||||
</defs>
|
||||
<style>
|
||||
</style>
|
||||
<use id="Background" href="#img1" x="13" y="21"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 383 KiB |
+133
-28
@@ -1,4 +1,4 @@
|
||||
import type { Metadata } from "next";
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import Script from "next/script";
|
||||
// Importação necessária para corrigir o erro de namespace e tipagem do children
|
||||
@@ -8,27 +8,36 @@ import "./globals.css";
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
adjustFontFallback: true,
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
adjustFontFallback: true,
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Evandro Fonseca Junior - Desenvolvedor Full-Stack",
|
||||
title: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
|
||||
description:
|
||||
"Desenvolvedor Full-Stack especializado em soluções web modernas com Angular, React, Node.js e computação em nuvem. Experiência em energia renovável e IoT.",
|
||||
"Engenheiro Full-Stack especializado em Next.js, React, Angular, Node.js e Tauri. Desenvolvedor de sistemas web escaláveis, aplicações desktop e automação. Experiência em PostgreSQL, MySQL, computação em nuvem e IoT.",
|
||||
keywords: [
|
||||
"desenvolvedor",
|
||||
"full-stack",
|
||||
"angular",
|
||||
"react",
|
||||
"node.js",
|
||||
"typescript",
|
||||
"engenheiro full-stack",
|
||||
"Next.js specialist",
|
||||
"React developer",
|
||||
"Tauri developer",
|
||||
"Angular",
|
||||
"Node.js",
|
||||
"TypeScript",
|
||||
"PostgreSQL",
|
||||
"MySQL",
|
||||
"computação em nuvem",
|
||||
"iot",
|
||||
"energia renovável",
|
||||
"IoT",
|
||||
"automação",
|
||||
"arquitetura de software",
|
||||
"sistemas escaláveis",
|
||||
],
|
||||
authors: [{ name: "Evandro Fonseca Junior" }],
|
||||
creator: "Evandro Fonseca Junior",
|
||||
@@ -38,25 +47,34 @@ export const metadata: Metadata = {
|
||||
address: false,
|
||||
telephone: false,
|
||||
},
|
||||
metadataBase: new URL("https://evandrofonsecajunior.dev"),
|
||||
metadataBase: new URL("https://evandro.dev.br"),
|
||||
alternates: {
|
||||
canonical: "/",
|
||||
},
|
||||
openGraph: {
|
||||
title: "Evandro Fonseca Junior - Desenvolvedor Full-Stack",
|
||||
title: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
|
||||
description:
|
||||
"Desenvolvedor Full-Stack especializado em soluções web modernas com Angular, React, Node.js e computação em nuvem.",
|
||||
url: "https://evandrofonsecajunior.dev",
|
||||
"Engenheiro Full-Stack especializado em Next.js, React, Angular, Node.js e Tauri. Desenvolvedor de sistemas web escaláveis e aplicações desktop.",
|
||||
url: "https://evandro.dev.br",
|
||||
siteName: "Evandro Fonseca Junior",
|
||||
locale: "pt_BR",
|
||||
type: "website",
|
||||
images: [
|
||||
{
|
||||
url: "/opengraph-image",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Evandro Fonseca Junior - Desenvolvedor Full-Stack",
|
||||
title: "Evandro Fonseca Junior - Engenheiro Full-Stack | Next.js, React, Tauri Specialist",
|
||||
description:
|
||||
"Desenvolvedor Full-Stack especializado em soluções web modernas com Angular, React, Node.js e computação em nuvem.",
|
||||
"Engenheiro Full-Stack especializado em Next.js, React, Angular, Node.js e Tauri. Desenvolvedor de sistemas web escaláveis e aplicações desktop.",
|
||||
creator: "@evandrodevbr",
|
||||
images: ["/opengraph-image"],
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
@@ -71,12 +89,56 @@ export const metadata: Metadata = {
|
||||
},
|
||||
};
|
||||
|
||||
export const viewport: Viewport = {
|
||||
themeColor: "#000000",
|
||||
width: "device-width",
|
||||
initialScale: 1,
|
||||
maximumScale: 5,
|
||||
};
|
||||
|
||||
// Interface tipada corretamente
|
||||
interface RootLayoutProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "ProfilePage",
|
||||
"mainEntity": {
|
||||
"@type": "Person",
|
||||
"name": "Evandro Fonseca Junior",
|
||||
"alternateName": "Evandro.dev",
|
||||
"jobTitle": "Engenheiro de Software Full-Stack",
|
||||
"url": "https://evandro.dev.br",
|
||||
"sameAs": [
|
||||
"https://github.com/evandrodevbr",
|
||||
"https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/",
|
||||
],
|
||||
"knowsAbout": [
|
||||
"Software Engineering",
|
||||
"Next.js",
|
||||
"React",
|
||||
"Angular",
|
||||
"Node.js",
|
||||
"TypeScript",
|
||||
"Tauri",
|
||||
"System Architecture",
|
||||
"Cloud Computing",
|
||||
"IoT",
|
||||
"Automation",
|
||||
"PostgreSQL",
|
||||
"MySQL",
|
||||
],
|
||||
"worksFor": {
|
||||
"@type": "Organization",
|
||||
"name": "Freelancer / Consultor Independente",
|
||||
},
|
||||
"description":
|
||||
"Engenheiro de software especializado em arquitetura web moderna, automação e sistemas de alta performance. Experiência em Next.js, React, Angular, Node.js e desenvolvimento de aplicações desktop com Tauri.",
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
@@ -98,16 +160,10 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
|
||||
<link rel="dns-prefetch" href="//www.linkedin.com" />
|
||||
<link rel="dns-prefetch" href="//github.com" />
|
||||
|
||||
{/* Favicon and icons */}
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
{/* SEO and Crawling */}
|
||||
<link rel="canonical" href="https://evandrofonsecajunior.dev" />
|
||||
<link rel="canonical" href="https://evandro.dev.br" />
|
||||
|
||||
{/* Theme color for mobile browsers */}
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="msapplication-TileColor" content="#000000" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta
|
||||
@@ -118,14 +174,14 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
|
||||
|
||||
{/* Performance hints */}
|
||||
<link rel="preload" href="/edev.jpeg" as="image" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=5"
|
||||
/>
|
||||
</head>
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
{children}
|
||||
<Script
|
||||
src="/analytics/api/script.js"
|
||||
@@ -135,6 +191,55 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
|
||||
data-replay-block-class="rr-block"
|
||||
data-replay-ignore-class="rr-ignore"
|
||||
strategy="afterInteractive"
|
||||
data-session-replay="true"
|
||||
data-track-errors="true"
|
||||
/>
|
||||
{/* Google Analytics - Interceptor para bypass de adblocker */}
|
||||
<Script
|
||||
id="google-analytics-proxy-interceptor"
|
||||
strategy="beforeInteractive"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
(function() {
|
||||
// Interceptar fetch
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(url, options) {
|
||||
if (typeof url === 'string' && url.includes('google-analytics.com')) {
|
||||
url = url.replace('https://www.google-analytics.com', '/ga');
|
||||
}
|
||||
return originalFetch.call(this, url, options);
|
||||
};
|
||||
|
||||
// Interceptar XMLHttpRequest
|
||||
const originalOpen = XMLHttpRequest.prototype.open;
|
||||
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
||||
if (typeof url === 'string' && url.includes('google-analytics.com')) {
|
||||
url = url.replace('https://www.google-analytics.com', '/ga');
|
||||
}
|
||||
return originalOpen.call(this, method, url, ...rest);
|
||||
};
|
||||
})();
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
{/* Google Analytics - Script principal via proxy */}
|
||||
<Script
|
||||
src="/gtm/js/G-QTT9QT0T3S"
|
||||
strategy="afterInteractive"
|
||||
async
|
||||
/>
|
||||
{/* Google Analytics - Inicialização */}
|
||||
<Script
|
||||
id="google-analytics-init"
|
||||
strategy="afterInteractive"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-QTT9QT0T3S');
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { MetadataRoute } from 'next'
|
||||
|
||||
export default function manifest(): MetadataRoute.Manifest {
|
||||
return {
|
||||
name: 'Evandro Fonseca Junior - Portfólio',
|
||||
short_name: 'Evandro.dev',
|
||||
description: 'Portfólio profissional de Evandro Fonseca Junior, Desenvolvedor Full-Stack',
|
||||
start_url: '/',
|
||||
display: 'standalone',
|
||||
background_color: '#000000',
|
||||
theme_color: '#000000',
|
||||
orientation: 'portrait-primary',
|
||||
categories: ['portfolio', 'developer', 'technology'],
|
||||
lang: 'pt-BR',
|
||||
dir: 'ltr',
|
||||
icons: [
|
||||
{
|
||||
src: '/favicon.ico',
|
||||
sizes: 'any',
|
||||
type: 'image/x-icon',
|
||||
},
|
||||
{
|
||||
src: '/icon.svg',
|
||||
sizes: 'any',
|
||||
type: 'image/svg+xml',
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import Link from "next/link";
|
||||
import { Home, ArrowLeft, Code2 } from "lucide-react";
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#030712] flex items-center justify-center px-6">
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<div className="mb-8">
|
||||
<Code2 className="w-24 h-24 text-blue-500 mx-auto mb-4 opacity-50" />
|
||||
<h1 className="text-6xl md:text-8xl font-black text-white mb-4">404</h1>
|
||||
<h2 className="text-2xl md:text-3xl font-bold text-slate-400 mb-4">
|
||||
Página não encontrada
|
||||
</h2>
|
||||
<p className="text-slate-500 mb-8">
|
||||
A página que você está procurando não existe ou foi movida.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="px-6 py-3 bg-blue-600 hover:bg-blue-500 text-white rounded-lg font-semibold transition-all flex items-center justify-center gap-2"
|
||||
>
|
||||
<Home className="w-5 h-5" />
|
||||
Voltar para Home
|
||||
</Link>
|
||||
<Link
|
||||
href="/#projects"
|
||||
className="px-6 py-3 border border-slate-800 hover:border-slate-600 text-slate-400 hover:text-white rounded-lg font-semibold transition-all flex items-center justify-center gap-2"
|
||||
>
|
||||
<ArrowLeft className="w-5 h-5" />
|
||||
Ver Projetos
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { ImageResponse } from 'next/og'
|
||||
|
||||
export const runtime = 'edge'
|
||||
export const alt = 'Evandro Fonseca Junior - Full Stack Developer'
|
||||
export const size = {
|
||||
width: 1200,
|
||||
height: 630,
|
||||
}
|
||||
export const contentType = 'image/png'
|
||||
|
||||
export default async function Image() {
|
||||
return new ImageResponse(
|
||||
(
|
||||
<div
|
||||
style={{
|
||||
background: '#030712',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: 'white',
|
||||
fontFamily: 'system-ui',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 64,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 20,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
Evandro Fonseca Junior
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 32,
|
||||
color: '#3b82f6',
|
||||
marginTop: 10,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
Desenvolvedor Full-Stack
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
{ ...size }
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { MetadataRoute } from 'next'
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
return {
|
||||
rules: [
|
||||
{
|
||||
userAgent: '*',
|
||||
allow: '/',
|
||||
disallow: ['/api/', '/_next/', '/admin/'],
|
||||
},
|
||||
],
|
||||
sitemap: 'https://evandro.dev.br/sitemap.xml',
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { MetadataRoute } from 'next'
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const baseUrl = 'https://evandro.dev.br'
|
||||
const currentDate = new Date().toISOString()
|
||||
|
||||
return [
|
||||
{
|
||||
url: baseUrl,
|
||||
lastModified: currentDate,
|
||||
changeFrequency: 'monthly',
|
||||
priority: 1.0,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#about`,
|
||||
lastModified: currentDate,
|
||||
changeFrequency: 'monthly',
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#skills`,
|
||||
lastModified: currentDate,
|
||||
changeFrequency: 'monthly',
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#experience`,
|
||||
lastModified: currentDate,
|
||||
changeFrequency: 'monthly',
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#projects`,
|
||||
lastModified: currentDate,
|
||||
changeFrequency: 'monthly',
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#contact`,
|
||||
lastModified: currentDate,
|
||||
changeFrequency: 'monthly',
|
||||
priority: 0.8,
|
||||
},
|
||||
]
|
||||
}
|
||||
+45
-15
@@ -18,23 +18,37 @@ const nextConfig: NextConfig = {
|
||||
async headers(): Promise<
|
||||
Array<{ source: string; headers: Array<{ key: string; value: string }> }>
|
||||
> {
|
||||
const securityHeaders = [
|
||||
{
|
||||
key: "X-Frame-Options",
|
||||
value: "DENY",
|
||||
},
|
||||
{
|
||||
key: "X-Content-Type-Options",
|
||||
value: "nosniff",
|
||||
},
|
||||
{
|
||||
key: "Referrer-Policy",
|
||||
value: "strict-origin-when-cross-origin",
|
||||
},
|
||||
{
|
||||
key: "Permissions-Policy",
|
||||
value: "camera=(), microphone=(), geolocation=()",
|
||||
},
|
||||
];
|
||||
|
||||
// HSTS apenas em produção com HTTPS
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
securityHeaders.push({
|
||||
key: "Strict-Transport-Security",
|
||||
value: "max-age=31536000; includeSubDomains; preload",
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
source: "/(.*)",
|
||||
headers: [
|
||||
{
|
||||
key: "X-Frame-Options",
|
||||
value: "DENY",
|
||||
},
|
||||
{
|
||||
key: "X-Content-Type-Options",
|
||||
value: "nosniff",
|
||||
},
|
||||
{
|
||||
key: "Referrer-Policy",
|
||||
value: "origin-when-cross-origin",
|
||||
},
|
||||
],
|
||||
headers: securityHeaders,
|
||||
},
|
||||
{
|
||||
source: "/static/(.*)",
|
||||
@@ -57,13 +71,29 @@ const nextConfig: NextConfig = {
|
||||
];
|
||||
},
|
||||
|
||||
// Proxy reverso para bypass de adblockers (Rybbit Analytics)
|
||||
// Proxy reverso para bypass de adblockers
|
||||
async rewrites() {
|
||||
return [
|
||||
// Rybbit Analytics
|
||||
{
|
||||
source: "/analytics/:match*",
|
||||
destination: "https://analytics.evandro.dev.br/:match*",
|
||||
},
|
||||
// Google Tag Manager - Script principal
|
||||
{
|
||||
source: "/gtm/js/:id",
|
||||
destination: "https://www.googletagmanager.com/gtag/js?id=:id",
|
||||
},
|
||||
// Google Analytics - Endpoints de coleta
|
||||
{
|
||||
source: "/ga/:match*",
|
||||
destination: "https://www.google-analytics.com/:match*",
|
||||
},
|
||||
// Google Analytics - Endpoint alternativo (g/collect)
|
||||
{
|
||||
source: "/g/:match*",
|
||||
destination: "https://www.google-analytics.com/g/:match*",
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024">
|
||||
<defs>
|
||||
<image width="978" height="981" id="img1" href="data:image/png;base64,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 truncated
|
||||
</defs>
|
||||
<style>
|
||||
</style>
|
||||
<use id="Background" href="#img1" x="13" y="21"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 383 KiB |
@@ -64,7 +64,7 @@
|
||||
"id": "nutriscan",
|
||||
"title": "NutriScan",
|
||||
"subtitle": "Análise Nutricional Inteligente",
|
||||
"description": "Aplicação web PWA para análise nutricional de produtos com integração Open Food Facts, busca por código de barras e modo offline completo.",
|
||||
"description": "PWA Next.js 14 com arquitetura App Router para análise nutricional. Resolve problema de acesso offline a dados nutricionais através de Service Worker e cache estratégico. Integração com Open Food Facts API, busca por código de barras via Web API e armazenamento local com MongoDB para histórico de usuários.",
|
||||
"longDescription": "Plataforma completa de análise nutricional que permite aos usuários escanear códigos de barras e obter informações detalhadas sobre produtos alimentícios, incluindo análise NutriScore, gráficos de nutrientes e sistema de filtros avançados.",
|
||||
"technologies": [
|
||||
"Next.js 14",
|
||||
@@ -98,7 +98,7 @@
|
||||
"id": "twins-lab",
|
||||
"title": "Twins Lab",
|
||||
"subtitle": "Plataforma IoT Industrial",
|
||||
"description": "Sistema IoT para monitoramento e controle de reatores industriais com análise preditiva, streaming de dados em tempo real e dashboards interativos.",
|
||||
"description": "Plataforma IoT Next.js com arquitetura de streaming em tempo real via WebSockets. Resolve problema de latência em monitoramento industrial através de comunicação bidirecional e análise preditiva com OpenRouter AI. Sistema de autenticação NextAuth, controle de dispositivos IoT e dashboards com atualização sub-segundo.",
|
||||
"longDescription": "Plataforma avançada de monitoramento industrial que integra dispositivos IoT, oferece controle em tempo real de reatores, análise preditiva com IA e sistema completo de autenticação para múltiplos usuários.",
|
||||
"technologies": [
|
||||
"Next.js",
|
||||
@@ -133,7 +133,7 @@
|
||||
"id": "reddit-explorer",
|
||||
"title": "Reddit Posts Explorer",
|
||||
"subtitle": "Análise de Conteúdo IA",
|
||||
"description": "Explorador de posts do Reddit focado em Inteligência Artificial com busca, filtros avançados e análise de conteúdo do r/artificial.",
|
||||
"description": "Aplicação Astro.js com arquitetura SSG otimizada para consumo de Reddit API. Resolve problema de rate limiting através de cache estratégico em MongoDB com Mongoose. Sistema de filtragem por data e ordenação, API REST própria e busca em tempo real com otimização de queries.",
|
||||
"longDescription": "Aplicação web que consome a API do Reddit para buscar, filtrar e analisar posts relacionados à Inteligência Artificial, oferecendo interface intuitiva para descoberta de conteúdo relevante.",
|
||||
"technologies": [
|
||||
"Astro.js",
|
||||
@@ -167,7 +167,7 @@
|
||||
"id": "sc-plus",
|
||||
"title": "SC Plus Aquicultura",
|
||||
"subtitle": "Landing Page Institucional",
|
||||
"description": "Landing page moderna para empresa de aquicultura com foco em sustentabilidade, tecnologia e inovação.",
|
||||
"description": "Landing page Next.js 15 com React 19 e Tailwind CSS 4. Arquitetura otimizada para Core Web Vitals com LCP < 2.5s através de code splitting e server-side rendering. SEO técnico implementado com meta tags dinâmicas e structured data.",
|
||||
"longDescription": "Site institucional responsivo desenvolvido com as mais recentes tecnologias web, otimizado para performance e SEO, apresentando os serviços e valores da empresa de aquicultura sustentável.",
|
||||
"technologies": [
|
||||
"Next.js 15",
|
||||
@@ -198,7 +198,7 @@
|
||||
"id": "gcc-installer",
|
||||
"title": "MinGW GCC Installer",
|
||||
"subtitle": "Ferramenta de Desenvolvimento",
|
||||
"description": "Aplicação desktop Python para automação completa de download, instalação e configuração de ambientes de desenvolvimento MinGW no Windows.",
|
||||
"description": "Aplicação desktop Python com Tkinter para automação de setup de ambiente GCC no Windows. Resolve problema de configuração manual complexa através de download assíncrono com threading, verificação de compatibilidade via Win32 API e integração automática com PATH do sistema. Utiliza 7-Zip para extração e Watchdog para monitoramento.",
|
||||
"longDescription": "Ferramenta automatizada que simplifica drasticamente o processo de configuração de ambiente de desenvolvimento GCC no Windows, incluindo verificação de compatibilidade, download automático e integração com o sistema.",
|
||||
"technologies": [
|
||||
"Python",
|
||||
|
||||
Reference in new issue
Block a user