feat(ui): enhance contact form messaging and particle background animation

- Improved the contact form's message generation with more professional and detailed templates
- Replaced the grid-based background animation with a WebGL-powered particle system using OGL
- Added GSAP for advanced animation capabilities
- Adjusted layout styling for better centering and spacing across components
- Enhanced visual feedback and interactivity of the animated background

This change significantly upgrades the user experience and visual appeal of the contact section while maintaining performance through efficient rendering techniques.
This commit is contained in:
¨evandrodevbr¨ committed 2025-09-03 00:51:29 -03:00
1 parent 90cf3c73ad
commit 780fd7c161
13 files changed
+1230 -203

No files matched your search

+71 -43
View File
@@ -53,67 +53,95 @@ export function ContactForm({ formType, setFormType }: ContactFormProps) {
const getGreetingMessageWithUserName = () => {
const hour = new Date().getHours();
const dayPart =
hour >= 8 && hour < 12
? "manhã"
: hour >= 12 && hour < 18
? "tarde"
: "noite";
const baseMessage = (name: string) => {
if (hour >= 8 && hour < 12) {
// Manhã
return `Bom dia Evandro, meu nome é ${name}. Vi seu portfólio e estou interessado nos seus serviços. Podemos conversar?`;
} else if (hour >= 13 && hour < 18) {
// Tarde
return `Boa tarde Evandro, meu nome é ${name}. Vi seu portfólio e estou interessado nos seus serviços. Podemos conversar?`;
} else {
// Noite
return `Olá Evandro, meu nome é ${name}. Vi seu portfólio e estou interessado nos seus serviços. Podemos conversar quando estiver disponível?`;
}
};
return baseMessage(userName);
return `Olá Evandro, espero que esta ${dayPart} esteja sendo produtiva.
Meu nome é ${userName} e entrei em contato pois vi seu portfólio e identifiquei que suas habilidades como Desenvolvedor Full-Stack podem agregar muito ao projeto que tenho em mente.
Gostaria de agendar uma conversa para discutirmos detalhes e entender como podemos trabalhar juntos de forma eficiente e produtiva.
Fico no aguardo do seu contato para marcarmos um horário que seja conveniente para ambos.
Atenciosamente,
${userName}`;
};
const generateAdvancedMessage = () => {
if (customMessage) return customMessage;
let message = `Olá Evandro,\n\n`;
// Saudação profissional
let message = `Prezado Evandro,\n\n`;
// Informações do contato
message += `Meu nome é ${userName}`;
if (userCompany) {
message += ` e sou de ${userCompany}`;
}
if (howFound) {
message += `. Conheci seu trabalho via ${howFound}`;
}
message += `.\n\n`;
message += `Estou entrando em contato para discutir um projeto de `;
if (projectType === "outro" && otherProjectType) {
message += `${otherProjectType}`;
} else if (projectType) {
message += `${projectType}`;
} else {
message += `[Tipo de Projeto Não Especificado]`;
message += `, represento a empresa ${userCompany}`;
}
message += `.\n`;
if (desiredDeadline) {
message += `O prazo desejado é ${desiredDeadline}.\n`;
}
if (budgetValue) {
message += `O orçamento disponível é ${budgetValue}.\n`;
}
if (technicalComplexity) {
message += `A complexidade técnica estimada é ${technicalComplexity}.\n`;
}
if (hasInternalTeam) {
message += `Já possuímos uma equipe técnica ${hasInternalTeam}.\n`;
if (howFound) {
message += `Conheci seu trabalho através de ${howFound}.\n`;
}
message += `\nMeus contatos:\n`;
message += `\n`;
// Detalhes do projeto
message += `=== DETALHES DO PROJETO ===\n`;
message += `Tipo de projeto: `;
if (projectType === "outro" && otherProjectType) {
message += `${otherProjectType}\n`;
} else if (projectType) {
message += `${projectType}\n`;
} else {
message += `Não especificado\n`;
}
if (desiredDeadline) {
message += `Prazo desejado: ${desiredDeadline}\n`;
}
if (budgetValue) {
message += `Orçamento disponível: ${budgetValue}\n`;
}
if (technicalComplexity) {
message += `Complexidade técnica estimada: ${technicalComplexity}\n`;
}
if (hasInternalTeam) {
message += `Equipe técnica interna: ${
hasInternalTeam === "sim"
? "Sim"
: hasInternalTeam === "nao"
? "Não"
: "Parcialmente"
}\n`;
}
message += `\n`;
// Contatos
message += `=== INFORMAÇÕES PARA CONTATO ===\n`;
if (userEmail) {
message += `Email: ${userEmail}\n`;
message += `📧 Email: ${userEmail}\n`;
}
if (userPhone) {
message += `Telefone: ${userPhone}\n`;
message += `📱 Telefone/WhatsApp: ${userPhone}\n`;
}
message += `\nAguardamos seu retorno para discutir os próximos passos.`;
message += `\n`;
// Mensagem final
message += `Estou entrando em contato pois acredito que seus conhecimentos como Desenvolvedor Full-Stack podem agregar muito ao projeto que tenho em mente.\n\n`;
message += `Fico no aguardo do seu contato para discutirmos detalhes e definirmos os próximos passos.\n\n`;
message += `Atenciosamente,\n`;
message += `${userName}`;
return message;
};
+1 -1
View File
@@ -36,7 +36,7 @@ export default function Experience() {
return (
<section
id="experience"
className="py-20 px-4 bg-gradient-to-b from-transparent to-black/20"
className="py-20 px-4 bg-gradient-to-b from-transparent to-black/20 mx-auto"
>
<div className="max-w-6xl mx-auto">
<motion.div
+2 -2
View File
@@ -86,8 +86,8 @@ export default function Hero() {
className="text-xl md:text-2xl lg:text-3xl text-gray-300 max-w-3xl mx-auto mb-12 leading-relaxed"
>
Especialista em soluções web modernas e inovadoras. Formado em
Engenharia da Computação, com conhecimentos sólidos em computação em
nuvem e inteligência artificial.
Engenharia da Computação, com conhecimentos em computação em nuvem e
inteligência artificial.
</motion.p>
{/* Location */}
+1 -1
View File
@@ -34,7 +34,7 @@ export default function Projects() {
const projects = data.projects.filter((project) => project.featured);
return (
<section id="projects" className="py-20 px-4">
<section id="projects" className="py-20 px-4 mx-auto">
<div className="max-w-6xl mx-auto">
<motion.div
initial={{ opacity: 0, y: 30 }}
+1 -1
View File
@@ -74,7 +74,7 @@ export function WorkModalities() {
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto justify-center">
{WorkModalitiesData.map((modality, index) => (
<motion.div
key={modality.title}