non-fungible-apps/ui/src/views/indexed-nfa/fragments/main.fragment.tsx

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>
);
};