diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index 5cda4d6..6d49650 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/package.json b/package.json index 84e98e2..cf024d2 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "react-string-replace": "^1.1.1", "react-syntax-highlighter": "^15.5.0", "react-tippy": "^1.4.0", + "react-toastify": "^10.0.4", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "styled-components": "^6.1.8", diff --git a/src/components/molecules/ContactForm/ContactForm.tsx b/src/components/molecules/ContactForm/ContactForm.tsx index 3ee4c87..8739441 100644 --- a/src/components/molecules/ContactForm/ContactForm.tsx +++ b/src/components/molecules/ContactForm/ContactForm.tsx @@ -1,31 +1,29 @@ 'use client'; import { Form, Formik } from 'formik'; -import { useEffect, useRef, useState } from 'react'; +import { useTheme } from 'next-themes'; +import React, { useEffect, useRef, useState } from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; import { Trans, useTranslation } from 'react-i18next'; +import { toast, ToastContainer } from 'react-toastify'; import * as Yup from 'yup'; +import 'react-toastify/dist/ReactToastify.css'; + import Button from '@/components/atoms/buttons/Button'; import { Input } from './Input'; import { Select } from './Select'; import { TextArea } from './TextArea'; -export interface Subject { - key: string; - value: string; -} - const ContactForm = () => { - const [success, setSuccess] = useState(false); - const [error, setError] = useState(false); - const recaptchaRef = useRef(null); const [isVerified, setIsVerified] = useState(false); const reCaptchaSiteKey = '6LcSyzAoAAAAAC7JTJ6gtOWW3cjTK_vKRm2WjEtC'; + const { theme } = useTheme(); + async function handleCaptchaSubmission(token: string | null) { const res = await fetch('/api/recaptcha', { body: JSON.stringify({ token }), @@ -41,12 +39,37 @@ const ContactForm = () => { setIsVerified(true); } else { setIsVerified(false); - setError(true); + showError(); // eslint-disable-next-line no-console console.error(error); } } + function showSuccess() { + toast(t('contacts.success'), { + type: 'success', + }); + } + + function showError() { + toast( + () => { + return ( + <> + + + info@martacodes.it + + + ); + }, + { + autoClose: 10000, + type: 'error', + }, + ); + } + useEffect(() => {}, [isVerified]); const { t } = useTranslation(); @@ -82,9 +105,6 @@ const ContactForm = () => { ) => { const json = JSON.stringify(formValues, null, 2); - setError(false); - setSuccess(false); - const res = await fetch('/api/contacts/send', { body: json, headers: { @@ -96,13 +116,13 @@ const ContactForm = () => { const { error } = await res.json(); if (error) { - setError(true); + showError(); setSubmitting(false); return; } setSubmitting(false); - setSuccess(true); + showSuccess(); resetForm(); recaptchaRef.current?.reset(); }; @@ -124,20 +144,6 @@ const ContactForm = () => { {({ isSubmitting }) => { return (
- {success && ( -
- {t('contacts.success')} -
- )} - {error && ( -
- - - info@martacodes.it - -
- )} - { : t('contacts.button.send')} + + ); }} diff --git a/src/styles/globals.css b/src/styles/globals.css index 82f0edd..1d7b803 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -36,6 +36,9 @@ --secondary-color-light: rgb(135, 208, 248); --primary-color-dark: rgb(74, 76, 204); --secondary-color-dark: rgb(95, 209, 249); + + /* Toastify */ + --toastify-toast-width: 450px !important; } /* Dark theme */ diff --git a/yarn.lock b/yarn.lock index 173ddae..492cc99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13688,6 +13688,7 @@ __metadata: react-string-replace: "npm:^1.1.1" react-syntax-highlighter: "npm:^15.5.0" react-tippy: "npm:^1.4.0" + react-toastify: "npm:^10.0.4" rehype-raw: "npm:^7.0.0" remark-gfm: "npm:^4.0.0" storybook: "npm:^7.6.16" @@ -17242,6 +17243,18 @@ __metadata: languageName: node linkType: hard +"react-toastify@npm:^10.0.4": + version: 10.0.4 + resolution: "react-toastify@npm:10.0.4" + dependencies: + clsx: "npm:^2.1.0" + peerDependencies: + react: ">=16" + react-dom: ">=16" + checksum: 3d31edf81e8b394fd0085615fd7ba9fb9546c7cdae56e5334df67b58d65450c73af14a8fc163f19ceed03cfee7a344d1af1489422536f52c9516ca45e9b61a37 + languageName: node + linkType: hard + "react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5"