Files
portifolio-evandrodevbr/app/components/ContactForm.tsx
T
¨evandrodevbr¨ 780fd7c161 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.
2025-09-03 00:51:29 -03:00

798 lines
29 KiB
TypeScript

"use client";
import { useState, ChangeEvent, FormEvent, useEffect } from "react";
import { usePortfolioData } from "@/lib/usePortfolioData";
import { motion } from "motion/react";
interface ContactFormProps {
formType: "simple" | "advanced";
setFormType: (type: "simple" | "advanced") => void;
}
export function ContactForm({ formType, setFormType }: ContactFormProps) {
const { data } = usePortfolioData();
const [contactMethod, setContactMethod] = useState<"whatsapp" | "email">(
"whatsapp"
);
const [userName, setUserName] = useState<string>("");
const [userEmail, setUserEmail] = useState<string>("");
const [userPhone, setUserPhone] = useState<string>("");
const [userCompany, setUserCompany] = useState<string>("");
const [howFound, setHowFound] = useState<string>("");
const [projectType, setProjectType] = useState<string>("");
const [otherProjectType, setOtherProjectType] = useState<string>(""); // Novo estado para "Outro" tipo de projeto
const [desiredDeadline, setDesiredDeadline] = useState<string>("");
const [budgetValue, setBudgetValue] = useState<string>(""); // Novo estado para o valor do orçamento
const [technicalComplexity, setTechnicalComplexity] = useState<string>("");
const [hasInternalTeam, setHasInternalTeam] = useState<string>("");
const [customMessage, setCustomMessage] = useState<string>("");
const [isDecisor, setIsDecisor] = useState<string>("");
const [projectApproved, setProjectApproved] = useState<string>("");
const [urgency, setUrgency] = useState<string>("");
const [preferredModality, setPreferredModality] = useState<string>("");
const [isExpanded, setIsExpanded] = useState<boolean>(false); // Novo estado para controlar a expansão do formulário avançado
const [nameError, setNameError] = useState<string | null>(null);
const [emailError, setEmailError] = useState<string | null>(null);
const [phoneError, setPhoneError] = useState<string | null>(null);
const [otherProjectTypeError, setOtherProjectTypeError] = useState<
string | null
>(null); // Novo estado de erro
const [honeypot, setHoneypot] = useState<string>(""); // Estado para o campo honeypot
const [startTime, setStartTime] = useState<number>(0); // Estado para o tempo de início do formulário
const [nameFocused, setNameFocused] = useState<boolean>(false);
const [emailFocused, setEmailFocused] = useState<boolean>(false);
const [phoneFocused, setPhoneFocused] = useState<boolean>(false);
useEffect(() => {
setStartTime(Date.now()); // Registra o tempo de carregamento do componente
}, []);
if (!data) {
return null; // Ou um componente de carregamento/erro
}
const getGreetingMessageWithUserName = () => {
const hour = new Date().getHours();
const dayPart =
hour >= 8 && hour < 12
? "manhã"
: hour >= 12 && hour < 18
? "tarde"
: "noite";
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;
// Saudação profissional
let message = `Prezado Evandro,\n\n`;
// Informações do contato
message += `Meu nome é ${userName}`;
if (userCompany) {
message += `, represento a empresa ${userCompany}`;
}
message += `.\n`;
if (howFound) {
message += `Conheci seu trabalho através de ${howFound}.\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`;
}
if (userPhone) {
message += `📱 Telefone/WhatsApp: ${userPhone}\n`;
}
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;
};
const handleNameChange = (e: ChangeEvent<HTMLInputElement>) => {
setUserName(e.target.value);
if (e.target.value.trim() !== "") setNameError(null);
};
const handleEmailChange = (e: ChangeEvent<HTMLInputElement>) => {
setUserEmail(e.target.value);
if (e.target.value.trim() !== "") setEmailError(null);
};
const handlePhoneChange = (e: ChangeEvent<HTMLInputElement>) => {
setUserPhone(e.target.value);
if (e.target.value.trim() !== "") setPhoneError(null);
};
const handleNameFocus = () => setNameFocused(true);
const handleEmailFocus = () => setEmailFocused(true);
const handlePhoneFocus = () => setPhoneFocused(true);
const handleCompanyChange = (e: ChangeEvent<HTMLInputElement>) => {
setUserCompany(e.target.value);
};
const handleHowFoundChange = (e: ChangeEvent<HTMLSelectElement>) => {
setHowFound(e.target.value);
};
const handleProjectTypeChange = (e: ChangeEvent<HTMLSelectElement>) => {
setProjectType(e.target.value);
};
const handleDesiredDeadlineChange = (e: ChangeEvent<HTMLSelectElement>) => {
setDesiredDeadline(e.target.value);
};
const handleBudgetValueChange = (e: ChangeEvent<HTMLInputElement>) => {
setBudgetValue(e.target.value);
};
const handleTechnicalComplexityChange = (
e: ChangeEvent<HTMLSelectElement>
) => {
setTechnicalComplexity(e.target.value);
};
const handleHasInternalTeamChange = (e: ChangeEvent<HTMLSelectElement>) => {
setHasInternalTeam(e.target.value);
};
const handleMessageChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setCustomMessage(e.target.value);
};
const generateWhatsAppUrl = () => {
const message = encodeURIComponent(
formType === "advanced"
? generateAdvancedMessage()
: customMessage || getGreetingMessageWithUserName()
);
const phone = data.contact.whatsapp.replace(/\D/g, ""); // Remove caracteres não numéricos
return `https://wa.me/${phone}?text=${message}`;
};
const generateEmailUrl = () => {
const subject = encodeURIComponent("Proposta de Projeto - Portfólio");
const body = encodeURIComponent(
formType === "advanced"
? generateAdvancedMessage()
: `Nome: ${userName}\nEmail: ${userEmail}\nTelefone: ${userPhone}\nEmpresa/Posição: ${userCompany}\nComo conheceu: ${howFound}\n\nTipo de Projeto: ${projectType}\nPrazo Desejado: ${desiredDeadline}\nOrçamento Disponível: ${budgetValue}\nComplexidade Técnica: ${technicalComplexity}\nTem equipe interna: ${hasInternalTeam}\n\nMensagem: ${
customMessage || getGreetingMessageWithUserName()
}`
);
return `mailto:${data.contact.email}?subject=${subject}&body=${body}`;
};
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
let hasError = false;
if (userName.trim() === "") {
setNameError("Por favor, insira seu nome.");
hasError = true;
} else {
setNameError(null);
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(userEmail)) {
setEmailError("Por favor, insira um email válido.");
hasError = true;
} else {
setEmailError(null);
}
if (userPhone.trim() === "") {
setPhoneError("Por favor, insira seu telefone.");
hasError = true;
} else {
setPhoneError(null);
}
if (projectType === "outro" && otherProjectType.trim() === "") {
setOtherProjectTypeError("Por favor, especifique o tipo de projeto.");
hasError = true;
} else {
setOtherProjectTypeError(null);
}
// Validação Honeypot
if (honeypot) {
console.log("Honeypot preenchido, provável bot.");
return; // Ignora a submissão
}
// Validação de tempo de preenchimento (mínimo de 3 segundos)
const timeElapsed = Date.now() - startTime;
if (timeElapsed < 3000) {
console.log("Formulário preenchido muito rápido, provável bot.");
return; // Ignora a submissão
}
if (hasError) return;
// Verificação de interação mínima
if (!nameFocused || !emailFocused || !phoneFocused) {
console.log("Campos principais não foram focados, provável bot.");
// Opcional: exibir uma mensagem de erro para o usuário
return;
}
if (contactMethod === "whatsapp") {
window.open(generateWhatsAppUrl(), "_blank");
} else {
window.open(generateEmailUrl(), "_blank");
}
};
const getCtaMessage = () => {
if (projectType === "consultoria") {
return "Agendar Consultoria Gratuita";
}
if (budgetValue && parseFloat(budgetValue.replace(/\D/g, "")) < 2000) {
return "Discutir Soluções de Baixo Custo";
}
if (projectType && desiredDeadline && budgetValue) {
return "Receber Proposta Personalizada";
}
return "Enviar Formulário";
};
const getEstimatedValue = () => {
let value = 0;
// Lógica de estimativa baseada nas respostas
switch (projectType) {
case "web-app":
value += 10000;
break;
case "landing-page":
value += 2000;
break;
case "mvp":
value += 5000;
break;
case "iot-app":
value += 15000;
break;
case "integracao":
value += 7000;
break;
case "manutencao":
value += 1000;
break;
case "consultoria":
value += 500;
break;
default:
break;
}
switch (desiredDeadline) {
case "1-3-weeks":
value *= 1.2; // Urgência aumenta o valor
break;
case "1-2-months":
value *= 1.1;
break;
case "6-plus-months":
value *= 0.9; // Prazo longo pode reduzir o valor
break;
default:
break;
}
switch (technicalComplexity) {
case "alta":
value *= 1.3;
break;
case "muito-alta":
value *= 1.5;
break;
default:
break;
}
if (hasInternalTeam === "nao") {
value *= 1.1; // Sem equipe interna pode indicar mais trabalho
}
// Ajustar pelo valor do orçamento, se aplicável
if (budgetValue) {
const parsedBudget = parseFloat(budgetValue.replace(/\D/g, ""));
if (!isNaN(parsedBudget)) {
// Se o valor estimado for maior que o orçamento fornecido, ajusta para o orçamento
value = Math.min(value, parsedBudget);
}
}
return value > 0 ? `Estimativa: R$ ${value.toFixed(2)}` : "Estimativa: N/A";
};
return (
<motion.div
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.8, delay: 0.4 }}
viewport={{ once: true }}
className="space-y-4"
>
<h3 className="text-2xl font-semibold mb-6 text-blue-primary">
Preencha o Formulário
</h3>
<div className="flex justify-center gap-4 mb-8">
<button
type="button"
onClick={() => setFormType("simple")}
className={`py-2 px-4 rounded-lg font-semibold transition-all duration-300 ${
formType === "simple"
? "bg-blue-primary text-white shadow-lg shadow-blue-primary/25 border-2 border-blue-500"
: "bg-gray-700 text-gray-300 opacity-50 cursor-pointer"
}`}
>
Formulário Simples
</button>
<button
type="button"
onClick={() => setFormType("advanced")}
className={`py-2 px-4 rounded-lg font-semibold transition-all duration-300 ${
formType === "advanced"
? "bg-blue-primary text-white shadow-lg shadow-blue-primary/25 border-2 border-blue-500"
: "bg-gray-700 text-gray-300 opacity-50 cursor-pointer"
}`}
>
Formulário Avançado
</button>
</div>
{formType === "simple" ? (
<form onSubmit={handleSubmit} className="space-y-6">
{/* Campo Honeypot */}
<div style={{ display: "none" }}>
<label htmlFor="honeypot">Não preencha este campo</label>
<input
type="text"
id="honeypot"
name="honeypot"
value={honeypot}
onChange={(e) => setHoneypot(e.target.value)}
/>
</div>
{/* Formulário Simples: Apenas Nome */}
<div>
<label
htmlFor="simple-user-name"
className="block text-sm font-medium text-gray-300 mb-2"
>
Seu Nome:
</label>
<input
type="text"
id="simple-user-name"
className={`w-full p-3 rounded-lg bg-white/5 border ${
nameError ? "border-red-500" : "border-white/10"
} text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent`}
placeholder="Seu nome"
value={userName}
onChange={handleNameChange}
onFocus={handleNameFocus}
required
/>
{nameError && (
<p className="text-red-400 text-xs mt-1">{nameError}</p>
)}
</div>
{/* Botão de Contato para o formulário simples */}
<motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
<button
type="submit"
className="w-full py-4 px-6 rounded-lg font-semibold text-lg transition-all duration-300 bg-green-600 hover:bg-green-700 text-white shadow-lg shadow-green-600/25"
onClick={() => window.open(generateWhatsAppUrl(), "_blank")}
>
Enviar Mensagem via WhatsApp
</button>
</motion.div>
</form>
) : (
<form onSubmit={handleSubmit} className="space-y-6">
{/* Campo Honeypot */}
<div style={{ display: "none" }}>
<label htmlFor="honeypot">Não preencha este campo</label>
<input
type="text"
id="honeypot"
name="honeypot"
value={honeypot}
onChange={(e) => setHoneypot(e.target.value)}
/>
</div>
{/* Dados Básicos */}
<div>
<h4 className="text-xl font-semibold mb-4 text-gray-200">
Dados Básicos
</h4>
<div className="space-y-4">
<div>
<label
htmlFor="user-name"
className="block text-sm font-medium text-gray-300 mb-2"
>
Nome Completo:
</label>
<input
type="text"
id="user-name"
className={`w-full p-3 rounded-lg bg-white/5 border ${
nameError ? "border-red-500" : "border-white/10"
} text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent`}
placeholder="Seu nome completo"
value={userName}
onChange={handleNameChange}
onFocus={handleNameFocus}
required
/>
{nameError && (
<p className="text-red-400 text-xs mt-1">{nameError}</p>
)}
</div>
<div>
<label
htmlFor="user-email"
className="block text-sm font-medium text-gray-300 mb-2"
>
Email Corporativo:
</label>
<input
type="email"
id="user-email"
className={`w-full p-3 rounded-lg bg-white/5 border ${
emailError ? "border-red-500" : "border-white/10"
} text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent`}
placeholder="[email protected]"
value={userEmail}
onChange={handleEmailChange}
onFocus={handleEmailFocus}
required
/>
{emailError && (
<p className="text-red-400 text-xs mt-1">{emailError}</p>
)}
</div>
<div>
<label
htmlFor="user-phone"
className="block text-sm font-medium text-gray-300 mb-2"
>
WhatsApp/Telefone:
</label>
<input
type="tel"
id="user-phone"
className={`w-full p-3 rounded-lg bg-white/5 border ${
phoneError ? "border-red-500" : "border-white/10"
} text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent`}
placeholder="(XX) XXXXX-XXXX"
value={userPhone}
onChange={handlePhoneChange}
onFocus={handlePhoneFocus}
required
/>
{phoneError && (
<p className="text-red-400 text-xs mt-1">{phoneError}</p>
)}
</div>
<div>
<label
htmlFor="user-company"
className="block text-sm font-medium text-gray-300 mb-2"
>
Empresa/Posição:
</label>
<input
type="text"
id="user-company"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent"
placeholder="Nome da empresa, sua posição"
value={userCompany}
onChange={handleCompanyChange}
/>
</div>
<div>
<label
htmlFor="how-found"
className="block text-sm font-medium text-gray-300 mb-2"
>
Como conheceu meu trabalho?
</label>
<select
id="how-found"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white focus:ring-2 focus:ring-blue-primary focus:border-transparent"
value={howFound}
onChange={handleHowFoundChange}
>
<option value="">Selecione uma opção</option>
<option value="linkedin">LinkedIn</option>
<option value="github">GitHub</option>
<option value="indicacao">Indicação</option>
<option value="pesquisa">Pesquisa Online</option>
<option value="outro">Outro</option>
</select>
</div>
</div>
</div>
{/* Tile de Expandir/Recolher */}
<div
onClick={() => setIsExpanded(!isExpanded)}
className="p-4 rounded-lg bg-white/5 border border-white/10 text-white cursor-pointer hover:bg-white/10 transition-colors duration-300 mb-6 flex justify-between items-center"
>
<h4 className="text-xl font-semibold text-gray-200">
{isExpanded
? "Detalhes do Projeto (Recolher)"
: "Detalhes do Projeto (Expandir)"}
</h4>
<svg
className={`w-6 h-6 transition-transform duration-300 ${
isExpanded ? "rotate-180" : ""
}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M19 9l-7 7-7-7"
></path>
</svg>
</div>
<div
className={`overflow-hidden transition-all duration-500 ease-in-out ${
isExpanded ? "max-h-[1000px] opacity-100" : "max-h-0 opacity-0"
} space-y-6`}
>
{/* Conteúdo do Formulário Avançado */}
{/* Sobre o Projeto */}
<div>
<h4 className="text-xl font-semibold mb-4 text-gray-200">
Sobre o Projeto
</h4>
<div className="space-y-4">
<div>
<label
htmlFor="project-type"
className="block text-sm font-medium text-gray-300 mb-2"
>
Tipo de Projeto:
</label>
<select
id="project-type"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white focus:ring-2 focus:ring-blue-primary focus:border-transparent"
value={projectType}
onChange={handleProjectTypeChange}
>
<option value="">Selecione o tipo</option>
<option value="web-app">Aplicação Web Completa</option>
<option value="landing-page">Landing Page</option>
<option value="mvp">MVP (Produto Mínimo Viável)</option>
<option value="iot-app">Aplicação IoT</option>
<option value="integracao">Integração de Sistemas</option>
<option value="manutencao">Manutenção/Ajustes</option>
<option value="consultoria">Consultoria/Mentoria</option>
<option value="outro">Outro</option>
</select>
</div>
{projectType === "outro" && (
<div>
<label
htmlFor="other-project-type"
className="block text-sm font-medium text-gray-300 mb-2"
>
Qual outro tipo de projeto?
</label>
<input
type="text"
id="other-project-type"
className={`w-full p-3 rounded-lg bg-white/5 border ${
otherProjectTypeError
? "border-red-500"
: "border-white/10"
} text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent`}
placeholder="Ex: Desenvolvimento de Plugin, Automação de Processos"
value={otherProjectType}
onChange={(e) => {
setOtherProjectType(e.target.value);
if (e.target.value.trim() !== "")
setOtherProjectTypeError(null);
}}
required
/>
{otherProjectTypeError && (
<p className="text-red-400 text-xs mt-1">
{otherProjectTypeError}
</p>
)}
</div>
)}
<div>
<label
htmlFor="desired-deadline"
className="block text-sm font-medium text-gray-300 mb-2"
>
Prazo Desejado:
</label>
<select
id="desired-deadline"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white focus:ring-2 focus:ring-blue-primary focus:border-transparent"
value={desiredDeadline}
onChange={handleDesiredDeadlineChange}
>
<option value="">Selecione o prazo</option>
<option value="1-3-weeks">1-3 Semanas</option>
<option value="1-2-months">1-2 Meses</option>
<option value="2-4-months">2-4 Meses</option>
<option value="4-6-months">4-6 Meses</option>
<option value="6-plus-months">Mais de 6 Meses</option>
</select>
</div>
<div>
<label
htmlFor="budget-value"
className="block text-sm font-medium text-gray-300 mb-2"
>
Orçamento Disponível (R$):
</label>
<input
type="text"
id="budget-value"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-primary focus:border-transparent"
placeholder="Ex: 5000, 10000, A Combinar"
value={budgetValue}
onChange={handleBudgetValueChange}
/>
</div>
<div>
<label
htmlFor="technical-complexity"
className="block text-sm font-medium text-gray-300 mb-2"
>
Complexidade Técnica Estimada:
</label>
<select
id="technical-complexity"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white focus:ring-2 focus:ring-blue-primary focus:border-transparent"
value={technicalComplexity}
onChange={handleTechnicalComplexityChange}
>
<option value="">Selecione a complexidade</option>
<option value="baixa">Baixa</option>
<option value="media">Média</option>
<option value="alta">Alta</option>
<option value="muito-alta">Muito Alta</option>
</select>
</div>
<div>
<label
htmlFor="has-internal-team"
className="block text-sm font-medium text-gray-300 mb-2"
>
Já tem equipe técnica interna?
</label>
<select
id="has-internal-team"
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white focus:ring-2 focus:ring-blue-primary focus:border-transparent"
value={hasInternalTeam}
onChange={handleHasInternalTeamChange}
>
<option value="">Selecione</option>
<option value="sim">Sim</option>
<option value="nao">Não</option>
<option value="parcial">Parcialmente</option>
</select>
</div>
</div>
</div>
{/* Custom Message Input */}
<div className="mb-6">
<label
htmlFor="custom-message"
className="block text-sm font-medium text-gray-300 mb-2"
>
Mensagem Adicional (Opcional):
</label>
<textarea
id="custom-message"
rows={4}
className="w-full p-3 rounded-lg bg-white/5 border border-white/10 text-white placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Descreva seu projeto ou suas necessidades aqui..."
value={customMessage}
onChange={handleMessageChange}
></textarea>
</div>
</div>
{/* Contact Button */}
<motion.div whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }}>
<button
type="submit"
className="w-full py-4 px-6 rounded-lg font-semibold text-lg transition-all duration-300 bg-blue-primary hover:bg-blue-primary/90 text-white shadow-lg shadow-blue-primary/25 border-2 border-blue-500"
>
{getCtaMessage()}
</button>
</motion.div>
{projectType && desiredDeadline && budgetValue && (
<p className="text-center text-lg font-semibold text-blue-400 mt-4">
{getEstimatedValue()}
</p>
)}
</form>
)}
</motion.div>
);
}