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