diff --git a/.pnp.cjs b/.pnp.cjs index 8c85360..2bf0c06 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -64,6 +64,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["next", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:13.0.5"],\ ["prettier", "npm:2.8.0"],\ ["react", "npm:18.2.0"],\ + ["react-countup", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:6.4.0"],\ ["react-dom", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:18.2.0"],\ ["react-is", "npm:18.2.0"],\ ["react-modal", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:3.16.1"],\ @@ -3294,6 +3295,34 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["@rollup/plugin-babel", [\ + ["npm:6.0.3", {\ + "packageLocation": "./.yarn/cache/@rollup-plugin-babel-npm-6.0.3-1259d28dd2-412c1c3bb5.zip/node_modules/@rollup/plugin-babel/",\ + "packageDependencies": [\ + ["@rollup/plugin-babel", "npm:6.0.3"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:9555373101f58738ea803ff9e79b0d8b52a66e88c21dac99d127fd080df7e60c5efb4c82f30a042556261bfb95e0c5292626cc000800b004d622753bbf9e02e5#npm:6.0.3", {\ + "packageLocation": "./.yarn/__virtual__/@rollup-plugin-babel-virtual-082525a879/0/cache/@rollup-plugin-babel-npm-6.0.3-1259d28dd2-412c1c3bb5.zip/node_modules/@rollup/plugin-babel/",\ + "packageDependencies": [\ + ["@rollup/plugin-babel", "virtual:9555373101f58738ea803ff9e79b0d8b52a66e88c21dac99d127fd080df7e60c5efb4c82f30a042556261bfb95e0c5292626cc000800b004d622753bbf9e02e5#npm:6.0.3"],\ + ["@babel/core", null],\ + ["@babel/helper-module-imports", "npm:7.18.6"],\ + ["@rollup/pluginutils", "virtual:082525a8792b89cbfd614faa6bcd1a9496584eedab2ae9d69d9f4375690e041544351047f44ef6dab868f44ac8fb8bbc2f5d9aa598e4e4521132888b2cfef8a9#npm:5.0.2"],\ + ["@types/babel__core", null],\ + ["@types/rollup", null],\ + ["rollup", null]\ + ],\ + "packagePeers": [\ + "@babel/core",\ + "@types/babel__core",\ + "@types/rollup",\ + "rollup"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@rollup/plugin-sucrase", [\ ["npm:4.0.4", {\ "packageLocation": "./.yarn/cache/@rollup-plugin-sucrase-npm-4.0.4-11cf77c62a-ccb01d7eb3.zip/node_modules/@rollup/plugin-sucrase/",\ @@ -3349,6 +3378,29 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["picomatch", "npm:2.3.1"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:5.0.2", {\ + "packageLocation": "./.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip/node_modules/@rollup/pluginutils/",\ + "packageDependencies": [\ + ["@rollup/pluginutils", "npm:5.0.2"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:082525a8792b89cbfd614faa6bcd1a9496584eedab2ae9d69d9f4375690e041544351047f44ef6dab868f44ac8fb8bbc2f5d9aa598e4e4521132888b2cfef8a9#npm:5.0.2", {\ + "packageLocation": "./.yarn/__virtual__/@rollup-pluginutils-virtual-7805b1dbc6/0/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip/node_modules/@rollup/pluginutils/",\ + "packageDependencies": [\ + ["@rollup/pluginutils", "virtual:082525a8792b89cbfd614faa6bcd1a9496584eedab2ae9d69d9f4375690e041544351047f44ef6dab868f44ac8fb8bbc2f5d9aa598e4e4521132888b2cfef8a9#npm:5.0.2"],\ + ["@types/estree", "npm:1.0.0"],\ + ["@types/rollup", null],\ + ["estree-walker", "npm:2.0.2"],\ + ["picomatch", "npm:2.3.1"],\ + ["rollup", null]\ + ],\ + "packagePeers": [\ + "@types/rollup",\ + "rollup"\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@rushstack/eslint-patch", [\ @@ -5503,6 +5555,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["countup.js", [\ + ["npm:2.3.2", {\ + "packageLocation": "./.yarn/cache/countup.js-npm-2.3.2-fce559ea32-77bb509cd1.zip/node_modules/countup.js/",\ + "packageDependencies": [\ + ["countup.js", "npm:2.3.2"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["create-hash", [\ ["npm:1.2.0", {\ "packageLocation": "./.yarn/cache/create-hash-npm-1.2.0-afd048e1ce-02a6ae3bb9.zip/node_modules/create-hash/",\ @@ -7342,6 +7403,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["next", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:13.0.5"],\ ["prettier", "npm:2.8.0"],\ ["react", "npm:18.2.0"],\ + ["react-countup", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:6.4.0"],\ ["react-dom", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:18.2.0"],\ ["react-is", "npm:18.2.0"],\ ["react-modal", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:3.16.1"],\ @@ -9180,6 +9242,30 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["react-countup", [\ + ["npm:6.4.0", {\ + "packageLocation": "./.yarn/cache/react-countup-npm-6.4.0-d1c6fe7973-259277fa70.zip/node_modules/react-countup/",\ + "packageDependencies": [\ + ["react-countup", "npm:6.4.0"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:6.4.0", {\ + "packageLocation": "./.yarn/__virtual__/react-countup-virtual-9555373101/0/cache/react-countup-npm-6.4.0-d1c6fe7973-259277fa70.zip/node_modules/react-countup/",\ + "packageDependencies": [\ + ["react-countup", "virtual:4b77e00d446246df1ed27001550885fbf1b51be18c660c1b5c357d3d763078ecef2a676194291a120f149b87573081e5af0621dc83cf1f83383639f39ac133c7#npm:6.4.0"],\ + ["@rollup/plugin-babel", "virtual:9555373101f58738ea803ff9e79b0d8b52a66e88c21dac99d127fd080df7e60c5efb4c82f30a042556261bfb95e0c5292626cc000800b004d622753bbf9e02e5#npm:6.0.3"],\ + ["@types/react", "npm:18.0.25"],\ + ["countup.js", "npm:2.3.2"],\ + ["react", "npm:18.2.0"]\ + ],\ + "packagePeers": [\ + "@types/react",\ + "react"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["react-dom", [\ ["npm:18.2.0", {\ "packageLocation": "./.yarn/cache/react-dom-npm-18.2.0-dd675bca1c-7d323310be.zip/node_modules/react-dom/",\ diff --git a/.yarn/cache/@rollup-plugin-babel-npm-6.0.3-1259d28dd2-412c1c3bb5.zip b/.yarn/cache/@rollup-plugin-babel-npm-6.0.3-1259d28dd2-412c1c3bb5.zip new file mode 100644 index 0000000..b4c5fef Binary files /dev/null and b/.yarn/cache/@rollup-plugin-babel-npm-6.0.3-1259d28dd2-412c1c3bb5.zip differ diff --git a/.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip b/.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip new file mode 100644 index 0000000..d898c50 Binary files /dev/null and b/.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip differ diff --git a/.yarn/cache/countup.js-npm-2.3.2-fce559ea32-77bb509cd1.zip b/.yarn/cache/countup.js-npm-2.3.2-fce559ea32-77bb509cd1.zip new file mode 100644 index 0000000..10a1c5c Binary files /dev/null and b/.yarn/cache/countup.js-npm-2.3.2-fce559ea32-77bb509cd1.zip differ diff --git a/.yarn/cache/react-countup-npm-6.4.0-d1c6fe7973-259277fa70.zip b/.yarn/cache/react-countup-npm-6.4.0-d1c6fe7973-259277fa70.zip new file mode 100644 index 0000000..180d69a Binary files /dev/null and b/.yarn/cache/react-countup-npm-6.4.0-d1c6fe7973-259277fa70.zip differ diff --git a/components/primary-button/index.tsx b/components/primary-button/index.tsx index cb6dd22..adac418 100644 --- a/components/primary-button/index.tsx +++ b/components/primary-button/index.tsx @@ -75,7 +75,7 @@ const StyledPrimaryButton = styled.button` } `; -const SpinnerWrapper = styled.div` +export const SpinnerWrapper = styled.div` display: flex; position: relative; @@ -92,7 +92,7 @@ const spinAnimation = keyframes` } `; -const Spinner = styled.div<{ animationDelay?: string }>` +export const Spinner = styled.div<{ animationDelay?: string }>` display: block; position: absolute; top: 0; diff --git a/constants/icns.ts b/constants/icns.ts index 805d0f9..719a6d8 100644 --- a/constants/icns.ts +++ b/constants/icns.ts @@ -20,6 +20,9 @@ export const RESOLVER_ADDRESS = process.env.NEXT_PUBLIC_ICNS_RESOLVER_CONTRACT_ADDRESS ?? "osmo1002awr7frr9wk44lc3vfzt0d2w6vz5z03ql6fszjsjy8vdcvk0sskruz3c"; +export const CLAIM_URL = + "https://lcd-osmosis.keplr.app/cosmwasm/wasm/v1/contract/osmo1mypljhatv0prfr9cjzzvamxdf2ctg34xkt50sudxads9zhqnyneqjuvy26/smart/eyJudW1fdG9rZW5zIjp7fX0="; + export const CHAIN_ALLOWLIST = process.env.NEXT_PUBLIC_CHAIN_ALLOWLIST || [ diff --git a/hooks/use-interval.tsx b/hooks/use-interval.tsx new file mode 100644 index 0000000..d30b06b --- /dev/null +++ b/hooks/use-interval.tsx @@ -0,0 +1,26 @@ +import { useEffect, useRef } from "react"; +import useIsomorphicLayoutEffect from "./use-isomorphic-layout-effect"; + +function useInterval(callback: () => void, delay: number | null) { + const savedCallback = useRef(callback); + + // Remember the latest callback if it changes. + useIsomorphicLayoutEffect(() => { + savedCallback.current = callback; + }, [callback]); + + // Set up the interval. + useEffect(() => { + // Don't schedule if no delay is specified. + // Note: 0 is a valid value for delay. + if (!delay && delay !== 0) { + return; + } + + const id = setInterval(() => savedCallback.current(), delay); + + return () => clearInterval(id); + }, [delay]); +} + +export default useInterval; diff --git a/hooks/use-isomorphic-layout-effect.tsx b/hooks/use-isomorphic-layout-effect.tsx new file mode 100644 index 0000000..d67ecc3 --- /dev/null +++ b/hooks/use-isomorphic-layout-effect.tsx @@ -0,0 +1,6 @@ +import { useEffect, useLayoutEffect } from "react"; + +const useIsomorphicLayoutEffect = + typeof window !== "undefined" ? useLayoutEffect : useEffect; + +export default useIsomorphicLayoutEffect; diff --git a/package.json b/package.json index 1eb0bbd..cd9f545 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "iron-session": "^6.3.1", "next": "13.0.5", "react": "18.2.0", + "react-countup": "^6.4.0", "react-dom": "18.2.0", "react-is": "^18.2.0", "react-modal": "^3.16.1", diff --git a/pages/index.tsx b/pages/index.tsx index ccd3717..9d9e115 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -6,17 +6,23 @@ import color from "../styles/color"; // Components import { ConnectWalletModal } from "../components/connect-wallet-modal"; -import { PrimaryButton } from "../components/primary-button"; +import { + PrimaryButton, + Spinner, + SpinnerWrapper, +} from "../components/primary-button"; // Image Assets import { useEffect, useState } from "react"; import { Logo } from "../components/logo"; -import { REFERRAL_KEY } from "../constants/icns"; +import { CLAIM_URL, REFERRAL_KEY } from "../constants/icns"; import { SELECTED_WALLET_KEY } from "../constants/wallet"; import StarIcon from "../public/images/svg/bg-asset-3.svg"; import CheckIcon from "../public/images/svg/check-icon.svg"; import MainLogo from "../public/images/svg/main-logo.svg"; import MainTitle from "../public/images/svg/main-title.svg"; +import CountUp from "react-countup"; +import useInterval from "../hooks/use-interval"; export default function Home() { const [currentReferral, setCurrentReferral] = useState(""); @@ -24,6 +30,8 @@ export default function Home() { const [isConnectWalletModalOpen, setIsConnectWalletModalOpen] = useState(false); + const [count, setCount] = useState<{ start: number; end: number }>(); + const onClickConnectWalletButton = async () => { amplitude.track("click connect wallet button"); @@ -46,10 +54,46 @@ export default function Home() { localStorage.removeItem(SELECTED_WALLET_KEY); }, []); + useEffect(() => { + setTimeout(() => { + countUpCallback(); + }, 1000); + }, []); + + useInterval(async () => { + await countUpCallback(); + }, 10000); + + const countUpCallback = async () => { + const response: { data: { count: number } } = await ( + await fetch(CLAIM_URL) + ).json(); + + setCount({ + start: (count?.end ?? 100) - 100, + end: response.data.count, + }); + }; + return ( + + {count ? ( + + + + ) : ( + + + + + + + )} + ICNS names claimed so far + @@ -150,6 +194,45 @@ const MainContainer = styled.div` } `; +const CountUpContainer = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 1.25rem; + + width: calc(25rem - 2px); + height: calc(5rem - 2px); + + position: absolute; + + margin-top: calc(10rem + 2px); + margin-left: calc(55rem + 2px); + + background-color: ${color.black}; +`; + +const CountUpText = styled.div` + font-family: "Inter", serif; + font-style: normal; + font-weight: 600; + font-size: 1rem; + line-height: 1.2rem; + letter-spacing: 0.46rem; + + color: ${color.white}; +`; + +const CountUpDescription = styled.div` + font-family: "Inter", serif; + font-style: normal; + font-weight: 500; + font-size: 0.875rem; + line-height: 1.1rem; + + color: ${color.grey["400"]}; +`; + const MainTitleContainer = styled.div` display: flex; flex-direction: column; diff --git a/yarn.lock b/yarn.lock index 8c7caa2..d3579c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2090,6 +2090,25 @@ __metadata: languageName: node linkType: hard +"@rollup/plugin-babel@npm:^6.0.2": + version: 6.0.3 + resolution: "@rollup/plugin-babel@npm:6.0.3" + dependencies: + "@babel/helper-module-imports": ^7.18.6 + "@rollup/pluginutils": ^5.0.1 + peerDependencies: + "@babel/core": ^7.0.0 + "@types/babel__core": ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + "@types/babel__core": + optional: true + rollup: + optional: true + checksum: 412c1c3bb5dd029cbf0b37315ad54b51ef378b8d2fd91d1ec44d73cade723cec8718b5affa2ce8a8b06660710d11765056fac4068521f18737ce26142506a8b1 + languageName: node + linkType: hard + "@rollup/plugin-sucrase@npm:4.0.4": version: 4.0.4 resolution: "@rollup/plugin-sucrase@npm:4.0.4" @@ -2124,6 +2143,22 @@ __metadata: languageName: node linkType: hard +"@rollup/pluginutils@npm:^5.0.1": + version: 5.0.2 + resolution: "@rollup/pluginutils@npm:5.0.2" + dependencies: + "@types/estree": ^1.0.0 + estree-walker: ^2.0.2 + picomatch: ^2.3.1 + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: edea15e543bebc7dcac3b0ac8bc7b8e8e6dbd46e2864dbe5dd28072de1fbd5b0e10d545a610c0edaa178e8a7ac432e2a2a52e547ece1308471412caba47db8ce + languageName: node + linkType: hard + "@rushstack/eslint-patch@npm:^1.1.3": version: 1.2.0 resolution: "@rushstack/eslint-patch@npm:1.2.0" @@ -2546,7 +2581,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*": +"@types/estree@npm:*, @types/estree@npm:^1.0.0": version: 1.0.0 resolution: "@types/estree@npm:1.0.0" checksum: 910d97fb7092c6738d30a7430ae4786a38542023c6302b95d46f49420b797f21619cdde11fa92b338366268795884111c2eb10356e4bd2c8ad5b92941e9e6443 @@ -3773,6 +3808,13 @@ __metadata: languageName: node linkType: hard +"countup.js@npm:^2.3.2": + version: 2.3.2 + resolution: "countup.js@npm:2.3.2" + checksum: 77bb509cd17619568c8d841f9dbba7d75c70948d7f9acd0a1acea80e3894c4b4173e27e8896268c1f53415ebee465229f1e623da5ad759083a618484ac4f9b60 + languageName: node + linkType: hard + "create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": version: 1.2.0 resolution: "create-hash@npm:1.2.0" @@ -4600,7 +4642,7 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^2.0.1": +"estree-walker@npm:^2.0.1, estree-walker@npm:^2.0.2": version: 2.0.2 resolution: "estree-walker@npm:2.0.2" checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc @@ -5243,6 +5285,7 @@ __metadata: next: 13.0.5 prettier: ^2.8.0 react: 18.2.0 + react-countup: ^6.4.0 react-dom: 18.2.0 react-is: ^18.2.0 react-modal: ^3.16.1 @@ -6862,6 +6905,18 @@ __metadata: languageName: node linkType: hard +"react-countup@npm:^6.4.0": + version: 6.4.0 + resolution: "react-countup@npm:6.4.0" + dependencies: + "@rollup/plugin-babel": ^6.0.2 + countup.js: ^2.3.2 + peerDependencies: + react: ">= 16.3.0" + checksum: 259277fa70fc778fa3d67b375f5c44fdc3c8e5c9cc73225605f456adff31406966ff00379cb23ec771cb624a70c91c46d8216583c9dfc3fedb69071d31cb3208 + languageName: node + linkType: hard + "react-dom@npm:18.2.0": version: 18.2.0 resolution: "react-dom@npm:18.2.0"