From 0f0af391853f702946925be2605637a698c2e33f Mon Sep 17 00:00:00 2001 From: Johnny Wu Date: Mon, 24 Jun 2024 18:25:56 -0700 Subject: [PATCH 1/4] feat: replace form with Google Form --- components/contact/ContactForm.jsx | 332 ++--------------------------- 1 file changed, 23 insertions(+), 309 deletions(-) diff --git a/components/contact/ContactForm.jsx b/components/contact/ContactForm.jsx index 981629b1c..524e42ccb 100644 --- a/components/contact/ContactForm.jsx +++ b/components/contact/ContactForm.jsx @@ -1,321 +1,35 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { toast } from 'react-toastify'; -import makeStyles from '@mui/styles/makeStyles' -import Grid from '@mui/material/Grid'; -import Button from '@mui/material/Button'; -import TextField from '@mui/material/TextField'; -import InputLabel from '@mui/material/InputLabel'; -import CircularProgress from '@mui/material/CircularProgress'; -import { showFeedbackSuccess, setErrorModal } from '@reducers/ui'; -import { sendGitRequest } from '@reducers/data'; -import 'react-toastify/dist/ReactToastify.css'; -import colors from '@theme/colors' -import fonts from '@theme/fonts'; -import typography from '@theme/typography'; -import borderRadius from '@theme/borderRadius'; +import React from 'react'; +import makeStyles from '@mui/styles/makeStyles'; const useStyles = makeStyles(theme => ({ - form: { - marginBottom: theme.spacing(20) + formContainer: { + width: '100%', + height: 'auto', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', }, - formLabel: { - fontSize: typography.h6.fontSize, - color: colors.primaryLight, - fontWeight: fonts.weight.medium, - marginTop: theme.spacing(2), - marginBottom: theme.spacing(2), - }, - formInput: { - backgroundColor: colors.formInput, - borderRadius: borderRadius.sm - }, - noBorder: { - border: "none", + iframe: { + border: 'none', + width: '100%', + height: '1200px', + minHeight: '856px', }, })); -const initialFormValues = { - firstName: '', - lastName: '', - email: '', - association: '', - message: '', - errors: { - missingFirstName: false, - invalidFirstName: false, - missingLastName: false, - invalidLastName: false, - missingEmail: false, - invalidEmail: false, - missingMessage: false, - invalidMessage: false, - }, - loading: false, -}; - -const toastEmitterSettings = { - position: 'bottom-right', - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, -}; - function ContactForm() { - const dispatch = useDispatch(); - const classes = useStyles() - - // mapStateToProps equivalent. - const displayFeedbackSuccess = useSelector(state => state.ui.displayFeedbackSuccess); - const openErrorModal = useSelector(state => state.ui.error.isOpen); - - const [formValues, setFormValues] = useState(initialFormValues); - - function clearFields() { - setFormValues({ - ...initialFormValues, - }); - } - - function setLoading(isLoading) { - setFormValues(prevState => ({ - ...prevState, - ...{ - loading: isLoading, - }, - })); - } - - // Initialize component. - useEffect(() => { - // componentDidMount code goes here... - if (displayFeedbackSuccess) { - toast.success('We received your message. Our team will contact you at the email address provided.', toastEmitterSettings); - clearFields(); - } - - if (openErrorModal) { - toast.error('We failed to process your message. Please try again later.', toastEmitterSettings); - setLoading(false); - } - - return () => { - // componentWillUnmount code goes here... - dispatch(showFeedbackSuccess(false)); - dispatch(setErrorModal(false)); - }; - }, [dispatch, displayFeedbackSuccess, openErrorModal]); - - // Helper methods. - function validateEmail(emailAddress) { - // A regular expression checking for a valid email format. - const VALID_EMAIL_FORMAT_REGEX = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/; - return VALID_EMAIL_FORMAT_REGEX.test(emailAddress); - } - - function validateName(name) { - // A regular expression checking for valid names (first and last). - const NAME_REGEX = /^[a-zA-Z]+$/; - return NAME_REGEX.test(name); - } - - const clearErrors = useCallback(() => { - setFormValues(prevState => ({ - ...prevState, - ...{ - errors: { - missingFirstName: false, - invalidFirstName: false, - missingLastName: false, - invalidLastName: false, - missingEmail: false, - invalidEmail: false, - missingMessage: false, - invalidMessage: false, - }, - }, - })); - }, []); - - const validateForm = useCallback(() => { - const noFirstName = formValues.firstName.trim().length === 0; - const notValidFirstName = !validateName(formValues.firstName.trim()); - const noLastName = formValues.lastName.trim().length === 0; - const notValidLastName = !validateName(formValues.lastName.trim()); - const noEmail = formValues.email.trim().length === 0; - const noMessage = formValues.message.trim().length === 0; - const incompleteEmail = (!noEmail && !validateEmail(formValues.email)); - const invalidMessageLength = formValues.message.trim().length < 6 - || formValues.message.trim().length > 1000; - if (!noFirstName && !noLastName && !notValidFirstName && !notValidLastName - && !noEmail && !incompleteEmail - && !noMessage && !invalidMessageLength) { - return true; - } - - setFormValues(prevState => ({ - ...prevState, - ...{ - errors: { - missingFirstName: noFirstName, - invalidFirstName: notValidFirstName, - missingLastName: noLastName, - invalidLastName: notValidLastName, - missingEmail: noEmail, - invalidEmail: incompleteEmail, - missingMessage: noMessage, - invalidMessage: invalidMessageLength, - }, - }, - })); - return false; - }, [formValues]); - - // Event handlers. - const onInputChange = useCallback(event => { - const { name, value } = event.target; - setFormValues(prevState => ({ ...prevState, [name]: value })); - }, []); - - const handleSubmit = useCallback(event => { - event.preventDefault(); - - if (!validateForm()) { - return; - } - - const body = [ - `First name: ${formValues.firstName.trim()}`, - `Last name: ${formValues.lastName.trim()}`, - `Email: ${formValues.email.trim()}`, - `Association: ${formValues.association.trim() || 'Not provided'}`, - `Message: ${formValues.message.trim()}`, - ].join('\n'); - - setLoading(true); - - // Dispatch action to redux with payload. - dispatch(sendGitRequest({ title: formValues.email, body })); - }, [dispatch, - formValues.association, - formValues.email, - formValues.firstName, - formValues.lastName, - formValues.message, - validateForm]); + const classes = useStyles(); return ( -
- - - - First Name* - - - - Last Name* - - - - - - Email* - - - - Association - - - - Message* - - - - - - - - -
+
+ +
); } From 781d7bf5673967a3a573603856e4fb4d8271a7c9 Mon Sep 17 00:00:00 2001 From: Johnny Wu Date: Fri, 28 Jun 2024 21:30:57 -0700 Subject: [PATCH 2/4] remove unused theme --- components/contact/ContactForm.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/contact/ContactForm.jsx b/components/contact/ContactForm.jsx index 524e42ccb..4217f5cba 100644 --- a/components/contact/ContactForm.jsx +++ b/components/contact/ContactForm.jsx @@ -1,7 +1,7 @@ import React from 'react'; import makeStyles from '@mui/styles/makeStyles'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles(({ formContainer: { width: '100%', height: 'auto', From c22c1f8288bf77c2049fb42b74574cb7d195fdac Mon Sep 17 00:00:00 2001 From: Johnny Wu Date: Fri, 28 Jun 2024 21:33:37 -0700 Subject: [PATCH 3/4] add comment --- components/contact/ContactForm.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/components/contact/ContactForm.jsx b/components/contact/ContactForm.jsx index 4217f5cba..77e296fa7 100644 --- a/components/contact/ContactForm.jsx +++ b/components/contact/ContactForm.jsx @@ -22,6 +22,7 @@ function ContactForm() { return (
+ {/* Embed the Google Form */}