upd
This commit is contained in:
@@ -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",
|
||||
|
||||
+98
-20
@@ -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<string>("");
|
||||
const [phone, setPhone] = useState<string>("");
|
||||
const [request, setRequest] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [isShowComplexCards, setIsShowComplexCards] = useState<boolean>(false);
|
||||
const [setModalComponent] = useModalStore((state) => [state.setComponent]);
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
@@ -51,25 +53,29 @@ function App() {
|
||||
async function handleSubmitSendMail(e: FormEvent<HTMLFormElement>) {
|
||||
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(<FeedbackFormSuccess />);
|
||||
} 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(<FeedbackForm />);
|
||||
}
|
||||
|
||||
if (window.location.hash === "#video1") {
|
||||
setModalComponent(
|
||||
<video
|
||||
muted={true}
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
controls={true}
|
||||
className="aspect-video w-full max-h-screen"
|
||||
>
|
||||
<source src="/videos/Revolution_Tower-min.mp4" type="video/mp4" />
|
||||
</video>
|
||||
);
|
||||
}
|
||||
|
||||
if (window.location.hash === "#video2") {
|
||||
setModalComponent(
|
||||
<video
|
||||
muted={true}
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
controls={true}
|
||||
className="aspect-video w-full max-h-screen"
|
||||
>
|
||||
<source src="/videos/Life_Residence-min.mp4" type="video/mp4" />
|
||||
</video>
|
||||
);
|
||||
}
|
||||
|
||||
if (window.location.hash === "#video3") {
|
||||
setModalComponent(
|
||||
<video
|
||||
muted={true}
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
controls={true}
|
||||
className="aspect-video w-full max-h-screen"
|
||||
>
|
||||
<source src="/videos/Masharov.mp4" type="video/mp4" />
|
||||
</video>
|
||||
);
|
||||
}
|
||||
|
||||
if (window.location.hash === "#video4") {
|
||||
setModalComponent(
|
||||
<video
|
||||
muted={true}
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
controls={true}
|
||||
className="aspect-video w-full max-h-screen"
|
||||
>
|
||||
<source src="/videos/Iskan_Abu_Dhabi.mp4" type="video/mp4" />
|
||||
</video>
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -951,7 +1017,7 @@ function App() {
|
||||
</Trans>
|
||||
}
|
||||
location={<Trans i18nKey="city1">Россия, Екатеринбург</Trans>}
|
||||
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() {
|
||||
<input
|
||||
required
|
||||
type="checkbox"
|
||||
defaultChecked={true}
|
||||
defaultChecked={false}
|
||||
className="absolute opacity-0 h-10 w-10 cursor-pointer"
|
||||
/>
|
||||
<div className="bg-[#212431] rounded-lg h-10 w-10 p-1">
|
||||
@@ -1249,9 +1315,15 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <ReCaptcha /> */}
|
||||
|
||||
<button
|
||||
disabled={isLoading}
|
||||
type="submit"
|
||||
className="2xl:text-3xl sm:text-2xl text-lg w-full px-8 py-4 bg-gradient-to-tr from-[#BC75FF] to-[#798FFF] rounded-full opacity-95 hover:opacity-100 transition-opacity"
|
||||
className={[
|
||||
"2xl:text-3xl sm:text-2xl text-lg w-full px-8 py-4 bg-gradient-to-tr from-[#BC75FF] to-[#798FFF] rounded-full transition-opacity",
|
||||
isLoading ? "opacity-50" : "opacity-95 hover:opacity-100",
|
||||
].join(" ")}
|
||||
>
|
||||
<Trans i18nKey="contactUsBtn">Отправить заявку</Trans>
|
||||
</button>
|
||||
@@ -1266,17 +1338,23 @@ function App() {
|
||||
<p className="2xl:text-xl sm:text-lg text-[#8088A7]">
|
||||
Email
|
||||
</p>
|
||||
<p className="2xl:text-3xl sm:text-2xl text-xl">
|
||||
<a
|
||||
href="mailto:info@graff.tech"
|
||||
className="2xl:text-3xl sm:text-2xl text-xl"
|
||||
>
|
||||
info@graff.tech
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<p className="2xl:text-xl sm:text-lg text-[#8088A7]">
|
||||
<Trans i18nKey="feedbackTitle2">Телефон</Trans>
|
||||
</p>
|
||||
<p className="2xl:text-3xl sm:text-2xl text-xl">
|
||||
<Trans i18nKey="phoneСountryСode">8</Trans> 800 770 00 76
|
||||
</p>
|
||||
<a
|
||||
href="tel:+78007700067"
|
||||
className="2xl:text-3xl sm:text-2xl text-xl"
|
||||
>
|
||||
<Trans i18nKey="phoneСountryСode">8</Trans> 800 770 00 67
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-8">
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -15,29 +15,34 @@ function FeedbackForm() {
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [phone, setPhone] = useState<string>("");
|
||||
const [request, setRequest] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
async function handleSubmitSendMail(e: FormEvent<HTMLFormElement>) {
|
||||
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(<FeedbackFormSuccess />);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
alert("Error sending, please try again later.");
|
||||
}
|
||||
}
|
||||
@@ -110,7 +115,7 @@ function FeedbackForm() {
|
||||
<input
|
||||
required
|
||||
type="checkbox"
|
||||
defaultChecked={true}
|
||||
defaultChecked={false}
|
||||
className="absolute opacity-0 h-10 w-10 cursor-pointer"
|
||||
/>
|
||||
<div className="bg-[#212431] rounded-lg h-10 w-10 p-1">
|
||||
@@ -145,8 +150,12 @@ function FeedbackForm() {
|
||||
</div>
|
||||
|
||||
<button
|
||||
disabled={isLoading}
|
||||
type="submit"
|
||||
className="2xl:text-3xl sm:text-2xl lg:text-lg w-full xl:px-8 lg:px-6 px-4 xl:py-4 lg:py-3 py-2 bg-gradient-to-tr from-[#BC75FF] to-[#798FFF] rounded-full opacity-95 hover:opacity-100 transition-opacity"
|
||||
className={[
|
||||
"2xl:text-3xl sm:text-2xl lg:text-lg w-full xl:px-8 lg:px-6 px-4 xl:py-4 lg:py-3 py-2 bg-gradient-to-tr from-[#BC75FF] to-[#798FFF] rounded-full opacity-95 hover:opacity-100 transition-opacity",
|
||||
isLoading ? "opacity-50" : "opacity-95 hover:opacity-100",
|
||||
].join(" ")}
|
||||
>
|
||||
<Trans i18nKey="contactUsBtn">Отправить заявку</Trans>
|
||||
</button>
|
||||
|
||||
@@ -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 <button onClick={handleReCaptchaVerify}>Verify recaptcha</button>;
|
||||
};
|
||||
|
||||
export default ReCaptcha;
|
||||
+6
-2
@@ -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: <App />,
|
||||
element: (
|
||||
// <GoogleReCaptchaProvider reCaptchaKey="6LegrF0oAAAAABVE0LjowPduCjSjFMZI9GQ5Le98">
|
||||
<App />
|
||||
// </GoogleReCaptchaProvider>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/main_video",
|
||||
|
||||
+15
-1
@@ -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==
|
||||
|
||||
Reference in New Issue
Block a user