This commit is contained in:
2023-10-02 14:16:23 +05:00
parent 388f4e2a7b
commit 1c49c38657
7 changed files with 173 additions and 43 deletions
+1
View File
@@ -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
View File
@@ -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">
+4 -6
View File
@@ -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;
+23 -14
View File
@@ -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>
+26
View File
@@ -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
View File
@@ -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
View File
@@ -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==