From 393c4a316d9657bf88c7b36ab4c21a8ce9a87b24 Mon Sep 17 00:00:00 2001 From: Camila Sosa Morales Date: Tue, 9 May 2023 10:31:29 -0300 Subject: [PATCH] feat: NFA detail page subraph integration (#254) * feat: nfa detail page with data from the subgraph * Update ui/src/views/indexed-nfa/fragments/aside.fragment.tsx Co-authored-by: Felipe Mendes --------- Co-authored-by: Felipe Mendes --- ui/graphql/queries.graphql | 29 +++- ui/src/utils/format.ts | 42 +++++ .../ap-form-step/create-ap-form-body.tsx | 4 +- .../views/access-point/create-ap.context.tsx | 14 +- .../explore/explore-list/nfa-search.styles.ts | 2 +- .../indexed-nfa/fragments/aside.fragment.tsx | 4 +- .../indexed-nfa/fragments/main.fragment.tsx | 146 ++++++------------ ui/src/views/indexed-nfa/indexed-nfa.tsx | 13 +- .../repo-branch-commit-fields.tsx | 1 + 9 files changed, 136 insertions(+), 119 deletions(-) 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 9cdd56f..b00c1bc 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 @@ -64,8 +64,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/explore/explore-list/nfa-search.styles.ts b/ui/src/views/explore/explore-list/nfa-search.styles.ts index 9955ee0..95c9b2b 100644 --- a/ui/src/views/explore/explore-list/nfa-search.styles.ts +++ b/ui/src/views/explore/explore-list/nfa-search.styles.ts @@ -1,4 +1,4 @@ -import { Flex, Icon, Input } from '@/components'; +import { Flex, Icon } from '@/components'; import { styled } from '@/theme'; export const NFASearchFragmentStyles = { diff --git a/ui/src/views/indexed-nfa/fragments/aside.fragment.tsx b/ui/src/views/indexed-nfa/fragments/aside.fragment.tsx index 69f07c0..b28c640 100644 --- a/ui/src/views/indexed-nfa/fragments/aside.fragment.tsx +++ b/ui/src/views/indexed-nfa/fragments/aside.fragment.tsx @@ -2,6 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { Link } from 'react-router-dom'; import { Button, Flex, Icon, NFAPreview } from '@/components'; +import { parseNumberToHexColor } from '@/utils/color'; import { IndexedNFA } from '../indexed-nfa.context'; import { IndexedNFAStyles as S } from '../indexed-nfa.styles'; @@ -10,8 +11,7 @@ const Preview: React.FC = () => { const { nfa } = IndexedNFA.useContext(); const color = useMemo( - // TODO: replace with util function - () => `#${`000000${nfa.color.toString(16)}`.slice(-6)}`, + () => `#${parseNumberToHexColor(nfa.color)}`, [nfa] ); diff --git a/ui/src/views/indexed-nfa/fragments/main.fragment.tsx b/ui/src/views/indexed-nfa/fragments/main.fragment.tsx index 286273e..ba08ed2 100644 --- a/ui/src/views/indexed-nfa/fragments/main.fragment.tsx +++ b/ui/src/views/indexed-nfa/fragments/main.fragment.tsx @@ -1,6 +1,7 @@ import React, { useMemo } from 'react'; import { Flex, Icon, IconName, ResolvedAddress, Text } from '@/components'; +import { getDate, getRepositoryFromURL, getTimeSince } from '@/utils'; import { IndexedNFA } from '../indexed-nfa.context'; import { IndexedNFAStyles as S } from '../indexed-nfa.styles'; @@ -33,10 +34,7 @@ const Header: React.FC = () => { - - {/* TODO: place correct data */} - 12/12/22 - + {getDate(nfa.createdAt)} @@ -81,14 +79,12 @@ const DataWrapper: React.FC = ({ 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'], + [getRepositoryFromURL(nfa.gitRepository.id), 'Repository'], + ['', 'Version'], [nfa.externalURL, 'Domain'], - [nfa.externalURL, 'Domain 2'], ]; }, [nfa]); @@ -137,29 +133,33 @@ const VerificationBanner: React.FC = ({ }; const Verification: React.FC = () => { + const { nfa } = IndexedNFA.useContext(); + return ( <> Verification - {/* TODO: Get verified from context */} - 0.5} /> + - {/* TODO: place correct data */} - polygon.eth - polygon/fe + + {nfa.verifier ? ( + {nfa.verifier?.id} + ) : ( + '-' + )} + + + {getRepositoryFromURL(nfa.gitRepository.id)} + ); }; -// 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 = () => { + const { + nfa: { accessPoints }, + } = IndexedNFA.useContext(); + return ( <> Frontends @@ -184,86 +184,33 @@ const AccessPoints: React.FC = () => { - {apMocks.map((item) => ( - - - - - {item.domain} - - {item.owner} - - {item.createdAt} - - + {accessPoints && accessPoints.length > 0 ? ( + accessPoints.map((item) => ( + + + + + {item.id} + + {item.owner.id} + + + {getTimeSince(item.createdAt)} + + + + + + )) + ) : ( + + + No results - ))} - - - - - ); -}; - -// 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 ( - <> - Versions - - - - - - - - - - - - - - - Commit - Preview - Time - - - - - {versionsMock.map((item) => ( - - - - {item.live && 'Live'} - - - {item.commit.slice(0, 6)} - - {item.preview} - - {item.time} - - - - - ))} + )} @@ -279,7 +226,6 @@ export const IndexedNFAMainFragment: React.FC = () => { - ); }; diff --git a/ui/src/views/indexed-nfa/indexed-nfa.tsx b/ui/src/views/indexed-nfa/indexed-nfa.tsx index 88cb844..232909a 100644 --- a/ui/src/views/indexed-nfa/indexed-nfa.tsx +++ b/ui/src/views/indexed-nfa/indexed-nfa.tsx @@ -2,8 +2,7 @@ import { useQuery } from '@apollo/client'; import { ethers } from 'ethers'; import { useNavigate, useParams } from 'react-router-dom'; -import { getNFADocument } from '@/graphclient'; -import { NFAMock } from '@/mocks'; +import { getNFADetailDocument } from '@/graphclient'; import { AppLog } from '@/utils'; import { @@ -26,7 +25,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)), @@ -43,9 +42,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 ( - + diff --git a/ui/src/views/mint/github-step/steps/github-repo-configuration/repo-configuration-body/repo-branch-commit-fields.tsx b/ui/src/views/mint/github-step/steps/github-repo-configuration/repo-configuration-body/repo-branch-commit-fields.tsx index e3ea135..62300fb 100644 --- a/ui/src/views/mint/github-step/steps/github-repo-configuration/repo-configuration-body/repo-branch-commit-fields.tsx +++ b/ui/src/views/mint/github-step/steps/github-repo-configuration/repo-configuration-body/repo-branch-commit-fields.tsx @@ -10,6 +10,7 @@ import { import { AppLog } from '@/utils'; import { Mint } from '@/views/mint/mint.context'; import { useMintFormContext } from '@/views/mint/nfa-step/form-step'; + import { TextStyles } from './repo-branch-commit-fields.styles'; export const RepoBranchCommitFields: React.FC = () => {