feat: UI refactor card header (#250)
* reactor: refactor card header * feat: custom card component * chore: animation on create ap success card * chore: remove old file * chore: global responsiveness (#251) * Update ui/src/components/card/card.tsx Co-authored-by: Felipe Mendes <zo.fmendes@gmail.com> --------- Co-authored-by: Felipe Mendes <zo.fmendes@gmail.com>
This commit is contained in:
parent
d2bad871c3
commit
cda25b9a3b
|
|
@ -11,10 +11,8 @@ export abstract class CardStyles {
|
|||
borderWidth: '$default',
|
||||
});
|
||||
|
||||
static readonly Heading = styled('h3', {
|
||||
color: '$slate12',
|
||||
fontSize: '$xl',
|
||||
fontWeight: '$medium',
|
||||
static readonly Header = styled('div', {
|
||||
width: '$full',
|
||||
});
|
||||
|
||||
static readonly Body = styled('div', {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable react/display-name */
|
||||
import React, { forwardRef } from 'react';
|
||||
|
||||
import { Flex } from '../layout';
|
||||
import { CardStyles } from './card.styles';
|
||||
|
||||
export abstract class Card {
|
||||
|
|
@ -15,18 +14,12 @@ export abstract class Card {
|
|||
}
|
||||
);
|
||||
|
||||
static readonly Heading = forwardRef<HTMLHeadingElement, Card.HeadingProps>(
|
||||
({ title, leftIcon, rightIcon, css, ...props }, ref) => {
|
||||
static readonly Header = CardStyles.Header;
|
||||
({ children, ...props }, ref) => {
|
||||
return (
|
||||
<Flex css={{ justifyContent: 'space-between', ...css }}>
|
||||
<Flex>
|
||||
{leftIcon}
|
||||
<CardStyles.Heading ref={ref} {...props}>
|
||||
{title}
|
||||
</CardStyles.Heading>
|
||||
</Flex>
|
||||
{rightIcon}
|
||||
</Flex>
|
||||
<CardStyles.Header ref={ref} {...props}>
|
||||
{children}
|
||||
</CardStyles.Header>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
@ -57,12 +50,7 @@ export namespace Card {
|
|||
typeof CardStyles.Container
|
||||
>;
|
||||
|
||||
export type HeadingProps = {
|
||||
title: string;
|
||||
css?: React.CSSProperties;
|
||||
leftIcon?: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
} & React.ComponentProps<typeof CardStyles.Heading>;
|
||||
export type HeadingProps = React.ComponentProps<typeof CardStyles.Header>;
|
||||
|
||||
export type BodyProps = React.ComponentProps<typeof CardStyles.Body>;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import { Card, Flex } from '@/components';
|
||||
import { styled } from '@/theme';
|
||||
|
||||
export const CustomCardStyles = {
|
||||
Container: styled(Card.Container, {
|
||||
maxWidth: '$107h',
|
||||
}),
|
||||
Title: {
|
||||
Container: styled(Flex, {
|
||||
justifyContent: 'space-between',
|
||||
}),
|
||||
Text: styled('h3', {
|
||||
color: '$slate12',
|
||||
fontSize: '$xl',
|
||||
fontWeight: '$medium',
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import { Card, Flex, Icon, IconButton } from '@/components';
|
||||
import { forwardStyledRef } from '@/theme';
|
||||
|
||||
import { CardStyles } from '../card.styles';
|
||||
import { CustomCardStyles as S } from './custom-card.styles';
|
||||
|
||||
export const CustomCardContainer = S.Container;
|
||||
|
||||
export abstract class CustomCardHeader {
|
||||
static readonly Default = forwardStyledRef<
|
||||
HTMLHeadingElement,
|
||||
CustomCard.HeadingProps
|
||||
>(({ title, onClickBack, ...props }, ref) => {
|
||||
return (
|
||||
<Card.Header ref={ref} {...props}>
|
||||
<S.Title.Container>
|
||||
<Flex css={{ gap: '$2' }}>
|
||||
{onClickBack && (
|
||||
<IconButton
|
||||
aria-label="back"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
onClick={onClickBack}
|
||||
/>
|
||||
)}
|
||||
<S.Title.Text>{title}</S.Title.Text>
|
||||
</Flex>
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
</S.Title.Container>
|
||||
</Card.Header>
|
||||
);
|
||||
});
|
||||
|
||||
static readonly Success = forwardStyledRef<
|
||||
HTMLHeadingElement,
|
||||
Omit<CustomCard.HeadingProps, 'onClickBack'>
|
||||
>(({ title, ...props }, ref) => {
|
||||
return (
|
||||
<Card.Header ref={ref} {...props}>
|
||||
<Flex css={{ gap: '$2' }}>
|
||||
<Icon
|
||||
name="check-circle"
|
||||
css={{ color: '$green11', fontSize: '$xl' }}
|
||||
/>
|
||||
<S.Title.Text>{title}</S.Title.Text>
|
||||
</Flex>
|
||||
</Card.Header>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export namespace CustomCard {
|
||||
export type ContainerProps = React.ComponentProps<typeof S.Container>;
|
||||
|
||||
export type HeadingProps = {
|
||||
title: string;
|
||||
onClickBack?: () => void;
|
||||
} & React.ComponentProps<typeof CardStyles.Header>;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './custom-card';
|
||||
|
|
@ -1 +1,2 @@
|
|||
export * from './card';
|
||||
export * from './custom-card';
|
||||
|
|
|
|||
|
|
@ -10,8 +10,11 @@ export abstract class PageStyles {
|
|||
width: '100%',
|
||||
minHeight: '85vh',
|
||||
maxWidth: '$6xl',
|
||||
padding: '0 $6',
|
||||
padding: '$6',
|
||||
margin: '0 auto',
|
||||
display: 'grid',
|
||||
|
||||
'@md': {
|
||||
padding: '0 $6',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Text } from '@/components';
|
||||
import { keyframes, styled } from '@/theme';
|
||||
|
||||
const Loading = keyframes({
|
||||
|
|
@ -13,7 +14,7 @@ const Loading = keyframes({
|
|||
});
|
||||
|
||||
export const ResolvedAddressStyles = {
|
||||
Container: styled('span', {
|
||||
Container: styled(Text, {
|
||||
'&[data-loading="true"]': {
|
||||
animation: `${Loading} 1s ease-in-out infinite`,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export const media = {
|
||||
// Breakpoints
|
||||
xs: '(min-width: 375px)',
|
||||
sm: '(min-width: 640px)',
|
||||
md: '(min-width: 768px)',
|
||||
lg: '(min-width: 1024px)',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
import { Card, Flex, Icon, IconButton, Stepper } from '@/components';
|
||||
import {
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
Stepper,
|
||||
} from '@/components';
|
||||
|
||||
import { CreateAccessPointFormBody } from './create-ap-form-body';
|
||||
|
||||
|
|
@ -6,28 +12,8 @@ export const CreateAccessPointForm: React.FC = () => {
|
|||
const { prevStep } = Stepper.useContext();
|
||||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<Card.Heading
|
||||
title="Enter Domain"
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={prevStep}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<CustomCardContainer>
|
||||
<CustomCardHeader.Default title="Enter Domain" onClickBack={prevStep} />
|
||||
<Card.Body>
|
||||
<Flex
|
||||
css={{
|
||||
|
|
@ -38,6 +24,6 @@ export const CreateAccessPointForm: React.FC = () => {
|
|||
<CreateAccessPointFormBody />
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { Button, Card, Grid, SpinnerDot, Stepper, Text } from '@/components';
|
||||
import { Button, Card, Flex, SpinnerDot, Stepper, Text } from '@/components';
|
||||
import { bunnyCDNActions, useAppDispatch, useBunnyCDNStore } from '@/store';
|
||||
|
||||
import { useAccessPointFormContext } from '../ap-form-step';
|
||||
|
|
@ -49,9 +49,10 @@ export const APRecordCardBody: React.FC = () => {
|
|||
</Text>
|
||||
</Card.Text>
|
||||
) : (
|
||||
<Grid
|
||||
<Flex
|
||||
css={{
|
||||
rowGap: '$6',
|
||||
gap: '$6',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Text>
|
||||
|
|
@ -73,7 +74,7 @@ export const APRecordCardBody: React.FC = () => {
|
|||
>
|
||||
I added the record
|
||||
</Button>
|
||||
</Grid>
|
||||
</Flex>
|
||||
)}
|
||||
</Card.Body>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,29 +1,9 @@
|
|||
import { Card, Icon, IconButton, Stepper } from '@/components';
|
||||
import { CustomCardHeader, Stepper } from '@/components';
|
||||
|
||||
export const APRecordCardHeader: React.FC = () => {
|
||||
const { prevStep } = Stepper.useContext();
|
||||
|
||||
return (
|
||||
<Card.Heading
|
||||
title="Create Record"
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={prevStep}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<CustomCardHeader.Default title="Create Record" onClickBack={prevStep} />
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { Card } from '@/components';
|
||||
import { CustomCardContainer } from '@/components';
|
||||
|
||||
import { APRecordCardBody } from './ap-record-body';
|
||||
import { APRecordCardHeader } from './ap-record-header';
|
||||
|
||||
export const APRecordStep: React.FC = () => {
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<CustomCardContainer>
|
||||
<APRecordCardHeader />
|
||||
<APRecordCardBody />
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import { useAccount } from 'wagmi';
|
|||
import {
|
||||
Button,
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
Icon,
|
||||
IconButton,
|
||||
ResolvedAddress,
|
||||
Stepper,
|
||||
Text,
|
||||
|
|
@ -40,7 +40,9 @@ export const AccessPointDataFragment: React.FC = () => {
|
|||
label="Owner"
|
||||
value={
|
||||
address ? (
|
||||
<ResolvedAddress truncated={false}>{address || ''}</ResolvedAddress>
|
||||
<ResolvedAddress truncated={false} ellipsis>
|
||||
{address}
|
||||
</ResolvedAddress>
|
||||
) : (
|
||||
'Please connect to wallet'
|
||||
)
|
||||
|
|
@ -111,28 +113,8 @@ export const CreateAccessPointPreview: React.FC = () => {
|
|||
}, [writeStatus, transactionStatus]);
|
||||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<Card.Heading
|
||||
title="Review Details"
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={prevStep}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<CustomCardContainer>
|
||||
<CustomCardHeader.Default title="Review Details" onClickBack={prevStep} />
|
||||
<Card.Body>
|
||||
<Flex css={{ flexDirection: 'column', gap: '$6' }}>
|
||||
<AccessPointDataFragment />
|
||||
|
|
@ -148,6 +130,6 @@ export const CreateAccessPointPreview: React.FC = () => {
|
|||
</Button>
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import { CustomCardContainer } from '@/components';
|
||||
import { keyframes, styled } from '@/theme';
|
||||
|
||||
const CardKeyFrames = keyframes({
|
||||
'0%': { opacity: 0 },
|
||||
'100%': { opacity: 1 },
|
||||
});
|
||||
|
||||
export const CreateApSuccessStyles = {
|
||||
Container: styled(CustomCardContainer, {
|
||||
animation: `${CardKeyFrames} 0.5s ease-in-out 0s`,
|
||||
}),
|
||||
};
|
||||
|
|
@ -1,29 +1,14 @@
|
|||
import { Button, Card, Flex, Icon, IconButton, Text } from '@/components';
|
||||
import { Button, Card, CustomCardHeader, Flex, Icon, Text } from '@/components';
|
||||
|
||||
import { CreateAccessPoint } from './create-ap.context';
|
||||
import { AccessPointDataFragment } from './create-ap-preview';
|
||||
import { CreateAccessPoint } from '../create-ap.context';
|
||||
import { AccessPointDataFragment } from '../create-ap-preview';
|
||||
import { CreateApSuccessStyles as S } from './create-ap-success.styles';
|
||||
|
||||
export const CreateAccessPointSuccess: React.FC = () => {
|
||||
const { nfa } = CreateAccessPoint.useContext();
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<Card.Heading
|
||||
title="Hosting Successful"
|
||||
leftIcon={
|
||||
<Icon
|
||||
name="check-circle"
|
||||
css={{ color: '$green11', fontSize: '$xl', mr: '$2' }}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<S.Container>
|
||||
<CustomCardHeader.Success title="Hosting Successful" />
|
||||
<Card.Body>
|
||||
<Flex css={{ flexDirection: 'column', gap: '$6' }}>
|
||||
<Text css={{ fontSize: '$sm', color: '$slate11' }}>
|
||||
|
|
@ -42,6 +27,6 @@ export const CreateAccessPointSuccess: React.FC = () => {
|
|||
</Flex>
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</S.Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './create-ap-success';
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import { Flex, Text } from '@/components';
|
||||
import { styled } from '@/theme';
|
||||
|
||||
import { Flex } from '../../../components/layout';
|
||||
|
||||
export const DisplayTextStyles = {
|
||||
Container: styled(Flex, {
|
||||
flexDirection: 'column',
|
||||
|
|
@ -13,7 +12,7 @@ export const DisplayTextStyles = {
|
|||
fontSize: '$xs',
|
||||
//TODO add variants
|
||||
}),
|
||||
Input: styled('span', {
|
||||
Input: styled(Text, {
|
||||
backgroundColor: '$slate1',
|
||||
borderColor: '$slate1',
|
||||
color: '$slate12',
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export const DisplayText: React.FC<DisplayTextProps> = ({
|
|||
return (
|
||||
<S.Container>
|
||||
<S.Label>{label}</S.Label>
|
||||
<S.Input>{value}</S.Input>
|
||||
<S.Input ellipsis>{value}</S.Input>
|
||||
</S.Container>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
import { Card, Grid, Stepper } from '@/components';
|
||||
import { MintCardHeader } from '@/views/mint/mint-card';
|
||||
import {
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
Stepper,
|
||||
} from '@/components';
|
||||
|
||||
import { GithubButton } from './github-button';
|
||||
|
||||
|
|
@ -7,10 +12,10 @@ export const GithubConnect: React.FC = () => {
|
|||
const { prevStep } = Stepper.useContext();
|
||||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<MintCardHeader title="Connect GitHub" onClickBack={prevStep} />
|
||||
<CustomCardContainer>
|
||||
<CustomCardHeader.Default title="Connect GitHub" onClickBack={prevStep} />
|
||||
<Card.Body>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<Flex css={{ gap: '$6', flexDirection: 'column' }}>
|
||||
<GithubButton />
|
||||
<Card.Text
|
||||
css={{
|
||||
|
|
@ -24,8 +29,8 @@ export const GithubConnect: React.FC = () => {
|
|||
After connecting your GitHub, your repositories will show here.
|
||||
</span>
|
||||
</Card.Text>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { CustomCardHeader } from '@/components';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
import { MintCardHeader } from '@/views/mint/mint-card';
|
||||
import { useMintFormContext } from '@/views/mint/nfa-step/form-step';
|
||||
|
||||
export const RepoConfigurationHeader: React.FC = () => {
|
||||
|
|
@ -22,7 +22,7 @@ export const RepoConfigurationHeader: React.FC = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<MintCardHeader
|
||||
<CustomCardHeader.Default
|
||||
title="Configure Repository"
|
||||
onClickBack={handlePrevStepClick}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { Card } from '@/components';
|
||||
import { CustomCardContainer } from '@/components';
|
||||
|
||||
import { RepoConfigurationBody } from './repo-configuration-body';
|
||||
import { RepoConfigurationHeader } from './repo-configuration-header';
|
||||
|
||||
export const GithubRepoConfiguration: React.FC = () => {
|
||||
return (
|
||||
<Card.Container css={{ minWidth: '17rem', maxWidth: '$107h' }}>
|
||||
<CustomCardContainer css={{ minWidth: '17rem' }}>
|
||||
<RepoConfigurationHeader />
|
||||
<RepoConfigurationBody />
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
import { Card, Flex, Icon } from '@/components';
|
||||
import {
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
Icon,
|
||||
} from '@/components';
|
||||
import { styled } from '@/theme';
|
||||
|
||||
export const GithubRepositorySelectionStyles = {
|
||||
Card: {
|
||||
Wrapper: styled(Card.Container, {
|
||||
maxWidth: '$107h',
|
||||
Wrapper: styled(CustomCardContainer, {
|
||||
maxHeight: '$95h',
|
||||
pr: '$3h',
|
||||
}),
|
||||
Header: styled(CustomCardHeader.Default, {
|
||||
pr: '$3h',
|
||||
}),
|
||||
Body: styled(Card.Body, {
|
||||
pt: '$4',
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -1,14 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
import {
|
||||
Card,
|
||||
Flex,
|
||||
Icon,
|
||||
IconButton,
|
||||
InputGroup,
|
||||
InputGroupText,
|
||||
Spinner,
|
||||
} from '@/components';
|
||||
import { Flex, InputGroup, InputGroupText, Spinner } from '@/components';
|
||||
import { useDebounce } from '@/hooks/use-debounce';
|
||||
import { useGithubStore } from '@/store';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
|
|
@ -55,27 +47,9 @@ export const GithubRepositoryConnection: React.FC = () => {
|
|||
|
||||
return (
|
||||
<S.Card.Wrapper>
|
||||
<Card.Heading
|
||||
<S.Card.Header
|
||||
title="Select Repository"
|
||||
css={{ pr: '$3h' }}
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="back"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={handlePrevStepClick}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="info"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
onClickBack={handlePrevStepClick}
|
||||
/>
|
||||
<S.Card.Body>
|
||||
<S.Container>
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
export * from './mint-card';
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
import { Card, Icon, IconButton } from '@/components';
|
||||
|
||||
type MintCardHeaderProps = {
|
||||
title: string;
|
||||
onClickBack: () => void;
|
||||
};
|
||||
|
||||
export const MintCardHeader: React.FC<MintCardHeaderProps> = ({
|
||||
title,
|
||||
onClickBack,
|
||||
}: MintCardHeaderProps) => {
|
||||
return (
|
||||
<Card.Heading
|
||||
title={title}
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={onClickBack}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -6,7 +6,14 @@ export const MintStyles = {
|
|||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
|
||||
'@media (min-width: 1024px)': {
|
||||
'@md': {
|
||||
//to align on center
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
},
|
||||
|
||||
'@lg': {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
import { useAccount } from 'wagmi';
|
||||
|
||||
import { Button, Card, Grid, Stepper } from '@/components';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
Stepper,
|
||||
} from '@/components';
|
||||
import { AppLog } from '@/utils';
|
||||
import { parseColorToNumber } from '@/utils/color';
|
||||
|
||||
import { Mint } from '../../mint.context';
|
||||
import { MintCardHeader } from '../../mint-card';
|
||||
import {
|
||||
AppDescriptionField,
|
||||
AppNameField,
|
||||
|
|
@ -78,20 +84,24 @@ export const MintFormStep: React.FC = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<MintCardHeader title="NFA Details" onClickBack={handlePrevStep} />
|
||||
<CustomCardContainer>
|
||||
<CustomCardHeader.Default
|
||||
title="NFA Details"
|
||||
onClickBack={handlePrevStep}
|
||||
/>
|
||||
<Card.Body>
|
||||
<Grid
|
||||
<Flex
|
||||
css={{
|
||||
rowGap: '$6',
|
||||
gap: '$6',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Grid css={{ rowGap: '$4' }}>
|
||||
<Flex css={{ gap: '$4', flexDirection: 'column' }}>
|
||||
<AppNameField />
|
||||
<AppDescriptionField />
|
||||
<EnsDomainField />
|
||||
<LogoField />
|
||||
</Grid>
|
||||
</Flex>
|
||||
<Button
|
||||
disabled={!isValid}
|
||||
colorScheme="blue"
|
||||
|
|
@ -100,8 +110,8 @@ export const MintFormStep: React.FC = () => {
|
|||
>
|
||||
Continue
|
||||
</Button>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
import { useQuery } from '@apollo/client';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { getVerifiersDocument } from '@/../.graphclient';
|
||||
import { Form, ResolvedAddress } from '@/components';
|
||||
import { useENSStore } from '@/store';
|
||||
|
||||
import { useMintFormContext } from '../form-step';
|
||||
|
||||
// TODO: remove mocked items after graphql api is fixed
|
||||
const mockedItems = [
|
||||
'0xdBb04e00D5ec8C9e3aeF811D315Ee7C147c5DBFD',
|
||||
'0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049',
|
||||
];
|
||||
|
||||
export const SelectVerifier: React.FC = () => {
|
||||
const {
|
||||
form: { verifier },
|
||||
} = useMintFormContext();
|
||||
|
||||
const {
|
||||
value: [selectedVerifier, setSelectedVerifier],
|
||||
} = verifier;
|
||||
|
||||
const { addressMap } = useENSStore();
|
||||
|
||||
const { data } = useQuery(getVerifiersDocument);
|
||||
|
||||
const items = useMemo(() => {
|
||||
if (!data) return [];
|
||||
|
||||
const verifiers = data.verifiers
|
||||
.map<string>((verifier) => verifier.id.toString())
|
||||
.concat(mockedItems);
|
||||
|
||||
return verifiers.map((verifier) => ({
|
||||
address: verifier,
|
||||
ens: addressMap[verifier]?.value,
|
||||
}));
|
||||
}, [data, addressMap]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedVerifier && items.length > 0) {
|
||||
setSelectedVerifier(items[0].address);
|
||||
}
|
||||
}, [selectedVerifier, setSelectedVerifier, items]);
|
||||
|
||||
return (
|
||||
<Form.Field context={verifier}>
|
||||
<Form.Combobox
|
||||
items={items}
|
||||
handleValue={(item) => item.address}
|
||||
queryKey={['address', 'ens']}
|
||||
>
|
||||
{({ Field, Options }) => (
|
||||
<>
|
||||
<Field>
|
||||
{(selected) =>
|
||||
selected ? (
|
||||
<ResolvedAddress>{selected.address}</ResolvedAddress>
|
||||
) : (
|
||||
'Select a Verifier'
|
||||
)
|
||||
}
|
||||
</Field>
|
||||
<Options>
|
||||
{(item) => <ResolvedAddress>{item.address}</ResolvedAddress>}
|
||||
</Options>
|
||||
</>
|
||||
)}
|
||||
</Form.Combobox>
|
||||
</Form.Field>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import { Card, Flex, Text } from '@/components';
|
||||
import { styled } from '@/theme';
|
||||
|
||||
export const VerifyNfaStepStyles = {
|
||||
Body: {
|
||||
Container: styled(Flex, {
|
||||
flexDirection: 'column',
|
||||
gap: '$6',
|
||||
}),
|
||||
Text: styled(Text, {
|
||||
color: '$slate11',
|
||||
fontSize: '$sm',
|
||||
}),
|
||||
VerifyContainer: styled(Card.Text, {
|
||||
p: '$4',
|
||||
textAlign: 'left',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
borderRadius: '$lg',
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
|
@ -1,88 +1,17 @@
|
|||
import { useQuery } from '@apollo/client';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { getVerifiersDocument } from '@/../.graphclient';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Flex,
|
||||
Form,
|
||||
ResolvedAddress,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Stepper,
|
||||
Switch,
|
||||
Text,
|
||||
} from '@/components';
|
||||
import { useENSStore } from '@/store';
|
||||
|
||||
import { Mint } from '../../mint.context';
|
||||
import { MintCardHeader } from '../../mint-card';
|
||||
import { useMintFormContext } from '../form-step';
|
||||
|
||||
// TODO: remove mocked items after graphql api is fixed
|
||||
const mockedItems = [
|
||||
'0xdBb04e00D5ec8C9e3aeF811D315Ee7C147c5DBFD',
|
||||
'0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049',
|
||||
];
|
||||
|
||||
const SelectVerifier: React.FC = () => {
|
||||
const {
|
||||
form: { verifier },
|
||||
} = useMintFormContext();
|
||||
|
||||
const {
|
||||
value: [selectedVerifier, setSelectedVerifier],
|
||||
} = verifier;
|
||||
|
||||
const { addressMap } = useENSStore();
|
||||
|
||||
const { data } = useQuery(getVerifiersDocument);
|
||||
|
||||
const items = useMemo(() => {
|
||||
if (!data) return [];
|
||||
|
||||
const verifiers = data.verifiers
|
||||
.map<string>((verifier) => verifier.id.toString())
|
||||
.concat(mockedItems);
|
||||
|
||||
return verifiers.map((verifier) => ({
|
||||
address: verifier,
|
||||
ens: addressMap[verifier]?.value,
|
||||
}));
|
||||
}, [data, addressMap]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedVerifier && items.length > 0) {
|
||||
setSelectedVerifier(items[0].address);
|
||||
}
|
||||
}, [selectedVerifier, setSelectedVerifier, items]);
|
||||
|
||||
return (
|
||||
<Form.Field context={verifier}>
|
||||
<Form.Combobox
|
||||
items={items}
|
||||
handleValue={(item) => item.address}
|
||||
queryKey={['address', 'ens']}
|
||||
>
|
||||
{({ Field, Options }) => (
|
||||
<>
|
||||
<Field>
|
||||
{(selected) =>
|
||||
selected ? (
|
||||
<ResolvedAddress>{selected.address}</ResolvedAddress>
|
||||
) : (
|
||||
'Select a Verifier'
|
||||
)
|
||||
}
|
||||
</Field>
|
||||
<Options>
|
||||
{(item) => <ResolvedAddress>{item.address}</ResolvedAddress>}
|
||||
</Options>
|
||||
</>
|
||||
)}
|
||||
</Form.Combobox>
|
||||
</Form.Field>
|
||||
);
|
||||
};
|
||||
import { SelectVerifier } from './select-verifier';
|
||||
import { VerifyNfaStepStyles as S } from './verify-nfa-step.styles';
|
||||
|
||||
export const VerifyNFAStep: React.FC = () => {
|
||||
const { prevStep } = Stepper.useContext();
|
||||
|
|
@ -100,30 +29,22 @@ export const VerifyNFAStep: React.FC = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<MintCardHeader title="Verify NFA" onClickBack={prevStep} />
|
||||
<CustomCardContainer>
|
||||
<CustomCardHeader.Default title="Verify NFA" onClickBack={prevStep} />
|
||||
<Card.Body>
|
||||
<Flex css={{ flexDirection: 'column', gap: '$6' }}>
|
||||
<Text css={{ color: '$slate11', fontSize: '$sm' }}>
|
||||
<S.Body.Container>
|
||||
<S.Body.Text>
|
||||
Below you can allow Fleek to be added as a controller to your NFA.
|
||||
This will allow Fleek to automatically verify your NFA and update
|
||||
builds and other metadata. It will not allow Fleek to transfer or
|
||||
burn your NFT. You can change this setting later on your NFA but
|
||||
adding it now will save you a transaction in the future. We
|
||||
recommend it so that your users can get verified NFAs.
|
||||
</Text>
|
||||
<Card.Text
|
||||
css={{
|
||||
p: '$4',
|
||||
textAlign: 'left',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
borderRadius: '$lg',
|
||||
}}
|
||||
>
|
||||
</S.Body.Text>
|
||||
<S.Body.VerifyContainer>
|
||||
<Text css={{ color: '$slate12' }}>Verify NFA</Text>
|
||||
<Switch checked={verifyNFA} onChange={setVerifyNFA} />
|
||||
</Card.Text>
|
||||
</S.Body.VerifyContainer>
|
||||
<SelectVerifier />
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
|
|
@ -133,8 +54,8 @@ export const VerifyNFAStep: React.FC = () => {
|
|||
>
|
||||
Continue
|
||||
</Button>
|
||||
</Flex>
|
||||
</S.Body.Container>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
import { Button, Card, Grid } from '@/components';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
Text,
|
||||
} from '@/components';
|
||||
import { NFAPreview } from '@/components';
|
||||
|
||||
import { useMintFormContext } from '../nfa-step/form-step';
|
||||
|
|
@ -16,8 +23,6 @@ type NftCardProps = {
|
|||
|
||||
export const NftCard: React.FC<NftCardProps> = ({
|
||||
title,
|
||||
leftIcon,
|
||||
rightIcon,
|
||||
message,
|
||||
buttonText,
|
||||
leftIconButton,
|
||||
|
|
@ -43,23 +48,21 @@ export const NftCard: React.FC<NftCardProps> = ({
|
|||
} = useMintFormContext();
|
||||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h', p: '$0' }}>
|
||||
<CustomCardContainer css={{ p: '$0' }}>
|
||||
<NFAPreview
|
||||
color={logoColor}
|
||||
logo={appLogo}
|
||||
name={appName}
|
||||
ens={ens}
|
||||
size={size}
|
||||
className="rounded-t-xhl"
|
||||
css={{
|
||||
bt: '1.25rem',
|
||||
}}
|
||||
/>
|
||||
<Card.Body css={{ p: '$7' }}>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<Card.Heading
|
||||
title={title}
|
||||
leftIcon={leftIcon}
|
||||
rightIcon={rightIcon}
|
||||
/>
|
||||
<span className="text-slate11 text-sm">{message}</span>
|
||||
<Flex css={{ gap: '$6', flexDirection: 'column' }}>
|
||||
<CustomCardHeader.Success title={title} />
|
||||
<Text css={{ color: '$slate11', fontSize: '$sm' }}>{message}</Text>
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
|
|
@ -70,8 +73,8 @@ export const NftCard: React.FC<NftCardProps> = ({
|
|||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,23 +1,18 @@
|
|||
import { Card, Grid, Icon, IconButton } from '@/components';
|
||||
import {
|
||||
Card,
|
||||
CustomCardContainer,
|
||||
CustomCardHeader,
|
||||
Flex,
|
||||
} from '@/components';
|
||||
|
||||
import { ConnectWalletButton } from './connect-wallet-button';
|
||||
|
||||
export const WalletStep: React.FC = () => {
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h' }}>
|
||||
<Card.Heading
|
||||
title="Connect Wallet"
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<CustomCardContainer>
|
||||
<CustomCardHeader.Default title="Connect Wallet" />
|
||||
<Card.Body>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<Flex css={{ gap: '$6', flexDirection: 'column' }}>
|
||||
<ConnectWalletButton />
|
||||
<Card.Text
|
||||
css={{
|
||||
|
|
@ -29,8 +24,8 @@ export const WalletStep: React.FC = () => {
|
|||
>
|
||||
<span>Connect with the wallet you want to mint & own the NFA.</span>
|
||||
</Card.Text>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
</CustomCardContainer>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue