Replaces the third-party iframe form on both the homepage and contact page with the self-hosted form: drag-and-drop photo upload, honeypot, rate limiting, inline validation, auto-reply email. Adds multer/sharp/nodemailer dependencies and the /api/contact endpoint to server.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
254 lines
12 KiB
HTML
254 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<script defer data-domain="beachpartyballoons.com" src="https://metrics.beachpartyballoons.com/js/script.hash.outbound-links.js"></script>
|
|
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
|
|
<link rel="apple-touch-icon" sizes="180x180" href="assets/favicon/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon/favicon-16x16.png">
|
|
<link rel="manifest" href="assets/favicon/site.webmanifest">
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="Beach Party Balloons - Your go-to shop for stunning balloon decorations, walk-in arrangements, and deliveries in CT">
|
|
<title>Beach Party Balloons</title>
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://cdn.jsdelivr.net/npm/bulma@1.0.2/css/bulma.min.css">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Autour+One&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="style.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
<script src="/nav.js" defer></script>
|
|
</head>
|
|
<body>
|
|
<div id="site-nav"></div>
|
|
<div class="update">
|
|
<div id="message"></div>
|
|
</div>
|
|
|
|
<button onclick="topFunction()" class="has-text-dark" id="top" title="Go to top">Top</button>
|
|
|
|
<div class="container is-justify-content-center padding">
|
|
<figure class="image">
|
|
<img src="assets/pics/classic/hero.webp" alt="Image 1" >
|
|
<img class="is-overlay" src="assets/logo/BeachPartyBalloons-logo.webp" alt="Image 2" style="width: 50%; height: auto; margin: auto;">
|
|
</figure>
|
|
</div>
|
|
<div class="is-flex-direction-column is-dark">
|
|
<h1 class="is-size-3" style="text-align: center;">Visit our store</h1>
|
|
<h2 class="is-size-4" style="text-align: center;"> <a target="_blank" href="https://maps.app.goo.gl/gRk6NztgMRUsSVJf9">554 Boston Post Road, Milford, CT 06460</a> </h2>
|
|
<h2 class="is-size-4" style="text-align: center;" ><a href="tel:203.283.5626">203.283.5626</a> </h2>
|
|
<div class="py-2 has-text-centered">
|
|
<a href="#contact-form">
|
|
<button class="button is-info">Contact Us</button>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container is-justify-content-center padding">
|
|
<img src="assets/pics/organic/img1.webp" alt="Image 1" >
|
|
</div>
|
|
|
|
<p class="is-size-5 has-text-centered">Walk-ins welcome!</p>
|
|
<p class="is-size-6 has-text-centered"> Pick up a balloon arrangement for birthdays or any occasion. We will make it while you wait! </p>
|
|
<p class="is-size-6 has-text-centered">We have hundreds of foil balloon choices in stock and over 70 latex colors! </p>
|
|
|
|
<p class="is-size-5 has-text-centered">...Or consult with one of our designers about your balloon decorating needs.</p>
|
|
|
|
<div class="container is-justify-content-center padding">
|
|
<img src="assets/pics/organic/img2.webp" alt="Image 1" >
|
|
</div>
|
|
<p class="is-size-5 has-text-centered">Delivery avalable!</p>
|
|
<p class="is-size-5 has-text-centered"> Have your balloons delivered! Our delivery staff will make sure your order arrives safe and sound!</p>
|
|
|
|
<div class="container is-justify-content-center padding">
|
|
<img src="assets/pics/helium/img1.webp" alt="Image 1" >
|
|
</div>
|
|
|
|
<p class="has-text-centered is-size-1">Shop Hours</p>
|
|
<p id="status" class="has-text-centered"></p>
|
|
<p id="hours-tuesday-friday" class="has-text-centered">Tuesday - Friday: 10:00 - 5:00</p>
|
|
<p id="hours-saturday" class="has-text-centered">Saturday: 9:00 - 3:00</p>
|
|
<p id="hours-sunday-monday" class="has-text-centered">Sunday - Monday: Closed</p>
|
|
|
|
<div class="form-container" id="contact-form">
|
|
<h2 class="is-size-3 has-text-centered">Contact Us</h2>
|
|
<form id="contactForm" novalidate>
|
|
<!-- Honeypot: hidden from humans, filled by bots -->
|
|
<div style="display:none;" aria-hidden="true">
|
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">Name <span class="has-text-danger">*</span></label>
|
|
<div class="control">
|
|
<input class="input" type="text" name="name" placeholder="Your name" required autocomplete="name">
|
|
</div>
|
|
<p class="help is-danger" id="err-name" style="display:none;"></p>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">Email <span class="has-text-danger">*</span></label>
|
|
<div class="control">
|
|
<input class="input" type="email" name="email" placeholder="you@example.com" required autocomplete="email">
|
|
</div>
|
|
<p class="help is-danger" id="err-email" style="display:none;"></p>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">Phone Number <span class="has-text-danger">*</span></label>
|
|
<div class="control">
|
|
<input class="input" type="tel" name="phone" placeholder="(203) 555-0123" required autocomplete="tel">
|
|
</div>
|
|
<p class="help is-danger" id="err-phone" style="display:none;"></p>
|
|
</div>
|
|
|
|
<div class="columns is-mobile">
|
|
<div class="column">
|
|
<div class="field">
|
|
<label class="label">Event Type</label>
|
|
<div class="control">
|
|
<div class="select is-fullwidth">
|
|
<select name="eventType">
|
|
<option value="">Select a type…</option>
|
|
<option value="Birthday">Birthday</option>
|
|
<option value="Corporate">Corporate</option>
|
|
<option value="Wedding">Wedding</option>
|
|
<option value="Walk-in">Walk-in</option>
|
|
<option value="Other">Other</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column">
|
|
<div class="field">
|
|
<label class="label">Event Date</label>
|
|
<div class="control">
|
|
<input class="input" type="date" name="eventDate">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">Message <span class="has-text-danger">*</span></label>
|
|
<div class="control">
|
|
<textarea class="textarea" name="message" placeholder="Tell us about your event…" rows="4" required></textarea>
|
|
</div>
|
|
<p class="help is-danger" id="err-message" style="display:none;"></p>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">Photos <span class="has-text-grey is-size-7">(up to 3 images)</span></label>
|
|
<div class="control">
|
|
<div id="dropzone">
|
|
<p><i class="fas fa-images"></i> Drag & drop photos here, or <span class="has-text-info" style="text-decoration:underline;">browse</span></p>
|
|
<p class="is-size-7 has-text-grey mt-1">JPEG · PNG · HEIC · WebP — max 10 MB each</p>
|
|
<input id="photoInput" type="file" name="photos" accept="image/*" multiple style="display:none;">
|
|
</div>
|
|
<div id="photoPreview"></div>
|
|
<p id="photoError" class="help is-danger" style="display:none;">Maximum 3 photos — extras were ignored.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="formAlert" class="notification" style="display:none;"></div>
|
|
|
|
<div class="field">
|
|
<div class="control">
|
|
<button type="submit" id="submitBtn" class="button is-info is-fullwidth">Send Message</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<hr class="section-divider">
|
|
<section class="section reviews-section">
|
|
<div class="container has-text-centered">
|
|
<h2 class="is-size-3">Google Reviews</h2>
|
|
<p class="is-size-6 has-text-grey">See what clients are saying, or leave a review after your event.</p>
|
|
<div class="reviews-summary mt-4">
|
|
<div class="reviews-stars" aria-label="Average rating: 5.0 out of 5">
|
|
<span>★</span><span>★</span><span>★</span><span>★</span><span>★</span>
|
|
</div>
|
|
<p class="is-size-5 has-text-weight-semibold">Rated <span id="reviewsRatingValue">5.0</span> on Google</p>
|
|
<p class="is-size-7 has-text-grey">Based on <span id="reviewsCountValue">100+ reviews</span></p>
|
|
</div>
|
|
<div class="reviews-grid mt-5" id="reviewsGrid">
|
|
<article class="review-card">
|
|
<p>"Stunning balloon arch and super easy to work with. Our guests loved it!"</p>
|
|
<p class="review-author">— Jordan M., Corporate Event</p>
|
|
</article>
|
|
<article class="review-card">
|
|
<p>"Professional setup and gorgeous colors. Made our celebration unforgettable."</p>
|
|
<p class="review-author">— Maria L., Birthday Party</p>
|
|
</article>
|
|
<article class="review-card">
|
|
<p>"Fast, friendly, and beautiful designs. Will book again for our next event."</p>
|
|
<p class="review-author">— Alex T., School Event</p>
|
|
</article>
|
|
</div>
|
|
<div class="buttons is-centered mt-4">
|
|
<a class="button is-info" target="_blank" rel="noopener" href="https://www.google.com/maps/place/Beach+Party+Balloons/@41.2305385,-73.0657635,17z/data=!3m1!4b1!4m6!3m5!1s0x89e80c66edb1f163:0xd0209d75415d0e41!8m2!3d41.2305385!4d-73.0657635!16s%2Fg%2F11bxc5f6tk?entry=ttu&g_ep=EgoyMDI1MTIwOS4wIKXMDSoASAFQAw%3D%3D">Read reviews</a>
|
|
<a class="button is-light" target="_blank" rel="noopener" href="https://g.page/r/CUEOXUF1nSDQEBE/review">Leave a review</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section trusted-section">
|
|
<div class="container">
|
|
<div class="has-text-centered mb-5">
|
|
<h2 class="is-size-3">Trusted by</h2>
|
|
<p class="is-size-6 has-text-grey">Brands and organizations we have had the joy of celebrating with.</p>
|
|
</div>
|
|
<div class="trusted-logos">
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/512px-Subway_icon.svg.webp" alt="Subway logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/Yale_press_logo.webp" alt="Yale logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/256px-Quinnipiac_University_logo_(2017).svg.webp" alt="Quinnipiac University logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/512px-University_of_New_Haven_logo.webp" alt="University of New Haven logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/Planet_Fitness_(2).webp" alt="Planet Fitness logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/Mohegan-Sun-Logo.webp" alt="Mohegan Sun logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/Post_university_of_conn_logo.webp" alt="Post University logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/logo-full-color.webp" alt="Edge Fitness logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/lincoln-culinary.webp" alt="Lincoln Culinary Institute logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/amazon.webp" alt="Amazon logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo trusted-logo--dark">
|
|
<img src="assets/trusted/woodwinds-2024-logo-white.webp" alt="Woodwinds logo" loading="lazy">
|
|
</figure>
|
|
<figure class="trusted-logo">
|
|
<img src="assets/trusted/sallys-apizza.webp" alt="Sally's Apizza logo" loading="lazy">
|
|
</figure>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div id="site-footer"></div>
|
|
<script src="script.js"></script>
|
|
<script src="update.js"></script>
|
|
<script src="reviews-data.js"></script>
|
|
<script src="reviews.js?v=6"></script>
|
|
<script src="contact-form.js"></script>
|
|
|
|
</body>
|
|
</html>
|