158 lines
4.5 KiB
JavaScript
158 lines
4.5 KiB
JavaScript
import { yupResolver } from '@hookform/resolvers/yup';
|
|
import _ from '@lodash';
|
|
import Button from '@mui/material/Button';
|
|
import TextField from '@mui/material/TextField';
|
|
import { forwardRef, memo, useState } from 'react';
|
|
import { Controller, useForm } from 'react-hook-form';
|
|
import { withTranslation } from 'react-i18next';
|
|
import * as yup from 'yup';
|
|
|
|
const defaultValues = {
|
|
name: '',
|
|
email: '',
|
|
message: '',
|
|
};
|
|
|
|
const StyledTextField = forwardRef((props, ref) => (
|
|
<TextField
|
|
InputProps={{
|
|
sx: {
|
|
background: (theme) => theme.palette.background.paper,
|
|
borderRadius: '10px',
|
|
},
|
|
}}
|
|
{...props}
|
|
ref={ref}
|
|
/>
|
|
));
|
|
|
|
function FeedbackForm({ t }) {
|
|
const [isFormSubmitted, setIsFormSubmitted] = useState(false);
|
|
|
|
const schema = yup.object().shape({
|
|
name: yup.string().required(t('feedback_required')),
|
|
email: yup.string().email(t('feedback_email_error')).required(t('feedback_required')),
|
|
message: yup
|
|
.string()
|
|
.required(t('feedback_required'))
|
|
.min(5, t('min_length_error', { length: 5 }))
|
|
.max(255, t('max_length_error', { length: 255 })),
|
|
});
|
|
|
|
const { control, formState, handleSubmit, setError } = useForm({
|
|
mode: 'onChange',
|
|
defaultValues,
|
|
resolver: yupResolver(schema),
|
|
});
|
|
|
|
const { isValid, dirtyFields, errors } = formState;
|
|
|
|
function onSubmit() {
|
|
// setError('root', 'error');
|
|
setIsFormSubmitted(true);
|
|
}
|
|
|
|
return (
|
|
<section id="contacts" className="pt-72 mb-88">
|
|
{!isFormSubmitted && (
|
|
<form
|
|
name="signinForm"
|
|
noValidate
|
|
className="grid grid-cols-2 gap-x-20 gap-y-32 px-80 py-40 bg-primary-light rounded-20"
|
|
onSubmit={handleSubmit(onSubmit)}
|
|
>
|
|
<legend className="col-span-2 justify-self-center max-w-[860px] mb-8 text-4xl font-medium text-center">
|
|
{t('feedback_title')}
|
|
</legend>
|
|
|
|
<Controller
|
|
name="name"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<StyledTextField
|
|
{...field}
|
|
label={t('feedback_name')}
|
|
type="text"
|
|
error={!!errors.name}
|
|
helperText={errors?.name?.message}
|
|
variant="outlined"
|
|
required
|
|
fullWidth
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="email"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<StyledTextField
|
|
{...field}
|
|
label={t('feedback_email')}
|
|
type="email"
|
|
error={!!errors.email}
|
|
helperText={errors?.email?.message}
|
|
variant="outlined"
|
|
required
|
|
fullWidth
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<Controller
|
|
name="message"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<TextField
|
|
{...field}
|
|
className="col-span-2 mb-8"
|
|
label={t('feedback_message')}
|
|
type="text"
|
|
error={!!errors.message}
|
|
helperText={errors?.message?.message}
|
|
variant="outlined"
|
|
required
|
|
multiline
|
|
rows={5}
|
|
fullWidth
|
|
InputProps={{
|
|
sx: {
|
|
padding: 0,
|
|
background: (theme) => theme.palette.background.paper,
|
|
borderRadius: '10px',
|
|
},
|
|
}}
|
|
// eslint-disable-next-line react/jsx-no-duplicate-props
|
|
inputProps={{
|
|
sx: {
|
|
padding: '16.5px 14px',
|
|
},
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
<div className="col-span-2 justify-self-center flex flex-col items-center justify-center gap-10 w-full">
|
|
<Button
|
|
variant="contained"
|
|
color="secondary"
|
|
className="w-[220px] text-base uppercase rounded-xl"
|
|
aria-label={t('feedback_btn')}
|
|
disabled={_.isEmpty(dirtyFields) || !isValid}
|
|
type="submit"
|
|
size="large"
|
|
>
|
|
{t('feedback_btn')}
|
|
</Button>
|
|
{errors.root?.message && (
|
|
<p className="text-l text-error-main">{errors.root?.message}</p>
|
|
)}
|
|
</div>
|
|
</form>
|
|
)}
|
|
</section>
|
|
);
|
|
}
|
|
|
|
export default withTranslation('homePage')(memo(FeedbackForm));
|