Files
portifolio-evandrodevbr/app/components/ContactForm.tsx
T
¨evandrodevbr¨ 90cf3c73ad feat: set up basic project structure and initial styling
This commit initializes the project with a basic Next.js setup, including:
- Integration of `tailwindcss` and `tw-animate-css` for styling.
- Definition of a comprehensive color palette using CSS variables for both light and dark themes, supporting a theming system.
- Implementation of a custom `aurora` keyframe animation.
- Configuration of global CSS styles for `border` and `body` elements.
- Setup of `next.config.ts` with image optimization, performance enhancements, and security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy).
- Update of `package.json` to include new dependencies for UI components (`class-variance-authority`, `clsx`, `lucide-react`, `motion`, `tailwind-merge`, `tailwindcss-animate`) and development tools (`@biomejs/biome`, `@tailwindcss/postcss`, `tw-animate-css`).
- Refinement of `app/layout.tsx` to include comprehensive metadata for SEO (title, description, keywords, authors, Open Graph, Twitter cards, robots), preconnect/dns-prefetch links for external resources, favicon, manifest, and mobile app meta tags.
- Restructuring of `app/page.tsx` to use dynamic imports for various sections (Hero, About, Skills, Experience, Projects, Contact, WorkModalities) to improve performance, and integration of `Squares` component for background effects.

This foundational commit prepares the application for further development by establishing a robust and performant base.
2025-09-02 22:30:47 -03:00

770 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 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);
};
const generateAdvancedMessage = () => {
if (customMessage) return customMessage;
let message = `Olá Evandro,\n\n`;
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 += `.\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`;
}
message += `\nMeus contatos:\n`;
if (userEmail) {
message += `Email: ${userEmail}\n`;
}
if (userPhone) {
message += `Telefone: ${userPhone}\n`;
}
message += `\nAguardamos seu retorno para discutir os próximos passos.`;
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>
);
}