add react-static-graphql sample app (#1569)

This commit is contained in:
Praveen Durairaj 2019-02-08 15:14:35 +05:30 committed by Shahidh K Muhammed
parent 9a6fa7fafc
commit 9c914f5637
19 changed files with 8137 additions and 0 deletions

View File

@ -0,0 +1,3 @@
{
"presets": ["react-static/babel-preset.js"]
}

View File

@ -0,0 +1,3 @@
module.exports = {
extends: 'react-tools',
}

View File

@ -0,0 +1,9 @@
node_modules
.next
.cache
dist
.tempdist
.DS_Store
yarn-error.log
.history
tmp

View File

@ -0,0 +1,117 @@
# react-static-graphql
A sample app to get started with [react-static](https://github.com/nozzle/react-static) site generator, Hasura GraphQL engine and Postgres as database.
# Tutorial
- Deploy Postgres and GraphQL Engine on Heroku:
[![Deploy to
heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/hasura/graphql-engine-heroku)
Please checkout our [docs](https://docs.hasura.io/1.0/graphql/manual/deployment/index.html) for other deployment methods
- Get the Heroku app URL (say `my-app.herokuapp.com`)
- Create `author` table:
Open Hasura console: visit https://my-app.herokuapp.com on a browser
Navigate to `Data` section in the top nav bar and create a table as follows:
![Create author table](../gatsby-postgres-graphql/assets/add_table.jpg)
- Insert sample data into `author` table:
![Insert data into author table](../gatsby-postgres-graphql/assets/insert_data.jpg)
Verify if the row is inserted successfully
![Insert data into author table](../gatsby-postgres-graphql/assets/browse_rows.jpg)
- Similarly, create an article table with the following data model:
table: `article`
columns: `id`, `title`, `content`, `author_id` (foreign key to `author` table's `id`) and `created_at`
![Create foreign key for author_id column to author's id](./assets/author_fk.png)
- Now create a relationship from article table to author table by going to the Relationships tab.
- Clone this repo:
```bash
git clone https://github.com/hasura/graphql-engine
cd graphql-engine/community/sample-apps/react-static-graphql
```
- Install npm modules:
```bash
yarn install
```
- Open `src/apollo.js` and configure Hasura's GraphQL Endpoint as follows:
```js
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import fetch from 'node-fetch'
const client = new ApolloClient({
link: new HttpLink({
uri: 'https://myapp.herokuapp.com/v1alpha1/graphql',
fetch
}),
cache: new InMemoryCache(),
})
export default client
```
Replace the `uri` argument with your Hasura GraphQL Endpoint.
- We have defined the graphql query in `src/graphql/queries/queries.js`.
- GraphQL query to fetch author information
```graphql
query {
author {
id
name
}
}
```
- GraphQL query to fetch articles written by author
```graphql
query($author: Int!) {
article(where: {author_id: {_eq: $author}}) {
id
title
content
created_at
}
}
```
- In `pages/blog.js`, we do the templating for listing all the authors and in `containers/Post.js`, we do the templating for listing all the articles written by a selected author.
- Run the app:
```bash
yarn start
```
- Test the app
Visit [http://localhost:3000](http://localhost:3000) to view the app
- Bundle app
```bash
yarn stage
```
- Serve Production app
```bash
yarn serve
```
For detailed explanation on how things work, checkout [react-static docs](https://github.com/nozzle/react-static).

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,32 @@
{
"name": "react-static-example-basic",
"private": true,
"scripts": {
"start": "react-static start",
"stage": "react-static build --staging",
"build": "react-static build",
"bundle": "react-static bundle",
"export": "react-static export",
"serve": "serve dist -p 3000 -s"
},
"dependencies": {
"@reach/router": "^1.2.1",
"apollo-cache-inmemory": "^1.4.2",
"apollo-client": "^2.4.12",
"apollo-link-http": "^1.5.9",
"axios": "^0.18.0",
"babel-loader": "^8.0.5",
"graphql": "^14.1.1",
"graphql-tag": "^2.10.1",
"node-fetch": "^2.3.0",
"react": "^16.6.3",
"react-apollo": "^2.4.1",
"react-dom": "^16.6.3",
"react-hot-loader": "^4.3.12",
"react-static": "^6.0.18"
},
"devDependencies": {
"eslint-config-react-tools": "1.x.x",
"serve": "10.1.1"
}
}

View File

@ -0,0 +1 @@
User-agent: *

View File

@ -0,0 +1,27 @@
import React from 'react'
import { Root, Routes } from 'react-static'
import { Link } from '@reach/router'
import { ApolloProvider } from 'react-apollo'
import client from './apollo'
import './app.css'
function App() {
return (
<ApolloProvider client={client}>
<Root>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/blog">Blog</Link>
</nav>
<div className="content">
<Routes />
</div>
</Root>
</ApolloProvider>
)
}
export default App

View File

@ -0,0 +1,14 @@
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import fetch from 'node-fetch'
const client = new ApolloClient({
link: new HttpLink({
uri: 'http://localhost:8080/v1alpha1/graphql', // replace this with your own Hasura GraphQL Endpoint
fetch
}),
cache: new InMemoryCache(),
})
export default client

View File

@ -0,0 +1,33 @@
body {
font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial,
'Lucida Grande', sans-serif;
font-weight: 300;
font-size: 16px;
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color: #108db8;
font-weight: bold;
}
img {
max-width: 100%;
}
nav {
width: 100%;
background: #108db8;
}
nav a {
color: white;
padding: 1rem;
display: inline-block;
}
.content {
padding: 1rem;
}

View File

@ -0,0 +1,21 @@
import React from 'react'
import { withRouteData } from 'react-static'
import { Link } from '@reach/router'
export default withRouteData(({ articles }) => {
const articlesList = articles.map((article, index) => {
return (
<div key={index}>
<h3>{article.title}</h3>
<p>{article.content}</p>
</div>
)}
)
return (
<div>
<Link to="/blog">{'<'} Back</Link>
<br />
{articlesList.length ? articlesList : 'There are no posts by this author'}
</div>
)}
)

View File

@ -0,0 +1,23 @@
import gql from "graphql-tag";
const GET_AUTHOR = gql`
query {
author {
id
name
}
}
`;
const GET_ARTICLE = gql`
query($author: Int!) {
article(where: {author_id: {_eq: $author}}) {
id
title
content
created_at
}
}
`;
export { GET_ARTICLE, GET_AUTHOR };

View File

@ -0,0 +1,27 @@
import React from 'react'
import ReactDOM from 'react-dom'
// Your top level component
import App from './App'
// Export your top level component as JSX (for static rendering)
export default App
// Render your app
if (typeof document !== 'undefined') {
const renderMethod = module.hot
? ReactDOM.render
: ReactDOM.hydrate || ReactDOM.render
const render = Comp => {
renderMethod(<Comp />, document.getElementById('root'))
}
// Render!
render(App)
// Hot Module Replacement
if (module.hot) {
module.hot.accept('./App', () => render(require('./App').default))
}
}

View File

@ -0,0 +1,7 @@
import React from 'react'
export default () => (
<div>
<h1>404 - Oh no's! We couldn't find that page :(</h1>
</div>
)

View File

@ -0,0 +1,7 @@
import React from 'react'
export default () => (
<div>
<p>React Static is a progressive static site generator for React.</p>
</div>
)

View File

@ -0,0 +1,23 @@
import React from 'react'
import { withRouteData } from 'react-static'
import { Link } from '@reach/router'
const Authors = ({ author }) => {
const authorList = author.map((item) => {
return (
<div key={item.id}>
<Link to={"/blog/" + item.id}>{item.name}</Link>
</div>
);
});
return (
<div>
{/* STATIC DATA FROM THE BUILD */}
<h1>Authors</h1>
{authorList.length ? authorList : 'There are no authors available'}
</div>
)
}
export default withRouteData(Authors)

View File

@ -0,0 +1,9 @@
import React from 'react'
import { withSiteData } from 'react-static'
export default withSiteData(() => (
<div style={{ textAlign: 'center' }}>
<h1>Welcome to React-Static</h1>
<p>This demo integrates <a href="https://github.com/hasura/graphql-engine">Hasura GraphQL Engine</a> and allows you to generate static sites with your Postgres database using GraphQL</p>
</div>
))

View File

@ -0,0 +1,39 @@
import client from './src/apollo'
import {GET_AUTHOR, GET_ARTICLE} from './src/graphql/queries'
export default {
getSiteData: () => ({
title: 'React Static with Hasura GraphQL',
}),
getRoutes: async () => {
const {
data: { author },
} = await client.query({
query: GET_AUTHOR,
})
return [
{
path: '/blog',
getData: () => ({author}),
children: author.map(item => ({
path: `/${item.id.toString()}`,
component: 'src/containers/Post',
getData: (resolvedRoute) => {
const path = resolvedRoute.route.path
const author_id = path.split("/")[1]
return client.query({
query: GET_ARTICLE,
variables: {author: author_id}
}).then( (resp) => {
const articles = resp.data.article;
if(articles) {
return {articles}
}
return {articles: []}
})
},
})),
},
]
},
}

File diff suppressed because it is too large Load Diff