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:
Evandro Fonseca Junior committed 2026-01-20 21:00:50 -03:00
1 parent 3f3fca11ab
commit ad6a76efdd
14 files changed
+467 -57

No files matched your search

+10
View File
@@ -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>
);
+11 -3
View File
@@ -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
View File
@@ -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>
+57
View File
@@ -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>
);