mirror of
https://github.com/theoludwig/theoludwig.git
synced 2025-05-29 22:37:44 +02:00
feat: add divlo.fr
This commit is contained in:
31
components/Contact/FormResult.tsx
Normal file
31
components/Contact/FormResult.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { FormState } from './FormState'
|
||||
import { ResultState } from './index'
|
||||
|
||||
export interface FormResultProps {
|
||||
state: ResultState
|
||||
}
|
||||
|
||||
export const FormResult: React.FC<FormResultProps> = (props) => {
|
||||
const { state } = props
|
||||
const { t } = useTranslation()
|
||||
|
||||
if (state === 'idle') {
|
||||
return null
|
||||
}
|
||||
|
||||
if (state === 'loading' || state === 'success') {
|
||||
return (
|
||||
<FormState state={state}>
|
||||
{t(`home:contact.result.${state}`)}
|
||||
</FormState>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<FormState state='error'>
|
||||
{t(`home:contact.result.${state}`)}
|
||||
</FormState>
|
||||
)
|
||||
}
|
39
components/Contact/FormState.tsx
Normal file
39
components/Contact/FormState.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
export interface FormStateProps extends React.ComponentPropsWithRef<'p'> {
|
||||
state: 'success' | 'error' | 'loading'
|
||||
children: string
|
||||
}
|
||||
|
||||
export const FormState: React.FC<FormStateProps> = props => {
|
||||
const { state, children, ...rest } = props
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='form-result text-center'>
|
||||
<p className={state} {...rest}>
|
||||
{['error', 'success'].includes(state) && (
|
||||
<b>
|
||||
{state === 'error' ? t('home:contact.error') : t('home:contact.success')}:
|
||||
</b>
|
||||
)}{' '}
|
||||
{children}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style jsx>{`
|
||||
.form-result {
|
||||
margin: 30px;
|
||||
}
|
||||
.success {
|
||||
color: #90ee90;
|
||||
}
|
||||
.error {
|
||||
color: #ff7f7f;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</>
|
||||
)
|
||||
}
|
89
components/Contact/index.tsx
Normal file
89
components/Contact/index.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
import { useState } from 'react'
|
||||
import Form, { HandleForm } from 'react-component-form'
|
||||
import axios from 'axios'
|
||||
|
||||
import { Input } from 'components/design/Input'
|
||||
import { Button } from 'components/design/Button'
|
||||
import { Textarea } from 'components/design/Textarea'
|
||||
import { FormResult } from './FormResult'
|
||||
|
||||
export const resultState = [
|
||||
'idle',
|
||||
'success',
|
||||
'loading',
|
||||
'requiredFields',
|
||||
'invalidEmail',
|
||||
'serverError'
|
||||
] as const
|
||||
|
||||
export type ResultState = typeof resultState[number]
|
||||
|
||||
export const Contact: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const [state, setState] = useState<ResultState>('idle')
|
||||
|
||||
const handleSubmit: HandleForm = async (formData, formElement) => {
|
||||
setState('loading')
|
||||
try {
|
||||
const { data } = await axios.post<{ type: ResultState }>(
|
||||
'/api/send-email',
|
||||
formData
|
||||
)
|
||||
if (data.type === 'success') {
|
||||
setState('success')
|
||||
return formElement.reset()
|
||||
}
|
||||
return setState('serverError')
|
||||
} catch (error) {
|
||||
const type = error.response.data.type
|
||||
if (resultState.includes(type)) {
|
||||
return setState(type)
|
||||
}
|
||||
return setState('serverError')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='col-24'>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<Input
|
||||
label={`${t('home:contact.nameField')} :`}
|
||||
type='text'
|
||||
name='name'
|
||||
autoComplete='off'
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
label='Email :'
|
||||
type='email'
|
||||
name='email'
|
||||
autoComplete='off'
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
label={`${t('home:contact.subjectField')} :`}
|
||||
type='text'
|
||||
name='subject'
|
||||
autoComplete='off'
|
||||
required
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
label='Message :'
|
||||
name='message'
|
||||
autoComplete='off'
|
||||
required
|
||||
/>
|
||||
|
||||
<div className='text-center'>
|
||||
<Button type='submit'>{t('home:contact.sendEmail')}</Button>
|
||||
</div>
|
||||
</Form>
|
||||
|
||||
<FormResult state={state} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
Reference in New Issue
Block a user