Add Skeleton views

This commit is contained in:
HeesungB 2022-12-06 23:53:31 +09:00
parent 047c9d6af8
commit 4ba6812c9a
5 changed files with 287 additions and 51 deletions

17
components/logo/index.tsx Normal file
View File

@ -0,0 +1,17 @@
// NextJs
import Image from "next/image";
// Image Assets
import LogoIcon from "../../public/images/svg/logo.svg";
// Styles
import { LogoContainer } from "./styled";
import { FunctionComponent } from "react";
export const Logo: FunctionComponent = () => {
return (
<LogoContainer>
<Image src={LogoIcon} fill={true} alt="Home Logo" />
</LogoContainer>
);
};

16
components/logo/styled.ts Normal file
View File

@ -0,0 +1,16 @@
// Styles
import styled from "styled-components";
export const LogoContainer = styled.div`
display: flex;
align-items: center;
justify-content: center;
position: absolute;
width: 160px;
height: 80px;
margin-top: 80px;
margin-left: 80px;
`;

View File

@ -1,24 +1,24 @@
// NextJs
import Image from "next/image"; import Image from "next/image";
import Link from "next/link";
// Styles // Styles
import styled from "styled-components"; import styled, { useTheme } from "styled-components";
import color from "../styles/color"; import color from "../styles/color";
// Components // Components
import { PrimaryButton } from "../components/primary-button"; import { PrimaryButton } from "../components/primary-button";
// Image Assets // Image Assets
import Logo from "../public/images/svg/logo.svg";
import MainTitle from "../public/images/svg/main-title.svg"; import MainTitle from "../public/images/svg/main-title.svg";
import MainLogo from "../public/images/svg/main-logo.svg"; import MainLogo from "../public/images/svg/main-logo.svg";
import CheckIcon from "../public/images/svg/check-icon.svg"; import CheckIcon from "../public/images/svg/check-icon.svg";
import { Logo } from "../components/logo";
export default function Home() { export default function Home() {
return ( return (
<Container> <Container>
<LogoContainer> <Logo />
<Image src={Logo} fill={true} objectFit="contain" alt="Home Logo" />
</LogoContainer>
<MainContainer> <MainContainer>
<MainTitleContainer> <MainTitleContainer>
@ -29,7 +29,9 @@ export default function Home() {
</MainTitleImageBackground> </MainTitleImageBackground>
<ConnectButtonContainer> <ConnectButtonContainer>
<PrimaryButton>Connect Wallet</PrimaryButton> <Link href="/verification">
<PrimaryButton>Connect Wallet</PrimaryButton>
</Link>
</ConnectButtonContainer> </ConnectButtonContainer>
<SubContainer> <SubContainer>
<CheckContainer> <CheckContainer>
@ -65,20 +67,6 @@ const Container = styled.div`
height: 100vh; height: 100vh;
`; `;
const LogoContainer = styled.div`
display: flex;
align-items: center;
justify-content: center;
position: absolute;
width: 10rem;
height: 5rem;
margin-top: 5rem;
margin-left: 5rem;
`;
const MainContainer = styled.div` const MainContainer = styled.div`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -113,7 +101,7 @@ const MainTitleImageContainer = styled.div`
position: relative; position: relative;
width: 55rem; width: 60rem;
height: 19.9rem; height: 19.9rem;
`; `;

View File

@ -1,32 +1,249 @@
import { useEffect, useState } from "react"; // Style
import styled from "styled-components";
interface AccessTokenResponse { import { Logo } from "../../components/logo";
access_token: string; import color from "../../styles/color";
}
export default function VerificationPage() { export default function VerificationPage() {
const [accessToken, setAccessToken] = useState<string>();
const fetchAccessToken = async (state: string, code: string) => {
const response: AccessTokenResponse = await (
await fetch(`/api/auth/access-token?state=${state}&code=${code}`)
).json();
setAccessToken(response.access_token);
};
useEffect(() => {
const [, state, code] =
window.location.search.match(
/^(?=.*state=([^&]+)|)(?=.*code=([^&]+)|).+$/,
) || [];
fetchAccessToken(state, code);
}, []);
return ( return (
<div> <Container>
<div>{accessToken}</div> <Logo />
</div>
<MainContainer>
<ContentContainer>
<ProfileContainer color={color.grey["700"]}>
<SkeletonCircle width="5.5rem" height="5.5rem" />
<ProfileContentContainer>
<SkeletonText width="5rem" height="1.5rem" />
<ProfileFollowContainer>
<SkeletonText width="8rem" height="1rem" />
<SkeletonText width="8rem" height="1rem" />
</ProfileFollowContainer>
<SkeletonText width="20rem" height="1rem" />
</ProfileContentContainer>
</ProfileContainer>
<SkeletonTitle />
<ChainContainer color={color.grey["700"]}>
<ChainItemContainer>
<ChainImageContainer width="3rem" height="3rem">
<SkeletonCircle width="3rem" height="3rem" />
</ChainImageContainer>
<ChainInfoContainer>
<SkeletonText width="4rem" height="1rem" />
<SkeletonText width="12rem" height="1rem" />
</ChainInfoContainer>
</ChainItemContainer>
<SkeletonDivider />
<ChainItemContainer>
<ChainImageContainer width="3rem" height="3rem">
<SkeletonCircle width="3rem" height="3rem" />
</ChainImageContainer>
<ChainInfoContainer>
<SkeletonText width="4rem" height="1rem" />
<SkeletonText width="12rem" height="1rem" />
</ChainInfoContainer>
</ChainItemContainer>
<SkeletonDivider />
<ChainItemContainer>
<ChainImageContainer width="3rem" height="3rem">
<SkeletonCircle width="3rem" height="3rem" />
</ChainImageContainer>
<ChainInfoContainer>
<SkeletonText width="4rem" height="1rem" />
<SkeletonText width="12rem" height="1rem" />
</ChainInfoContainer>
</ChainItemContainer>
<SkeletonDivider />
<ChainItemContainer>
<ChainImageContainer width="3rem" height="3rem">
<SkeletonCircle width="3rem" height="3rem" />
</ChainImageContainer>
<ChainInfoContainer>
<SkeletonText width="4rem" height="1rem" />
<SkeletonText width="12rem" height="1rem" />
</ChainInfoContainer>
</ChainItemContainer>
<SkeletonDivider />
<ChainItemContainer>
<ChainImageContainer width="3rem" height="3rem">
<SkeletonCircle width="3rem" height="3rem" />
</ChainImageContainer>
<ChainInfoContainer>
<SkeletonText width="4rem" height="1rem" />
<SkeletonText width="12rem" height="1rem" />
</ChainInfoContainer>
</ChainItemContainer>
</ChainContainer>
<ButtonContainer>
<SkeletonButton />
</ButtonContainer>
</ContentContainer>
</MainContainer>
</Container>
); );
} }
const Container = styled.div`
width: 100vw;
height: 100vh;
`;
const MainContainer = styled.div`
display: flex;
justify-content: center;
color: white;
`;
const ContentContainer = styled.div`
display: flex;
flex-direction: column;
width: 40rem;
margin-top: 5rem;
`;
const ProfileContainer = styled.div`
display: flex;
flex-direction: row;
width: 100%;
padding: 2rem 2rem;
background-color: ${(props) => props.color};
`;
const ProfileContentContainer = styled.div`
display: flex;
flex-direction: column;
gap: 1rem;
margin-left: 1.5rem;
`;
const ProfileFollowContainer = styled.div`
display: flex;
flex-direction: row;
gap: 2rem;
`;
const ChainContainer = styled.div`
display: flex;
flex-direction: column;
gap: 1rem;
width: 100%;
padding: 2rem 2rem 1rem 2rem;
background-color: ${(props) => props.color};
`;
const ChainItemContainer = styled.div`
display: flex;
flex-direction: row;
gap: 1rem;
`;
const ChainImageContainer = styled.div<WidthHeightProps>`
width: ${(props) => props.width};
height: ${(props) => props.height};
position: relative;
`;
const ChainInfoContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.5rem;
`;
const ButtonContainer = styled.div`
display: flex;
justify-content: center;
margin-top: 2rem;
`;
interface WidthHeightProps {
width: string | number;
height: string | number;
}
const SkeletonAnimation = styled.div`
opacity: 0.35 !important;
background-image: linear-gradient(
0.25turn,
transparent,
${color.grey["400"]},
transparent
),
linear-gradient(${color.grey["500"]}, ${color.grey["500"]}),
radial-gradient(
38px circle at 19px 19px,
${color.grey["500"]} 50%,
transparent 51%
),
linear-gradient(${color.grey["500"]}, ${color.grey["500"]});
background-repeat: no-repeat;
background-size: 315px 250px, 315px 180px, 100px 100px, 225px 30px;
background-position: -315px 0, 0 0, 0px 190px, 50px 195px;
animation: loading 2s infinite;
@keyframes loading {
to {
background-position: 315px 0, 0 0, 0 190px, 50px 195px;
}
}
`;
const SkeletonCircle = styled(SkeletonAnimation)<WidthHeightProps>`
width: ${(props) => props.width};
height: ${(props) => props.height};
background-color: ${color.grey["500"]};
border-radius: 50%;
`;
const SkeletonText = styled(SkeletonAnimation)<WidthHeightProps>`
width: ${(props) => props.width};
height: ${(props) => props.height};
`;
const SkeletonTitle = styled.div`
width: 8rem;
height: 1.5rem;
margin-top: 3rem;
margin-bottom: 1rem;
background-color: ${color.grey["700"]};
`;
const SkeletonButton = styled.div`
width: 12rem;
height: 4rem;
background-color: ${color.grey["700"]};
`;
const SkeletonDivider = styled(SkeletonAnimation)`
width: 100%;
height: 1px;
background-color: ${color.grey["600"]};
`;

View File

@ -7,12 +7,10 @@ export const GlobalStyle = createGlobalStyle`
margin: 0; margin: 0;
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
font-size: 16px;
background-color: ${color.black}; background-color: ${color.black};
font-size: 0.85vw;
//font-size: 22px;
background-size: 5rem 5rem; background-size: 5rem 5rem;
background-position: top left; background-position: top left;
background-repeat: repeat; background-repeat: repeat;