From 2019a9b79e212a1085f248c87cd3035b47ddaf7b Mon Sep 17 00:00:00 2001 From: Giacomo Baggio Date: Tue, 10 Aug 2021 11:15:53 +0200 Subject: [PATCH 1/5] Fix page reloading --- .../form-messages/models/form-messages.settings.json | 3 ++- .../page/sections/ContactsSection/ContactsSection.tsx | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/api/form-messages/models/form-messages.settings.json b/backend/api/form-messages/models/form-messages.settings.json index e73d2ce..243d346 100644 --- a/backend/api/form-messages/models/form-messages.settings.json +++ b/backend/api/form-messages/models/form-messages.settings.json @@ -2,7 +2,8 @@ "kind": "collectionType", "collectionName": "form_messages", "info": { - "name": "formMessages" + "name": "formMessages", + "description": "" }, "options": { "increments": true, diff --git a/frontend/features/page/sections/ContactsSection/ContactsSection.tsx b/frontend/features/page/sections/ContactsSection/ContactsSection.tsx index 2aa88a9..a990345 100644 --- a/frontend/features/page/sections/ContactsSection/ContactsSection.tsx +++ b/frontend/features/page/sections/ContactsSection/ContactsSection.tsx @@ -263,8 +263,6 @@ function reducer(state: FormState, action: FormAction) { state.validationErrors.message = null; } - event?.preventDefault(); - return { ...state, validationErrors: result.validationErrors, @@ -333,6 +331,13 @@ export function ContactsForm() { [] ); + function onSubmit(event: React.FormEvent) { + event.preventDefault(); + dispatch({ + type: FormActionType.Submit, + }); + } + return ( dispatch({ type: FormActionType.Submit })} + onSubmit={onSubmit} as="form" display={ state.status === FormStatus.Submitted ? "none" : "inline-block" From dfeec737cc4a6158be6d6259769e4aefebd458c0 Mon Sep 17 00:00:00 2001 From: Giacomo Baggio Date: Thu, 12 Aug 2021 13:28:33 +0200 Subject: [PATCH 2/5] Update ContactsSection.tsx --- .../ContactsSection/ContactsSection.tsx | 82 +++++++++++++------ 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/frontend/features/page/sections/ContactsSection/ContactsSection.tsx b/frontend/features/page/sections/ContactsSection/ContactsSection.tsx index a990345..b00f0d1 100644 --- a/frontend/features/page/sections/ContactsSection/ContactsSection.tsx +++ b/frontend/features/page/sections/ContactsSection/ContactsSection.tsx @@ -64,7 +64,8 @@ export function ContactsSectionBlock({ my="0" mx="auto" pos="relative" - flexDir="column"> + flexDir="column" + > + } + > @@ -97,7 +99,8 @@ export function ContactsSectionBlock({ flexDir={{ base: "column", md: "row", - }}> + }} + > + flexDir="column" + > + lineHeight="1.1em" + > @@ -127,7 +132,8 @@ export function ContactsSectionBlock({ fontSize="sm" pt="14" lineHeight="1.8em" - textDecoration="none"> + textDecoration="none" + > @@ -139,19 +145,22 @@ export function ContactsSectionBlock({ + onHoverColor="rgba(29, 161, 242, 1)" + > + onHoverColor="rgba(59, 89, 152, 1)" + > + onHoverColor="rgba(24, 23, 23, 1)" + > @@ -275,6 +284,7 @@ function reducer(state: FormState, action: FormAction) { // Display thanks page ...state, status: FormStatus.Submitted, + // API call POST to slack :) }; case FormActionType.Failed: @@ -359,19 +369,22 @@ export function ContactsForm() { sm: "row", md: "column", lg: "row", - }}> + }} + > + pb="12" + > + pb="5" + > Thank you! @@ -384,7 +397,8 @@ export function ContactsForm() { as="form" display={ state.status === FormStatus.Submitted ? "none" : "inline-block" - }> + } + > + pos="relative" + > + } + > + mb="0" + > Name + transition="all 0.4s ease 0s" + > + display="inline-block" + > + } + > + display="block" + > Email + transition="all 0.4s ease 0s" + > @@ -530,7 +552,8 @@ export function ContactsForm() { w="calc(100% - 10px)" m="2.5" pos="relative" - display="inline-block"> + display="inline-block" + > + } + > + display="block" + > Message + transition="all 0.4s ease 0s" + > {state.submitError} @@ -620,7 +646,8 @@ export function ContactsForm() { }} mt="10" mr="2.5" - mb="2.5"> + mb="2.5" + > + }} + > SEND From 1f66eb3d2ffc5515624c68d934bf5e88e7f14c24 Mon Sep 17 00:00:00 2001 From: Giacomo Baggio Date: Tue, 17 Aug 2021 13:34:08 +0200 Subject: [PATCH 3/5] Add notification on Strapi --- frontend/.env.environment | 3 +- frontend/components/AppProviders.tsx | 3 +- .../ContactsSection/ContactsSection.tsx | 152 ++++++++++++------ frontend/package-lock.json | 28 ++++ frontend/package.json | 1 + frontend/pages/api/send.ts | 39 +++++ 6 files changed, 171 insertions(+), 55 deletions(-) create mode 100644 frontend/pages/api/send.ts diff --git a/frontend/.env.environment b/frontend/.env.environment index 393ac2b..9734f03 100644 --- a/frontend/.env.environment +++ b/frontend/.env.environment @@ -1 +1,2 @@ -NEXT_PUBLIC_STRAPI_URL=http://localhost:1337 \ No newline at end of file +NEXT_PUBLIC_STRAPI_URL=http://localhost:1337 + diff --git a/frontend/components/AppProviders.tsx b/frontend/components/AppProviders.tsx index 714da90..71ecb26 100644 --- a/frontend/components/AppProviders.tsx +++ b/frontend/components/AppProviders.tsx @@ -66,7 +66,8 @@ const EditButton = () => { position="fixed" right="4" bottom="4" - onClick={() => (cms.enabled ? cms.disable() : cms.enable())}> + onClick={() => (cms.enabled ? cms.disable() : cms.enable())} + > {cms.enabled ? `Stop Editing ` : `Edit this Site `} ); diff --git a/frontend/features/page/sections/ContactsSection/ContactsSection.tsx b/frontend/features/page/sections/ContactsSection/ContactsSection.tsx index b00f0d1..5ccd79f 100644 --- a/frontend/features/page/sections/ContactsSection/ContactsSection.tsx +++ b/frontend/features/page/sections/ContactsSection/ContactsSection.tsx @@ -6,7 +6,6 @@ import { FormErrorMessage, FormLabel, Input, - Text, } from "@chakra-ui/react"; import * as React from "react"; import { @@ -123,9 +122,9 @@ export function ContactsSectionBlock({ > - + - + prop == null || prop === "" + ); return { ...state, - validationErrors: result.validationErrors, - status: hasValidationErrors ? FormStatus.Idle : FormStatus.Submitting, + status: hasNoErrors ? FormStatus.Submitting : FormStatus.Idle, }; } @@ -284,18 +269,23 @@ function reducer(state: FormState, action: FormAction) { // Display thanks page ...state, status: FormStatus.Submitted, - // API call POST to slack :) + // API POST call to slack :) }; case FormActionType.Failed: return { // Resta in idle, setta errore e resetta i campi? ...state, - submitError: "Error while sending your message", status: FormStatus.Idle, }; + case FormActionType.ValidationFailed: + return { + ...state, + validationErrors: action.validationErrors, + }; + default: { assertNever(action); } @@ -304,6 +294,35 @@ function reducer(state: FormState, action: FormAction) { export function ContactsForm() { const [state, dispatch] = React.useReducer(reducer, blankForm); + + function validateErrors(values: FormState["values"]) { + const regex = /^[^@\s]+@[^@\s\.]+\.[^@\.\s]+$/; + + const validationErrors: FormState["validationErrors"] = { + name: null, + email: null, + message: null, + }; + + if (values.name.trim().length === 0) { + validationErrors.name = "Please insert your name"; + } else { + validationErrors.name = null; + } + + if (!regex.test(state.values.email)) { + validationErrors.email = "Please insert a valid email"; + } else { + validationErrors.email = null; + } + if (state.values.message.trim().length == 0) { + validationErrors.message = "Please insert a message"; + } else { + validationErrors.message = null; + } + return validationErrors; + } + React.useEffect(() => { if (state.status === FormStatus.Submitting) { async function sendMessage() { @@ -341,12 +360,32 @@ export function ContactsForm() { [] ); - function onSubmit(event: React.FormEvent) { - event.preventDefault(); - dispatch({ - type: FormActionType.Submit, - }); - } + const onFormSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + const validationErrors = validateErrors(state.values); + + const hasNoErrors = Object.values(validationErrors).every( + (prop) => prop == null || prop === "" + ); + + if (hasNoErrors) { + try { + dispatch({ type: FormActionType.Submit }); + await fetch("/api/send", { + body: JSON.stringify({ data: state.values }), + method: "POST", + }); + } catch (error) { + dispatch({ type: FormActionType.Failed }); + } + } else { + dispatch({ + type: FormActionType.ValidationFailed, + validationErrors: validationErrors, + }); + } + }; return ( - Thank you! - - + + We'll get in touch soon. - + @@ -460,7 +500,9 @@ export function ContactsForm() { placeholder="Peter Smith" isRequired /> - {state.validationErrors.name} + + {state.validationErrors.name} + @@ -534,7 +577,9 @@ export function ContactsForm() { type="email" placeholder="example@yourdomain.com" /> - {state.validationErrors.email} + + {state.validationErrors.email} + @@ -603,7 +649,7 @@ export function ContactsForm() { type="text" placeholder="Hi there..." /> - + {state.validationErrors.message} - {state.submitError} + {state.submitError}