feat: Implement contact form with email functionality#14
Merged
Conversation
…ing fixes - Add contact form with reCAPTCHA v3 integration - Implement email system using Nodemailer with Gmail SMTP - Create contact form modal for equipment pages - Add navigation buttons to equipment detail pages - Fix visual editing issues: - Resolve 'toString' prop warning in dataAttr utility - Add text sanitization for stega encoding - Clean up zero-width spaces and non-printable characters - Add environment variables for: - SMTP configuration - reCAPTCHA keys - Contact email addresses - Implement email templates with product information - Add copy-to-sender functionality - Set up proper email routing with Reply-To headers - Add toast notifications for form feedback - Create test page for contact form functionality - Fix build and type generation issues The contact form is now fully functional with spam protection, email notifications, and proper error handling. Visual editing has been improved with better data sanitization and encoding.
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR adds a fully functional contact form with spam protection, email notifications, and various sanitization/visual fixes.
- Integrates a contact form (modal & standalone) with reCAPTCHA v3, honeypot, and “send copy” functionality
- Implements email sending via Nodemailer, configures SMTP env vars, and builds HTML templates
- Introduces text sanitization utilities and fixes data-attribute encoding issues
Reviewed Changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| web/sanity/lib/utils.ts | URI-encodes data-sanity attribute to handle special characters |
| web/package.json | Adds form, email, and reCAPTCHA dependencies |
| web/lib/nodemailer.ts | Sets up Nodemailer transporter and environment variable checks |
| web/app/layout.tsx | Wraps app in ReCaptchaProvider and ContactFormProvider |
| web/app/hooks/useContactForm.ts | Hook managing modal open state and product info |
| web/app/equipment/[slug]/page.tsx | Replaces server component with client-only EquipmentClient |
| web/app/equipment/[slug]/EquipmentClient.tsx | Adds “Contact Us” modal and navigation buttons |
| web/app/context/ContactFormContext.tsx | Context provider exposing form controls |
| web/app/contact/page.tsx | Standalone contact page with toasts |
| web/app/components/ReCaptchaProvider.tsx | Provides reCAPTCHA v3 context |
| web/app/components/EquipmentGrid.tsx | Adds sanitizeForStega helper and sanitizes titles/taglines |
| web/app/components/Email.tsx | Defines email template for submissions |
| web/app/components/ContactFormModal.tsx | Modal wrapper handling focus, escape, outside clicks |
| web/app/components/ContactForm.tsx | Contact form with recaptcha, honeypot, sendCopy, and notifications |
| web/app/api/contact/route.ts | API route verifying recaptcha/honeypot and dispatching emails |
| studio/src/schemaTypes/documents/contactSubmission.ts | Defines schema for storing form submissions |
Comments suppressed due to low confidence (6)
web/app/equipment/[slug]/page.tsx:3
- These imports (
getUsedEquipmentQuery,usedEquipmentSlugs) are no longer referenced after switching toEquipmentClient; remove them to clean up unused imports.
import { getUsedEquipmentQuery, usedEquipmentSlugs } from '@/sanity/lib/queries';
web/app/components/EquipmentGrid.tsx:104
- [nitpick] The variable
sanitizedTitleshadows an outer declaration of the same name; consider using a distinct name likeequipmentTitleSanitizedto improve clarity.
const sanitizedTitle = sanitizeForStega(equipment.title);
web/app/components/ContactFormModal.tsx:60
- Include an accessible label (e.g.,
aria-label="Close modal") on this button so screen readers can convey its purpose.
<button onClick={onClose} className="text-gray-500 hover:text-gray-700 focus:outline-none">
web/sanity/lib/utils.ts:103
- [nitpick] Consider adding a JSDoc comment explaining why the attribute is URI-encoded and how consumers should decode it, for better maintainability.
// Encode the data attribute to handle special characters
web/app/api/contact/route.ts:1
- No tests cover the
/api/contactroute. Consider adding unit or integration tests to verify reCAPTCHA validation, honeypot handling, and email-sending logic.
import { NextResponse } from 'next/server';
web/package.json:24
- The
@sendgrid/maildependency is added but not used anywhere in the codebase; consider removing it to avoid unused dependencies.
"@sendgrid/mail": "^8.1.5",
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat: Implement contact form with email functionality and visual editing fixes:
The contact form is now fully functional with spam protection, email notifications, and proper error handling. Visual editing has been improved with better data sanitization and encoding.