grub775.gitverse.ru
240 строк · 8.7 Кб
1/* eslint-disable react-hooks/exhaustive-deps */
2import React, { Fragment, useEffect, useState } from 'react'
3import Head from 'next/head'
4
5import { useDispatch, useSelector } from 'react-redux'
6
7import { useTranslation } from 'next-i18next'
8import { motion, AnimatePresence } from 'framer-motion'
9import { NextSeo } from 'next-seo'
10import { asyncContactRequest, contactSetRequest } from '@Actions/contact'
11
12// import checkedSVG from '@Public/static/checked.svg'
13import warningSVG from '@Public/static/warning.svg'
14import Image from 'next/image'
15import { AppDispatch, RootState } from '@Src/store'
16import { IContactState } from '@Interfaces/contact'
17
18const ContactContainer = () => {
19const { t } = useTranslation(['contact'])
20const dispatch: AppDispatch = useDispatch()
21const contactState: IContactState = useSelector(
22(state: RootState) => state.contact,
23)
24const [name, setName] = useState('')
25const [email, setEmail] = useState('')
26const [subject, setSubject] = useState('')
27const [message, setMessage] = useState('')
28
29const handleInputName = (event: React.ChangeEvent<HTMLInputElement>) => {
30setName(event.target.value)
31}
32
33const handleInputEmail = (event: React.ChangeEvent<HTMLInputElement>) => {
34setEmail(event.target.value)
35}
36
37const handleInputSubject = (event: React.ChangeEvent<HTMLInputElement>) => {
38setSubject(event.target.value)
39}
40
41const handleInputMessage = (
42event: React.ChangeEvent<HTMLTextAreaElement>,
43) => {
44setMessage(event.target.value)
45}
46
47const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
48event.preventDefault()
49
50if (!contactState.isResponse) {
51dispatch(asyncContactRequest({ name, email, subject, message }))
52}
53}
54
55useEffect(() => {
56if (contactState.isResponse || contactState.prevIsResponse) {
57setTimeout(() => {
58dispatch(
59contactSetRequest({
60isError: false,
61isResponse: false,
62prevIsResponse: false,
63}),
64)
65}, 3000)
66}
67}, [contactState.isResponse, contactState.prevIsResponse])
68
69useEffect(
70() => () => {
71dispatch(
72contactSetRequest({
73isError: false,
74isResponse: false,
75prevIsResponse: false,
76}),
77)
78},
79[],
80)
81
82return (
83<>
84<Head>
85<title>{t('contact:title')}</title>
86</Head>
87<NextSeo
88openGraph={{
89type: 'website',
90title: t('contact:og.title'),
91description: t('contact:og.description'),
92}}
93/>
94<motion.section
95className="contact d-flex flex-column justify-content-center align-items-center"
96key="my_unique_key432"
97initial={{ opacity: 0 }}
98animate={{ opacity: 1 }}
99transition={{ duration: 0.3 }}
100>
101<div className="container">
102<div className="row justify-content-center align-items-center">
103<AnimatePresence mode="wait" initial={false}>
104{contactState.prevIsResponse ? (
105<motion.div
106className="col-12 col-lg-6 text-center mb-30"
107key="my_unique_key4322"
108initial={{ opacity: 0 }}
109animate={{ opacity: 1 }}
110exit={{ opacity: 0 }}
111transition={{ duration: 0.3 }}
112>
113<Image
114className="cap__image mb-10"
115src={warningSVG}
116alt="checked"
117priority
118/>
119<h3 className="cap__title cap__title--medium text-lowercase">
120{t('contact:form.warning-message.title')}
121</h3>
122</motion.div>
123) : (
124<>
125<motion.div
126className="col-12 col-lg-6 text-center"
127key="my_unique_key432222"
128initial={{ opacity: 0 }}
129animate={{ opacity: 1 }}
130exit={{ opacity: 0 }}
131transition={{ duration: 0.3 }}
132>
133<h3 className="cap__title">{t('contact:title')}</h3>
134<h3 className="cap__text">{t('contact:subtitle')}</h3>
135</motion.div>
136
137<motion.div
138className="col-12 col-lg-12"
139key="my_unique_key4322223211"
140initial={{ opacity: 0 }}
141animate={{ opacity: 1 }}
142exit={{ opacity: 0 }}
143transition={{ duration: 0.3 }}
144>
145<div className="row justify-content-center">
146<div className="col-12 col-lg-6 col-xl-6">
147<div className="row d-flex justify-content-center align-items-center h-100">
148<div className="col-12 mb-auto">
149<form
150id="contact"
151className="row disable"
152onSubmit={handleSubmit}
153>
154<div className="col-6 mt-30">
155<input
156name="name"
157minLength={1}
158onChange={handleInputName}
159className="form__input"
160placeholder={t(
161'contact:form.placeholders.name',
162)}
163required
164/>
165</div>
166<div className="col-6 mt-30">
167<input
168name="email"
169type="email"
170onChange={handleInputEmail}
171className="form__input"
172placeholder={t(
173'contact:form.placeholders.email',
174)}
175required
176/>
177</div>
178<div className="col-12 mt-30">
179<input
180name="subject"
181minLength={5}
182onChange={handleInputSubject}
183className="form__input"
184placeholder={t(
185'contact:form.placeholders.subject',
186)}
187required
188/>
189</div>
190
191<div className="col-12 mt-30">
192<textarea
193name="message"
194className="form__input form__textarea"
195onChange={handleInputMessage}
196placeholder={t(
197'contact:form.placeholders.message',
198)}
199minLength={5}
200required
201/>
202</div>
203
204<div className="col-12 mt-30">
205<button
206type="submit"
207className="form__btn ml-auto mr-auto"
208placeholder="Message"
209>
210{contactState.isResponse && (
211<div className="form__btn-loader">
212<div className="dot-floating" />
213</div>
214)}
215<div
216style={{
217opacity: contactState.isResponse ? 0 : 1,
218}}
219>
220{t('contact:form.buttons.send')}
221</div>
222</button>
223</div>
224</form>
225</div>
226</div>
227</div>
228</div>
229</motion.div>
230</>
231)}
232</AnimatePresence>
233</div>
234</div>
235</motion.section>
236</>
237)
238}
239
240export default ContactContainer
241