Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

ClientForm.jsx 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import React, { useRef } from 'react';
  2. import TagInput from '../TagInput';
  3. import img from '../../assets/images/Inqueries.png';
  4. import * as Yup from 'yup';
  5. import { Formik, Form, ErrorMessage } from 'formik';
  6. import { ClientFormContext } from '../../context';
  7. import { useContext, useState } from 'react';
  8. import * as emailjs from 'emailjs-com';
  9. import { motion } from 'framer-motion';
  10. import ReactGA from 'react-ga4';
  11. import ReCAPTCHA from 'react-google-recaptcha';
  12. import axios from 'axios';
  13. import { useEffect } from 'react';
  14. const api_url = process.env.REACT_APP_API_URL;
  15. export default function ClientForm({ mg, img, cta }) {
  16. //search context for prevous entry TODO
  17. const [btnText, setBtnText] = useState('');
  18. const { clientForm, setClientForm } = useContext(ClientFormContext);
  19. const [sucMsg, setSucMsg] = useState(false);
  20. const captchaRef = useRef(null);
  21. const [msgText, setMsgText] = useState('');
  22. const changeFormHandler = event => {
  23. const { name, value } = event.target;
  24. setClientForm({
  25. ...clientForm,
  26. [name]: value,
  27. });
  28. };
  29. useEffect(() => {
  30. setBtnText(cta);
  31. },[cta]);
  32. const validationSchema = Yup.object({
  33. subject: Yup.string()
  34. .min(2, 'Subject too short')
  35. .max(50, 'Subject too long')
  36. .required('Subject is Required'),
  37. email: Yup.string().email('Invalid email format').required('Email is Required'),
  38. firstName: Yup.string()
  39. .min(2, 'First name too short')
  40. .max(50, 'First name too long')
  41. .required('First Name is Required'),
  42. lastName: Yup.string()
  43. .min(2, 'Last name too short')
  44. .max(50, 'Last name too long')
  45. .required('Last Name is Required'),
  46. description: Yup.string()
  47. .trim()
  48. .min(2, 'Description too short')
  49. .required('Description is Required'),
  50. });
  51. return (
  52. <div className="mt-10 sm:mt-0 mx-auto">
  53. <div className="md:grid md:grid-cols-2 md:gap-6">
  54. <motion.div
  55. className="mt-5 md:mt-0 md:col-span-1"
  56. initial={{ x: -60, opacity: 0 }}
  57. animate={{ x: 0, opacity: 1 }}
  58. exit={{ x: -60, opacity: 0 }}
  59. transition={{ duration: 0.3, ease: 'easeOut' }}
  60. >
  61. <Formik
  62. initialValues={clientForm}
  63. validationSchema={validationSchema}
  64. onSubmit={async values => {
  65. const data = {
  66. Tag: values.tag,
  67. Subject: values.subject,
  68. Email: values.email,
  69. Firstname: values.firstName,
  70. Lastname: values.lastName,
  71. Description: values.description,
  72. };
  73. const token = captchaRef.current.getValue();
  74. captchaRef.current.reset();
  75. if (token.length === 0) {
  76. setSucMsg(true);
  77. setMsgText('Please fill reCAPTCHA and try again. Thank you!');
  78. } else {
  79. await axios
  80. .post(`${process.env.REACT_APP_CAPTCHA_API}/verify-token`, { token })
  81. .then(res => {
  82. setSucMsg(true);
  83. if (res.data.data.success) {
  84. setMsgText('Submission Succesful! Thank you!');
  85. mg.messages.create('dilig.net', {
  86. from: `${values.firstName} ${values.lastName} <${values.email}>`,
  87. to: ['hr@dilig.net'],
  88. subject: `${values.subject}`,
  89. text: `${values.description}`,
  90. html: `<p>${values.description}</p>`,
  91. });
  92. } else setMsgText('Please fill reCAPTCHA and try again. Thank you!');
  93. })
  94. .catch(error => {
  95. //console.log(error);
  96. });
  97. }
  98. ReactGA.event('contact', {
  99. category: 'Contact',
  100. action: 'Business Inquiry',
  101. });
  102. }}
  103. >
  104. {props => (
  105. <Form onSubmit={props.handleSubmit}>
  106. <div className=" sm:rounded-md">
  107. <div className="py-2 sm:py-6">
  108. <div className="">
  109. <div className="col-span-1 sm:col-span-1">
  110. <div className="py-1">
  111. <TagInput changeFormHandler={changeFormHandler} props={props} />
  112. </div>
  113. <div className="py-1">
  114. <label
  115. htmlFor="first-name"
  116. className="block text-sm font-medium text-gray-700 dark:text-gray-400"
  117. >
  118. First name
  119. </label>
  120. <input
  121. type="text"
  122. name="firstName"
  123. id="firstName"
  124. onBlur={changeFormHandler}
  125. value={props.values.firstName}
  126. onChange={props.handleChange}
  127. autoComplete="given-name"
  128. className="mt-1 focus:ring-dg-primary-600 focus:border-dg-primary-900 dark:bg-dg-primary-1500 dark:text-white block w-full shadow-sm sm:text-sm border-dg-primary-600 rounded-md transition duration-200"
  129. />
  130. <div className="h-4">
  131. <ErrorMessage
  132. name="firstName"
  133. component="div"
  134. className="text-sm text-right text-red-600"
  135. />
  136. </div>
  137. </div>
  138. <div className="py-1">
  139. <label
  140. htmlFor="last-name"
  141. className="block text-sm font-medium text-gray-700 dark:text-gray-400"
  142. >
  143. Last name
  144. </label>
  145. <input
  146. onBlur={changeFormHandler}
  147. type="text"
  148. name="lastName"
  149. id="lastName"
  150. value={props.values.lastName}
  151. onChange={props.handleChange}
  152. autoComplete="family-name"
  153. className="mt-1 focus:ring-dg-primary-900 focus:border-dg-primary-900 dark:bg-dg-primary-1500 dark:text-white block w-full shadow-sm sm:text-sm border-dg-primary-600 rounded-md transition duration-200"
  154. />
  155. <div className="h-4">
  156. <ErrorMessage
  157. name="lastName"
  158. component="div"
  159. className="text-sm text-right text-red-600"
  160. />
  161. </div>
  162. </div>
  163. <div className="py-1">
  164. <label
  165. htmlFor="email"
  166. className="block text-sm font-medium text-gray-700 dark:text-gray-400"
  167. >
  168. Email
  169. </label>
  170. <input
  171. onBlur={changeFormHandler}
  172. type="email"
  173. name="email"
  174. id="email"
  175. value={props.values.email}
  176. onChange={props.handleChange}
  177. autoComplete="email"
  178. className="mt-1 focus:ring-dg-primary-900 focus:border-dg-primary-900 dark:bg-dg-primary-1500 dark:text-white dark:autofill:text-white dark:autofill:bg-dg-primary-1500 block w-full shadow-sm sm:text-sm border-dg-primary-600 rounded-md transition duration-200"
  179. />
  180. <div className="h-4">
  181. <ErrorMessage
  182. name="email"
  183. component="div"
  184. className="text-sm text-right text-red-600"
  185. />
  186. </div>
  187. </div>
  188. {/* <div className="form-check py-2">
  189. <input
  190. className="form-check-input appearance-none h-6 w-6 border text-dg-primary-900 border-dg-primary-600 rounded-sm bg-white checked:dg-primary-900 checked:border-dg-primary-900 focus:outline-none transition duration-200 align-top bg-no-repeat bg-center bg-contain float-left cursor-pointer focus:ring-dg-primary-900"
  191. type="checkbox"
  192. value=""
  193. id="meeting"
  194. />
  195. <label
  196. className="ml-3 form-check-label inline-block text-gray-800"
  197. htmlFor="meeting"
  198. >
  199. Schedule a meeting right away
  200. </label>
  201. </div> */}
  202. <div className="py-1">
  203. <label
  204. htmlFor="Description"
  205. className="block text-sm font-medium text-gray-700 dark:text-gray-400"
  206. >
  207. Description
  208. </label>
  209. <textarea
  210. onBlur={changeFormHandler}
  211. type="text"
  212. placeholder="Describe your question or proposition..."
  213. className="resize-y min-h-12 h-32 rounded-md mt-1 text-base focus:ring-dg-primary-900 focus:border-dg-primary-900 dark:bg-dg-primary-1500 dark:text-white sm:text-sm border-dg-primary-600 block w-full shadow-sm transition duration-200"
  214. name="description"
  215. id="description"
  216. value={props.values.description}
  217. onChange={props.handleChange}
  218. ></textarea>
  219. <div className="h-4">
  220. <ErrorMessage
  221. name="description"
  222. component="div"
  223. className="text-sm text-right text-red-600"
  224. />
  225. </div>
  226. </div>
  227. <div className="items-center justify-end flex">
  228. <ReCAPTCHA
  229. sitekey={process.env.REACT_APP_SITE_KEY}
  230. ref={captchaRef}
  231. />
  232. </div>
  233. <div className=" py-3 text-right">
  234. <button
  235. type="submit"
  236. className="btn btn_primary transition-all inline-flex justify-center py-4 px-14 border border-transparent shadow-md text-sm font-semibold rounded-xl text-white bg-dg-primary-600 hover:bg-dg-primary-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dg-primary-600"
  237. >
  238. {btnText}
  239. </button>
  240. </div>
  241. {sucMsg && (
  242. <div className={'text-sm text-right text-dg-primary-900'}>
  243. {msgText}
  244. </div>
  245. )}
  246. </div>
  247. <div className="col-span-1 sm:col-span-1 lg:col-span-1"></div>
  248. </div>
  249. </div>
  250. </div>
  251. </Form>
  252. )}
  253. </Formik>
  254. </motion.div>
  255. <motion.div
  256. className="mt-5 md:mt-0 md:col-span-1 flex items-center"
  257. initial={{ x: 60, opacity: 0 }}
  258. animate={{ x: 0, opacity: 1 }}
  259. exit={{ x: 60, opacity: 0 }}
  260. transition={{ duration: 0.3, ease: 'easeOut' }}
  261. >
  262. <img src={api_url + img.data.attributes.url} alt={img.data.attributes.alternativeText} />
  263. </motion.div>
  264. </div>
  265. </div>
  266. );
  267. }