Gatsby Booking Form Generator

Let visitors book appointments or services

Back to Generator

Form Preview

Gatsby Code

import React, { useState } from 'react';
import { navigate } from 'gatsby';
import './form-styles.css'; // You can create a separate CSS file or use styled-components

const BookingFormForm = () => {
  // State for form data
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    phone: '',
    service: '',
    date: '',
    time: '',
  });

  // State for form submission
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submitSuccess, setSubmitSuccess] = useState(false);
  const [submitError, setSubmitError] = useState('');

  // Handle input changes
  const handleChange = (e) => {
    const { name, value, type, checked } = e.target;
    
    if (type === 'checkbox') {
      // Handle checkboxes differently based on multiple or single
      if (name === 'consent' || name === 'terms' || name === 'remember') {
        setFormData({
          ...formData,
          [name]: checked ? 'Yes' : ''
        });
      } else {
        // For multiple checkbox options
        if (checked) {
          setFormData({
            ...formData,
            [name]: [...formData[name], value]
          });
        } else {
          setFormData({
            ...formData,
            [name]: formData[name].filter(item => item !== value)
          });
        }
      }
    } else {
      setFormData({
        ...formData,
        [name]: value
      });
    }
  };

  // Handle form submission
  const handleSubmit = async (e) => {
    e.preventDefault();
    setIsSubmitting(true);
    setSubmitError('');
    
    try {
      // Call the Gatsby Function to handle form submission
      const response = await fetch('/api/form-submission', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          formName: 'booking-form',
          formData,
        }),
      });
      
      const data = await response.json();
      
      if (!response.ok) {
        throw new Error(data.message || 'Form submission failed');
      }
      
      // Reset form on success
      setFormData({
        name: '',
        email: '',
        phone: '',
        service: '',
        date: '',
        time: '',
      });
      setSubmitSuccess(true);
      
      // Optionally redirect to a thank you page
      // navigate('/thank-you');
    } catch (error) {
      console.error('Error submitting form:', error);
      setSubmitError(error.message || 'Something went wrong. Please try again.');
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div className="form-container">
      {submitSuccess ? (
        <div className="success-message">
          <h3>Thank you for your submission!</h3>
          <p>We have received your information and will be in touch soon.</p>
          <button 
            className="reset-button"
            onClick={() => setSubmitSuccess(false)}
          >
            Submit another response
          </button>
        </div>
      ) : (
        <form onSubmit={handleSubmit} className="gatsby-form">
          <div className="form-group">
            <label htmlFor="name">
              Full Name *
            </label>
            <input
              type="text"
              id="name"
              name="name"
              value={formData.name}
              onChange={handleChange}
              required={true}
            />
          </div>
          <div className="form-group">
            <label htmlFor="email">
              Email Address *
            </label>
            <input
              type="email"
              id="email"
              name="email"
              value={formData.email}
              onChange={handleChange}
              required={true}
            />
          </div>
          <div className="form-group">
            <label htmlFor="phone">
              Phone Number *
            </label>
            <input
              type="tel"
              id="phone"
              name="phone"
              value={formData.phone}
              onChange={handleChange}
              required={true}
            />
          </div>
          <div className="form-group">
            <label htmlFor="service">
              Service *
            </label>
            <select
              id="service"
              name="service"
              value={formData.service}
              onChange={handleChange}
              required={true}
            >
              <option value="">Select an option</option>
              <option value="Service A">Service A</option>
              <option value="Service B">Service B</option>
              <option value="Service C">Service C</option>
            </select>
          </div>
          <div className="form-group">
            <label htmlFor="date">
              Preferred Date *
            </label>
            <input
              type="date"
              id="date"
              name="date"
              value={formData.date}
              onChange={handleChange}
              required={true}
            />
          </div>
          <div className="form-group">
            <label htmlFor="time">
              Preferred Time *
            </label>
            <select
              id="time"
              name="time"
              value={formData.time}
              onChange={handleChange}
              required={true}
            >
              <option value="">Select an option</option>
              <option value="Morning">Morning</option>
              <option value="Afternoon">Afternoon</option>
              <option value="Evening">Evening</option>
            </select>
          </div>
          {submitError && (
            <div className="error-message">
              {submitError}
            </div>
          )}
          
          <div className="form-group">
            <button
              type="submit"
              disabled={isSubmitting}
              className="submit-button"
            >
              {isSubmitting ? 'Submitting...' : 'Submit'}
            </button>
          </div>
        </form>
      )}
    </div>
  );
};

export default BookingFormForm;

/*
// Create a Gatsby Function for handling form submissions
// Save this at /src/api/form-submission.js

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method not allowed' });
  }

  try {
    const { formName, formData } = req.body;
    
    // Here you would typically:
    // 1. Validate the data
    // 2. Send to an external service, database, or email
    // 3. Handle any post-submission logic
    
    console.log('Form submission received:', { formName, formData });
    
    // Example integration with ParrotForms
    // const parrotFormsResponse = await fetch('https://api.parrotforms.com/v1/submissions', {
    //   method: 'POST',
    //   headers: {
    //     'Content-Type': 'application/json',
    //     'Authorization': 'Bearer YOUR_PARROTFORMS_API_KEY'
    //   },
    //   body: JSON.stringify({ formName, formData }),
    // });
    // 
    // if (!parrotFormsResponse.ok) {
    //   throw new Error('Failed to submit to ParrotForms');
    // }
    
    // Return success response
    return res.status(200).json({ 
      success: true, 
      message: 'Form submitted successfully' 
    });
  } catch (error) {
    console.error('Error processing form submission:', error);
    return res.status(500).json({ 
      success: false, 
      message: 'Error processing form submission' 
    });
  }
}
*/

/*
/* Save this at /src/components/form-styles.css */

.form-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 2rem;
  background-color: #f9f9f9;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.gatsby-form {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.form-group label {
  font-weight: 600;
  font-size: 0.9rem;
  color: #333;
}

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="tel"],
.form-group input[type="number"],
.form-group input[type="password"],
.form-group input[type="date"],
.form-group select,
.form-group textarea {
  padding: 0.75rem;
  border-radius: 4px;
  border: 1px solid #ddd;
  font-size: 1rem;
  width: 100%;
}

.form-group textarea {
  min-height: 120px;
}

.radio-group,
.checkbox-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.radio-item,
.checkbox-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.submit-button {
  background-color: #663399; /* Gatsby purple */
  color: white;
  border: none;
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
}

.submit-button:hover {
  background-color: #542c85;
}

.submit-button:disabled {
  background-color: #9d7cbe;
  cursor: not-allowed;
}

.success-message {
  text-align: center;
  color: #2e7d32;
  padding: 1rem;
  background-color: #e8f5e9;
  border-radius: 4px;
}

.error-message {
  color: #d32f2f;
  padding: 0.75rem;
  margin-bottom: 1rem;
  background-color: #ffebee;
  border-radius: 4px;
  font-size: 0.9rem;
}

.reset-button {
  background-color: transparent;
  color: #663399;
  border: 1px solid #663399;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  margin-top: 1rem;
  font-size: 0.9rem;
  cursor: pointer;
}

.reset-button:hover {
  background-color: #f5f0fa;
}
*/

Installation

How to setup Gatsby Booking form

  1. 1

    Sign up to parrotforms.com

    Create your first form API endpoint then copy your endpoint.

    Screenshot Placeholder
  2. 2

    Copy the example code

    Use the copy button above to copy the entire code snippet.

    Screenshot Placeholder
  3. 3

    Paste the code and update the endpoint

    Replace the form API endpoint with the one you got in step 1.

    Screenshot Placeholder
  4. 4

    Collect submissions

    View and manage all form submissions in your parrotForms dashboard.

    Screenshot Placeholder

Need more advanced forms?

Create a free parrotForms account to access more templates, save your forms, and collect submissions.

Create a Free Account