From 8f25dce7cb5b97f4aacc3de6d1cc89ae41929d51 Mon Sep 17 00:00:00 2001 From: Ian Mancini Date: Thu, 10 Dec 2020 22:57:17 -0300 Subject: [PATCH] Add Contact page --- package-lock.json | 41 +++++++++ package.json | 2 + src/components/Form.tsx | 185 ++++++++++++++++++++++++++++++++++++++++ src/pages/_app.tsx | 13 ++- src/pages/contact.tsx | 40 +++++++++ src/theme.ts | 3 + 6 files changed, 280 insertions(+), 4 deletions(-) create mode 100644 src/components/Form.tsx create mode 100644 src/pages/contact.tsx diff --git a/package-lock.json b/package-lock.json index 9ec2b95..fb88adc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8937,6 +8937,11 @@ "shallowequal": "^1.1.0" } }, + "react-hook-form": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-6.12.2.tgz", + "integrity": "sha512-O72E2DXyk7djFqyy6eYi5yESGweKe0CNHHPS0Mx4JazpLbE4Ox+66ldZ23f0J5ZN/krEjDWRD+hUfg5Shvfhtw==" + }, "react-icons": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.11.0.tgz", @@ -9031,6 +9036,16 @@ } } }, + "react-textarea-autosize": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz", + "integrity": "sha512-3GLWFAan2pbwBeoeNDoqGmSbrShORtgWfaWX0RJDivsUrpShh01saRM5RU/i4Zmf+whpBVEY5cA90Eq8Ub1N3w==", + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" + } + }, "react-textfit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/react-textfit/-/react-textfit-1.1.0.tgz", @@ -10870,6 +10885,11 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "ts-essentials": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz", + "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==" + }, "ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", @@ -11190,6 +11210,27 @@ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.4.tgz", "integrity": "sha512-rXpsyvOnqdScyied4Uglsp14qzag1JIemLeTWGKbwpotWht57hbP78aNT+Q4wdFKQfQibbUX4fb6Qb4y11aVOQ==" }, + "use-composed-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", + "requires": { + "ts-essentials": "^2.0.3" + } + }, + "use-isomorphic-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.0.tgz", + "integrity": "sha512-kady5Z1O1qx5RitodCCKbpJSVEtECXYcnBnb5Q48Bz5V6gBmTu85ZcGdVwVFs8+DaOurNb/L5VdGHoQRMknghw==" + }, + "use-latest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", + "requires": { + "use-isomorphic-layout-effect": "^1.0.0" + } + }, "use-sidecar": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.3.tgz", diff --git a/package.json b/package.json index 88cdc5d..492227a 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,10 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "react-headroom": "^3.0.0", + "react-hook-form": "^6.12.2", "react-icons": "^3.11.0", "react-markdown": "^5.0.3", + "react-textarea-autosize": "^8.3.0", "react-textfit": "^1.1.0", "responsive-loader": "^2.2.0", "sharp": "^0.26.3", diff --git a/src/components/Form.tsx b/src/components/Form.tsx new file mode 100644 index 0000000..ca7ad25 --- /dev/null +++ b/src/components/Form.tsx @@ -0,0 +1,185 @@ +import { useState, forwardRef } from 'react' +import { useFormContext } from 'react-hook-form' +import TextareaAutosize from 'react-textarea-autosize' +import { + Button, + Flex, + Stack, + Box, + Text, + Input, + FormControl, + FormErrorMessage, + InputProps, + Textarea, +} from '@chakra-ui/react' + +const CustomInput = forwardRef( + ({ name, ...props }, ref) => { + return ( + + ) + }, +) + +CustomInput.displayName = 'CustomInput' + +type FormFields = { + name: string + email: string + message: string +} + +const sendMessage = async () => { + return new Promise((resolve) => { + setTimeout(() => { + alert('¡Este formulario no es real!') + resolve(true) + }, 1500) + }) +} + +const ContactForm: React.FC = () => { + const [sending, setSending] = useState(false) + const [error, setError] = useState(false) + + const { formState, register, handleSubmit, errors, reset } = useFormContext() + const { isSubmitSuccessful } = formState + + const onSubmit = async (/* data: FormFields */) => { + setSending(true) + setError(false) + + sendMessage() + .then(() => { + setSending(false) + setError(false) + }) + .catch(() => { + setSending(false) + setError(true) + }) + } + + const buttonText = (() => { + if (sending) { + return 'Enviando' + } + if (isSubmitSuccessful) { + return '¡Enviado!' + } + return 'Enviar' + })() + + return ( + + + + + Este campo es obligatorio + + + + + + {errors.email + ? errors.email.type === 'required' + ? 'Este campo es obligatorio' + : null || errors.email.type === 'pattern' + ? 'La dirección de correo electrónico no es válida' + : null + : null} + + + + +