mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-02 03:00:32 -04:00
Setup NextJS App with URQL and dummy pokemon data
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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.*
|
||||
|
||||
@@ -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/*"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
15
packages/web/.eslintrc.json
Normal file
15
packages/web/.eslintrc.json
Normal 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
22
packages/web/README.md
Normal 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)
|
||||
5
packages/web/graphql/client.ts
Normal file
5
packages/web/graphql/client.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { createClient } from 'urql'
|
||||
|
||||
export const client = createClient({
|
||||
url: 'https://graphql-pokemon.now.sh/',
|
||||
})
|
||||
20
packages/web/graphql/getPokemon.ts
Normal file
20
packages/web/graphql/getPokemon.ts
Normal 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
|
||||
}
|
||||
22
packages/web/graphql/getPokemons.ts
Normal file
22
packages/web/graphql/getPokemons.ts
Normal 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
2
packages/web/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
23
packages/web/package.json
Normal file
23
packages/web/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
36
packages/web/pages/index.tsx
Normal file
36
packages/web/pages/index.tsx
Normal 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;
|
||||
47
packages/web/pages/pokemon/[name].tsx
Normal file
47
packages/web/pages/pokemon/[name].tsx
Normal 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,
|
||||
},
|
||||
};
|
||||
};
|
||||
14
packages/web/tsconfig.json
Normal file
14
packages/web/tsconfig.json
Normal 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"]
|
||||
}
|
||||
1
packages/web/types/pokemon.ts
Normal file
1
packages/web/types/pokemon.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type Pokemon = { name: string, image: string }
|
||||
Reference in New Issue
Block a user