Skip to content

Commit

Permalink
Merge pull request #339 from zkLinkProtocol/feat/google-recaptcha
Browse files Browse the repository at this point in the history
add recaptcha for daily rolutte
  • Loading branch information
MickWang authored Jul 25, 2024
2 parents 15a4758 + a884493 commit cd534ec
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
VITE_PROJECT_ID=aa1989b48f2f9f37e9e29811f97d58af
VITE_IS_MAINTENANCE = 0
VITE_MAINTENANCE_TIPS = 'The website is currently undergoing maintenance to add support for Phase II Upgrading.'

VITE_SITE_KEY="6LcfgBYqAAAAAMWveYEvnQQFNg33AU71GBj60Rwl"
VITE_SECRET_KEY="6LcfgBYqAAAAAHCFhPK_oiBKNts8JXKRMh9auxxr"
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
gtag("js", new Date());
gtag("config", "G-LHZKFW0MBZ");
</script>

<script src="https://www.recaptcha.net/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=en" async
defer></script>

</head>

<body>
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"react": "^18.2.0",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
"react-google-recaptcha": "^3.1.0",
"react-hot-toast": "^2.4.1",
"react-icons": "^5.0.1",
"react-loadable": "^5.5.0",
Expand All @@ -55,6 +56,7 @@
"@types/qs": "^6.9.12",
"@types/react": "^18.2.56",
"@types/react-dom": "^18.2.19",
"@types/react-google-recaptcha": "^2.1.9",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"@vitejs/plugin-react": "^4.2.1",
Expand Down
48 changes: 46 additions & 2 deletions src/components/DashboardS2/DailyRoulette/DailyBox.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import styled from "styled-components";
import { useCallback, useMemo } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
import DailyDrawModal from "./DailyDrawModal";
import { useDisclosure } from "@nextui-org/react";
import { dailyOpen } from "@/api";
import { useReCaptchaStore } from "@/hooks/useReCaptchaStore";
import GoogleRecaptcha from "@/components/GoogleRecaptcha";
dayjs.extend(utc);
dayjs.extend(timezone);
export enum BoxType {
Expand All @@ -24,6 +26,14 @@ interface DailyBoxProps {
remain?: number;
}

const RecaptchaContainer = styled.div`
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
`;

const DailyBox = (props: DailyBoxProps) => {
const modal = useDisclosure();
const { type, weekday, date, amount, index, remain, onDrawed } = props;
Expand Down Expand Up @@ -52,11 +62,39 @@ const DailyBox = (props: DailyBoxProps) => {
return `Exactly in ${hours + (index - 5) * 24} Hours`;
}
}, [index]);

const { reCaptchaTs, reCaptchaValue } = useReCaptchaStore();

const [isShowRecaptcha, setIsShowRecaptcha] = useState(false);

useEffect(() => {
console.log("isShowRecaptcha", isShowRecaptcha);
}, [isShowRecaptcha]);

const handleClaim = useCallback(async () => {
console.log("handleClaim");

if (type === BoxType.Active) {
const ts = Date.now();

if (
reCaptchaTs === 0 ||
ts - reCaptchaTs > 1000 * 60 * 60 * 12 ||
!reCaptchaValue
) {
setIsShowRecaptcha(true);
return;
}
modal.onOpen();
}
}, [type, modal]);
}, [type, modal, reCaptchaValue, reCaptchaTs]);

const handleReCaptchaSuccess = () => {
console.log("handleReCaptchaSuccess");
setIsShowRecaptcha(false);
modal.onOpen();
};

return (
<Container>
<p className="weekday">{weekday}</p>
Expand Down Expand Up @@ -100,6 +138,12 @@ const DailyBox = (props: DailyBoxProps) => {
onDrawed={onDrawed}
remain={remain}
/>

{isShowRecaptcha && (
<RecaptchaContainer>
<GoogleRecaptcha onSuccess={handleReCaptchaSuccess} />
</RecaptchaContainer>
)}
</Container>
);
};
Expand Down
50 changes: 50 additions & 0 deletions src/components/GoogleRecaptcha.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useReCaptchaStore } from "@/hooks/useReCaptchaStore";
import { useEffect, useState } from "react";

interface GoogleRecaptchaProps {
onSuccess?: () => void;
}

export default function GoogleRecaptcha({ onSuccess }: GoogleRecaptchaProps) {
const [grecaptchaId, setGrecaptchaId] = useState<any>(null);
const [isRecaptchaLoad, setIsRecaptchaLoad] = useState(true);

const { setReCaptchaTs, setReCaptchaValue } = useReCaptchaStore();

const onChange = (value: string) => {
console.log("Captcha value:", value);
const ts = Date.now();
setReCaptchaValue(value);
setReCaptchaTs(ts);
onSuccess?.();
};

useEffect(() => {
setTimeout(() => {
const grecaptcha = (window as any)?.grecaptcha?.render("robot", {
sitekey: "6LcfgBYqAAAAAMWveYEvnQQFNg33AU71GBj60Rwl",
theme: "light",
size: "normal",
callback: onChange,
});
// console.log('grecaptcha', grecaptcha)
setGrecaptchaId(grecaptcha);
if (!grecaptcha && grecaptcha !== 0) {
setIsRecaptchaLoad(false);
} else {
setIsRecaptchaLoad(true);
}
}, 1000);
}, []);
return (
<div className="min-w-[304px] min-h-[78px] bg-[#fff] flex justify-center items-center">
<div id="robot"></div>
{!isRecaptchaLoad && (
<div className="text-[#000] text-[16px]">
Due to your internet cannot access Google reCAPTCHA service, we can't
verify if you're human or bot. Please check your internet setting.
</div>
)}
</div>
);
}
27 changes: 27 additions & 0 deletions src/hooks/useReCaptchaStore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";

export type ReCaptchaStore = {
reCaptchaValue: string;
reCaptchaTs: number;
setReCaptchaValue: (reCaptchaValue: string) => void;
setReCaptchaTs: (reCaptchaTs: number) => void;
};

export const useReCaptchaStore = create<ReCaptchaStore>()(
persist(
(set, get) => ({
reCaptchaValue: "",
reCaptchaTs: 0,
setReCaptchaValue: (reCaptchaValue: string) => {
set({ reCaptchaValue });
},
setReCaptchaTs: (reCaptchaTs: number) => {
set({ reCaptchaTs });
},
}),
{
name: "ReCaptchaStore",
}
)
);
2 changes: 2 additions & 0 deletions src/pages/DashboardS2/index2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { epochList } from "@/constants/epoch";
import PremiusAd from "@/components/DashboardS2/PremiusAd";
import ZKLClaimAd from "@/components/DashboardS2/ZKLClaimAd";
import MysteryBoxIII from "@/components/Dashboard/MysteryBoxIII";
import GoogleRecaptcha from "@/components/GoogleRecaptcha";
export type TotalTvlItem = {
symbol: string;
tokenAddress: string;
Expand Down Expand Up @@ -601,6 +602,7 @@ export default function Dashboard() {
<div className="side fixed right-[32px] top-[120px] z-[999] max-w-[400px]">
<ZKLClaimAd />
<MysteryBoxIII />
{/* <GoogleRecaptcha /> */}
</div>
<div className="mt-[29.6px] mx-auto max-w-[1246px] ">
<CardBox2 className="flex justify-between">
Expand Down
4 changes: 2 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export default defineConfig({
port: 3001,
proxy: {
"/app-api": {
// target: "https://goerli.app.zklink.io",
target: "https://app-api.zklink.io",
target: "https://goerli.app.zklink.io",
// target: "https://app-api.zklink.io",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/app-api/, ""),
},
Expand Down
25 changes: 24 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3480,6 +3480,13 @@
dependencies:
"@types/react" "*"

"@types/react-google-recaptcha@^2.1.9":
version "2.1.9"
resolved "https://registry.yarnpkg.com/@types/react-google-recaptcha/-/react-google-recaptcha-2.1.9.tgz#cd1ffe571fe738473b66690a86dad6c9d3648427"
integrity sha512-nT31LrBDuoSZJN4QuwtQSF3O89FVHC4jLhM+NtKEmVF5R1e8OY0Jo4//x2Yapn2aNHguwgX5doAq8Zo+Ehd0ug==
dependencies:
"@types/react" "*"

"@types/react@*", "@types/react@^18.2.56":
version "18.2.67"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.67.tgz#96b7af0b5e79c756f4bdd981de2ca28472c858e5"
Expand Down Expand Up @@ -5350,7 +5357,7 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"

hoist-non-react-statics@^3.3.1:
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1:
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==
Expand Down Expand Up @@ -6587,6 +6594,14 @@ radix3@^1.1.0:
resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.1.tgz#60a56876ffec62c88a22396a6a1c4c7efe9eb4b1"
integrity sha512-yUUd5VTiFtcMEx0qFUxGAv5gbMc1un4RvEO1JZdP7ZUl/RHygZK6PknIKntmQRZxnMY3ZXD2ISaw1ij8GYW1yg==

react-async-script@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/react-async-script/-/react-async-script-1.2.0.tgz#ab9412a26f0b83f5e2e00de1d2befc9400834b21"
integrity sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==
dependencies:
hoist-non-react-statics "^3.3.0"
prop-types "^15.5.0"

react-device-detect@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/react-device-detect/-/react-device-detect-2.2.3.tgz#97a7ae767cdd004e7c3578260f48cf70c036e7ca"
Expand All @@ -6602,6 +6617,14 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"

react-google-recaptcha@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/react-google-recaptcha/-/react-google-recaptcha-3.1.0.tgz#44aaab834495d922b9d93d7d7a7fb2326315b4ab"
integrity sha512-cYW2/DWas8nEKZGD7SCu9BSuVz8iOcOLHChHyi7upUuVhkpkhYG/6N3KDiTQ3XAiZ2UAZkfvYKMfAHOzBOcGEg==
dependencies:
prop-types "^15.5.0"
react-async-script "^1.2.0"

react-hot-toast@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.4.1.tgz#df04295eda8a7b12c4f968e54a61c8d36f4c0994"
Expand Down

0 comments on commit cd534ec

Please sign in to comment.