forked from LaconicNetwork/icns-frontend
Add final check modal
This commit is contained in:
parent
e0151666b2
commit
68d8ba31aa
196
components/final-check-modal/index.tsx
Normal file
196
components/final-check-modal/index.tsx
Normal file
@ -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<void>;
|
||||
}
|
||||
|
||||
export const FinalCheckModal: FunctionComponent<Props> = (props) => {
|
||||
const {
|
||||
twitterUserName,
|
||||
walletInfo,
|
||||
isModalOpen,
|
||||
onCloseModal,
|
||||
onClickRegisterButton,
|
||||
} = props;
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<ReactModal
|
||||
isOpen={isModalOpen}
|
||||
onRequestClose={onCloseModal}
|
||||
ariaHideApp={false}
|
||||
style={{
|
||||
overlay: { background: "#121212cc" },
|
||||
content: {
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
right: "auto",
|
||||
bottom: "auto",
|
||||
padding: 0,
|
||||
marginRight: "-50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
background: color.grey["800"],
|
||||
border: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ModalContainer>
|
||||
<ModalTitle>Final Checks</ModalTitle>
|
||||
<MainText>You are claiming the ICNS name</MainText>
|
||||
<ICNSNameContainer>
|
||||
<BoldText>{twitterUserName}</BoldText>
|
||||
<TwitterImageContainer>
|
||||
<Image
|
||||
src={TwitterIcon}
|
||||
fill={true}
|
||||
sizes="2rem"
|
||||
alt="twitter icon"
|
||||
/>
|
||||
</TwitterImageContainer>
|
||||
</ICNSNameContainer>
|
||||
<MainText>on</MainText>
|
||||
<BoldText>{walletInfo?.name}</BoldText>
|
||||
<MainText>({walletInfo?.bech32Address})</MainText>
|
||||
<Divider />
|
||||
<SubText>
|
||||
☑️ ICNS name can only be claimed once per Twitter account.
|
||||
<br />
|
||||
☑️ ICNS name can’t be transferred at this time.
|
||||
<br />
|
||||
☑️ Please make sure you’ve selected the right account on your wallet.
|
||||
</SubText>
|
||||
|
||||
<SubText>
|
||||
<SubBoldText>{MINIMUM_OSMO_FEE}</SubBoldText> will be spent as a
|
||||
spam-prevention fee.
|
||||
</SubText>
|
||||
|
||||
<ButtonContainer>
|
||||
<SecondaryButton
|
||||
onClick={async () => {
|
||||
await router.push("/");
|
||||
}}
|
||||
>
|
||||
Use a different account
|
||||
</SecondaryButton>
|
||||
<RegisterButton>
|
||||
<PrimaryButton onClick={onClickRegisterButton}>
|
||||
Register
|
||||
</PrimaryButton>
|
||||
</RegisterButton>
|
||||
</ButtonContainer>
|
||||
</ModalContainer>
|
||||
</ReactModal>
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
`;
|
24
components/secondary-button/index.tsx
Normal file
24
components/secondary-button/index.tsx
Normal file
@ -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;
|
||||
`;
|
@ -107,8 +107,6 @@ const SkeletonButton = styled.div`
|
||||
width: 12rem;
|
||||
height: 4rem;
|
||||
|
||||
padding-top: 1.5rem;
|
||||
|
||||
background-color: ${color.grey["800"]};
|
||||
`;
|
||||
|
||||
|
@ -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<KeplrWallet>();
|
||||
const [walletKey, setWalletKey] = useState<{
|
||||
name: string;
|
||||
pubKey: Uint8Array;
|
||||
bech32Address: string;
|
||||
}>();
|
||||
|
||||
const [chainList, setChainList] = useState<ChainItemType[]>([]);
|
||||
const [disabledChainList, setDisabledChainList] = useState<ChainItemType[]>(
|
||||
@ -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 && (
|
||||
<AgreeContainer
|
||||
onClick={() => {
|
||||
setIsAgree(!isAgree);
|
||||
}}
|
||||
>
|
||||
<AgreeCheckBox type="checkbox" checked={isAgree} readOnly />I
|
||||
check that Osmo is required for this transaction
|
||||
</AgreeContainer>
|
||||
)}
|
||||
{/*<AgreeContainer*/}
|
||||
{/* onClick={() => {*/}
|
||||
{/* setIsAgree(!isAgree);*/}
|
||||
{/* }}*/}
|
||||
{/*>*/}
|
||||
{/* <AgreeCheckBox type="checkbox" checked={isAgree} readOnly />I*/}
|
||||
{/* check that Osmo is required for this transaction*/}
|
||||
{/*</AgreeContainer>*/}
|
||||
|
||||
{chainList.length > 0 && (
|
||||
<ButtonContainer disabled={isRegisterButtonDisable}>
|
||||
@ -422,6 +434,14 @@ export default function VerificationPage() {
|
||||
</ContentContainer>
|
||||
)}
|
||||
</MainContainer>
|
||||
|
||||
<FinalCheckModal
|
||||
twitterUserName={twitterAuthInfo?.username}
|
||||
walletInfo={walletKey}
|
||||
isModalOpen={isModalOpen}
|
||||
onCloseModal={() => setModalOpen(false)}
|
||||
onClickRegisterButton={handleRegistration}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@ -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"]};
|
||||
// `;
|
||||
|
3
public/images/svg/twitter-modal-icon.svg
Normal file
3
public/images/svg/twitter-modal-icon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="32" height="33" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M28 8.786C27.118 9.17667 26.1694 9.43733 25.1687 9.56067C26.186 8.95667 26.9687 7.99333 27.336 6.85533C26.384 7.41333 25.3294 7.82333 24.2074 8.03933C23.3114 7.08933 22.0334 6.5 20.6174 6.5C17.8974 6.5 15.6927 8.68533 15.6927 11.38C15.6927 11.7613 15.7374 12.1327 15.8214 12.4933C11.7294 12.288 8.10005 10.3427 5.67205 7.39067C5.24538 8.112 5.00538 8.95667 5.00538 9.848C5.00538 11.542 5.87271 13.0333 7.19538 13.912C6.38805 13.8873 5.62805 13.6627 4.96271 13.3027C4.96271 13.3173 4.96271 13.3393 4.96271 13.36C4.96271 15.7273 6.66071 17.6987 8.91138 18.1473C8.50005 18.26 8.06538 18.3227 7.61738 18.3227C7.29938 18.3227 6.98938 18.2867 6.68938 18.2327C7.31605 20.1673 9.13405 21.5813 11.288 21.6233C9.60271 22.93 7.48005 23.7127 5.17205 23.7127C4.77338 23.7127 4.38338 23.69 3.99805 23.6433C6.17871 25.024 8.76805 25.8333 11.5474 25.8333C20.604 25.8333 25.5587 18.396 25.5587 11.944C25.5587 11.7327 25.552 11.522 25.542 11.314C26.5087 10.6313 27.342 9.77 28 8.786Z" fill="#03A9F4"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue
Block a user