parent
7e11780f1c
commit
8f25dce7cb
@ -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<HTMLInputElement, InputProps>(
|
||||||
|
({ name, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
name={name}
|
||||||
|
type="text"
|
||||||
|
variant="flushed"
|
||||||
|
borderColor="gray"
|
||||||
|
borderBottomWidth="1px"
|
||||||
|
focusBorderColor="primary"
|
||||||
|
ref={ref}
|
||||||
|
_disabled={{ color: 'gray' }}
|
||||||
|
_autofill={{ background: 'none' }}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<Box w="100%">
|
||||||
|
<Stack
|
||||||
|
as="form"
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
flexDir="column"
|
||||||
|
flexWrap="nowrap"
|
||||||
|
w="480px"
|
||||||
|
maxW="calc(100% - 4rem)"
|
||||||
|
m="2rem auto"
|
||||||
|
spacing="3rem"
|
||||||
|
>
|
||||||
|
<FormControl id="name" isInvalid={errors.name}>
|
||||||
|
<CustomInput
|
||||||
|
name="name"
|
||||||
|
placeholder="Nombre"
|
||||||
|
aria-label="Nombre"
|
||||||
|
disabled={isSubmitSuccessful}
|
||||||
|
ref={register({ required: true })}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage>Este campo es obligatorio</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl id="email" isInvalid={errors.email}>
|
||||||
|
<CustomInput
|
||||||
|
name="email"
|
||||||
|
placeholder="e-mail"
|
||||||
|
aria-label="e-mail"
|
||||||
|
disabled={isSubmitSuccessful}
|
||||||
|
ref={register({
|
||||||
|
required: true,
|
||||||
|
pattern: /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage>
|
||||||
|
{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}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl id="message" isInvalid={errors.message}>
|
||||||
|
<Textarea
|
||||||
|
as={TextareaAutosize}
|
||||||
|
minRows={1}
|
||||||
|
borderBottomWidth="1px"
|
||||||
|
name="message"
|
||||||
|
aria-label="mensaje"
|
||||||
|
placeholder="Mensaje"
|
||||||
|
resize="none"
|
||||||
|
minH={0}
|
||||||
|
variant="flushed"
|
||||||
|
borderColor="gray"
|
||||||
|
focusBorderColor="primary"
|
||||||
|
overflow="hidden"
|
||||||
|
disabled={isSubmitSuccessful}
|
||||||
|
ref={register({ required: true })}
|
||||||
|
_disabled={{ color: 'gray' }}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage>Este campo es obligatorio</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<Flex>
|
||||||
|
<Input
|
||||||
|
type="submit"
|
||||||
|
disabled={sending || isSubmitSuccessful}
|
||||||
|
opacity="1 !important"
|
||||||
|
value={buttonText}
|
||||||
|
bg={sending ? 'lightGray' : isSubmitSuccessful ? 'green' : 'blue'}
|
||||||
|
borderRadius="primary"
|
||||||
|
color={sending ? 'gray' : 'white'}
|
||||||
|
cursor={!sending || !isSubmitSuccessful ? 'pointer' : 'default'}
|
||||||
|
fontWeight="bold"
|
||||||
|
border="none"
|
||||||
|
outline="none"
|
||||||
|
py="1em"
|
||||||
|
fontSize="xl"
|
||||||
|
h="auto"
|
||||||
|
w="100%"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
{error ? (
|
||||||
|
<Text color="red.500">
|
||||||
|
Ocurrió un error. Por favor, intentalo nuevamente más tarde.
|
||||||
|
</Text>
|
||||||
|
) : null}
|
||||||
|
{isSubmitSuccessful ? (
|
||||||
|
<Button variant="link" onClick={() => reset()}>
|
||||||
|
Enviar un nuevo mensaje
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ContactForm
|
@ -0,0 +1,40 @@
|
|||||||
|
import { Heading, Text, Box, Flex } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
import ReactMarkdown from 'react-markdown'
|
||||||
|
import SEO from '../components/SEO'
|
||||||
|
import Form from '../components/Form'
|
||||||
|
|
||||||
|
const Contact: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SEO title="Contact" />
|
||||||
|
<Box w={['100%', '100%', '1220px']} pt="2rem" px="1rem" mx="auto">
|
||||||
|
<Flex wrap="wrap">
|
||||||
|
<Box w="50%" pr="3rem">
|
||||||
|
<Heading fontSize={['3xl', '3xl', '7xl']} mb="3rem">
|
||||||
|
¡Trabajemos juntes!
|
||||||
|
</Heading>
|
||||||
|
</Box>
|
||||||
|
<Box w="50%" pt="6rem">
|
||||||
|
<Text
|
||||||
|
as={ReactMarkdown}
|
||||||
|
fontWeight="300"
|
||||||
|
lineHeight="1.9"
|
||||||
|
pb="2rem"
|
||||||
|
sx={{ p: { display: 'block', pb: '2rem' } }}
|
||||||
|
>
|
||||||
|
Mandanos un mensaje y encaremos ese proyecto que tenés en mente :D
|
||||||
|
</Text>
|
||||||
|
<Form />
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Contact
|
||||||
|
|
||||||
|
export async function getStaticProps() {
|
||||||
|
return { props: {} }
|
||||||
|
}
|
Loading…
Reference in new issue