Merge pull request #2 from icns-xyz/Heesung/countup-invitelink

Add Optional logics
This commit is contained in:
JungHwan Tony Yun 2022-12-21 22:57:57 +09:00 committed by GitHub
commit 7addde9981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 407 additions and 10 deletions

86
.pnp.cjs generated
View File

@ -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/",\

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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;

View File

@ -1,18 +1,77 @@
import color from "../../styles/color";
import styled from "styled-components";
import { TwitterAuthInfoResponse } from "../../types";
import { FunctionComponent } from "react";
import { FunctionComponent, useEffect, useState } from "react";
import Image from "next/image";
import ICNSIcon from "../../public/images/svg/icns-logo.svg";
interface Props {
isOwner?: boolean;
twitterProfileInformation?: TwitterAuthInfoResponse | null;
}
export const TwitterProfile: FunctionComponent<Props> = (props) => {
const { twitterProfileInformation } = props;
const { isOwner, twitterProfileInformation } = props;
const [isCopied, setIsCopied] = useState<boolean>(false);
const onClickInviteLink = async () => {
await navigator.clipboard.writeText(
`https://app.icns.xyz?referral=${twitterProfileInformation?.username}`,
);
setIsCopied(true);
setTimeout(() => {
setIsCopied(false);
}, 1000);
};
return (
<ProfileContainer color={color.grey["900"]}>
{isCopied ? (
<InviteLinkContainer>
copied
<CopiedIcon
width="14"
height="12"
viewBox="0 0 14 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2 4.92614L6.08333 9.9375L12.5 2.0625"
stroke="current"
strokeWidth="2"
strokeLinecap="square"
/>
</CopiedIcon>
</InviteLinkContainer>
) : (
<InviteLinkContainer onClick={onClickInviteLink}>
copy invite link
<CopyIcon
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
viewBox="0 0 16 16"
>
<path
stroke="current"
strokeLinecap="square"
strokeWidth="1.5"
d="M10.667 2.667h-8v8"
/>
<path
stroke="current"
strokeLinecap="square"
strokeWidth="1.5"
d="M5.417 5.417H13.25V13.25H5.417z"
/>
</CopyIcon>
</InviteLinkContainer>
)}
<ProfileImageContainer>
<Image
src={twitterProfileInformation?.profile_image_url ?? ""}
@ -24,7 +83,13 @@ export const TwitterProfile: FunctionComponent<Props> = (props) => {
<ProfileContentContainer>
<ProfileNameContainer>
{twitterProfileInformation?.name}
<ProfileName>{twitterProfileInformation?.name}</ProfileName>
{isOwner ? (
<IsOwnerIcon>
<ICNSIcon />
</IsOwnerIcon>
) : null}
</ProfileNameContainer>
<ProfileUserNameContainer>
@{twitterProfileInformation?.username}
@ -58,6 +123,8 @@ export const ProfileContainer = styled.div`
display: flex;
flex-direction: row;
position: relative;
width: 100%;
padding: 1.5rem 2rem;
@ -65,6 +132,45 @@ export const ProfileContainer = styled.div`
background-color: ${(props) => props.color};
`;
const CopyIcon = styled.svg`
stroke: ${color.grey["100"]};
`;
const CopiedIcon = styled.svg`
stroke: ${color.grey["100"]};
`;
export const InviteLinkContainer = styled.div`
display: flex;
flex-direction: row;
align-items: center;
gap: 0.2rem;
position: absolute;
top: 1.75rem;
right: 1.5rem;
font-family: "Inter", serif;
font-style: normal;
font-weight: 600;
font-size: 0.875rem;
line-height: 0.875rem;
text-transform: uppercase;
color: ${color.grey["100"]};
cursor: pointer;
&:hover {
color: ${color.grey["200"]};
${CopyIcon} {
stroke: ${color.grey["200"]};
}
}
`;
export const ProfileContentContainer = styled.div`
display: flex;
flex-direction: column;
@ -87,6 +193,12 @@ export const ProfileImageContainer = styled.div`
`;
export const ProfileNameContainer = styled.div`
display: flex;
flex-direction: row;
align-items: center;
`;
export const ProfileName = styled.div`
font-weight: 600;
font-size: 1.2rem;
line-height: 1.5rem;
@ -94,6 +206,15 @@ export const ProfileNameContainer = styled.div`
color: ${color.white};
`;
export const IsOwnerIcon = styled.div`
height: 1px;
background-color: red;
margin-top: 0.1rem;
display: flex;
align-items: center;
`;
export const ProfileUserNameContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;

View File

@ -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 ||
[

26
hooks/use-interval.tsx Normal file
View File

@ -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;

View File

@ -0,0 +1,6 @@
import { useEffect, useLayoutEffect } from "react";
const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
export default useIsomorphicLayoutEffect;

View File

@ -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",

View File

@ -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 (
<Container>
<Logo />
<CountUpContainer>
{count ? (
<CountUpText>
<CountUp start={count?.start} end={count?.end ?? 0} duration={1} />
</CountUpText>
) : (
<SpinnerWrapper>
<Spinner />
<Spinner />
<Spinner />
<Spinner />
</SpinnerWrapper>
)}
<CountUpDescription>ICNS names claimed so far</CountUpDescription>
</CountUpContainer>
<MainContainer>
<MainTitleContainer>
<MainTitleImageBackground>
@ -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;

View File

@ -554,7 +554,10 @@ export default function VerificationPage() {
) : (
<ContentContainer>
<BackButton />
<TwitterProfile twitterProfileInformation={twitterAuthInfo} />
<TwitterProfile
isOwner={isOwner}
twitterProfileInformation={twitterAuthInfo}
/>
<ChainListTitleContainer>
<ChainListTitle>Chain List</ChainListTitle>
<SearchInput

View File

@ -0,0 +1,13 @@
<svg width="19" height="20" viewBox="0 0 19 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="0.5" width="19" height="19" rx="9.5" fill="#121212"/>
<path d="M3.95654 6.78418H6.28393V10.0425H3.95654V6.78418Z" fill="#FB5232"/>
<rect x="3.95654" y="4.45654" width="2.32738" height="2.32738" rx="1.16369" fill="#FFCDC4"/>
<rect x="7.21484" y="10.042" width="2.32738" height="5.58572" fill="#EBFFBF"/>
<path d="M3.95654 10.042V10.042C5.75607 10.042 7.21488 11.5008 7.21488 13.3003V15.6277H3.95654V10.042Z" fill="#00B86E"/>
<path d="M6.28394 7.2494C6.28394 5.70695 7.53434 4.45654 9.0768 4.45654H15.128V10.0423H9.0768C7.53434 10.0423 6.28394 8.79186 6.28394 7.2494V7.2494Z" fill="#F4CC3E"/>
<path d="M8.61133 7.24966C8.61133 6.99258 8.81973 6.78418 9.07681 6.78418H15.128V7.71513H9.07681C8.81973 7.71513 8.61133 7.50673 8.61133 7.24966V7.24966Z" fill="#121212"/>
<path d="M9.5421 12.8353C9.5421 12.4686 9.61434 12.1054 9.75469 11.7666C9.89505 11.4277 10.1008 11.1198 10.3601 10.8605C10.6195 10.6011 10.9273 10.3954 11.2662 10.2551C11.605 10.1147 11.9682 10.0425 12.335 10.0425L12.335 12.8353H9.5421Z" fill="#BED4FF"/>
<path d="M15.1278 12.835C15.1278 13.2017 15.0556 13.5649 14.9152 13.9037C14.7749 14.2426 14.5692 14.5505 14.3098 14.8098C14.0505 15.0692 13.7426 15.2749 13.4037 15.4152C13.0649 15.5556 12.7017 15.6278 12.335 15.6278L12.335 12.835H15.1278Z" fill="#5A4CFA"/>
<path d="M12.335 10.0425H15.1278L12.335 12.8353V10.0425Z" fill="#BED4FF"/>
<path d="M12.335 15.6279H9.5421L12.335 12.8351V15.6279Z" fill="#5A4CFA"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -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"