Divided into several components

This commit is contained in:
HeesungB 2022-12-09 20:59:52 +09:00
parent 4b866891ac
commit fc58cad6a8
9 changed files with 449 additions and 339 deletions

View File

@ -0,0 +1,63 @@
import { AccountInfo } from "../../types";
import { FunctionComponent } from "react";
import {
ChainImageContainer,
ChainInfoContainer,
ChainItemContainer,
} from "./chain-list";
import Image from "next/image";
import color from "../../styles/color";
import styled from "styled-components";
interface Props {
chainInfo: AccountInfo;
}
export const ChainItem: FunctionComponent<Props> = (props) => {
const { chainInfo } = props;
return (
<ChainItemContainer key={chainInfo.prefix} isLoading={false}>
<ChainImageContainer width="3rem" height="3rem">
<Image
src={chainInfo.chainImageUrl}
fill={true}
alt={`${chainInfo.prefix} chain image`}
/>
</ChainImageContainer>
<ChainInfoContainer>
<ChainName>{`.${chainInfo.prefix}`}</ChainName>
<WalletAddress>{chainInfo.address}</WalletAddress>
</ChainInfoContainer>
<Flex1 />
<ChainCheckBox />
</ChainItemContainer>
);
};
const ChainName = styled.div`
font-weight: 600;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["100"]};
`;
const WalletAddress = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["400"]};
`;
const Flex1 = styled.div`
flex: 1;
`;
const ChainCheckBox = styled.input.attrs({ type: "checkbox" })`
width: 1.5rem;
height: 1.5rem;
`;

View File

@ -0,0 +1,59 @@
import { FunctionComponent } from "react";
import { AccountInfo, WidthHeightProps } from "../../types";
import color from "../../styles/color";
import styled from "styled-components";
import { ChainItem } from "./chain-item";
interface Props {
chainList: AccountInfo[];
}
export const ChainList: FunctionComponent<Props> = (props) => {
const { chainList } = props;
return (
<ChainContainer color={color.grey["800"]}>
{chainList.map((chainInfo) => (
<ChainItem key={chainInfo.prefix} chainInfo={chainInfo} />
))}
</ChainContainer>
);
};
export const ChainContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
max-height: 33rem;
overflow: scroll;
background-color: ${(props) => props.color};
`;
export const ChainItemContainer = styled.div<{ isLoading: boolean }>`
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
padding: 1.5rem;
cursor: pointer;
&:hover {
background: ${(props) => (props.isLoading ? null : color.grey["700"])};
}
`;
export const ChainImageContainer = styled.div<WidthHeightProps>`
width: ${(props) => props.width};
height: ${(props) => props.height};
position: relative;
`;
export const ChainInfoContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.5rem;
`;

View File

@ -0,0 +1,2 @@
export * from "./chain-list";
export * from "./chain-item";

View File

@ -7,7 +7,7 @@ export const PrimaryButton = styled.button`
border: none;
background-color: ${color.primary};
background-color: ${color.orange["100"]};
padding: 11px 30px;
font-family: "Inter", serif;
@ -16,7 +16,16 @@ export const PrimaryButton = styled.button`
font-size: 1.5rem;
line-height: 20px;
color: ${color.orange};
color: ${color.orange["50"]};
cursor: pointer;
&:hover {
transition-duration: 0.5s;
background-color: ${color.orange["200"]};
}
&:disabled {
background-color: ${color.orange["200"]};
}
`;

View File

@ -1,3 +1,5 @@
export * from "./skeleton-animation";
export * from "./skeleton-circle";
export * from "./skeleton-text";
export * from "./skeleton-chain-list";

View File

@ -0,0 +1,140 @@
import styled from "styled-components";
import color from "../../styles/color";
import { FunctionComponent } from "react";
import { SkeletonAnimation } from "./skeleton-animation";
import { SkeletonCircle } from "./skeleton-circle";
import { SkeletonText } from "./skeleton-text";
import {
ChainListTitleContainer,
ContentContainer,
ButtonContainer,
} from "../../pages/verification";
import {
ProfileContainer,
ProfileContentContainer,
ProfileFollowContainer,
ProfileNameContainer,
ProfileUserNameContainer,
} from "../twitter-profile";
import {
ChainContainer,
ChainImageContainer,
ChainInfoContainer,
ChainItemContainer,
} from "../chain-list";
export const SkeletonChainList: FunctionComponent = () => (
<ContentContainer>
<ProfileContainer color={color.grey["700"]}>
<SkeletonCircle width="5.5rem" height="5.5rem" />
<ProfileContentContainer>
<ProfileNameContainer>
<SkeletonText width="5rem" height="1.5rem" />
</ProfileNameContainer>
<ProfileUserNameContainer>
<SkeletonText width="5rem" height="1rem" />
</ProfileUserNameContainer>
<ProfileFollowContainer>
<SkeletonText width="8rem" height="1rem" />
<SkeletonText width="8rem" height="1rem" />
</ProfileFollowContainer>
<SkeletonText width="20rem" height="1rem" />
</ProfileContentContainer>
</ProfileContainer>
<ChainListTitleContainer>
<SkeletonTitle />
</ChainListTitleContainer>
<ChainContainer color={color.grey["700"]}>
<ChainItemContainer isLoading={true}>
<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 isLoading={true}>
<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 isLoading={true}>
<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 isLoading={true}>
<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 isLoading={true}>
<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 />
</ChainContainer>
<ButtonContainer>
<SkeletonButton />
</ButtonContainer>
</ContentContainer>
);
const SkeletonTitle = styled.div`
width: 8rem;
height: 1.5rem;
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["500"]};
`;

View File

@ -0,0 +1,133 @@
import color from "../../styles/color";
import styled from "styled-components";
import { TwitterAuthInfoResponse } from "../../types";
import { FunctionComponent } from "react";
import Image from "next/image";
interface Props {
twitterProfileInformation?: TwitterAuthInfoResponse | null;
}
export const TwitterProfile: FunctionComponent<Props> = (props) => {
const { twitterProfileInformation } = props;
return (
<ProfileContainer color={color.grey["800"]}>
<ProfileImageContainer>
<Image
src={twitterProfileInformation?.profile_image_url ?? ""}
fill={true}
alt="twitter profile image"
/>
</ProfileImageContainer>
<ProfileContentContainer>
<ProfileNameContainer>
{twitterProfileInformation?.name}
</ProfileNameContainer>
<ProfileUserNameContainer>
@{twitterProfileInformation?.username}
</ProfileUserNameContainer>
<ProfileFollowContainer>
<ProfileFollowerContainer>
<ProfileFollowBold>
{twitterProfileInformation?.public_metrics?.following_count}
</ProfileFollowBold>{" "}
Following
</ProfileFollowerContainer>
<ProfileFollowerContainer>
<ProfileFollowBold>
{twitterProfileInformation?.public_metrics?.followers_count}
</ProfileFollowBold>{" "}
Followers
</ProfileFollowerContainer>
</ProfileFollowContainer>
<ProfileDescriptionContainer>
{twitterProfileInformation?.description}
</ProfileDescriptionContainer>
</ProfileContentContainer>
</ProfileContainer>
);
};
export const ProfileContainer = styled.div`
display: flex;
flex-direction: row;
width: 100%;
padding: 1.5rem 2rem;
background-color: ${(props) => props.color};
`;
export const ProfileContentContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.85rem;
margin-left: 1.5rem;
`;
export const ProfileImageContainer = styled.div`
width: 5rem;
height: 5rem;
margin-top: -3rem;
border-radius: 50%;
overflow: hidden;
position: relative;
`;
export const ProfileNameContainer = styled.div`
font-weight: 600;
font-size: 1.2rem;
line-height: 1.5rem;
color: ${color.white};
`;
export const ProfileUserNameContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["100"]};
`;
export const ProfileFollowContainer = styled.div`
display: flex;
flex-direction: row;
gap: 1.5rem;
`;
export const ProfileFollowerContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["400"]};
`;
export const ProfileFollowBold = styled.span`
font-weight: 600;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.white};
`;
export const ProfileDescriptionContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["100"]};
`;

View File

@ -19,14 +19,15 @@ import color from "../../styles/color";
// Components
import { Logo } from "../../components/logo";
import {
SkeletonAnimation,
SkeletonCircle,
SkeletonText,
} from "../../components/skeleton";
import { SkeletonChainList } from "../../components/skeleton";
import { PrimaryButton } from "../../components/primary-button";
import { AccountInfos } from "../../config";
import {
ProfileContainer,
TwitterProfile,
} from "../../components/twitter-profile";
import { ChainList } from "../../components/chain-list";
export default function VerificationPage() {
const [twitterAuthInfo, setTwitterAuthInfo] =
@ -48,24 +49,24 @@ export default function VerificationPage() {
setTwitterAuthInfo(newTwitterAuthInfo);
const verifierMsg: VerifierMsg = {
unique_twitter_id: newTwitterAuthInfo.id,
name: newTwitterAuthInfo.username,
claimer: "osmo1y5mm5nj5m8ttddt5ccspek6xgyyavehrkak7gq",
contract_address: "osmo1y5mm5nj5m8ttddt5ccspek6xgyyavehrkak7gq",
chain_id: "osmosis-1",
};
await request<IcnsVerificationResponse>("/api/icns-verification", {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
msg: JSON.stringify(verifierMsg),
authToken: newTwitterAuthInfo.accessToken,
}),
});
// const verifierMsg: VerifierMsg = {
// unique_twitter_id: newTwitterAuthInfo.id,
// name: newTwitterAuthInfo.username,
// claimer: "osmo1y5mm5nj5m8ttddt5ccspek6xgyyavehrkak7gq",
// contract_address: "osmo1y5mm5nj5m8ttddt5ccspek6xgyyavehrkak7gq",
// chain_id: "osmosis-1",
// };
//
// await request<IcnsVerificationResponse>("/api/icns-verification", {
// method: "post",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({
// msg: JSON.stringify(verifierMsg),
// authToken: newTwitterAuthInfo.accessToken,
// }),
// });
setIsLoading(false);
}
@ -80,164 +81,17 @@ export default function VerificationPage() {
<MainContainer>
{isLoading ? (
<ContentContainer>
<ProfileContainer color={color.grey["700"]}>
<SkeletonCircle width="5.5rem" height="5.5rem" />
<ProfileContentContainer>
<ProfileNameContainer>
<SkeletonText width="5rem" height="1.5rem" />
</ProfileNameContainer>
<ProfileUserNameContainer>
<SkeletonText width="5rem" height="1rem" />
</ProfileUserNameContainer>
<ProfileFollowContainer>
<SkeletonText width="8rem" height="1rem" />
<SkeletonText width="8rem" height="1rem" />
</ProfileFollowContainer>
<SkeletonText width="20rem" height="1rem" />
</ProfileContentContainer>
</ProfileContainer>
<ChainListTitleContainer>
<SkeletonText width="8rem" height="1.5rem" />
</ChainListTitleContainer>
<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>
<SkeletonDivider />
</ChainContainer>
<ButtonContainer>
<SkeletonButton />
</ButtonContainer>
</ContentContainer>
<SkeletonChainList />
) : (
<ContentContainer>
<ProfileContainer color={color.grey["700"]}>
<ProfileImageContainer>
<Image
src={twitterAuthInfo?.profile_image_url ?? ""}
alt="profile image"
fill={true}
/>
</ProfileImageContainer>
<ProfileContentContainer>
<ProfileNameContainer>
{twitterAuthInfo?.name}
</ProfileNameContainer>
<ProfileUserNameContainer>
{twitterAuthInfo?.username}
</ProfileUserNameContainer>
<ProfileFollowContainer>
<ProfileFollowerContainer>
<ProfileFollowBold>
{twitterAuthInfo?.public_metrics?.following_count}
</ProfileFollowBold>{" "}
Following
</ProfileFollowerContainer>
<ProfileFollowerContainer>
<ProfileFollowBold>
{twitterAuthInfo?.public_metrics?.followers_count}
</ProfileFollowBold>{" "}
Followers
</ProfileFollowerContainer>
</ProfileFollowContainer>
<ProfileDescriptionContainer>
{twitterAuthInfo?.description}
</ProfileDescriptionContainer>
</ProfileContentContainer>
</ProfileContainer>
<TwitterProfile twitterProfileInformation={twitterAuthInfo} />
<ChainListTitleContainer>
<ChainListTitle>Chain List</ChainListTitle>
<SearchContainer>Search</SearchContainer>
</ChainListTitleContainer>
<ChainContainer color={color.grey["700"]}>
{AccountInfos.map((accountInfo) => (
<ChainItemContainer key={accountInfo.prefix}>
<ChainImageContainer width="3rem" height="3rem">
<Image
src={accountInfo.chainImageUrl}
alt={`${accountInfo.prefix} image`}
fill={true}
/>
</ChainImageContainer>
<ChainInfoContainer>
<ChainName>{`.${accountInfo.prefix}`}</ChainName>
<WalletAddress>{accountInfo.address}</WalletAddress>
</ChainInfoContainer>
<Flex1 />
<ChainCheckBox />
</ChainItemContainer>
))}
</ChainContainer>
<ChainList chainList={AccountInfos} />
<ButtonContainer>
<PrimaryButton>Register</PrimaryButton>
@ -261,7 +115,7 @@ const MainContainer = styled.div`
color: white;
`;
const ContentContainer = styled.div`
export const ContentContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
@ -271,143 +125,14 @@ const ContentContainer = styled.div`
margin-top: 5rem;
`;
const ProfileContainer = styled.div`
display: flex;
flex-direction: row;
width: 100%;
padding: 1.5rem 2rem;
background-color: ${(props) => props.color};
`;
const ProfileContentContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.85rem;
margin-left: 1.5rem;
`;
const ProfileFollowContainer = styled.div`
display: flex;
flex-direction: row;
gap: 1.5rem;
`;
const ChainContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
max-height: 33rem;
overflow: scroll;
background-color: ${(props) => props.color};
`;
const ChainItemContainer = styled.div`
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
padding: 1.5rem;
&:hover {
background: ${color.grey["900"]};
}
`;
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`
width: 10rem;
export const ButtonContainer = styled.div`
width: 12rem;
height: 4rem;
margin-top: 2rem;
`;
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"]};
`;
const ProfileImageContainer = styled.div`
width: 5rem;
height: 5rem;
margin-top: -3rem;
border-radius: 50%;
overflow: hidden;
position: relative;
`;
const ProfileNameContainer = styled.div`
font-weight: 600;
font-size: 1.2rem;
line-height: 1.5rem;
color: ${color.white};
`;
const ProfileUserNameContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["100"]};
`;
const ProfileFollowerContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["400"]};
`;
const ProfileFollowBold = styled.span`
font-weight: 600;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.white};
`;
const ProfileDescriptionContainer = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["300"]};
`;
const ChainListTitleContainer = styled.div`
export const ChainListTitleContainer = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
@ -438,28 +163,3 @@ const SearchContainer = styled.div`
background-color: ${color.grey["700"]};
`;
const ChainName = styled.div`
font-weight: 600;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["100"]};
`;
const WalletAddress = styled.div`
font-weight: 500;
font-size: 0.8rem;
line-height: 1rem;
color: ${color.grey["400"]};
`;
const Flex1 = styled.div`
flex: 1;
`;
const ChainCheckBox = styled.input.attrs({ type: "checkbox" })`
width: 1.5rem;
height: 1.5rem;
`;

View File

@ -1,7 +1,12 @@
const primary = "#FB5232";
const orange = "#FFCDC3";
const orange = {
50: "#FFCDC3",
100: "#FB5232",
200: "#A13E2A",
300: "#62332A",
400: "#442924",
};
const white = "#FCFCFC";
const grey = {
100: "#A3A3A3",
200: "#868686",
@ -13,12 +18,9 @@ const grey = {
800: "#242424",
900: "#181818",
};
const white = "#FFFFFF";
const black = "#121212";
const color = {
primary,
grey,
white,
black,