Setup NextJS App with URQL and dummy pokemon data

This commit is contained in:
Hammad Jutt
2020-07-23 19:32:25 -06:00
parent 73c49e6a43
commit 3c961052a1
15 changed files with 1109 additions and 407 deletions

5
.gitignore vendored
View File

@@ -3,10 +3,14 @@ node_modules
# IDE
.idea
# next.js
.next/
# build files
build
autogen
dist
out/
# testing
coverage
@@ -26,4 +30,5 @@ yarn-error.log*
.yarn/*
!.yarn/releases
!.yarn/plugins
.pnp
.pnp.*

View File

@@ -24,7 +24,8 @@
"lint": "eslint --ignore-path .gitignore \"./packages/**/*.{ts,tsx,js,jsx}\"",
"typecheck": "lerna run --parallel typecheck",
"precommit": "lerna run --concurrency 1 --stream precommit",
"prepush": "yarn typecheck && yarn lint"
"prepush": "yarn typecheck && yarn lint",
"web": "yarn --cwd packages/web/"
},
"workspaces": [
"packages/*"

View File

@@ -1,4 +1,4 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## DEPRECATED, PLEASE SEE packages/web insteaed
## Available Scripts

View File

@@ -0,0 +1,15 @@
{
"rules": {
"react/react-in-jsx-scope": "off"
},
"overrides": [
{
"files": ["./pages/**/*.{ts,tsx}"],
"rules": {
// NextJS requires default exports for pages
"import/no-default-export": "off",
"import/prefer-default-export": "error"
}
}
]
}

22
packages/web/README.md Normal file
View File

@@ -0,0 +1,22 @@
## MetaGame NextJS Web App
In the project directory, you can run:
### `yarn dev`
Runs the app in the development mode.<br />
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.<br />
### `yarn typecheck`
Runs TypeScript to check if there are any type errors
### `yarn build`
Builds the app and exports the static site for production to the `out` folder.
### `yarn start`
Runs the NextJS server for production use (We generate a static site right now, not running a server)

View File

@@ -0,0 +1,5 @@
import { createClient } from 'urql'
export const client = createClient({
url: 'https://graphql-pokemon.now.sh/',
})

View File

@@ -0,0 +1,20 @@
import { Pokemon } from '../types/pokemon';
import { client } from './client'
const pokemonQuery = `
query firstTwentyPokemons($name: String!) {
pokemon(name: $name) {
name
image
}
}
`
export const getPokemon = async (name: string | undefined): Promise<Pokemon | null> => {
if (!name) return null;
const {
data: { pokemon },
} = await client.query(pokemonQuery, { name }).toPromise()
return pokemon
}

View File

@@ -0,0 +1,22 @@
import { Pokemon } from '../types/pokemon';
import { client } from './client'
const firstTwentyPokemonsQuery = `
query firstTwentyPokemons {
pokemons(first: 20) {
image
name
}
}
`
export const getPokemons = async (): Promise<Array<Pokemon>> => {
const {
data: { pokemons },
} = await client.query(firstTwentyPokemonsQuery).toPromise()
return pokemons.map((pokemon: Pokemon) => ({
...pokemon,
name: pokemon.name.toLowerCase(),
}))
}

2
packages/web/next-env.d.ts vendored Normal file
View File

@@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

23
packages/web/package.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "@metafam/web",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next",
"build": "next build && next export",
"start": "next start",
"typecheck": "tsc",
"precommit": "yarn lint-staged"
},
"dependencies": {
"@types/node": "^14.0.23",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"graphql": "^15.0.0",
"isomorphic-unfetch": "^3.0.0",
"next": "latest",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"urql": "^1.9.7"
}
}

View File

@@ -0,0 +1,36 @@
import { GetStaticProps } from 'next';
import Link from 'next/link'
import { getPokemons } from '../graphql/getPokemons'
import { Pokemon } from '../types/pokemon';
type Props = {
pokemon: Array<Pokemon>
}
const Home: React.FC<Props> = ({ pokemon }) => (
<ul>
{pokemon.map((p) => (
<li key={p.name}>
<Link as={`/pokemon/${p.name}`} href="pokemon/[name]">
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a>
<h2 style={{ textTransform: 'capitalize' }}>{p.name}</h2>
<img src={p.image} alt={p.name}/>
</a>
</Link>
</li>
))}
</ul>
);
export const getStaticProps: GetStaticProps<Props> = async () => {
const pokemon = await getPokemons()
return {
props: {
pokemon,
},
}
}
export default Home;

View File

@@ -0,0 +1,47 @@
import { GetStaticPaths, GetStaticProps } from 'next';
import Error from 'next/error';
import { getPokemon } from '../../graphql/getPokemon';
import { getPokemons } from '../../graphql/getPokemons';
import { Pokemon } from '../../types/pokemon';
type Props = {
pokemon: Pokemon | null
}
const PokemonPage: React.FC<Props> = ({ pokemon }) => {
if (!pokemon) {
return <Error statusCode={404}/>;
}
return (
<div>
<h1>{pokemon.name}</h1>
<img src={pokemon.image} alt={pokemon.name}/>
</div>
);
};
export default PokemonPage;
export const getStaticPaths: GetStaticPaths = async () => {
const pokemons = await getPokemons();
return {
paths: pokemons.map(({ name }) => ({
params: { name },
})),
fallback: false,
};
};
export const getStaticProps: GetStaticProps<Props, { name: string }> = async (context) => {
const name = context.params?.name;
const pokemon = await getPokemon(name);
return {
props: {
pokemon,
},
};
};

View File

@@ -0,0 +1,14 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"allowJs": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": ["dom", "es2017"],
"noEmit": true
},
"exclude": ["node_modules"],
"include": ["**/*.ts", "**/*.tsx", "next-env.d.ts"]
}

View File

@@ -0,0 +1 @@
export type Pokemon = { name: string, image: string }

1299
yarn.lock

File diff suppressed because it is too large Load Diff