chore: UI setup subgraph querying (#152)

* wip: querying with graph-client and apollo

* feat: fetching last nfts minted with basic pagination

* chore: add .graphclient folder to gitignore and update readme

* chore: teste pagination

* chore: add create ap button in NFA

* chore: remove unsued files

* fix: fix CI

* Update test.yml

* chore: add config to handle graphclient imports

* chore: update queries

* chore: update list nfa views

* chore: add graphql folder. remove unused env variable
This commit is contained in:
Camila Sosa Morales 2023-03-08 15:28:16 -05:00 committed by GitHub
parent 7387b68571
commit 9db81d2025
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 2599 additions and 510 deletions

View File

@ -1,46 +1,46 @@
name: Contract
on:
pull_request:
branches:
- main
- develop
paths:
- 'contracts/**'
jobs:
test-contracts:
runs-on: ubuntu-latest
defaults:
run:
working-directory: contracts
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Install Dependencies
run: yarn --ignore-scripts
- name: Audit
run: yarn audit --groups dependencies
- name: Compile
run: yarn compile
- name: Run Test
run: yarn test
name: Contract
on:
pull_request:
branches:
- main
- develop
paths:
- 'contracts/**'
jobs:
test-contracts:
runs-on: ubuntu-latest
defaults:
run:
working-directory: contracts
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Install Dependencies
run: yarn --ignore-scripts
- name: Audit
run: yarn audit --groups dependencies
- name: Compile
run: yarn compile
- name: Run Test
run: yarn test

View File

@ -2,7 +2,7 @@ name: UI
on:
pull_request:
branches:
branches:
- main
- develop
paths:
@ -29,8 +29,10 @@ jobs:
- name: Install Dependencies
run: yarn --ignore-scripts
- name: Create .graphclient folder
run: yarn graphclient build
- name: Audit
run: yarn audit --groups dependencies

3
ui/.gitignore vendored
View File

@ -1 +1,2 @@
dist
dist
.graphclient

10
ui/.graphclientrc.yml Normal file
View File

@ -0,0 +1,10 @@
# .graphclientrc.yml
sources:
- name: FleekNFA
handler:
graphql:
endpoint: https://api.thegraph.com/subgraphs/name/emperororokusaki/flk-test-subgraph #replace for nfa subgraph
documents:
- ./graphql/*.graphql

View File

@ -23,11 +23,14 @@ To run the UI localy follow the steps:
```bash
$ yarn
```
3. To use ConnecKit is neccessary get an [Alchemy ID](https://alchemy.com/), so create an App and get the credentials. Then set the following .env file
```bash
VITE_ALCHEMY_API_KEY
VITE_ALCHEMY_APP_NAME
```
Also, you'll need to set up your firebase cretendials to make work the github login. Add to the .env file the following variables
```bash
@ -42,7 +45,13 @@ To run the UI localy follow the steps:
Get them from the project settings on the firebase dashboard. Read [this article](https://support.google.com/firebase/answer/7015592?hl=en#zippy=%2Cin-this-article) to know how to get your porject config
4. Start the local server running the app:
4. Build the queries to run the project:
```bash
$ yarn graphclient build
```
5. Start the local server running the app:
```bash
$ yarn dev

View File

@ -0,0 +1,20 @@
query lastMintsPaginated($pageSize: Int, $skip: Int) {
newMints(
first: $pageSize
skip: $skip
orderDirection: desc
orderBy: tokenId
) {
id
tokenId
description
name
}
}
query totalTokens {
tokens {
id
}
}

View File

@ -6,14 +6,17 @@
"scripts": {
"dev": "vite",
"dev:css": "tailwindcss -o ./tailwind.css --watch && yarn dev",
"build": "vite build",
"build": "yarn graphclient build && vite build",
"postinstall": "graphclient build",
"preview": "vite preview",
"storybook": "export SET NODE_OPTIONS=--openssl-legacy-provider && start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"author": "Fleek",
"dependencies": {
"@apollo/client": "^3.7.9",
"@ethersproject/providers": "^5.7.2",
"@graphprotocol/client-apollo": "^1.0.16",
"@headlessui/react": "^1.7.8",
"@radix-ui/colors": "^0.1.8",
"@radix-ui/react-avatar": "^1.0.1",
@ -26,6 +29,7 @@
"connectkit": "^1.1.3",
"firebase": "^9.17.1",
"formik": "^2.2.9",
"graphql": "^16.6.0",
"octokit": "^2.0.14",
"path": "^0.12.7",
"react": "^18.2.0",
@ -38,6 +42,7 @@
"@babel/core": "^7.20.12",
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@graphprotocol/client-cli": "^2.2.19",
"@storybook/addon-actions": "^6.5.15",
"@storybook/addon-essentials": "^6.5.15",
"@storybook/addon-interactions": "^6.5.15",

View File

@ -4,6 +4,7 @@ import { ComponentsTest, Home, Mint } from './views';
import { SVGTestScreen } from './views/svg-test'; // TODO: remove when done
import { ConnectKitButton } from 'connectkit';
import { MintTest } from './views/mint-test';
import { CreateAP } from './views/access-point';
export const App = () => {
themeGlobals();
@ -18,6 +19,7 @@ export const App = () => {
<Route path="/home" element={<Home />} />
<Route path="/mint" element={<Mint />} />
<Route path="/svg" element={<SVGTestScreen />} />
<Route path="/create-ap/:id" element={<CreateAP />} />
{/** TODO remove for release */}
<Route path="/components-test" element={<ComponentsTest />} />
<Route path="/mint-test" element={<MintTest />} />

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
import React from 'react';
import {
ApolloClient,
InMemoryCache,
ApolloProvider as Provider,
} from '@apollo/client';
import { GraphApolloLink } from '@graphprotocol/client-apollo';
import * as GraphClient from '@/graphclient';
const client = new ApolloClient({
link: new GraphApolloLink(GraphClient),
cache: new InMemoryCache(),
});
type ApolloProviderProps = {
children: React.ReactNode;
};
export const ApolloProvider: React.FC<ApolloProviderProps> = ({ children }) => {
return <Provider client={client}>{children}</Provider>;
};

View File

@ -1,3 +1,4 @@
import { ApolloProvider } from './apollo-provider';
import { ConnectkitProvider } from './connectkit-provider';
import { ReactQueryProvider } from './react-query-provider';
import { ReduxProvider } from './redux-provider';
@ -10,7 +11,9 @@ export const Providers: React.FC<ProviderProps> = ({ children }) => {
return (
<ReduxProvider>
<ReactQueryProvider>
<ConnectkitProvider>{children}</ConnectkitProvider>
<ApolloProvider>
<ConnectkitProvider>{children}</ConnectkitProvider>
</ApolloProvider>
</ReactQueryProvider>
</ReduxProvider>
);

View File

@ -0,0 +1,6 @@
import { useParams } from 'react-router-dom';
export const CreateAP = () => {
const { id } = useParams();
return <>Token to create AP:{id}</>;
};

View File

@ -0,0 +1 @@
export * from './create-ap';

View File

@ -1,7 +1,15 @@
import { Flex } from '@/components';
import { Link } from 'react-router-dom';
import { NFAList } from './nfa-list/nfa-list';
export const Home = () => {
return (
<>
<Flex css={{ flexDirection: 'column', margin: '$60' }}>
<h1>Home</h1>
</>
<Link to="/mint">
<u>Mint NFA!</u>
</Link>
<NFAList />
</Flex>
);
};

View File

@ -0,0 +1 @@
export * from './nfa-list';

View File

@ -0,0 +1,90 @@
import { lastMintsPaginatedDocument, totalTokensDocument } from '@/graphclient';
import { Button, Card, Flex, NoResults } from '@/components';
import { FleekERC721 } from '@/integrations/ethereum/contracts';
import { useQuery } from '@apollo/client';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
const pageSize = 10; //Set this size to test pagination
export const NFAList = () => {
const [pageNumber, setPageNumber] = useState(1);
const [totalPages, setTotalPages] = useState(0);
const {
data: totalTokens,
loading: loadingTotalTokens,
error: errorTotalTokens,
} = useQuery(totalTokensDocument);
const {
data: dataMintedTokens,
loading: loadingMintedTokens,
error: errorMintedTokens,
} = useQuery(lastMintsPaginatedDocument, {
variables: {
//first page is 0
pageSize,
skip: pageNumber > 0 ? (pageNumber - 1) * pageSize : pageNumber,
},
});
useEffect(() => {
if (totalTokens && totalTokens.tokens.length > 0) {
setTotalPages(Math.ceil(totalTokens.tokens.length / pageSize));
}
}, [totalTokens]);
if (loadingMintedTokens || loadingTotalTokens) return <div>Loading...</div>; //TODO handle loading
if (errorMintedTokens || errorTotalTokens) return <div>Error</div>; //TODO handle error
const handlePreviousPage = () => {
if (pageNumber > 1) {
setPageNumber((prevState) => prevState - 1);
}
};
const handleNextPage = () => {
if (pageNumber + 1 <= totalPages)
setPageNumber((prevState) => prevState + 1);
};
return (
<Flex css={{ flexDirection: 'column', margin: '$5', gap: '$2' }}>
<Flex css={{ gap: '$2' }}>
{/* TODO this will be remove when we have pagination component */}
<span>items per page: {pageSize}</span>
<span>
page: {pageNumber}/{totalPages}
</span>
<Button onClick={handlePreviousPage} disabled={pageNumber === 1}>
Previous page
</Button>
<Button onClick={handleNextPage} disabled={pageNumber === totalPages}>
Next page
</Button>
</Flex>
<Flex css={{ gap: '$2' }}>
{dataMintedTokens && dataMintedTokens.newMints.length > 0 ? (
dataMintedTokens.newMints.map((mint) => (
<Card.Container key={mint.tokenId}>
<Card.Heading title={mint.name} />
<Card.Body css={{ display: 'flex', flexDirection: 'column' }}>
<a
target="_blank"
href={`https://testnets.opensea.io/assets/mumbai/${FleekERC721.address}/${mint.tokenId}`}
>
<u>Open NFA on Opensea</u>
</a>
<Link to={`/create-ap/${mint.tokenId}`}>Create AP</Link>
</Card.Body>
</Card.Container>
))
) : (
<NoResults />
)}
</Flex>
</Flex>
);
};

View File

@ -7,7 +7,9 @@
"rootDirs": ["src"],
"baseUrl": "src",
"paths": {
"@/*": ["*"]
"@/*": ["*"],
"@/graphclient": ["../.graphclient"],
"@/graphclient/*": ["../.graphclient/*"]
},
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
@ -21,5 +23,5 @@
"isolatedModules": true,
"types": ["vite/client"]
},
"include": ["./src", "./*.ts"]
"include": ["./src", "./.graphclient", "./*.ts"]
}

File diff suppressed because it is too large Load Diff