Skip to main content
The Contact Form provides visitors with an easy way to reach out for project inquiries, collaborations, or general questions. It features email integration, real-time validation, and automated responses.

Overview

Located in src/components/ContactSection.tsx, this component offers:
  • Professional contact form with validation
  • Email API integration for message delivery
  • Real-time status feedback (success/error messages)
  • Auto-reply system for sender confirmation
  • Direct email fallback for redundancy
  • Responsive design with attractive layout

User Experience Flow

Sending a Message

  1. Fill Form: User enters name, email, subject, and message
  2. Submit: Click “Enviar Mensagem” button
  3. Loading State: Button shows spinner and “Enviando…” text
  4. Confirmation: Success message appears, form resets
  5. Auto-Reply: User receives confirmation email automatically

Form Fields

  • Name: Full name of the sender
  • Email: Reply-to email address
  • Subject: Brief topic description
  • Message: Detailed message (multi-line)

Form Implementation

State Management

const [formData, setFormData] = useState({
  name: "",
  email: "",
  subject: "",
  message: "",
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle');

Form Structure

<form onSubmit={handleSubmit} className="space-y-4">
  {/* Name field */}
  <div>
    <label htmlFor="name" className="block text-sm font-medium mb-2">
      Nome
    </label>
    <input
      type="text"
      id="name"
      name="name"
      value={formData.name}
      onChange={handleChange}
      required
      className="w-full px-4 py-3 rounded-xl bg-secondary border border-border"
      placeholder="Seu nome"
    />
  </div>
  
  {/* Email, Subject, Message fields... */}
  
  <Button type="submit" disabled={isSubmitting}>
    {isSubmitting ? (
      <><Loader2 className="animate-spin" /> Enviando...</>
    ) : (
      <><Send /> Enviar Mensagem</>
    )}
  </Button>
</form>

API Integration

The form submits to the backend contact endpoint:
const handleSubmit = async (e: React.FormEvent) => {
  e.preventDefault();
  setIsSubmitting(true);
  setSubmitStatus('idle');

  try {
    const response = await fetch('/api/contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        name: formData.name,
        email: formData.email,
        subject: formData.subject,
        message: formData.message,
      }),
    });

    if (response.ok) {
      setSubmitStatus('success');
      setFormData({ name: "", email: "", subject: "", message: "" });
      setTimeout(() => setSubmitStatus('idle'), 5000);
    } else {
      throw new Error('Erro ao enviar mensagem');
    }
  } catch (error) {
    console.error('Erro ao enviar email:', error);
    setSubmitStatus('error');
    setTimeout(() => setSubmitStatus('idle'), 5000);
  } finally {
    setIsSubmitting(false);
  }
};
Status messages automatically disappear after 5 seconds to keep the UI clean and prevent confusion.

Status Feedback

Success Message

{submitStatus === 'success' && (
  <div className="flex items-center gap-2 p-4 rounded-xl bg-green-500/10 border border-green-500/20 text-green-500">
    <CheckCircle className="w-5 h-5" />
    <span>Mensagem enviada com sucesso! Responderei em breve.</span>
  </div>
)}

Error Message

{submitStatus === 'error' && (
  <div className="flex items-center gap-2 p-4 rounded-xl bg-red-500/10 border border-red-500/20 text-red-500">
    <XCircle className="w-5 h-5" />
    <span>Erro ao enviar mensagem. Tente novamente ou use o email direto.</span>
  </div>
)}

Direct Contact Fallback

Below the form, a direct email option is provided:
<div className="p-6 rounded-xl bg-secondary border border-border">
  <div className="flex items-center gap-3 text-muted-foreground">
    <Mail className="w-5 h-5 text-primary" />
    <div>
      <p className="text-sm">Email direto</p>
      <a
        href="mailto:[email protected]"
        className="text-foreground hover:text-primary transition-colors"
      >
        [email protected]
      </a>
    </div>
  </div>
</div>
The direct email option ensures users can always contact you, even if the API is temporarily unavailable.

Two-Column Layout

The section uses a responsive grid layout:
<div className="grid lg:grid-cols-2 gap-12 items-start max-w-5xl mx-auto">
  {/* Left: Contact Form */}
  <ScrollReveal variant="fade-right" delay={100}>
    <div className="space-y-6">
      {/* Form content */}
    </div>
  </ScrollReveal>
  
  {/* Right: Decorative Image */}
  <ScrollReveal variant="fade-left" delay={300}>
    <div className="relative flex justify-center lg:justify-end">
      <div className="relative bg-card rounded-3xl p-8 border border-border">
        <img
          src={memojiThinking}
          alt="Contato"
          className="w-64 h-64 md:w-80 md:h-80 object-contain mx-auto animate-float"
        />
      </div>
    </div>
  </ScrollReveal>
</div>

Visual Effects

The decorative image includes:
  • Glow effect: Gradient blur background
  • Float animation: Gentle up-down motion
  • Card container: Bordered rounded card
  • Scroll animation: Slides in from left with delay

Section Header

<div className="text-center mb-16">
  <span className="section-title">Contato</span>
  <h2 className="heading-md">
    Vamos trabalhar <span className="text-gradient">juntos?</span>
  </h2>
  <p className="text-muted-foreground mt-4 max-w-2xl mx-auto">
    Estou disponível para projetos freelance de desenvolvimento web,
    análise de dados e automação. Entre em contato e vamos transformar
    suas ideias em realidade!
  </p>
</div>

Form Validation

Client-Side Validation

HTML5 validation is used for basic checks:
<input
  type="email"
  required
  placeholder="[email protected]"
/>

Server-Side Validation

The backend API validates:
  • Email format (proper structure)
  • Required fields (none empty)
  • Message length (reasonable limits)
  • Spam detection (rate limiting)
For backend validation details, see the API Reference section.

Email System

When a message is submitted, two emails are sent:

1. Notification Email (to you)

To: [email protected]
Subject: [Portfolio] New Contact: {subject}

Name: {name}
Email: {email}
Subject: {subject}

Message:
{message}

2. Confirmation Email (to sender)

To: {email}
Subject: Mensagem recebida - André Ruperto

Olá {name},

Recebi sua mensagem sobre "{subject}" e responderei em breve.

Obrigado pelo contato!

André Ruperto

Email Templates

Custom HTML email templates are used for professional appearance. Preview them in the Admin Panel.

Responsive Design

Mobile (< 1024px)

  • Stacked layout (form then image)
  • Full-width form fields
  • Smaller decorative image
  • Maintained padding

Desktop (≥ 1024px)

  • Two-column grid
  • Form on left, image on right
  • Larger decorative image
  • Generous spacing

Accessibility Features

  • Semantic HTML: Proper label-input associations
  • ARIA labels: Clear button descriptions
  • Keyboard navigation: Full tab support
  • Focus indicators: Visible focus states
  • Error messages: Descriptive feedback
  • Loading states: Disabled state during submission
<label htmlFor="email" className="block text-sm font-medium mb-2">
  Email
</label>
<input
  type="email"
  id="email"
  name="email"
  aria-required="true"
  aria-invalid={submitStatus === 'error'}
/>

Integration with Backend

The contact form relies on the Express backend:
// Backend endpoint: POST /api/contact
// Expected body: { name, email, subject, message }
// Response: { success: boolean }
For backend implementation details, see:

Testing the Form

Before deploying, test the contact form thoroughly:
  1. Submit valid message - should succeed
  2. Submit with invalid email - should show validation error
  3. Submit with empty fields - should show required field errors
  4. Test direct email link - should open email client
  5. Verify both notification and confirmation emails are received

Common Issues

Form Not Submitting

  • Check API endpoint is accessible
  • Verify CORS settings in backend
  • Check browser console for errors

Emails Not Sending

  • Verify SMTP credentials in .env
  • Check email service configuration
  • Review server logs for errors

Validation Errors

  • Ensure all required fields are filled
  • Check email format is valid
  • Verify backend validation rules
For troubleshooting, see Common Issues.

Build docs developers (and LLMs) love