286 lines
8.6 KiB
TypeScript
286 lines
8.6 KiB
TypeScript
import React, { useMemo } from 'react';
|
|
|
|
import { Flex, Icon, IconName, ResolvedAddress, Text } from '@/components';
|
|
|
|
import { IndexedNFA } from '../indexed-nfa.context';
|
|
import { IndexedNFAStyles as S } from '../indexed-nfa.styles';
|
|
|
|
type HeaderDataProps = {
|
|
label: string;
|
|
children: React.ReactNode;
|
|
};
|
|
|
|
const HeaderData: React.FC<HeaderDataProps> = ({
|
|
label,
|
|
children,
|
|
}: HeaderDataProps) => (
|
|
<Flex css={{ gap: '$2' }}>
|
|
<Text css={{ color: '$slate11' }}>{label}</Text>
|
|
<Text css={{ color: '$slate12' }}>{children}</Text>
|
|
</Flex>
|
|
);
|
|
|
|
const Header: React.FC = () => {
|
|
const { nfa } = IndexedNFA.useContext();
|
|
|
|
return (
|
|
<>
|
|
<S.Main.Heading>{nfa.name}</S.Main.Heading>
|
|
<Flex css={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
|
<HeaderData label="Owner">
|
|
<ResolvedAddress>{nfa.owner.id}</ResolvedAddress>
|
|
</HeaderData>
|
|
|
|
<S.Main.Divider.Elipse />
|
|
|
|
<HeaderData label="Created">
|
|
{/* TODO: place correct data */}
|
|
12/12/22
|
|
</HeaderData>
|
|
|
|
<S.Main.Divider.Elipse />
|
|
|
|
<HeaderData label="Access Points">
|
|
{nfa.accessPoints?.length ?? 0}
|
|
</HeaderData>
|
|
</Flex>
|
|
<S.Main.Divider.Line />
|
|
</>
|
|
);
|
|
};
|
|
|
|
const Description: React.FC = () => {
|
|
const { nfa } = IndexedNFA.useContext();
|
|
|
|
return (
|
|
<>
|
|
<S.Main.SectionHeading css={{ marginTop: 0 }}>
|
|
Description
|
|
</S.Main.SectionHeading>
|
|
<S.Main.DataContainer as={S.Main.Paragraph}>
|
|
{nfa.description}
|
|
</S.Main.DataContainer>
|
|
</>
|
|
);
|
|
};
|
|
|
|
type DataWrapperProps = React.PropsWithChildren<{
|
|
label: string | number;
|
|
}>;
|
|
|
|
const DataWrapper: React.FC<DataWrapperProps> = ({
|
|
children,
|
|
label,
|
|
}: DataWrapperProps) => (
|
|
<S.Main.DataContainer key={label} css={{ flex: 1, minWidth: '45%' }}>
|
|
<Text css={{ color: '$slate12', fontWeight: 700 }}>{children || '-'}</Text>
|
|
<Text css={{ color: '$slate11' }}>{label}</Text>
|
|
</S.Main.DataContainer>
|
|
);
|
|
|
|
const Traits: React.FC = () => {
|
|
const { nfa } = IndexedNFA.useContext();
|
|
|
|
// TODO: place correct data
|
|
const traitsToShow = useMemo(() => {
|
|
return [
|
|
[nfa.ENS, 'ENS'],
|
|
[nfa.gitRepository.id, 'Repository'],
|
|
[10, 'Version'],
|
|
[nfa.externalURL, 'Domain'],
|
|
[nfa.externalURL, 'Domain 2'],
|
|
];
|
|
}, [nfa]);
|
|
|
|
return (
|
|
<>
|
|
<S.Main.SectionHeading>Traits</S.Main.SectionHeading>
|
|
<S.Main.DataList>
|
|
{traitsToShow.map(([value, label]) => (
|
|
<DataWrapper key={label} label={label}>
|
|
{value}
|
|
</DataWrapper>
|
|
))}
|
|
</S.Main.DataList>
|
|
</>
|
|
);
|
|
};
|
|
|
|
type VerificationBannerProps = {
|
|
verified: boolean;
|
|
};
|
|
|
|
const VerificationBanner: React.FC<VerificationBannerProps> = ({
|
|
verified,
|
|
}: VerificationBannerProps) => {
|
|
const [text, icon] = useMemo<[string, IconName]>(() => {
|
|
if (verified)
|
|
return ['This Non Fungible Application is Verified.', 'verified'];
|
|
return ['This Non Fungible Application is not Verified.', 'error'];
|
|
}, [verified]);
|
|
|
|
return (
|
|
<S.Main.VerificationBanner verified={verified}>
|
|
{text}
|
|
<Icon
|
|
name={icon}
|
|
css={{
|
|
fontSize: '3.5rem',
|
|
color: '$black',
|
|
position: 'absolute',
|
|
right: 'calc(8% - 1.75rem)',
|
|
zIndex: 1,
|
|
}}
|
|
/>
|
|
</S.Main.VerificationBanner>
|
|
);
|
|
};
|
|
|
|
const Verification: React.FC = () => {
|
|
return (
|
|
<>
|
|
<S.Main.SectionHeading>Verification</S.Main.SectionHeading>
|
|
{/* TODO: Get verified from context */}
|
|
<VerificationBanner verified={Math.random() > 0.5} />
|
|
<S.Main.DataList>
|
|
{/* TODO: place correct data */}
|
|
<DataWrapper label="Verifier">polygon.eth</DataWrapper>
|
|
<DataWrapper label="Repository">polygon/fe</DataWrapper>
|
|
</S.Main.DataList>
|
|
</>
|
|
);
|
|
};
|
|
|
|
// TODO: replace mocks with fetched data
|
|
const apMocks = new Array(10).fill(0).map((_, index) => ({
|
|
approved: Math.random() > 0.5,
|
|
domain: `domain${index}.com`,
|
|
owner: '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049',
|
|
createdAt: `${Math.floor(Math.random() * 30)}m ago`,
|
|
}));
|
|
|
|
const AccessPoints: React.FC = () => {
|
|
return (
|
|
<>
|
|
<S.Main.SectionHeading>Frontends</S.Main.SectionHeading>
|
|
<S.Main.Table.Container>
|
|
<S.Main.Table.Root>
|
|
<colgroup>
|
|
<col span={1} style={{ width: '9.5%' }} />
|
|
<col span={1} style={{ width: '32.5%' }} />
|
|
<col span={1} style={{ width: '32.5%' }} />
|
|
<col span={1} style={{ width: '16%' }} />
|
|
<col span={1} style={{ width: '9.5%' }} />
|
|
</colgroup>
|
|
<S.Main.Table.Head>
|
|
<S.Main.Table.Row>
|
|
<S.Main.Table.Data>
|
|
<S.Main.Table.Marker />
|
|
</S.Main.Table.Data>
|
|
<S.Main.Table.Data>Domain</S.Main.Table.Data>
|
|
<S.Main.Table.Data>Owner</S.Main.Table.Data>
|
|
<S.Main.Table.Data>Created</S.Main.Table.Data>
|
|
<S.Main.Table.Data />
|
|
</S.Main.Table.Row>
|
|
</S.Main.Table.Head>
|
|
<S.Main.Table.Body>
|
|
{apMocks.map((item) => (
|
|
<S.Main.Table.Row key={item.domain}>
|
|
<S.Main.Table.Data align="center">
|
|
<S.Main.Table.Marker
|
|
variant={item.approved ? 'active' : 'inactive'}
|
|
/>
|
|
</S.Main.Table.Data>
|
|
<S.Main.Table.Data>{item.domain}</S.Main.Table.Data>
|
|
<S.Main.Table.Data>
|
|
<ResolvedAddress>{item.owner}</ResolvedAddress>
|
|
</S.Main.Table.Data>
|
|
<S.Main.Table.Data>{item.createdAt}</S.Main.Table.Data>
|
|
<S.Main.Table.Data>
|
|
<Icon name="external-link" />
|
|
</S.Main.Table.Data>
|
|
</S.Main.Table.Row>
|
|
))}
|
|
</S.Main.Table.Body>
|
|
</S.Main.Table.Root>
|
|
</S.Main.Table.Container>
|
|
</>
|
|
);
|
|
};
|
|
|
|
// TODO: replace mocks with fetched data
|
|
const versionsMock = new Array(10).fill(0).map((_, index) => ({
|
|
live: index === 0,
|
|
commit: (Math.random() * 0xfffffffff).toString(16),
|
|
preview: `test: subgraph matchstick tests for access points and acl refactor (#150
|
|
)
|
|
|
|
* fix: errors from deprecated entities.`,
|
|
time: `${Math.floor(Math.random() * 30)}m ago`,
|
|
}));
|
|
|
|
const Versions: React.FC = () => {
|
|
return (
|
|
<>
|
|
<S.Main.SectionHeading>Versions</S.Main.SectionHeading>
|
|
<S.Main.Table.Container>
|
|
<S.Main.Table.Root>
|
|
<colgroup>
|
|
<col span={1} style={{ width: '9.5%' }} />
|
|
<col span={1} style={{ width: '15%' }} />
|
|
<col span={1} style={{ width: '50%' }} />
|
|
<col span={1} style={{ width: '16%' }} />
|
|
<col span={1} style={{ width: '9.5%' }} />
|
|
</colgroup>
|
|
<S.Main.Table.Head>
|
|
<S.Main.Table.Row>
|
|
<S.Main.Table.Data>
|
|
<S.Main.Table.Marker />
|
|
</S.Main.Table.Data>
|
|
<S.Main.Table.Data>Commit</S.Main.Table.Data>
|
|
<S.Main.Table.Data>Preview</S.Main.Table.Data>
|
|
<S.Main.Table.Data>Time</S.Main.Table.Data>
|
|
<S.Main.Table.Data />
|
|
</S.Main.Table.Row>
|
|
</S.Main.Table.Head>
|
|
<S.Main.Table.Body>
|
|
{versionsMock.map((item) => (
|
|
<S.Main.Table.Row key={item.commit}>
|
|
<S.Main.Table.Data>
|
|
<S.Main.Table.Marker
|
|
variant={item.live ? 'active' : 'inactive'}
|
|
text={item.live}
|
|
>
|
|
{item.live && 'Live'}
|
|
</S.Main.Table.Marker>
|
|
</S.Main.Table.Data>
|
|
<S.Main.Table.Data>{item.commit.slice(0, 6)}</S.Main.Table.Data>
|
|
<S.Main.Table.Data title={item.preview}>
|
|
{item.preview}
|
|
</S.Main.Table.Data>
|
|
<S.Main.Table.Data>{item.time}</S.Main.Table.Data>
|
|
<S.Main.Table.Data>
|
|
<Icon name="external-link" />
|
|
</S.Main.Table.Data>
|
|
</S.Main.Table.Row>
|
|
))}
|
|
</S.Main.Table.Body>
|
|
</S.Main.Table.Root>
|
|
</S.Main.Table.Container>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const IndexedNFAMainFragment: React.FC = () => {
|
|
return (
|
|
<S.Main.Container>
|
|
<Header />
|
|
<Description />
|
|
<Traits />
|
|
<Verification />
|
|
<AccessPoints />
|
|
<Versions />
|
|
</S.Main.Container>
|
|
);
|
|
};
|