diff --git a/components/connect-wallet-modal/index.tsx b/components/connect-wallet-modal/index.ts similarity index 100% rename from components/connect-wallet-modal/index.tsx rename to components/connect-wallet-modal/index.ts diff --git a/components/final-check-modal/index.tsx b/components/final-check-modal/index.tsx new file mode 100644 index 0000000..d012fe4 --- /dev/null +++ b/components/final-check-modal/index.tsx @@ -0,0 +1,196 @@ +import { FunctionComponent } from "react"; +import color from "../../styles/color"; +import ReactModal from "react-modal"; +import styled from "styled-components"; +import TwitterIcon from "../../public/images/svg/twitter-modal-icon.svg"; +import Image from "next/image"; +import { PrimaryButton } from "../primary-button"; +import { SecondaryButton } from "../secondary-button"; +import { MINIMUM_OSMO_FEE } from "../../constants/wallet"; +import { useRouter } from "next/router"; + +interface Props { + twitterUserName: string | undefined; + walletInfo: + | { name: string; pubKey: Uint8Array; bech32Address: string } + | undefined; + isModalOpen: boolean; + onCloseModal: () => void; + onClickRegisterButton: () => Promise; +} + +export const FinalCheckModal: FunctionComponent = (props) => { + const { + twitterUserName, + walletInfo, + isModalOpen, + onCloseModal, + onClickRegisterButton, + } = props; + const router = useRouter(); + + return ( + + + Final Checks + You are claiming the ICNS name + + {twitterUserName} + + twitter icon + + + on + {walletInfo?.name} + ({walletInfo?.bech32Address}) + + + ☑️ ICNS name can only be claimed once per Twitter account. +
+ ☑️ ICNS name can’t be transferred at this time. +
+ ☑️ Please make sure you’ve selected the right account on your wallet. +
+ + + {MINIMUM_OSMO_FEE} will be spent as a + spam-prevention fee. + + + + { + await router.push("/"); + }} + > + Use a different account + + + + Register + + + +
+
+ ); +}; + +const ModalContainer = styled.div` + display: flex; + flex-direction: column; + gap: 0.625rem; + + width: 50rem; + + padding: 1.75rem 2rem; +`; + +const ModalTitle = styled.div` + font-family: "Inter", serif; + font-style: normal; + font-weight: 700; + font-size: 1.5rem; + line-height: 1.8rem; + + margin-bottom: 1rem; + + color: ${color.white}; +`; + +const ICNSNameContainer = styled.div` + display: flex; + flex-direction: row; + align-items: center; + + gap: 0.5rem; +`; + +const TwitterImageContainer = styled.div` + width: 2rem; + height: 2rem; + + margin-top: 0.4rem; + + position: relative; +`; + +const MainText = styled.div` + font-family: "Inter", serif; + font-style: normal; + font-weight: 600; + font-size: 1rem; + line-height: 1.2rem; + + color: ${color.white}; +`; + +const SubText = styled.div` + font-family: "Inter", serif; + font-style: normal; + font-weight: 500; + font-size: 1rem; + line-height: 1.5rem; + + color: ${color.grey["300"]}; +`; + +const SubBoldText = styled.span` + color: ${color.grey["100"]}; +`; + +const BoldText = styled.div` + font-family: "Inter", serif; + font-style: normal; + font-weight: 600; + font-size: 2rem; + line-height: 2.5rem; + + color: ${color.orange["50"]}; +`; + +const Divider = styled.div` + width: 100%; + + margin: 1.625rem 0; + + border: 0.5px solid ${color.grey["500"]}; +`; + +const ButtonContainer = styled.div` + display: flex; + flex-direction: row; + height: 3.5rem; + + margin-top: 2.5rem; + padding: 0 4.25rem; + + gap: 3.5rem; +`; + +const RegisterButton = styled.div` + width: 10rem; +`; diff --git a/components/secondary-button/index.tsx b/components/secondary-button/index.tsx new file mode 100644 index 0000000..3190f37 --- /dev/null +++ b/components/secondary-button/index.tsx @@ -0,0 +1,24 @@ +import styled from "styled-components"; +import color from "../../styles/color"; + +export const SecondaryButton = styled.button` + width: 100%; + height: 100%; + + border: none; + + padding: 11px 30px; + + font-family: "Inter", serif; + font-style: normal; + font-weight: 600; + font-size: 1.25rem; + line-height: 1.25rem; + letter-spacing: 0.07em; + text-transform: uppercase; + + color: ${color.white}; + background-color: ${color.grey["300"]}; + + cursor: pointer; +`; diff --git a/components/skeleton/skeleton-chain-list.tsx b/components/skeleton/skeleton-chain-list.tsx index 4a22be2..2611eb2 100644 --- a/components/skeleton/skeleton-chain-list.tsx +++ b/components/skeleton/skeleton-chain-list.tsx @@ -107,8 +107,6 @@ const SkeletonButton = styled.div` width: 12rem; height: 4rem; - padding-top: 1.5rem; - background-color: ${color.grey["800"]}; `; diff --git a/pages/verification/index.tsx b/pages/verification/index.tsx index b1ee6fe..f84d9ed 100644 --- a/pages/verification/index.tsx +++ b/pages/verification/index.tsx @@ -56,6 +56,7 @@ import { import { makeClaimMessage, makeSetRecordMessage } from "../../messages"; import Axios from "axios"; import { BackButton } from "../../components/back-button"; +import { FinalCheckModal } from "../../components/final-check-modal"; export default function VerificationPage() { const router = useRouter(); @@ -64,6 +65,11 @@ export default function VerificationPage() { const [isLoading, setIsLoading] = useState(true); const [wallet, setWallet] = useState(); + const [walletKey, setWalletKey] = useState<{ + name: string; + pubKey: Uint8Array; + bech32Address: string; + }>(); const [chainList, setChainList] = useState([]); const [disabledChainList, setDisabledChainList] = useState( @@ -77,7 +83,9 @@ export default function VerificationPage() { const [searchValue, setSearchValue] = useState(""); const [isOwner, setIsOwner] = useState(false); - const [isAgree, setIsAgree] = useState(false); + // const [isAgree, setIsAgree] = useState(false); + + const [isModalOpen, setModalOpen] = useState(false); useEffect(() => { init(); @@ -147,15 +155,15 @@ export default function VerificationPage() { registeredQueryResponse.data.name, ); - const addressesQueryResponse = await queryAddressesFromTwitterName( - registeredQueryResponse.data.name, - ); - if (keplrWallet) { const key = await keplrWallet.getKey(MainChainId); setIsOwner(ownerOfQueryResponse.data.owner === key.bech32Address); } + const addressesQueryResponse = await queryAddressesFromTwitterName( + registeredQueryResponse.data.name, + ); + setRegisteredChainList(addressesQueryResponse.data.addresses); } } catch (error) { @@ -175,9 +183,11 @@ export default function VerificationPage() { if (keplr) { const keplrWallet = new KeplrWallet(keplr); + const key = await keplrWallet.getKey(MainChainId); await fetchChainList(keplrWallet); setWallet(keplrWallet); + setWalletKey(key); return keplrWallet; } else { @@ -253,8 +263,18 @@ export default function VerificationPage() { } }; - const onClickRegistration = async () => { + const onClickRegistration = () => { amplitude.track("click register button"); + + console.log(isOwner); + if (isOwner) { + handleRegistration(); + } else { + setModalOpen(true); + } + }; + + const handleRegistration = async () => { try { const { state, code } = checkTwitterAuthQueryParameter( window.location.search, @@ -263,16 +283,14 @@ export default function VerificationPage() { const adr36Infos = await checkAdr36(); - if (wallet && adr36Infos) { - const key = await wallet.getKey(MainChainId); - + if (wallet && walletKey && adr36Infos) { const icnsVerificationList = await verifyTwitterAccount( - key.bech32Address, + walletKey.bech32Address, twitterInfo.accessToken, ); const registerMsg = makeClaimMessage( - key.bech32Address, + walletKey.bech32Address, twitterInfo.username, icnsVerificationList, localStorage.getItem(REFERRAL_KEY) ?? undefined, @@ -280,7 +298,7 @@ export default function VerificationPage() { const addressMsgs = adr36Infos.map((adr36Info) => { return makeSetRecordMessage( - key.bech32Address, + walletKey.bech32Address, twitterInfo.username, adr36Info, ); @@ -305,7 +323,7 @@ export default function VerificationPage() { const simulated = await simulateMsgs( chainInfo, - key.bech32Address, + walletKey.bech32Address, { proto: protoMsgs, }, @@ -317,7 +335,7 @@ export default function VerificationPage() { const txHash = await sendMsgs( wallet, chainInfo, - key.bech32Address, + walletKey.bech32Address, { amino: aminoMsgs, proto: protoMsgs, @@ -346,11 +364,7 @@ export default function VerificationPage() { const isRegisterButtonDisable = (() => { const hasCheckedItem = checkedItems.size > 0; - if (isOwner) { - return !hasCheckedItem; - } else { - return !(isAgree && hasCheckedItem); - } + return !hasCheckedItem; })(); return ( @@ -398,16 +412,14 @@ export default function VerificationPage() { setCheckedItems={setCheckedItems} /> - {!isOwner && ( - { - setIsAgree(!isAgree); - }} - > - I - check that Osmo is required for this transaction - - )} + {/* {*/} + {/* setIsAgree(!isAgree);*/} + {/* }}*/} + {/*>*/} + {/* I*/} + {/* check that Osmo is required for this transaction*/} + {/**/} {chainList.length > 0 && ( @@ -422,6 +434,14 @@ export default function VerificationPage() { )} + + setModalOpen(false)} + onClickRegisterButton={handleRegistration} + /> ); } @@ -461,6 +481,8 @@ export const ButtonContainer = styled.div<{ disabled?: boolean }>` width: 11rem; height: 3.5rem; + margin-top: 1.5rem; + background-color: ${(props) => props.disabled ? color.orange["300"] : color.orange["100"]}; `; @@ -485,30 +507,30 @@ const ChainListTitle = styled.div` color: ${color.white}; `; -const AgreeContainer = styled.div` - display: flex; - align-items: center; - gap: 0.5rem; - - font-family: "Inter", serif; - font-style: normal; - font-weight: 500; - font-size: 0.8rem; - line-height: 0.8rem; - - text-transform: uppercase; - user-select: none; - - color: ${color.grey["400"]}; - - padding: 2rem 0; - - cursor: pointer; -`; - -const AgreeCheckBox = styled.input.attrs({ type: "checkbox" })` - width: 1.2rem; - height: 1.2rem; - - accent-color: ${color.orange["200"]}; -`; +// const AgreeContainer = styled.div` +// display: flex; +// align-items: center; +// gap: 0.5rem; +// +// font-family: "Inter", serif; +// font-style: normal; +// font-weight: 500; +// font-size: 0.8rem; +// line-height: 0.8rem; +// +// text-transform: uppercase; +// user-select: none; +// +// color: ${color.grey["400"]}; +// +// padding: 2rem 0; +// +// cursor: pointer; +// `; +// +// const AgreeCheckBox = styled.input.attrs({ type: "checkbox" })` +// width: 1.2rem; +// height: 1.2rem; +// +// accent-color: ${color.orange["200"]}; +// `; diff --git a/public/images/svg/twitter-modal-icon.svg b/public/images/svg/twitter-modal-icon.svg new file mode 100644 index 0000000..cacf611 --- /dev/null +++ b/public/images/svg/twitter-modal-icon.svg @@ -0,0 +1,3 @@ + + +