diff --git a/components/primary-button/index.tsx b/components/primary-button/index.tsx index c7e3e12..45aa9f3 100644 --- a/components/primary-button/index.tsx +++ b/components/primary-button/index.tsx @@ -1,18 +1,36 @@ import { ButtonHTMLAttributes, FunctionComponent } from "react"; -import styled from "styled-components"; +import styled, { keyframes } from "styled-components"; import color from "../../styles/color"; -export const PrimaryButton: FunctionComponent< - ButtonHTMLAttributes -> = ({ children, ...props }) => { +interface PrimaryButtonProps extends ButtonHTMLAttributes { + isLoading?: boolean; +} + +export const PrimaryButton: FunctionComponent = ({ + children, + isLoading, + ...props +}) => { return ( - {children} + {isLoading ? ( + + + + + + + ) : ( + {children} + )} ); }; const StyledPrimaryButton = styled.button` + display: flex; + align-items center; + justify-content: center; width: 100%; height: 100%; @@ -54,3 +72,39 @@ const StyledPrimaryButton = styled.button` color: ${color.orange["50"]}; } `; + +const SpinnerWrapper = styled.div` + display: flex; + position: relative; + + width: 20px; + height: 20px; +`; + +const spinAnimation = keyframes` + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +`; + +const Spinner = styled.div<{ animationDelay?: string }>` + display: block; + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + animation: ${spinAnimation} 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + ${({ animationDelay }) => + animationDelay ? `animation-delay: ${animationDelay};` : ""} + + border-radius: 100%; + border-style: solid; + border-width: 3px; + border-color: white transparent transparent transparent; +`; diff --git a/pages/verification/index.tsx b/pages/verification/index.tsx index f84d9ed..9ad1960 100644 --- a/pages/verification/index.tsx +++ b/pages/verification/index.tsx @@ -62,7 +62,8 @@ export default function VerificationPage() { const router = useRouter(); const [twitterAuthInfo, setTwitterAuthInfo] = useState(); - const [isLoading, setIsLoading] = useState(true); + const [isLoadingInit, setIsLoadingInit] = useState(true); + const [isLoadingRegistration, setIsLoadingRegistration] = useState(false); const [wallet, setWallet] = useState(); const [walletKey, setWalletKey] = useState<{ @@ -173,7 +174,7 @@ export default function VerificationPage() { console.error(error); } finally { - setIsLoading(false); + setIsLoadingInit(false); } } }; @@ -267,6 +268,7 @@ export default function VerificationPage() { amplitude.track("click register button"); console.log(isOwner); + if (isOwner) { handleRegistration(); } else { @@ -276,6 +278,8 @@ export default function VerificationPage() { const handleRegistration = async () => { try { + setIsLoadingRegistration(true); + const { state, code } = checkTwitterAuthQueryParameter( window.location.search, ); @@ -358,6 +362,8 @@ export default function VerificationPage() { if (Axios.isAxiosError(error)) { console.error((error?.response?.data as QueryError).message); } + } finally { + setIsLoadingRegistration(false); } }; @@ -372,7 +378,7 @@ export default function VerificationPage() { - {isLoading ? ( + {isLoadingInit ? ( ) : ( @@ -426,6 +432,7 @@ export default function VerificationPage() { Register