chore: mint form (#115)
* wip: form for mint * style: change bgcolor for disabled button * fix: add key to list items * styles: add some spacings and border radius * refactor: change type file and move file validation to form * feat: add minted nft card. add wallet step * refactor: add mint card header to not repeat code * styles: add border radius to svg * styles: fix styles on mint view * style: fix height mint view * fix: fix save repository config * chore: changes based on PR review
This commit is contained in:
parent
60af583479
commit
04dc4a95c7
|
|
@ -24,6 +24,7 @@ export abstract class CardStyles {
|
|||
|
||||
static readonly Text = styled('div', {
|
||||
backgroundColor: '$slate1',
|
||||
width: '$full',
|
||||
borderRadius: '$xl',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
|
@ -31,5 +32,6 @@ export abstract class CardStyles {
|
|||
alignItems: 'center',
|
||||
textAlign: 'center',
|
||||
color: '$slate8',
|
||||
fontSize: '$sm',
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,10 +160,11 @@ export const StyledButton = styled('button', {
|
|||
whiteSpace: 'nowrap',
|
||||
verticalAlign: 'middle',
|
||||
userSelect: 'none',
|
||||
fontWeight: '$medium',
|
||||
fontWeight: '$normal',
|
||||
'&:disabled': {
|
||||
cursor: 'not-allowed',
|
||||
opacity: '0.4',
|
||||
backgroundColor: '$slate3',
|
||||
},
|
||||
|
||||
variants: {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ type DropdownOptionProps = {
|
|||
|
||||
const DropdownOption = ({ option }: DropdownOptionProps) => (
|
||||
<Listbox.Option
|
||||
key={option.value}
|
||||
className={({ active }) =>
|
||||
`relative cursor-default select-none py-2 px-3.5 text-slate11 rounded-xl mb-2 text-sm ${
|
||||
active ? 'bg-slate5 text-slate12' : 'bg-transparent'
|
||||
|
|
@ -35,7 +34,7 @@ type DropdownButtonProps = {
|
|||
|
||||
const DropdownButton = ({ selectedValue, open }: DropdownButtonProps) => (
|
||||
<Listbox.Button
|
||||
className={`relative w-full cursor-default bg-transparent border-solid border border-slate7 py-3 pl-3.5 pr-10 text-left focus:outline-none sm:text-sm ${
|
||||
className={`relative w-full cursor-default bg-transparent border-solid border border-slate7 py-3 pl-3.5 pr-10 h-11 text-left focus:outline-none sm:text-sm ${
|
||||
open ? 'border-b-0 rounded-t-xl bg-black border-slate6' : 'rounded-xl'
|
||||
}`}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ import { AiOutlineDown } from '@react-icons/all-files/ai/AiOutlineDown';
|
|||
import { BiSearch } from '@react-icons/all-files/bi/BiSearch';
|
||||
import { IoCloudUploadSharp } from '@react-icons/all-files/io5/IoCloudUploadSharp';
|
||||
import { MetamaskIcon, EthereumIcon } from './custom';
|
||||
import { IoCheckmarkCircleSharp } from '@react-icons/all-files/io5/IoCheckmarkCircleSharp';
|
||||
import { AiOutlineTwitter } from '@react-icons/all-files/ai/AiOutlineTwitter';
|
||||
|
||||
export const IconLibrary = Object.freeze({
|
||||
back: IoArrowBackCircleSharp,
|
||||
check: AiOutlineCheck,
|
||||
'check-circle': IoCheckmarkCircleSharp,
|
||||
'chevron-down': AiOutlineDown,
|
||||
ethereum: EthereumIcon,
|
||||
github: IoLogoGithub,
|
||||
|
|
@ -17,6 +20,7 @@ export const IconLibrary = Object.freeze({
|
|||
upload: IoCloudUploadSharp,
|
||||
metamask: MetamaskIcon, //remove if not used
|
||||
search: BiSearch,
|
||||
twitter: AiOutlineTwitter,
|
||||
});
|
||||
|
||||
export type IconName = keyof typeof IconLibrary;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { Flex } from '../../layout';
|
||||
import { dripStitches } from '../../../theme';
|
||||
import { forwardRef, useRef, useState } from 'react';
|
||||
import { forwardRef, useRef } from 'react';
|
||||
import { Icon } from '../icon';
|
||||
import { Form } from '../../../components/form/form';
|
||||
|
||||
const { styled } = dripStitches;
|
||||
|
||||
|
|
@ -15,44 +14,24 @@ const BorderInput = styled('div', {
|
|||
borderWidth: '$default',
|
||||
borderRadius: '$lg',
|
||||
zIndex: '$docked',
|
||||
my: '$1h',
|
||||
|
||||
'&:hover': {
|
||||
borderColor: '$gray8',
|
||||
},
|
||||
});
|
||||
|
||||
const DEFAULT_MAX_FILE_SIZE = 10; // in KB
|
||||
|
||||
// The file size must be capped to a size that the contract can handle
|
||||
const validateFileSize = (
|
||||
file: File,
|
||||
maxSize = DEFAULT_MAX_FILE_SIZE
|
||||
): boolean => {
|
||||
return file.size <= 1024 * maxSize;
|
||||
};
|
||||
|
||||
type InputFileProps = {
|
||||
value: File | null;
|
||||
onChange: (file: File | null) => void;
|
||||
value: string;
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
} & React.ComponentProps<typeof Flex>;
|
||||
|
||||
export const StyledInputFile = forwardRef<HTMLDivElement, InputFileProps>(
|
||||
({ value: file, onChange, css, ...props }, ref) => {
|
||||
const inputFileRef = useRef<HTMLInputElement>(null);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
|
||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
e.preventDefault();
|
||||
setErrorMessage(null);
|
||||
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
if (validateFileSize(e.target.files[0])) onChange(e.target.files[0]);
|
||||
else {
|
||||
onChange(null);
|
||||
setErrorMessage('File size is too big');
|
||||
}
|
||||
}
|
||||
onChange(e);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -68,12 +47,8 @@ export const StyledInputFile = forwardRef<HTMLDivElement, InputFileProps>(
|
|||
{...props}
|
||||
onClick={() => inputFileRef.current?.click()}
|
||||
>
|
||||
{file ? (
|
||||
<img
|
||||
className="absolute w-14 h-14"
|
||||
src={URL.createObjectURL(file)}
|
||||
alt="logo"
|
||||
/>
|
||||
{file !== '' ? (
|
||||
<img className="absolute w-14 h-14" src={file} alt="logo" />
|
||||
) : (
|
||||
<Icon name="upload" size="md" css={{ position: 'absolute' }} />
|
||||
)}
|
||||
|
|
@ -87,7 +62,6 @@ export const StyledInputFile = forwardRef<HTMLDivElement, InputFileProps>(
|
|||
onChange={handleFileChange}
|
||||
/>
|
||||
</Flex>
|
||||
{errorMessage && <Form.Error>{errorMessage}</Form.Error>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export const spacing = {
|
|||
3: '0.75rem', // 12px
|
||||
'3h': '0.875rem', // 14px
|
||||
4: '1rem', // 16px
|
||||
'4h': '1.125rem', // 18px
|
||||
5: '1.25rem', // 20px
|
||||
6: '1.5rem', // 24px
|
||||
7: '1.75rem', // 28px
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import { Form } from '@/components';
|
||||
import { Mint } from '../../mint.context';
|
||||
|
||||
export const AppDescriptionField = () => {
|
||||
const { appDescription, setAppDescription } = Mint.useContext();
|
||||
|
||||
const handleAppDescriptionChange = (
|
||||
e: React.ChangeEvent<HTMLTextAreaElement>
|
||||
) => {
|
||||
setAppDescription(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Form.Field>
|
||||
<Form.Label>Description</Form.Label>
|
||||
<Form.Textarea
|
||||
placeholder="Add information about your project here."
|
||||
css={{ height: 'auto' }}
|
||||
value={appDescription}
|
||||
onChange={handleAppDescriptionChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { Form } from '@/components';
|
||||
import { Mint } from '../../mint.context';
|
||||
|
||||
export const AppNameField = () => {
|
||||
const { appName, setAppName } = Mint.useContext();
|
||||
|
||||
const handleAppNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setAppName(e.target.value);
|
||||
};
|
||||
return (
|
||||
<Form.Field>
|
||||
<Form.Label>Name</Form.Label>
|
||||
<Form.Input
|
||||
placeholder="Your app name"
|
||||
value={appName}
|
||||
onChange={handleAppNameChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { Form } from '@/components';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
|
||||
export const DomainField = () => {
|
||||
const { domain, setDomain } = Mint.useContext();
|
||||
|
||||
const handleDomainChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setDomain(e.target.value);
|
||||
};
|
||||
return (
|
||||
<Form.Field css={{ flex: 1 }}>
|
||||
<Form.Label>Domain</Form.Label>
|
||||
<Form.Input
|
||||
placeholder="mydomain.com"
|
||||
value={domain}
|
||||
onChange={handleDomainChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { Flex } from '@/components';
|
||||
import { DomainField } from './domain-field';
|
||||
import { EnsField } from './ens-field';
|
||||
|
||||
export const EnsDomainField = () => (
|
||||
<Flex css={{ columnGap: '$4' }}>
|
||||
<EnsField />
|
||||
<DomainField />
|
||||
</Flex>
|
||||
);
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { Dropdown, DropdownItem, Form } from '@/components';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
|
||||
// TODO remove after integration with wallet
|
||||
const ensList: DropdownItem[] = [
|
||||
{
|
||||
value: 'fleek.eth',
|
||||
label: 'fleek.eth',
|
||||
},
|
||||
{
|
||||
value: 'ens.eth',
|
||||
label: 'ens.eth',
|
||||
},
|
||||
{
|
||||
value: 'cami.eth',
|
||||
label: 'cami.eth',
|
||||
},
|
||||
];
|
||||
|
||||
export const EnsField = () => {
|
||||
const { ens, setEns } = Mint.useContext();
|
||||
|
||||
const handleEnsChange = (item: DropdownItem) => {
|
||||
setEns(item);
|
||||
};
|
||||
|
||||
return (
|
||||
<Form.Field css={{ flex: 1 }}>
|
||||
<Form.Label>ENS</Form.Label>
|
||||
<Dropdown
|
||||
items={ensList}
|
||||
selectedValue={ens}
|
||||
onChange={handleEnsChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './ens-domain-field';
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
export * from './logo-field';
|
||||
export * from './app-name-field';
|
||||
export * from './app-description-field';
|
||||
export * from './ens-domain-field';
|
||||
export * from './verify-nfa-field';
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { Card, Flex } from '@/components';
|
||||
import { useRef } from 'react';
|
||||
// @ts-ignore
|
||||
import ColorThief from 'colorthief';
|
||||
import { Mint } from '../../../mint.context';
|
||||
|
||||
export const ColorPicker = () => {
|
||||
const { appLogo, logoColor, setLogoColor } = Mint.useContext();
|
||||
const imageRef = useRef<HTMLImageElement>(null);
|
||||
|
||||
const handleLogoLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {
|
||||
const colorArray = new ColorThief().getColor(imageRef.current);
|
||||
const hexColor = `#${colorArray
|
||||
.map((c: number) => c.toString(16).padStart(2, '0'))
|
||||
.join('')}`;
|
||||
setLogoColor(hexColor);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card.Text css={{ height: '$22', mt: '$6' }}>
|
||||
<Flex css={{ gap: '$3h' }}>
|
||||
<span>Primary Color</span>
|
||||
{/* TODO crate color picker component */}
|
||||
<input
|
||||
type="color"
|
||||
value={logoColor}
|
||||
onChange={(e) => setLogoColor(e.target.value)}
|
||||
/>
|
||||
</Flex>
|
||||
<img
|
||||
className="hidden"
|
||||
src={appLogo}
|
||||
ref={imageRef}
|
||||
onLoad={handleLogoLoad}
|
||||
style={{ width: '50px', height: '50px' }}
|
||||
/>
|
||||
</Card.Text>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './logo-field';
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { Flex, Form } from '@/components';
|
||||
import { useState } from 'react';
|
||||
import { Mint } from '../../../mint.context';
|
||||
import { fileToBase64, validateFileSize } from '../../form.utils';
|
||||
import { ColorPicker } from './color-picker';
|
||||
|
||||
export const LogoField = () => {
|
||||
const { appLogo, setAppLogo, setLogoColor } = Mint.useContext();
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
|
||||
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
|
||||
if (file) {
|
||||
if (validateFileSize(file)) {
|
||||
const fileBase64 = await fileToBase64(file);
|
||||
setAppLogo(fileBase64);
|
||||
setErrorMessage(null);
|
||||
//TODO remove console.log
|
||||
// To send to the contract the logo needs to be a base64 string
|
||||
console.log('Sending to contract:', fileBase64);
|
||||
} else {
|
||||
setAppLogo('');
|
||||
setLogoColor('');
|
||||
setErrorMessage('File size is too big');
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Flex css={{ width: '$full', gap: '$4h', alignItems: 'flex-start' }}>
|
||||
<Form.Field>
|
||||
<Form.Label>Logo</Form.Label>
|
||||
<Form.LogoFileInput value={appLogo} onChange={handleFileChange} />
|
||||
{errorMessage && <Form.Error>{errorMessage}</Form.Error>}
|
||||
</Form.Field>
|
||||
<ColorPicker />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { Card, Flex, Grid } from '@/components';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
|
||||
export const VerifyNFAField = () => {
|
||||
const { verifyNFA, setVerifyNFA } = Mint.useContext();
|
||||
|
||||
const handleVerifyNFAChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setVerifyNFA(e.target.checked);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card.Text css={{ p: '$4', textAlign: 'left' }}>
|
||||
{/* TODO replace for grid */}
|
||||
<Flex css={{ gap: '$10' }}>
|
||||
<Grid css={{ rowGap: '$1h' }}>
|
||||
<span>Verify NFA</span>
|
||||
<span>
|
||||
Add Fleek as a controller to be verified, learn more here.
|
||||
</span>
|
||||
</Grid>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={verifyNFA}
|
||||
onChange={handleVerifyNFAChange}
|
||||
/>
|
||||
</Flex>
|
||||
</Card.Text>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//TODO create env variable
|
||||
const DEFAULT_MAX_FILE_SIZE = 10; // in KB
|
||||
|
||||
/**
|
||||
* The file size must be capped to a size that the contract can handle
|
||||
*/
|
||||
export const validateFileSize = (
|
||||
file: File,
|
||||
maxSize = DEFAULT_MAX_FILE_SIZE
|
||||
): boolean => {
|
||||
return file.size <= 1024 * maxSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the File from the input to a base64 string.
|
||||
*/
|
||||
export const fileToBase64 = (file: File): Promise<string> =>
|
||||
new Promise<string>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => resolve(reader.result?.toString() || '');
|
||||
reader.onerror = reject;
|
||||
});
|
||||
|
||||
/**
|
||||
* Converts a hex color string to a number.
|
||||
*/
|
||||
export const parseColorToNumber = (color: string): number => {
|
||||
const hexColor = color.replace('#', '');
|
||||
return parseInt(hexColor, 16);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './mint-form';
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import { Button, Card, Grid, Stepper } from '@/components';
|
||||
import { Mint } from '../mint.context';
|
||||
import {
|
||||
LogoField,
|
||||
AppDescriptionField,
|
||||
AppNameField,
|
||||
EnsDomainField,
|
||||
VerifyNFAField,
|
||||
} from './fields';
|
||||
import { MintCardHeader } from '../mint-card';
|
||||
|
||||
export const FormStep = () => {
|
||||
const { prevStep, nextStep } = Stepper.useContext();
|
||||
const { appName, appDescription, domain } = Mint.useContext();
|
||||
|
||||
return (
|
||||
<Card.Container css={{ width: '$107h' }}>
|
||||
<MintCardHeader title="NFA Details" onClickBack={prevStep} />
|
||||
<Card.Body>
|
||||
<Grid
|
||||
css={{
|
||||
rowGap: '$6',
|
||||
}}
|
||||
>
|
||||
<Grid css={{ rowGap: '$4' }}>
|
||||
<AppNameField />
|
||||
<AppDescriptionField />
|
||||
<LogoField />
|
||||
<EnsDomainField />
|
||||
<VerifyNFAField />
|
||||
</Grid>
|
||||
<Button
|
||||
disabled={!appName || !appDescription || !domain}
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
onClick={nextStep}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</Grid>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
import {
|
||||
Button,
|
||||
Card,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
Form,
|
||||
Grid,
|
||||
Icon,
|
||||
IconButton,
|
||||
Stepper,
|
||||
} from '@/components';
|
||||
import React, { useState } from 'react';
|
||||
import { Mint } from '../mint.context';
|
||||
import { RepoRow } from './github-repository-selection';
|
||||
|
||||
//TODO remove once it's integrated with GH login
|
||||
const branches: DropdownItem[] = [
|
||||
{
|
||||
label: 'master',
|
||||
value: 'master',
|
||||
},
|
||||
{
|
||||
label: 'develop',
|
||||
value: 'develop',
|
||||
},
|
||||
{
|
||||
label: 'feature/branch',
|
||||
value: 'feature/branch',
|
||||
},
|
||||
];
|
||||
|
||||
export const GithubRepoConfiguration: React.FC = () => {
|
||||
const {
|
||||
repositoryName,
|
||||
branchName,
|
||||
commitHash,
|
||||
setGithubStep,
|
||||
setRepositoryConfig,
|
||||
} = Mint.useContext();
|
||||
const { nextStep } = Stepper.useContext();
|
||||
const [branchSelected, setBranchSelected] = useState(branchName);
|
||||
const [commitHashSelected, setCommitHashSelected] = useState(commitHash);
|
||||
|
||||
const handlePrevStepClick = () => {
|
||||
setGithubStep(2);
|
||||
setRepositoryConfig('', '');
|
||||
};
|
||||
|
||||
const handleBranchChange = (dorpdownOption: DropdownItem) => {
|
||||
//TODO we'll have to check the data that GH API returns
|
||||
setBranchSelected(dorpdownOption.value);
|
||||
};
|
||||
|
||||
const handleCommitHashChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setCommitHashSelected(e.target.value);
|
||||
};
|
||||
|
||||
const handleContinueClick = () => {
|
||||
setRepositoryConfig(branchSelected, commitHashSelected);
|
||||
nextStep();
|
||||
};
|
||||
|
||||
return (
|
||||
<Card.Container css={{ width: '$107h' }}>
|
||||
<Card.Heading
|
||||
title="Configure Repository"
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={handlePrevStepClick}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Card.Body css={{ pt: '$2' }}>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<RepoRow
|
||||
repo={repositoryName}
|
||||
css={{ mb: '0' }}
|
||||
button={
|
||||
<Button
|
||||
colorScheme="gray"
|
||||
disabled
|
||||
variant="outline"
|
||||
css={{ py: '$1', height: '$5', borderRadius: '$md' }}
|
||||
>
|
||||
Use for NFA
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<Form.Field>
|
||||
<Form.Label>Git Branch</Form.Label>
|
||||
<Dropdown
|
||||
items={branches}
|
||||
selectedValue={{ label: branchSelected, value: branchSelected }}
|
||||
onChange={handleBranchChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Label>Git Commit</Form.Label>
|
||||
<Form.Input
|
||||
placeholder="693f89763dbb7a6c9ce0711cc34591a4c8c77198"
|
||||
value={commitHashSelected}
|
||||
onChange={handleCommitHashChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Button
|
||||
disabled={!branchSelected || !commitHashSelected}
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
onClick={handleContinueClick}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</Grid>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import { Stepper } from '@/components';
|
||||
import { useState } from 'react';
|
||||
import { Mint } from '../mint.context';
|
||||
import { GithubConnect } from './github-connect-step';
|
||||
import { GithubRepoConfiguration } from './github-repo-configuration';
|
||||
import { GithubRepositoryConnection } from './github-repository-selection';
|
||||
import {
|
||||
GithubConnect,
|
||||
GithubRepoConfiguration,
|
||||
GithubRepositoryConnection,
|
||||
} from './steps';
|
||||
|
||||
export const GithubStep = () => {
|
||||
const { githubStep } = Mint.useContext();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Button, Card, Grid, Icon, IconButton } from '@/components';
|
||||
import { Mint } from '../mint.context';
|
||||
import { Mint } from '../../../mint.context';
|
||||
|
||||
export const GithubConnect: React.FC = () => {
|
||||
const { setGithubStep } = Mint.useContext();
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './github-connect-step';
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './repo-configuration';
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
import {
|
||||
Button,
|
||||
Card,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
Form,
|
||||
Grid,
|
||||
Stepper,
|
||||
} from '@/components';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
import { useState } from 'react';
|
||||
import { RepoRow } from '../github-repository-selection';
|
||||
|
||||
//TODO remove once it's integrated with GH login
|
||||
const branches: DropdownItem[] = [
|
||||
{
|
||||
label: 'master',
|
||||
value: 'master',
|
||||
},
|
||||
{
|
||||
label: 'develop',
|
||||
value: 'develop',
|
||||
},
|
||||
{
|
||||
label: 'feature/branch',
|
||||
value: 'feature/branch',
|
||||
},
|
||||
];
|
||||
|
||||
export const RepoConfigurationBody = () => {
|
||||
const { repositoryName, branchName, commitHash, setRepositoryConfig } =
|
||||
Mint.useContext();
|
||||
|
||||
const { nextStep } = Stepper.useContext();
|
||||
const [branchSelected, setBranchSelected] = useState(branchName);
|
||||
const [commitHashSelected, setCommitHashSelected] = useState(commitHash);
|
||||
console.log(branchSelected);
|
||||
const handleBranchChange = (dorpdownOption: DropdownItem) => {
|
||||
//TODO we'll have to check the data that GH API returns
|
||||
console.log(dorpdownOption);
|
||||
setBranchSelected(dorpdownOption);
|
||||
};
|
||||
|
||||
const handleCommitHashChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setCommitHashSelected(e.target.value);
|
||||
};
|
||||
|
||||
const handleContinueClick = () => {
|
||||
setRepositoryConfig(branchSelected, commitHashSelected);
|
||||
nextStep();
|
||||
};
|
||||
|
||||
return (
|
||||
<Card.Body css={{ pt: '$2' }}>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<RepoRow
|
||||
repo={repositoryName}
|
||||
css={{ mb: '0' }}
|
||||
button={
|
||||
<Button
|
||||
colorScheme="gray"
|
||||
disabled
|
||||
variant="outline"
|
||||
css={{ py: '$1', height: '$5', borderRadius: '$md' }}
|
||||
>
|
||||
Use for NFA
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<Form.Field>
|
||||
<Form.Label>Git Branch</Form.Label>
|
||||
<Dropdown
|
||||
items={branches}
|
||||
selectedValue={branchSelected}
|
||||
onChange={handleBranchChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Label>Git Commit</Form.Label>
|
||||
<Form.Input
|
||||
placeholder="693f89763dbb7a6c9ce0711cc34591a4c8c77198"
|
||||
value={commitHashSelected}
|
||||
onChange={handleCommitHashChange}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Button
|
||||
disabled={!branchSelected || !commitHashSelected}
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
onClick={handleContinueClick}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</Grid>
|
||||
</Card.Body>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { DropdownItem } from '@/components';
|
||||
import { MintCardHeader } from '@/views/mint/mint-card';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
|
||||
export const RepoConfigurationHeader = () => {
|
||||
const { setGithubStep, setRepositoryConfig } = Mint.useContext();
|
||||
|
||||
const handlePrevStepClick = () => {
|
||||
setGithubStep(2);
|
||||
setRepositoryConfig({} as DropdownItem, '');
|
||||
};
|
||||
|
||||
return (
|
||||
<MintCardHeader
|
||||
title="Configure Repository"
|
||||
onClickBack={handlePrevStepClick}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { Card } from '@/components';
|
||||
import { RepoConfigurationBody } from './repo-configuration-body';
|
||||
import { RepoConfigurationHeader } from './repo-configuration-header';
|
||||
|
||||
export const GithubRepoConfiguration: React.FC = () => {
|
||||
return (
|
||||
<Card.Container css={{ width: '$107h' }}>
|
||||
<RepoConfigurationHeader />
|
||||
<RepoConfigurationBody />
|
||||
</Card.Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@ import {
|
|||
Card,
|
||||
Combobox,
|
||||
ComboboxItem,
|
||||
DropdownItem,
|
||||
Flex,
|
||||
Grid,
|
||||
Icon,
|
||||
|
|
@ -11,8 +12,9 @@ import {
|
|||
} from '@/components';
|
||||
import { Input } from '@/components/core/input';
|
||||
import { Separator } from '@/components/core/separator.styles';
|
||||
import { MintCardHeader } from '@/views/mint/mint-card';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
import React, { forwardRef, useRef, useState } from 'react';
|
||||
import { Mint } from '../mint.context';
|
||||
|
||||
//TODO remove once it's integrated with GH login
|
||||
const repos = [
|
||||
|
|
@ -80,7 +82,7 @@ export const GithubRepositoryConnection: React.FC = () => {
|
|||
const handleSelectRepo = (repo: string) => {
|
||||
setRepositoryName(repo);
|
||||
setGithubStep(3);
|
||||
setRepositoryConfig('', '');
|
||||
setRepositoryConfig({} as DropdownItem, '');
|
||||
};
|
||||
|
||||
const filteredRepositories =
|
||||
|
|
@ -92,26 +94,9 @@ export const GithubRepositoryConnection: React.FC = () => {
|
|||
|
||||
return (
|
||||
<Card.Container css={{ maxWidth: '$107h', maxHeight: '$95h', pb: '$0h' }}>
|
||||
<Card.Heading
|
||||
<MintCardHeader
|
||||
title="Select Repository"
|
||||
leftIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="back" />}
|
||||
css={{ mr: '$2' }}
|
||||
onClick={handlePrevStepClick}
|
||||
/>
|
||||
}
|
||||
rightIcon={
|
||||
<IconButton
|
||||
aria-label="Add"
|
||||
colorScheme="gray"
|
||||
variant="link"
|
||||
icon={<Icon name="info" />}
|
||||
/>
|
||||
}
|
||||
onClickBack={handlePrevStepClick}
|
||||
/>
|
||||
<Card.Body css={{ pt: '$4' }}>
|
||||
<Grid css={{ rowGap: '$2' }}>
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './github-repository-selection';
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export * from './github-repository-selection';
|
||||
export * from './github-repo-configuration';
|
||||
export * from './github-connect';
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './mint-card';
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import { Card, Icon, IconButton } from '@/components';
|
||||
|
||||
type MintCardHeaderProps = {
|
||||
title: string;
|
||||
onClickBack: () => void;
|
||||
};
|
||||
|
||||
export const MintCardHeader: React.FC<MintCardHeaderProps> = ({
|
||||
title,
|
||||
onClickBack,
|
||||
}) => {
|
||||
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" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,41 +1,18 @@
|
|||
import { IconButton, Icon, Stepper, Card } from '@/components';
|
||||
import { Stepper } from '@/components';
|
||||
import { FormStep } from './form-step';
|
||||
import { MintPreview } from './preview-step/mint-preview';
|
||||
import { GithubStep } from './github-step';
|
||||
import { MintStep } from './mint-step';
|
||||
import { WalletStep } from './wallet-step';
|
||||
import { Mint } from './mint.context';
|
||||
|
||||
//TODO remove after mint flow is done
|
||||
const Heading = ({ title }: { title: string }) => {
|
||||
const { prevStep } = Stepper.useContext();
|
||||
|
||||
return (
|
||||
<Card.Heading
|
||||
title={title}
|
||||
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" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
import { NftMinted } from './nft-minted';
|
||||
|
||||
export const MintStepper = () => {
|
||||
return (
|
||||
<Stepper.Root initialStep={1}>
|
||||
<Mint.Provider>
|
||||
const { sucessMint } = Mint.useContext();
|
||||
|
||||
if (!sucessMint) {
|
||||
return (
|
||||
<Stepper.Root initialStep={1}>
|
||||
<Stepper.Container>
|
||||
<Stepper.Step>
|
||||
<MintStep header="Connect GitHub and select repository">
|
||||
|
|
@ -45,41 +22,25 @@ export const MintStepper = () => {
|
|||
|
||||
<Stepper.Step>
|
||||
<MintStep header="Connect your Ethereum Wallet to mint an NFA">
|
||||
<Card.Container>
|
||||
<Heading title="Connect Wallet" />
|
||||
<Card.Body>
|
||||
<span>Step 2</span>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
<WalletStep />
|
||||
</MintStep>
|
||||
</Stepper.Step>
|
||||
|
||||
<Stepper.Step>
|
||||
<MintStep header="Finalize a few key things for your DyDx NFA">
|
||||
<Card.Container>
|
||||
<Heading title="NFA Detail" />
|
||||
<Card.Body>
|
||||
<span>Step 3</span>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
<MintStep header="Finalize a few key things for your NFA">
|
||||
<FormStep />
|
||||
</MintStep>
|
||||
</Stepper.Step>
|
||||
|
||||
<Stepper.Step>
|
||||
<MintStep header="Review your DyDx NFA and mint it on Polygon">
|
||||
<Card.Container>
|
||||
<Heading title="Mint NFA" />
|
||||
<Card.Body>
|
||||
<span>Step 4</span>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
<MintStep header="Review your NFA and mint it on Polygon">
|
||||
<MintPreview />
|
||||
</MintStep>
|
||||
</Stepper.Step>
|
||||
</Stepper.Container>
|
||||
</Mint.Provider>
|
||||
</Stepper.Root>
|
||||
);
|
||||
}
|
||||
|
||||
{/* TODO remove buttons when finish to integrate all the flow */}
|
||||
{/* <StepperButton /> */}
|
||||
</Stepper.Root>
|
||||
);
|
||||
return <NftMinted />;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,31 @@
|
|||
import { DropdownItem } from '@/components';
|
||||
import { createContext } from '@/utils';
|
||||
import { useState } from 'react';
|
||||
|
||||
export type MintContext = {
|
||||
repositoryName: string;
|
||||
branchName: string;
|
||||
branchName: DropdownItem; //get value from DropdownItem to mint
|
||||
commitHash: string;
|
||||
githubStep: number;
|
||||
appName: string;
|
||||
appDescription: string;
|
||||
appLogo: string;
|
||||
logoColor: string;
|
||||
ens: DropdownItem; //maybe it would be a DropdownItem
|
||||
domain: string;
|
||||
verifyNFA: boolean;
|
||||
sucessMint: boolean | undefined;
|
||||
setGithubStep: (step: number) => void;
|
||||
setRepositoryName: (repo: string) => void;
|
||||
setRepositoryConfig: (branch: string, hash: string) => void;
|
||||
setRepositoryConfig: (branch: DropdownItem, hash: string) => void;
|
||||
setAppName: (name: string) => void;
|
||||
setAppDescription: (description: string) => void;
|
||||
setAppLogo: (logo: string) => void;
|
||||
setLogoColor: (color: string) => void;
|
||||
setEns: (ens: DropdownItem) => void;
|
||||
setDomain: (domain: string) => void;
|
||||
setVerifyNFA: (verify: boolean) => void;
|
||||
setSucessMint: (sucess: boolean) => void;
|
||||
};
|
||||
|
||||
const [MintProvider, useContext] = createContext<MintContext>({
|
||||
|
|
@ -21,18 +38,33 @@ export abstract class Mint {
|
|||
static readonly useContext = useContext;
|
||||
|
||||
static readonly Provider: React.FC<Mint.ProviderProps> = ({ children }) => {
|
||||
//Github Connection
|
||||
const [repositoryName, setRepositoryName] = useState('');
|
||||
const [branchName, setBranchName] = useState('');
|
||||
const [branchName, setBranchName] = useState({} as DropdownItem);
|
||||
const [commitHash, setCommitHash] = useState('');
|
||||
const [githubStep, setGithubStepContext] = useState(1);
|
||||
|
||||
//NFA Details
|
||||
const [appName, setAppName] = useState('');
|
||||
const [appDescription, setAppDescription] = useState('');
|
||||
const [appLogo, setAppLogo] = useState('');
|
||||
const [logoColor, setLogoColor] = useState('');
|
||||
const [ens, setEns] = useState({} as DropdownItem);
|
||||
const [domain, setDomain] = useState('');
|
||||
const [verifyNFA, setVerifyNFA] = useState(true);
|
||||
|
||||
//Mint state
|
||||
//true means it's minted
|
||||
//false means it's not minted yet
|
||||
const [sucessMint, setSucessMint] = useState<boolean>(false);
|
||||
|
||||
const setGithubStep = (step: number): void => {
|
||||
if (step > 0 && step <= 3) {
|
||||
setGithubStepContext(step);
|
||||
}
|
||||
};
|
||||
|
||||
const setRepositoryConfig = (branch: string, hash: string) => {
|
||||
const setRepositoryConfig = (branch: DropdownItem, hash: string) => {
|
||||
setBranchName(branch);
|
||||
setCommitHash(hash);
|
||||
};
|
||||
|
|
@ -44,9 +76,25 @@ export abstract class Mint {
|
|||
branchName,
|
||||
commitHash,
|
||||
githubStep,
|
||||
appName,
|
||||
appDescription,
|
||||
appLogo,
|
||||
logoColor,
|
||||
ens,
|
||||
domain,
|
||||
verifyNFA,
|
||||
sucessMint,
|
||||
setGithubStep,
|
||||
setRepositoryConfig,
|
||||
setRepositoryName,
|
||||
setAppName,
|
||||
setAppDescription,
|
||||
setAppLogo,
|
||||
setLogoColor,
|
||||
setEns,
|
||||
setDomain,
|
||||
setVerifyNFA,
|
||||
setSucessMint,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
import { Flex } from '@/components';
|
||||
import { MintStepper } from './mint-stepper';
|
||||
import { Mint as MintContext } from './mint.context';
|
||||
|
||||
export const Mint = () => (
|
||||
<Flex css={{ height: 'inherit', justifyContent: 'center' }}>
|
||||
<Flex
|
||||
css={{
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
css={{
|
||||
height: '100%',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<MintContext.Provider>
|
||||
<MintStepper />
|
||||
</Flex>
|
||||
</MintContext.Provider>
|
||||
</Flex>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export * from './nft-card';
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
import { Button, Card, Grid } from '@/components';
|
||||
import { Mint } from '../mint.context';
|
||||
import { SVGPreview } from './svg-preview';
|
||||
|
||||
type NftCardProps = {
|
||||
title: string;
|
||||
leftIcon: React.ReactNode;
|
||||
rightIcon?: React.ReactNode;
|
||||
message: string;
|
||||
buttonText: string;
|
||||
leftIconButton?: React.ReactNode;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
export const NftCard: React.FC<NftCardProps> = ({
|
||||
title,
|
||||
leftIcon,
|
||||
rightIcon,
|
||||
message,
|
||||
buttonText,
|
||||
leftIconButton,
|
||||
onClick,
|
||||
}) => {
|
||||
const size = '26.5rem';
|
||||
const { appLogo, logoColor, appName, ens } = Mint.useContext();
|
||||
|
||||
return (
|
||||
<Card.Container css={{ width: '$107h', p: '$0' }}>
|
||||
<SVGPreview
|
||||
color={logoColor}
|
||||
logo={appLogo}
|
||||
name={appName}
|
||||
ens={ens.label}
|
||||
size={size}
|
||||
css="rounded-t-xhl"
|
||||
/>
|
||||
<Card.Body css={{ p: '$7' }}>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<Card.Heading
|
||||
title={title}
|
||||
leftIcon={leftIcon}
|
||||
rightIcon={rightIcon}
|
||||
/>
|
||||
{/* TODO replace for real price when integrate with wallet */}
|
||||
<span className="text-slate11 text-sm">{message}</span>
|
||||
{/* TODO add desabled when user doesnt have enough MATIC */}
|
||||
{/* TODO repalce for app name when connect with context */}
|
||||
<Button
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
onClick={onClick}
|
||||
leftIcon={leftIconButton}
|
||||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
type SVGPreviewProps = {
|
||||
color: string;
|
||||
logo: string;
|
||||
name: string;
|
||||
ens?: string;
|
||||
css?: string;
|
||||
size: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* SVGPreview renders the NFA image based in the provided props.
|
||||
*/
|
||||
export const SVGPreview: React.FC<SVGPreviewProps> = ({
|
||||
color,
|
||||
logo,
|
||||
name,
|
||||
ens = '',
|
||||
css = '',
|
||||
size,
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 1065 1065"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`${css}`}
|
||||
>
|
||||
<rect width="1065" height="1065" fill="url(#background)" />
|
||||
<rect
|
||||
opacity="0.2"
|
||||
width="1065"
|
||||
height="1065"
|
||||
fill="url(#background-radial)"
|
||||
/>
|
||||
|
||||
<g filter="url(#diskette-shadow)">
|
||||
<path
|
||||
d="M857.231 279.712L902.24 286.675C910.547 287.96 917.915 292.721 922.5 299.768L938.894 324.964C942.249 330.12 943.311 336.437 941.827 342.406L937.798 358.615L924.049 356.65L919.416 374.084L934.068 376.24L791.947 922.152C788.109 936.896 773.694 946.308 758.651 943.893L179.636 850.928C162.318 848.147 151.215 830.987 155.776 814.051L160.478 796.59L704.315 879.574L857.231 279.712Z"
|
||||
fill="#050505"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M840.231 240.712L885.24 247.675C893.547 248.961 900.915 253.722 905.5 260.768L921.894 285.965C925.249 291.12 926.311 297.437 924.827 303.406L920.798 319.616L907.049 317.65L902.416 335.084L917.068 337.241L774.947 883.152C771.109 897.896 756.694 907.308 741.651 904.893L162.636 811.928C145.318 809.147 134.215 791.987 138.776 775.051L143.478 757.59L687.315 840.574L840.231 240.712Z"
|
||||
fill="url(#main)"
|
||||
/>
|
||||
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M319.847 161.502C310.356 160.007 300.674 166.326 298.221 175.616L138.724 779.758C136.271 789.048 141.977 797.79 151.468 799.285L740.061 891.973C749.553 893.467 759.235 887.148 761.687 877.858L902.405 344.854L889.158 342.768L898.872 305.972L912.119 308.059L913.733 301.946C914.837 297.762 914.309 293.476 912.251 289.927L893.484 257.569C891.153 253.549 887.063 250.823 882.221 250.061L828.205 241.554C822.224 240.613 815.869 242.783 811.427 247.284L805.686 253.103C804.205 254.603 802.087 255.326 800.093 255.013L783.611 252.417L734.3 439.196C731.439 450.035 720.143 457.407 709.07 455.663L328.847 395.788C317.774 394.045 311.117 383.845 313.978 373.007L366.528 173.962L366.533 173.941C367.234 171.24 365.572 168.702 362.81 168.267L319.847 161.502ZM369.392 174.414L368.652 177.217L316.843 373.458C314.39 382.748 320.096 391.49 329.587 392.985L709.81 452.86C719.301 454.354 728.983 448.035 731.436 438.745L780.747 251.966L783.245 242.504L783.985 239.701L369.392 174.414Z"
|
||||
fill="#131316"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
stroke="url(#main)"
|
||||
stroke-width="4"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M319.847 161.502C310.356 160.007 300.674 166.326 298.221 175.616L138.724 779.758C136.271 789.048 141.977 797.79 151.468 799.285L740.061 891.973C749.553 893.467 759.235 887.148 761.687 877.858L902.405 344.854L889.158 342.768L898.872 305.972L912.119 308.059L913.733 301.946C914.837 297.762 914.309 293.476 912.251 289.927L893.484 257.569C891.153 253.549 887.063 250.823 882.221 250.061L828.205 241.554C822.224 240.613 815.869 242.783 811.427 247.284L805.686 253.103C804.205 254.603 802.087 255.326 800.093 255.013L783.611 252.417L734.3 439.196C731.439 450.035 720.143 457.407 709.07 455.663L328.847 395.788C317.774 394.045 311.117 383.845 313.978 373.007L366.528 173.962L366.533 173.941C367.234 171.24 365.572 168.702 362.81 168.267L319.847 161.502ZM369.392 174.414L368.652 177.217L316.843 373.458C314.39 382.748 320.096 391.49 329.587 392.985L709.81 452.86C719.301 454.354 728.983 448.035 731.436 438.745L780.747 251.966L783.245 242.504L783.985 239.701L369.392 174.414Z"
|
||||
fill="url(#diskette-gradient)"
|
||||
fill-opacity="0.2"
|
||||
/>
|
||||
|
||||
<path
|
||||
d="M335.38 208.113C335.922 208.198 336.417 207.686 336.283 207.179L330.39 184.795C330.249 184.261 329.529 184.148 329.129 184.597L312.358 203.411C311.978 203.838 312.174 204.458 312.716 204.544L317.962 205.37C318.357 205.432 318.595 205.796 318.493 206.183L314.7 220.551C314.597 220.938 314.835 221.302 315.231 221.364L324.539 222.83C324.935 222.893 325.338 222.629 325.44 222.242L329.233 207.875C329.336 207.488 329.739 207.224 330.135 207.286L335.38 208.113Z"
|
||||
fill="url(#main)"
|
||||
/>
|
||||
<path
|
||||
d="M319.282 269.087C319.824 269.173 320.319 268.661 320.186 268.154L314.292 245.77C314.151 245.236 313.431 245.123 313.031 245.572L296.261 264.386C295.88 264.812 296.076 265.433 296.618 265.518L301.864 266.344C302.259 266.407 302.497 266.771 302.395 267.158L298.602 281.526C298.5 281.913 298.737 282.277 299.133 282.339L308.441 283.805C308.837 283.867 309.24 283.604 309.343 283.217L313.136 268.849C313.238 268.462 313.641 268.199 314.037 268.261L319.282 269.087Z"
|
||||
fill="black"
|
||||
fill-opacity="0.5"
|
||||
/>
|
||||
<path
|
||||
d="M303.184 330.062C303.726 330.148 304.221 329.636 304.088 329.128L298.194 306.745C298.053 306.211 297.333 306.098 296.933 306.547L280.163 325.361C279.782 325.787 279.979 326.408 280.52 326.493L285.766 327.319C286.161 327.382 286.399 327.746 286.297 328.133L282.504 342.501C282.402 342.888 282.639 343.252 283.035 343.314L292.344 344.78C292.739 344.842 293.142 344.579 293.245 344.192L297.038 329.824C297.14 329.437 297.543 329.174 297.939 329.236L303.184 330.062Z"
|
||||
fill="black"
|
||||
fill-opacity="0.5"
|
||||
/>
|
||||
|
||||
<path
|
||||
stroke="url(#main)"
|
||||
stroke-width="6"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M290.109 463.418C292.358 454.902 301.233 449.11 309.933 450.48L771.07 523.096C779.77 524.467 785 532.48 782.752 540.996L692.086 884.418L199.443 806.84L290.109 463.418Z"
|
||||
fill="black"
|
||||
fill-opacity="0.14"
|
||||
/>
|
||||
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
stroke="url(#main)"
|
||||
stroke-width="6"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M787.589 237.349L460.354 185.818L406.325 390.469C403.872 399.759 409.578 408.501 419.069 409.996L711.934 456.114C721.425 457.609 731.107 451.29 733.56 442L787.589 237.349ZM660.269 245.01C655.523 244.263 650.682 247.423 649.456 252.068L607.386 411.418C606.16 416.063 609.013 420.434 613.759 421.181L682.499 432.006C687.245 432.753 692.086 429.594 693.312 424.949L735.382 265.599C736.608 260.954 733.755 256.583 729.01 255.835L660.269 245.01Z"
|
||||
fill="url(#main)"
|
||||
/>
|
||||
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M864.643 283.937C865.186 283.605 865.708 284.257 865.239 284.683L844.268 303.719C843.938 304.018 844.093 304.517 844.526 304.548L853.726 305.207C854.184 305.24 854.321 305.787 853.942 306.071L833.884 321.112C833.506 321.396 833.643 321.943 834.101 321.976L844.007 322.685C844.491 322.72 844.605 323.319 844.177 323.58L797.752 351.954C797.209 352.286 796.687 351.634 797.156 351.209L818.403 331.922C818.733 331.622 818.577 331.123 818.145 331.092L808.748 330.42C808.292 330.387 808.154 329.843 808.529 329.558L828.054 314.744C828.43 314.459 828.291 313.915 827.835 313.882L818.389 313.206C817.904 313.171 817.79 312.572 818.218 312.311L864.643 283.937Z"
|
||||
fill="white"
|
||||
/>
|
||||
|
||||
<g transform="matrix(0.987827 0.155557 -0.255261 0.966872 250 735)">
|
||||
<text
|
||||
font-family="Inter, sans-serif"
|
||||
font-weight="bold"
|
||||
font-size="42"
|
||||
fill="#E5E7F8"
|
||||
>
|
||||
{name}
|
||||
</text>
|
||||
<text
|
||||
font-family="Inter, sans-serif"
|
||||
font-weight="normal"
|
||||
y="40"
|
||||
font-size="22"
|
||||
fill="#7F8192"
|
||||
>
|
||||
{ens}
|
||||
</text>
|
||||
</g>
|
||||
|
||||
<image
|
||||
width="167"
|
||||
height="167"
|
||||
transform="matrix(0.987827 0.155557 -0.255261 0.966872 444.117 524.17)"
|
||||
href={logo}
|
||||
/>
|
||||
|
||||
<defs>
|
||||
<filter
|
||||
id="diskette-shadow"
|
||||
x="70.7489"
|
||||
y="195.712"
|
||||
width="955.733"
|
||||
height="832.558"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" />
|
||||
<feBlend in="SourceGraphic" />
|
||||
<feGaussianBlur stdDeviation="42" />
|
||||
</filter>
|
||||
|
||||
<linearGradient
|
||||
id="background"
|
||||
x1="532.5"
|
||||
y1="0"
|
||||
x2="532.5"
|
||||
y2="1065"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop />
|
||||
<stop offset="1" stop-color="#131313" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="background-radial"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(532.5 532.5) rotate(89.961) scale(735)"
|
||||
>
|
||||
<stop stop-color={color} />
|
||||
<stop offset="1" stop-color={color} stop-opacity="0" />
|
||||
</radialGradient>
|
||||
|
||||
<linearGradient
|
||||
id="diskette-gradient"
|
||||
x1="925.626"
|
||||
y1="256.896"
|
||||
x2="136.779"
|
||||
y2="800.203"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color={color} />
|
||||
<stop offset="1" stop-color="#2C313F" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="main">
|
||||
<stop stop-color={color} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import { Icon } from '@/components';
|
||||
import { NftCard } from './nft-card';
|
||||
|
||||
export const NftMinted = () => {
|
||||
return (
|
||||
<NftCard
|
||||
title="Mint Successful"
|
||||
leftIcon={
|
||||
<Icon
|
||||
name="check-circle"
|
||||
css={{ color: '$green11', fontSize: '$xl', mr: '$2' }}
|
||||
/>
|
||||
}
|
||||
message="You have successfully minted your NFA."
|
||||
buttonText="Tweet about your NFA!"
|
||||
onClick={() => {
|
||||
alert('TODO: Tweet about your NFA!');
|
||||
}}
|
||||
leftIconButton={<Icon name="twitter" />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './mint-preview';
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { Icon, IconButton, Stepper } from '@/components';
|
||||
import { Mint } from '@/views/mint/mint.context';
|
||||
import { NftCard } from '../nft-card';
|
||||
|
||||
export const MintPreview = () => {
|
||||
const { prevStep } = Stepper.useContext();
|
||||
const { setSucessMint } = Mint.useContext();
|
||||
|
||||
//TODO handle error when minting
|
||||
|
||||
return (
|
||||
<NftCard
|
||||
title="Mint NFA"
|
||||
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" />}
|
||||
/>
|
||||
}
|
||||
message="Minting this NFA will cost 0.0008 MATIC."
|
||||
buttonText="Mint NFA"
|
||||
onClick={() => {
|
||||
setSucessMint(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from './wallet-step';
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { Button, Card, Grid, Icon, Stepper } from '@/components';
|
||||
import { MintCardHeader } from '../mint-card';
|
||||
|
||||
export const WalletStep = () => {
|
||||
const { prevStep, nextStep } = Stepper.useContext();
|
||||
return (
|
||||
<Card.Container>
|
||||
<MintCardHeader title="Connect Wallet" onClickBack={prevStep} />
|
||||
<Card.Body>
|
||||
<Grid css={{ rowGap: '$6' }}>
|
||||
<Button
|
||||
iconSpacing="52"
|
||||
size="lg"
|
||||
variant="ghost"
|
||||
css={{
|
||||
backgroundColor: '$slate4',
|
||||
color: '$slate12',
|
||||
py: '$2h',
|
||||
}}
|
||||
onClick={nextStep}
|
||||
rightIcon={
|
||||
<Icon
|
||||
name="metamask"
|
||||
css={{ color: 'white', fontSize: '$4xl' }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
Metamask
|
||||
</Button>
|
||||
<Card.Text
|
||||
css={{ height: '$46h', width: '$95', fontSize: '$md', px: '$12' }}
|
||||
>
|
||||
<span>Connect with the wallet you want to mint & own the NFA.</span>
|
||||
</Card.Text>
|
||||
</Grid>
|
||||
</Card.Body>
|
||||
</Card.Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -11,8 +11,8 @@ module.exports = {
|
|||
slate11: 'rgba(155, 161, 166, 1)',
|
||||
slate12: 'rgba(236, 237, 238, 1)',
|
||||
},
|
||||
width: {
|
||||
inherit: 'inherit',
|
||||
borderRadius: {
|
||||
xhl: '1.25rem',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue