diff --git a/ui/graphql/queries.graphql b/ui/graphql/queries.graphql index a7cac93..e68bcd3 100644 --- a/ui/graphql/queries.graphql +++ b/ui/graphql/queries.graphql @@ -38,7 +38,7 @@ query getLatestNFAs { } } -query getNFA($id: ID!) { +query getNFADetail($id: ID!) { token(id: $id) { tokenId owner { @@ -50,6 +50,33 @@ query getNFA($id: ID!) { externalURL logo color + createdAt + accessPoints { + createdAt + contentVerified + owner { + id + } + id + } + verified + verifier { + id + } + gitRepository { + id + } + } +} + +query getNFA($id: ID!) { + token(id: $id) { + tokenId + name + ENS + externalURL + logo + color } } diff --git a/ui/src/utils/format.ts b/ui/src/utils/format.ts index 04914b2..d5eeb18 100644 --- a/ui/src/utils/format.ts +++ b/ui/src/utils/format.ts @@ -10,3 +10,45 @@ export const getRepoAndCommit = (url: string): object => { export const contractAddress = (address: string): string => { return `${address.slice(0, 6)}...${address.slice(-4)}`; }; + +export const getRepositoryFromURL = (url: string): string => { + const urlSplitted = url.split('/'); + return `${urlSplitted[3]}/${urlSplitted[4]}`; +}; + +export const getDate = (date: number): string => { + return new Date(date * 1000).toLocaleDateString(); +}; + +/** + * @param date date in tiemstamp format + * @returns time since date + */ +export const getTimeSince = (date: number): string => { + const now = new Date().getTime(); //in timestamp format + + const milliseconds = now - date * 1000; + const seconds = milliseconds / 1000; + const minutes = Math.round((seconds / 60) % 60); + const days = Math.round(seconds / (60 * 60 * 24)); + const hours = Math.round(minutes % 60); + const months = Math.round(days / 30.5); + const years = Math.round(months / 12); + + if (years > 0) { + return `${years} year${years > 1 ? 's' : ''} ago`; + } + if (months > 0) { + return `${months} month${months > 1 ? 's' : ''} ago`; + } + if (days > 0) { + return `${days} day${days > 1 ? 's' : ''} ago`; + } + if (hours > 0) { + return `${hours} hour${hours > 1 ? 's' : ''} ago`; + } + if (minutes > 0) { + return `${minutes} min ago`; + } + return `${Math.round(seconds)} sec ago}`; +}; diff --git a/ui/src/views/access-point/ap-form-step/create-ap-form-body.tsx b/ui/src/views/access-point/ap-form-step/create-ap-form-body.tsx index 41fb535..932e393 100644 --- a/ui/src/views/access-point/ap-form-step/create-ap-form-body.tsx +++ b/ui/src/views/access-point/ap-form-step/create-ap-form-body.tsx @@ -70,8 +70,8 @@ export const CreateAccessPointFormBody: React.FC = () => { }, onCompleted(data) { if (data.token && id) { - const { name, tokenId, logo, color, externalURL: domain } = data.token; - setNfa({ name, tokenId, logo, color, domain }); + const { name, tokenId, logo, color, externalURL } = data.token; + setNfa({ name, tokenId, logo, color, externalURL }); } else { AppLog.errorToast("We couldn't find the NFA you are looking for"); } diff --git a/ui/src/views/access-point/create-ap.context.tsx b/ui/src/views/access-point/create-ap.context.tsx index 119f29c..68bc729 100644 --- a/ui/src/views/access-point/create-ap.context.tsx +++ b/ui/src/views/access-point/create-ap.context.tsx @@ -2,17 +2,15 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { useState } from 'react'; +import { Token } from '@/graphclient'; import { EthereumHooks } from '@/integrations'; import { useFleekERC721Billing } from '@/store'; import { AppLog, createContext } from '@/utils'; -export type NFA = { - tokenId: string; - name: string; - logo: string; - color: number; - domain: string; -}; +export type NFA = Pick< + Token, + 'tokenId' | 'name' | 'logo' | 'color' | 'externalURL' +>; export type AccessPointContext = { billing: string | undefined; @@ -43,7 +41,7 @@ export abstract class CreateAccessPoint { name: '', logo: '', color: 0, - domain: '', + externalURL: '', }); const value = { diff --git a/ui/src/views/indexed-nfa/fragments/main.fragment.tsx b/ui/src/views/indexed-nfa/fragments/main.fragment.tsx index 9ac9595..b4ecb2c 100644 --- a/ui/src/views/indexed-nfa/fragments/main.fragment.tsx +++ b/ui/src/views/indexed-nfa/fragments/main.fragment.tsx @@ -3,7 +3,15 @@ import React, { useState } from 'react'; import Rectangle1 from '@/assets/Rectangle-199.png'; import Rectangle2 from '@/assets/Rectangle-200.png'; import Rectangle3 from '@/assets/Rectangle-201.png'; -import { Combobox, Flex, ResolvedAddress, Text } from '@/components'; +import { + Combobox, + Flex, + Icon, + IconName, + ResolvedAddress, + Text, +} from '@/components'; +import { getDate, getRepositoryFromURL, getTimeSince } from '@/utils'; import { IndexedNFAStyles as S } from '../indexed-nfa.styles'; @@ -54,10 +62,134 @@ const Header: React.FC = () => { )} + {/* + + {nfa.owner.id} + + + + + {getDate(nfa.createdAt)} + + + + + {nfa.accessPoints?.length ?? 0} + + */} + {/* */} ); }; +// const Description: React.FC = () => { +// const { nfa } = IndexedNFA.useContext(); + +// return ( +// <> +// +// Description +// +// +// {nfa.description} +// +// +// ); +// }; + +// type DataWrapperProps = React.PropsWithChildren<{ +// label: string | number; +// }>; + +// const DataWrapper: React.FC = ({ +// children, +// label, +// }: DataWrapperProps) => ( +// +// {children || '-'} +// {label} +// +// ); + +// const Traits: React.FC = () => { +// const { nfa } = IndexedNFA.useContext(); + +// const traitsToShow = useMemo(() => { +// return [ +// [nfa.ENS, 'ENS'], +// [getRepositoryFromURL(nfa.gitRepository.id), 'Repository'], +// ['', 'Version'], +// [nfa.externalURL, 'Domain'], +// ]; +// }, [nfa]); + +// return ( +// <> +// Traits +// +// {traitsToShow.map(([value, label]) => ( +// +// {value} +// +// ))} +// +// +// ); +// }; + +// type VerificationBannerProps = { +// verified: boolean; +// }; + +// const VerificationBanner: React.FC = ({ +// 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 ( +// +// {text} +// +// +// ); +// }; + +// const Verification: React.FC = () => { +// const { nfa } = IndexedNFA.useContext(); + +// return ( +// <> +// Verification +// +// +// +// {nfa.verifier ? ( +// {nfa.verifier?.id} +// ) : ( +// '-' +// )} +// +// +// {getRepositoryFromURL(nfa.gitRepository.id)} +// +// +// +// ); +// }; + const thumbnailMocks = [Rectangle1, Rectangle2, Rectangle3]; // TODO: replace mocks with fetched data const apMocks = new Array(20).fill(0).map((_, index) => ({ @@ -101,6 +233,68 @@ const AccessPointsListFragment: React.FC = () => { ); }; +// const AccessPoints: React.FC = () => { +// const { +// nfa: { accessPoints }, +// } = IndexedNFA.useContext(); + +// return ( +// <> +// Frontends +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// Domain +// Owner +// Created +// +// +// +// +// {accessPoints && accessPoints.length > 0 ? ( +// accessPoints.map((item) => ( +// +// +// +// +// {item.id} +// +// {item.owner.id} +// +// +// {getTimeSince(item.createdAt)} +// +// +// +// +// +// )) +// ) : ( +// +// +// No results +// +// +// )} +// +// +// +// +// ); +// }; export const IndexedNFAMainFragment: React.FC = () => { return ( diff --git a/ui/src/views/indexed-nfa/indexed-nfa.tsx b/ui/src/views/indexed-nfa/indexed-nfa.tsx index 007f000..773af84 100644 --- a/ui/src/views/indexed-nfa/indexed-nfa.tsx +++ b/ui/src/views/indexed-nfa/indexed-nfa.tsx @@ -4,8 +4,7 @@ import { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { App } from '@/app.context'; -import { getNFADocument } from '@/graphclient'; -import { NFAMock } from '@/mocks'; +import { getNFADetailDocument } from '@/graphclient'; import { AppLog } from '@/utils'; import { parseNumberToHexColor } from '@/utils/color'; @@ -36,7 +35,7 @@ export const IndexedNFAView: React.FC = () => { navigate('/', { replace: true }); }; - const { loading, data = { token: {} } } = useQuery(getNFADocument, { + const { loading, data = { token: {} } } = useQuery(getNFADetailDocument, { skip: id === undefined, variables: { id: ethers.utils.hexlify(Number(id)), @@ -55,9 +54,13 @@ export const IndexedNFAView: React.FC = () => { return ; } - // TODO: replace NFAMock with real data from useQuery + if (!data.token) { + //TODO add 404 page + return
Token not found
; + } + return ( - +