diff --git a/frontend/src/app/(i18n)/[locale]/project/[id]/page.tsx b/frontend/src/app/(i18n)/[locale]/project/[id]/page.tsx index 7484fd7..69827fe 100644 --- a/frontend/src/app/(i18n)/[locale]/project/[id]/page.tsx +++ b/frontend/src/app/(i18n)/[locale]/project/[id]/page.tsx @@ -2,14 +2,30 @@ import { useTranslations } from 'next-intl'; import { useParams } from 'next/navigation'; -import { FaArrowLeft } from 'react-icons/fa6'; +import { FaArrowLeft, FaGithub, FaExternalLinkAlt } from 'react-icons/fa'; import Link from 'next/link'; import Image from 'next/image'; const projectsData = [ - { id: 1, tech: ["Next.js", "Tailwind CSS", "TypeScript", "Framer Motion"], imageUrl: "/project1.jpg", repoUrl: "https://github.com/joaoloureiro/portfolio-app" }, - { id: 2, tech: ["Traefik", "Docker", "Linux", "Homelab"], imageUrl: "/project2.jpg" }, - { id: 3, tech: ["React", "TypeScript", "Styled-Components"], imageUrl: "/project3.jpg", liveUrl: "https://happy.joaoloureiro.dev.br/" } + { + id: 1, + tech: ["Next.js", "React", "TypeScript", "Tailwind CSS", "Node.js", "Express"], + imageUrl: "/Portfolio.png", + repoUrl: "https://github.com/joaonloureiro/portfolio-app", + liveUrl: "https://joaoloureiro.dev.br" + }, + { + id: 2, + tech: ["Docker", "Proxmox", "Traefik", "Gitea", "MariaDB", "RabbitMQ", "Prometheus", "Grafana", "N8N"], + imageUrl: "/ProxmoxServer.png", + }, + { + id: 3, + tech: ["React", "TypeScript", "Styled-Components", "Node.js", "Express", "MariaDB"], + imageUrl: "/Happy.png", + repoUrl: "https://github.com/joaonloureiro/happy-app", + liveUrl: "https://happy.joaoloureiro.dev.br/" + } ]; export default function ProjectPage() { @@ -19,43 +35,93 @@ export default function ProjectPage() { const project = projectsData.find(p => p.id === projectId); if (!project) { - return
Project not found
; - } - - return ( -
-
- + return ( +
+

Project Not Found

+ {t('back_to_projects')} -

{t(`project_${project.id}_title`)}

-
-
- {t(`project_${project.id}_title`)} +
+ ); + } + + // Helper function to safely get the features array from translations + const getProjectFeatures = (id: number): string[] => { + try { + const features = t.raw(`project_${id}_features`); + return Array.isArray(features) ? features : []; + } catch (error) { + return []; + } + }; + + const projectFeatures = getProjectFeatures(project.id); + + return ( +
+
+ + + {t('back_to_projects')} + + +
+
+ {t(`project_${project.id}_title`)} +
+

+ {t(`project_${project.id}_title`)} +

-
-

{t('about_project')}

-

{t(`project_${project.id}_description`)}

-

{t('tech_used')}

-
- {project.tech.map(t => ( - - {t} - - ))} -
-
- {project.liveUrl && ( - - {t('live_link')} - - )} - {project.repoUrl && ( - - {t('repo_link')} - - )} + +
+
+
+

{t('about_project')}

+

{t(`project_${project.id}_details`)}

+ +

{t(`project_${project.id}_features_title`)}

+
    + {projectFeatures.map((feature, index) => ( +
  • $1') }} /> + ))} +
+
+ +
diff --git a/frontend/src/app/components/Header.tsx b/frontend/src/app/components/Header.tsx index 47c1719..2b91c5e 100644 --- a/frontend/src/app/components/Header.tsx +++ b/frontend/src/app/components/Header.tsx @@ -1,37 +1,92 @@ 'use client'; +import { useState, useEffect, useRef } from 'react'; import Link from 'next/link'; import { useTranslations } from 'next-intl'; import { useTheme } from '@/configuration/ThemeContext'; -import { SunIcon, MoonIcon } from '@heroicons/react/24/outline'; // Install @heroicons/react +import { SunIcon, MoonIcon, Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'; import Image from 'next/image'; import LanguageSwitcher from "@/app/components/LanguageSwitcher"; export default function Header() { const t = useTranslations('navigation'); const { theme, toggleTheme } = useTheme(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + const headerRef = useRef(null); + + // Close the menu when a link is clicked + const handleLinkClick = () => { + setIsMenuOpen(false); + }; + + // Effect to handle closing menu on outside click + useEffect(() => { + const handleOutsideClick = (event: MouseEvent) => { + if (isMenuOpen && headerRef.current && !headerRef.current.contains(event.target as Node)) { + setIsMenuOpen(false); + } + }; + + document.addEventListener('mousedown', handleOutsideClick); + return () => { + document.removeEventListener('mousedown', handleOutsideClick); + }; + }, [isMenuOpen]); + + // Prevent background scrolling when the mobile menu is open + useEffect(() => { + if (isMenuOpen) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = 'auto'; + } + }, [isMenuOpen]); return ( -
+
+ + {/* Mobile Menu Panel */} + {isMenuOpen && ( +
+
+ {t('about')} + {t('projects')} + {t('contact')} + +
+ + +
+
+
+ )}
); -} +} \ No newline at end of file diff --git a/frontend/src/app/components/sections/Hero.tsx b/frontend/src/app/components/sections/Hero.tsx index 32ff0a0..49f78bc 100644 --- a/frontend/src/app/components/sections/Hero.tsx +++ b/frontend/src/app/components/sections/Hero.tsx @@ -14,7 +14,7 @@ export default function Hero() {

{t('subtitle')}

- + {t('cta_button')}
diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 99e1bcd..1df2e01 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -83,6 +83,10 @@ h3 { font-size: 1.75rem; } -webkit-animation: wheel 1.5s infinite; } +section[id] { + scroll-margin-top: var(--header-height); +} + @keyframes wheel { to { opacity: 0; diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 981d771..d15c784 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -17,34 +17,58 @@ "hero": { "greeting": "Hello, I'm", "title": "Software Developer & Web Enthusiast", - "sequence_1": "Full-Stack Software Developer", - "sequence_2": ".NET & Cloud Enthusiast", - "sequence_3": "Passionate about Technology", "subtitle": "I build modern, responsive, and user-friendly web applications from front-end to back-end.", "cta_button": "See My Work" }, "about": { "title": "About Me", - "paragraph1": "Driven by a passion for creating elegant solutions to complex problems, my journey in software development began with a deep curiosity for how things work. I thrive on turning ideas into reality through clean, efficient, and scalable code.", - "paragraph2": "I specialize in the JavaScript ecosystem, with a strong focus on technologies like React, Next.js, and Node.js. I'm a lifelong learner, always eager to explore new frameworks and programming paradigms to stay at the forefront of technology.", - "paragraph3": "When I'm not at my keyboard, I enjoy exploring the outdoors, reading about new tech trends, and contributing to open-source projects. I believe the best products are built at the intersection of great technology and human-centric design." + "paragraph1": "I am a Full Stack Developer driven by a passion for building, automating, and scaling robust applications. My journey into technology began with a desire to understand how complex systems work, and it has evolved into a career dedicated to crafting elegant, high-performance solutions.", + "paragraph2": "With a strong foundation in the .NET and JavaScript ecosystems, I specialize in creating modern web applications using technologies like Next.js, React, and Node.js. However, my curiosity extends beyond code. As you can see from my Homelab project, I am deeply engaged with the full development lifecycle, including CI/CD, containerization with Docker, and infrastructure management.", + "paragraph3": "I thrive on challenges and am constantly exploring new technologies, from database administration with MariaDB and Redis to workflow automation with N8N and message queuing with RabbitMQ. This hands-on approach to DevOps and self-hosting allows me to build not just features, but resilient and scalable systems." }, "skills": { - "title": "Minhas Tecnologias", - "backend": "Backend & Linguagens", + "title": "My Tech Stack", + "backend": "Backend & Languages", "frontend": "Frontend", - "databases": "Bancos de Dados & Dados", + "databases": "Databases & Data", "cloud": "Cloud & DevOps" }, "projects": { "title": "Projects I've Built", - "project_1_title": "Portfolio", - "project_1_description": "The very site you are on now! Built with Next.js and Tailwind CSS, statically exported for maximum performance.", - "project_2_title": "Homelab", - "project_2_description": "My personal homelab, running on a Raspberry Pi with Docker and Traefik. I host several services, including this portfolio.", + "project_1_title": "Personal Portfolio", + "project_1_description": "The very site you are on now! A full-stack application built with Next.js, Tailwind CSS, and a Node.js backend to showcase my work and skills.", + "project_1_details": "This portfolio is a full-stack application designed to showcase my skills and projects. It features a modern, decoupled architecture with a Next.js frontend and a Node.js backend. The project is automatically deployed via Gitea Actions, with PM2 managing the processes on the server for zero-downtime restarts.", + "project_1_features_title": "Key Features:", + "project_1_features": [ + "**Internationalization (i18n):** Fully translated in English and Portuguese with `next-intl`.", + "**Responsive Design:** Optimized for all devices using Tailwind CSS.", + "**Interactive UI:** Includes a theme switcher (dark/light mode) and toast notifications.", + "**Robust Backend:** An Express.js server handles contact form submissions securely using Nodemailer." + ], + "project_2_title": "Homelab & DevOps Playground", + "project_2_description": "A self-hosted infrastructure running on Proxmox, showcasing a wide range of DevOps and backend services.", + "project_2_details": "This project is my personal Homelab, a self-hosted cloud environment that serves as a practical playground for exploring DevOps concepts and hosting production-level services. It demonstrates my ability to manage a full-stack ecosystem, from networking and security to CI/CD and automation.", + "project_2_features_title": "Hosted Services & Skills:", + "project_2_features": [ + "**CI/CD & Version Control:** Self-hosted **Gitea** for source code management and continuous integration.", + "**Containerization & Orchestration:** **Docker** for containerizing applications, managed within a **Proxmox** virtualized environment.", + "**Networking & Security:** **Traefik** as a reverse proxy for routing traffic, with **Authelia** for single sign-on (SSO) and **Cloudflare Tunnels** for secure external access.", + "**Databases:** Hosting and management of **MariaDB** and **Redis** for various applications.", + "**Monitoring & Observability:** A full monitoring stack with **Prometheus** for data collection, **Grafana** for visualization, and **Pi-hole** for network-wide ad blocking.", + "**Automation & Messaging:** **N8N** for workflow automation and **RabbitMQ** for message queuing between services.", + "**AI & Machine Learning:** Self-hosted **Ollama** for experimenting with large language models locally." + ], "project_3_title": "Happy", - "project_3_description": "A site to find orphanages to visit. Built with React, TypeScript and Styled-Components.", - "tech_used": "Technologies Used:", + "project_3_description": "A full-stack application to connect people with orphanages, built with React, Node.js, and a self-hosted MariaDB.", + "project_3_details": "Happy is a full-stack web application designed to connect people with orphanages, making it easier to schedule visits. Developed as part of Rocketseat's Next Level Week, this project showcases a complete technology stack, from a modern frontend to a robust backend and database.", + "project_3_features_title": "Core Functionalities:", + "project_3_features": [ + "**Interactive Map:** Users can view registered orphanages on a dynamic Google Map.", + "**Detailed Information:** Each orphanage has a dedicated page with photos and visiting hours.", + "**User Contributions:** A complete form allows users to register new orphanages.", + "**Modern Stack:** Built with **React 18** for a fast, responsive UI and a **Node.js/Express** backend connected to a self-hosted **MariaDB**." + ], + "tech_used": "Technologies Used", "page_link": "See Details", "live_link": "Live Demo", "repo_link": "View Code", @@ -57,18 +81,7 @@ "form_name": "Your Name", "form_email": "Your Email", "form_message": "Your Message", - "submit_button": "Send Message", - "status_sending": "Sending your message...", - "status_success": "Message sent successfully. Thank you!", - "status_error_failed": "Failed to send message. Please try again.", - "status_error_all_fields": "All fields are required.", - "status_error_invalid_email": "Please enter a valid email address.", - "status_error_generic": "An unexpected error occurred. Please try again later.", - "server_unexpected_error": "An unexpected server error occurred. Please try again later.", - "smtp_auth_failed": "Authentication with the mail server failed.", - "smtp_connection_failed": "Could not connect to the mail server.", - "smtp_invalid_recipient": "Invalid recipient email address.", - "smtp_generic_error": "A mail-sending error occurred." + "submit_button": "Send Message" }, "footer": { "copyright": "All rights reserved.", diff --git a/frontend/src/locales/pt.json b/frontend/src/locales/pt.json index 2c9992f..481da3c 100644 --- a/frontend/src/locales/pt.json +++ b/frontend/src/locales/pt.json @@ -17,34 +17,58 @@ "hero": { "greeting": "Olá, eu sou o", "title": "Desenvolvedor de Software & Entusiasta Web", - "sequence_1": "Desenvolvedor de Software Full-Stack", - "sequence_2": "Entusiasta em .NET & Cloud", - "sequence_3": "Apaixonado por Tecnologia", "subtitle": "Eu construo aplicações web modernas, responsivas e fáceis de usar, do front-end ao back-end.", "cta_button": "Veja Meus Projetos" }, "about": { "title": "Sobre Mim", - "paragraph1": "Movido pela paixão de criar soluções elegantes para problemas complexos, minha jornada no desenvolvimento de software começou com uma profunda curiosidade sobre como as coisas funcionam. Adoro transformar ideias em realidade através de código limpo, eficiente e escalável.", - "paragraph2": "Sou especialista no ecossistema JavaScript, com forte foco em tecnologias como React, Next.js e Node.js. Estou em constante aprendizado, sempre ansioso para explorar novos frameworks e paradigmas de programação para me manter na vanguarda da tecnologia.", - "paragraph3": "Quando não estou no meu teclado, gosto de explorar a natureza, ler sobre novas tendências tecnológicas e contribuir para projetos de código aberto. Acredito que os melhores produtos são construídos na interseção de ótima tecnologia e design centrado no ser humano." + "paragraph1": "Sou um Desenvolvedor Full Stack movido pela paixão de construir, automatizar e escalar aplicações robustas. Minha jornada na tecnologia começou com o desejo de entender como sistemas complexos funcionam e evoluiu para uma carreira dedicada a criar soluções elegantes e de alta performance.", + "paragraph2": "Com uma base sólida nos ecossistemas .NET e JavaScript, minha especialidade é a criação de aplicações web modernas utilizando tecnologias como Next.js, React e Node.js. No entanto, minha curiosidade vai além do código. Como você pode ver no meu projeto de Homelab, estou profundamente envolvido com todo o ciclo de vida de desenvolvimento, incluindo CI/CD, conteinerização com Docker e gerenciamento de infraestrutura.", + "paragraph3": "Eu prospero em desafios e estou constantemente explorando novas tecnologias, desde a administração de bancos de dados com MariaDB e Redis até a automação de fluxos de trabalho com N8N e filas de mensagens com RabbitMQ. Essa abordagem prática em DevOps e auto-hospedagem me permite construir não apenas funcionalidades, mas sistemas resilientes e escaláveis." }, "skills": { - "title": "My Tech Stack", - "backend": "Backend & Languages", + "title": "Minhas Tecnologias", + "backend": "Backend & Linguagens", "frontend": "Frontend", - "databases": "Databases & Data", + "databases": "Bancos de Dados & Dados", "cloud": "Cloud & DevOps" }, "projects": { "title": "Projetos que Construí", - "project_1_title": "Portfólio", - "project_1_description": "O próprio site em que você está agora! Construído com Next.js e Tailwind CSS, exportado estaticamente para máxima performance.", - "project_2_title": "Homelab", - "project_2_description": "Meu homelab pessoal, rodando em um Raspberry Pi com Docker e Traefik. Eu hospedo vários serviços, incluindo este portfólio.", + "project_1_title": "Portfólio Pessoal", + "project_1_description": "O próprio site em que você está agora! Uma aplicação full-stack construída com Next.js, Tailwind CSS e um backend Node.js para exibir meu trabalho e habilidades.", + "project_1_details": "Este portfólio é uma aplicação full-stack projetada para mostrar minhas habilidades e projetos. Possui uma arquitetura moderna e desacoplada, com um frontend em Next.js e um backend em Node.js. O projeto é implantado automaticamente via Gitea Actions, com o PM2 gerenciando os processos no servidor para reinicializações sem tempo de inatividade.", + "project_1_features_title": "Principais Características:", + "project_1_features": [ + "**Internacionalização (i18n):** Totalmente traduzido para inglês e português com `next-intl`.", + "**Design Responsivo:** Otimizado para todos os dispositivos usando Tailwind CSS.", + "**UI Interativa:** Inclui um seletor de tema (modo claro/escuro) e notificações para feedback de formulários.", + "**Backend Robusto:** Um servidor Express.js lida com os envios do formulário de contato de forma segura usando o Nodemailer." + ], + "project_2_title": "Homelab & Playground DevOps", + "project_2_description": "Uma infraestrutura auto-hospedada rodando em Proxmox, demonstrando uma vasta gama de serviços de DevOps e backend.", + "project_2_details": "Este projeto é o meu Homelab pessoal, um ambiente de nuvem auto-hospedado que serve como um playground prático para explorar conceitos de DevOps e hospedar serviços de nível de produção. Ele demonstra minha capacidade de gerenciar um ecossistema full-stack, desde redes e segurança até CI/CD e automação.", + "project_2_features_title": "Serviços Hospedados & Habilidades:", + "project_2_features": [ + "**CI/CD & Controle de Versão:** **Gitea** auto-hospedado para gerenciamento de código-fonte e integração contínua.", + "**Conteinerização & Orquestração:** **Docker** para conteinerizar aplicações, gerenciado em um ambiente virtualizado **Proxmox**.", + "**Redes & Segurança:** **Traefik** como proxy reverso para roteamento de tráfego, com **Authelia** para single sign-on (SSO) e **Cloudflare Tunnels** para acesso externo seguro.", + "**Bancos de Dados:** Hospedagem e gerenciamento de **MariaDB** e **Redis** para diversas aplicações.", + "**Monitoramento & Observabilidade:** Uma stack completa de monitoramento com **Prometheus** para coleta de dados, **Grafana** para visualização e **Pi-hole** para bloqueio de anúncios em toda a rede.", + "**Automação & Mensageria:** **N8N** para automação de fluxos de trabalho e **RabbitMQ** para enfileiramento de mensagens entre serviços.", + "**IA & Machine Learning:** **Ollama** auto-hospedado para experimentar com grandes modelos de linguagem localmente." + ], "project_3_title": "Happy", - "project_3_description": "Um site para encontrar orfanatos para visitar. Construído com React, TypeScript e Styled-Components.", - "tech_used": "Tecnologias Utilizadas:", + "project_3_description": "Uma aplicação full-stack para conectar pessoas a orfanatos, construída com React, Node.js e um MariaDB auto-hospedado.", + "project_3_details": "Happy é uma aplicação web full-stack projetada para conectar pessoas a orfanatos, facilitando o agendamento de visitas. Desenvolvido como parte da Next Level Week da Rocketseat, este projeto exibe uma stack de tecnologia completa, desde um frontend moderno até um backend e banco de dados robustos.", + "project_3_features_title": "Funcionalidades Principais:", + "project_3_features": [ + "**Mapa Interativo:** Os usuários podem visualizar orfanatos cadastrados em um mapa dinâmico do Google.", + "**Informações Detalhadas:** Cada orfanato possui uma página dedicada com fotos e horários de visita.", + "**Contribuições de Usuários:** Um formulário completo permite que os usuários cadastrem novos orfanatos.", + "**Stack Moderna:** Construído com **React 18** para uma UI rápida e responsiva, e um backend **Node.js/Express** conectado a um **MariaDB** auto-hospedado." + ], + "tech_used": "Tecnologias Utilizadas", "page_link": "Ver Detalhes", "live_link": "Ver ao Vivo", "repo_link": "Ver Código", @@ -57,18 +81,7 @@ "form_name": "Seu Nome", "form_email": "Seu Email", "form_message": "Sua Mensagem", - "submit_button": "Enviar Mensagem", - "status_sending": "Enviando sua mensagem...", - "status_success": "Mensagem enviada com sucesso. Obrigado!", - "status_error_failed": "Falha ao enviar a mensagem. Por favor, tente novamente.", - "status_error_all_fields": "Todos os campos são obrigatórios.", - "status_error_invalid_email": "Por favor, insira um email válido.", - "status_error_generic": "Ocorreu um erro inesperado. Tente novamente mais tarde.", - "server_unexpected_error": "Ocorreu um erro inesperado no servidor. Por favor, tente novamente mais tarde.", - "smtp_auth_failed": "Falha na autenticação com o servidor de email.", - "smtp_connection_failed": "Não foi possível conectar ao servidor de email.", - "smtp_invalid_recipient": "Endereço de email do destinatário inválido.", - "smtp_generic_error": "Ocorreu um erro ao enviar o email." + "submit_button": "Enviar Mensagem" }, "footer": { "copyright": "Todos os direitos reservados.",