diff --git a/client/package.json b/client/package.json index 5dd6ad1..84cca81 100644 --- a/client/package.json +++ b/client/package.json @@ -18,6 +18,7 @@ "ky": "^0.33.3", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-google-recaptcha-v3": "^1.10.1", "react-i18next": "^12.3.1", "react-input-mask": "^2.0.4", "react-player": "^2.12.0", diff --git a/client/src/App.tsx b/client/src/App.tsx index 5e5cd1f..43c466a 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -18,6 +18,7 @@ import Map from "./components/Map"; import FeedbackFormSuccess from "./components/FeedbackFormSuccess"; import StreamCard2 from "./components/StreamCard2"; import { useParams } from "react-router-dom"; +// import ReCaptcha from "./components/ReCaptcha"; function App() { const params = useParams(); @@ -25,6 +26,7 @@ function App() { const [email, setEmail] = useState(""); const [phone, setPhone] = useState(""); const [request, setRequest] = useState(""); + const [isLoading, setIsLoading] = useState(false); const [isShowComplexCards, setIsShowComplexCards] = useState(false); const [setModalComponent] = useModalStore((state) => [state.setComponent]); const videoRef = useRef(null); @@ -51,25 +53,29 @@ function App() { async function handleSubmitSendMail(e: FormEvent) { e.preventDefault(); - const result: any = await api - .post("mail", { - json: { - fullname, - email, - phone, - request, - }, - }) - .json(); + setIsLoading(true); + + try { + const result: any = await api + .post("mail", { + json: { + fullname, + email, + phone, + request, + }, + }) + .json(); - if (result.ok) { setFullname(""); setEmail(""); setPhone(""); setRequest(""); setModalComponent(); - } else { + setIsLoading(false); + } catch (error) { + setIsLoading(false); alert("Error sending, please try again later."); } } @@ -86,6 +92,10 @@ function App() { setVideoBuffering(false); } + // function handleVerify(token: string) { + // console.log("handleVerify", token); + // } + useEffect(() => { document.title = t("title"); }, [changeLanguage]); @@ -94,6 +104,62 @@ function App() { if (window.location.hash === "#feedback") { setModalComponent(); } + + if (window.location.hash === "#video1") { + setModalComponent( + + ); + } + + if (window.location.hash === "#video2") { + setModalComponent( + + ); + } + + if (window.location.hash === "#video3") { + setModalComponent( + + ); + } + + if (window.location.hash === "#video4") { + setModalComponent( + + ); + } }, []); return ( @@ -951,7 +1017,7 @@ function App() { } location={Россия, Екатеринбург} - video="/videos/RE_Volution_Towers.mp4" + video="/videos/Revolution_Tower-min.mp4" logo={"/images/company_logos/NKS/Normal.svg"} platforms={["touchscreen"]} /> @@ -1210,7 +1276,7 @@ function App() {
@@ -1249,9 +1315,15 @@ function App() {
+ {/* */} + @@ -1266,17 +1338,23 @@ function App() {

Email

-

+ info@graff.tech -

+

Телефон

-

- 8 800 770 00 76 -

+ + 8 800 770 00 67 +
diff --git a/client/src/components/ComplexCard.tsx b/client/src/components/ComplexCard.tsx index dab8efb..0baaf16 100644 --- a/client/src/components/ComplexCard.tsx +++ b/client/src/components/ComplexCard.tsx @@ -1,8 +1,6 @@ -import React, { useEffect, useState } from "react"; -import Modal from "./Modal"; import useModalStore from "../store/modal"; -interface IRelevantExpCard { +interface IComplexCard { image: string; name: string | JSX.Element; location: string | JSX.Element; @@ -11,14 +9,14 @@ interface IRelevantExpCard { platforms: string[]; // touchscreen, vr, mobile } -function RelevantExpCard({ +function ComplexCard({ image, name, location, video, logo, platforms, -}: IRelevantExpCard) { +}: IComplexCard) { const [modalComponent, setModalComponent] = useModalStore((state) => [ state.component, state.setComponent, @@ -164,4 +162,4 @@ function RelevantExpCard({ ); } -export default RelevantExpCard; +export default ComplexCard; diff --git a/client/src/components/FeedbackForm.tsx b/client/src/components/FeedbackForm.tsx index 0c79a0d..ff31f0c 100644 --- a/client/src/components/FeedbackForm.tsx +++ b/client/src/components/FeedbackForm.tsx @@ -15,29 +15,34 @@ function FeedbackForm() { const [email, setEmail] = useState(""); const [phone, setPhone] = useState(""); const [request, setRequest] = useState(""); + const [isLoading, setIsLoading] = useState(false); async function handleSubmitSendMail(e: FormEvent) { e.preventDefault(); - const result: any = await api - .post("mail", { - json: { - fullname, - email, - phone, - request, - }, - }) - .json(); + setIsLoading(true); + + try { + const result: any = await api + .post("mail", { + json: { + fullname, + email, + phone, + request, + }, + }) + .json(); - if (result.ok) { setFullname(""); setEmail(""); setPhone(""); setRequest(""); setModalComponent(); - } else { + setIsLoading(false); + } catch (error) { + setIsLoading(false); alert("Error sending, please try again later."); } } @@ -110,7 +115,7 @@ function FeedbackForm() {
@@ -145,8 +150,12 @@ function FeedbackForm() {
diff --git a/client/src/components/ReCaptcha.tsx b/client/src/components/ReCaptcha.tsx new file mode 100644 index 0000000..5bcde10 --- /dev/null +++ b/client/src/components/ReCaptcha.tsx @@ -0,0 +1,26 @@ +import React, { useCallback, useEffect } from "react"; +import { useGoogleReCaptcha } from "react-google-recaptcha-v3"; + +const ReCaptcha = () => { + const { executeRecaptcha } = useGoogleReCaptcha(); + + // Create an event handler so you can call the verification on button click event or form submit + const handleReCaptchaVerify = useCallback(async () => { + if (!executeRecaptcha) { + console.log("Execute recaptcha not yet available"); + return; + } + + const token = await executeRecaptcha("yourAction"); + // Do whatever you want with the token + }, [executeRecaptcha]); + + // You can use useEffect to trigger the verification as soon as the component being loaded + useEffect(() => { + handleReCaptchaVerify(); + }, [handleReCaptchaVerify]); + + return ; +}; + +export default ReCaptcha; diff --git a/client/src/main.tsx b/client/src/main.tsx index 29881ef..5db9323 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -1,4 +1,3 @@ -import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./i18n"; @@ -7,6 +6,7 @@ import "./index.css"; import DefaultLayout from "./layouts/DefaultLayout"; import StreamPage from "./StreamPage"; import MainVideoPage from "./MainVideoPage"; +// import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3"; const router = createBrowserRouter([ { @@ -15,7 +15,11 @@ const router = createBrowserRouter([ children: [ { index: true, - element: , + element: ( + // + + // + ), }, { path: "/main_video", diff --git a/client/yarn.lock b/client/yarn.lock index 3ac43da..ca2e4a5 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -774,6 +774,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + html-parse-stringify@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" @@ -1158,6 +1165,13 @@ react-fast-compare@^3.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== +react-google-recaptcha-v3@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.1.tgz#5b125bc0dec123206431860e8800e188fc735aff" + integrity sha512-K3AYzSE0SasTn+XvV2tq+6YaxM+zQypk9rbCgG4OVUt7Rh4ze9basIKefoBz9sC0CNslJj9N1uwTTgRMJQbQJQ== + dependencies: + hoist-non-react-statics "^3.3.2" + react-i18next@^12.3.1: version "12.3.1" resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.3.1.tgz#30134a41a2a71c61dc69c6383504929aed1c99e7" @@ -1174,7 +1188,7 @@ react-input-mask@^2.0.4: invariant "^2.2.4" warning "^4.0.2" -react-is@^16.13.1: +react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==