├── .codeclimate.yml ├── .babelrc ├── logo.png ├── .gitignore ├── actions ├── index.js └── todo.js ├── static ├── img │ ├── favicon.ico │ ├── android-chrome-144x144.png │ ├── android-chrome-192x192.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ └── splashscreen-icon-384x384.png └── manifest.json ├── .prettierrc ├── reducers ├── index.js └── todos.js ├── .gitpod.yml ├── .editorconfig ├── components ├── TodoItem.js ├── Fork.js └── Todo.js ├── .travis.yml ├── utils ├── store.js ├── offline.js └── sw.js ├── package.json ├── server.js ├── pages ├── index.js ├── _document.js └── _app.js ├── next.config.js ├── license └── readme.md /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | Javascript: true -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ "next/babel" ] 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | static/sw.js 3 | .next 4 | *-error.log 5 | *lock.json 6 | yarn.lock 7 | -------------------------------------------------------------------------------- /actions/index.js: -------------------------------------------------------------------------------- 1 | export const ADD_TODO = 'ADD_TODO' 2 | export const REMOVE_TODO = 'REMOVE_TODO' 3 | -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/static/img/favicon.ico -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "useTabs": true, 5 | "tabWidth": 2 6 | } 7 | -------------------------------------------------------------------------------- /static/img/android-chrome-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/static/img/android-chrome-144x144.png -------------------------------------------------------------------------------- /static/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/static/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /static/img/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/static/img/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /static/img/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/static/img/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /static/img/splashscreen-icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitpod-io/NextSimpleStarter/HEAD/static/img/splashscreen-icon-384x384.png -------------------------------------------------------------------------------- /reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | 3 | import todos from './todos' 4 | 5 | export default combineReducers({ todos }) 6 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | ports: 2 | - port: 3000 3 | onOpen: open-preview 4 | tasks: 5 | - init: yarn 6 | command: yarn dev 7 | github: 8 | prebuilds: 9 | pullRequestsFromForks: true 10 | -------------------------------------------------------------------------------- /actions/todo.js: -------------------------------------------------------------------------------- 1 | import { ADD_TODO, REMOVE_TODO } from './' 2 | 3 | export function addTodo(text) { 4 | return { 5 | type: ADD_TODO, 6 | text 7 | } 8 | } 9 | 10 | export function removeTodo(todo) { 11 | return { 12 | type: REMOVE_TODO, 13 | todo 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,.*rc,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /components/TodoItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const TodoItem = ({ todo, remove }) => { 4 | return ( 5 |
  • 6 | {' '} 13 | {todo.text} 14 |
  • 15 | ) 16 | } 17 | 18 | export default TodoItem 19 | -------------------------------------------------------------------------------- /reducers/todos.js: -------------------------------------------------------------------------------- 1 | import { ADD_TODO, REMOVE_TODO } from '../actions' 2 | 3 | export default function(state = [], action) { 4 | const { type, text, todo } = action 5 | 6 | switch (type) { 7 | case ADD_TODO: 8 | return [ 9 | ...state, 10 | { 11 | id: Math.random() 12 | .toString(36) 13 | .substring(2), 14 | text 15 | } 16 | ] 17 | case REMOVE_TODO: 18 | return state.filter(i => i !== todo) 19 | default: 20 | return state 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - '6' 7 | - '10' 8 | 9 | install: 10 | - npm install 11 | 12 | cache: 13 | directories: 14 | - node_modules 15 | 16 | # Necessary to compile native modules for io.js v3 or Node.js v4 17 | env: 18 | - CXX=g++-4.8 19 | 20 | # Necessary to compile native modules for io.js v3 or Node.js v4 21 | addons: 22 | apt: 23 | sources: 24 | - ubuntu-toolchain-r-test 25 | packages: 26 | - g++-4.8 27 | -------------------------------------------------------------------------------- /utils/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, compose, applyMiddleware } from 'redux' 2 | 3 | import rootReducer from '../reducers' 4 | 5 | const enhancers = compose( 6 | typeof window !== 'undefined' && process.env.NODE_ENV !== 'production' 7 | ? window.devToolsExtension && window.devToolsExtension() 8 | : f => f 9 | ) 10 | 11 | const createStoreWithMiddleware = applyMiddleware()(createStore) 12 | 13 | export default initialState => 14 | createStoreWithMiddleware(rootReducer, initialState, enhancers) 15 | -------------------------------------------------------------------------------- /components/Fork.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Fork = ({ stars }) => ( 4 |
    5 |
    9 | 10 | 13 | 14 |
    15 | 22 |
    23 | ) 24 | 25 | export default Fork 26 | -------------------------------------------------------------------------------- /utils/offline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Registers our Service Worker on the site 3 | * Need more? check out: 4 | * https://github.com/GoogleChrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js 5 | */ 6 | 7 | if ( 8 | process.env.NODE_ENV === 'production' && 9 | typeof window !== 'undefined' && 10 | 'serviceWorker' in navigator 11 | ) { 12 | navigator.serviceWorker 13 | .register('/sw.js') 14 | .then(function(reg) { 15 | console.log('Service worker registered (0-0) ') 16 | }) 17 | .catch(function(e) { 18 | console.error('Error during service worker registration:', e) 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-simple-starter", 3 | "version": "1.0.0", 4 | "repository": { 5 | "url": "https://github.com/ooade/NextSimpleStarter" 6 | }, 7 | "license": "MIT", 8 | "dependencies": { 9 | "isomorphic-fetch": "^2.2.1", 10 | "next": "^8.0.0", 11 | "next-redux-wrapper": "^2.0.0", 12 | "react": "^16.8.1", 13 | "react-dom": "^16.8.1", 14 | "react-redux": "^6.0.0", 15 | "redux": "^3.7.2" 16 | }, 17 | "scripts": { 18 | "dev": "node server", 19 | "build": "next build", 20 | "start": "NODE_ENV=production node server" 21 | }, 22 | "devDependencies": { 23 | "workbox-webpack-plugin": "^4.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require('http') 2 | const path = require('path') 3 | const next = require('next') 4 | 5 | const dev = process.env.NODE_ENV !== 'production' 6 | const app = next({ dir: '.', dev }) 7 | const handle = app.getRequestHandler() 8 | 9 | const PORT = process.env.PORT || 3000 10 | 11 | app.prepare().then(_ => { 12 | const server = createServer((req, res) => { 13 | if (req.url === '/sw.js' || req.url.startsWith('/precache-manifest')) { 14 | app.serveStatic(req, res, path.join(__dirname, '.next', req.url)) 15 | } else { 16 | handle(req, res) 17 | } 18 | }) 19 | 20 | server.listen(PORT, err => { 21 | if (err) throw err 22 | 23 | console.log(`> App running on port ${PORT}`) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import 'isomorphic-fetch' 2 | import React from 'react' 3 | import { connect } from 'react-redux' 4 | 5 | import Fork from '../components/Fork' 6 | import Todo from '../components/Todo' 7 | 8 | // Port in to using useState hooks, if you need state 9 | const Index = ({ stars }) => ( 10 |
    11 | 12 |
    13 | 14 |
    15 |
    16 | ) 17 | 18 | Index.getInitialProps = async({ store }) => { 19 | // Adding a default/initialState can be done as follows: 20 | // store.dispatch({ type: 'ADD_TODO', text: 'It works!' }); 21 | const res = await fetch( 22 | 'https://api.github.com/repos/ooade/NextSimpleStarter' 23 | ) 24 | const json = await res.json() 25 | return { stars: json.stargazers_count } 26 | } 27 | 28 | export default connect()(Index) 29 | -------------------------------------------------------------------------------- /static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NextSimpleStarter", 3 | "short_name": "Next PWA", 4 | "icons": [ 5 | { 6 | "src": "img/apple-touch-icon-120x120.png", 7 | "sizes": "120x120", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "img/apple-touch-icon-152x152.png", 12 | "sizes": "152x152", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "img/android-chrome-144x144.png", 17 | "sizes": "144x144", 18 | "type": "image/png" 19 | }, 20 | { 21 | "src": "img/android-chrome-192x192.png", 22 | "sizes": "192x192", 23 | "type": "image/png" 24 | }, 25 | { 26 | "src": "img/splashscreen-icon-384x384.png", 27 | "sizes": "384x384", 28 | "type": "image/png" 29 | } 30 | ], 31 | "start_url": "/", 32 | "display": "standalone", 33 | "theme_color": "#673ab7", 34 | "background_color": "#EEE" 35 | } 36 | -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Document, { Head, Main, NextScript } from 'next/document' 3 | 4 | export default class MyDocument extends Document { 5 | render() { 6 | return ( 7 | 8 | 9 | 13 | 14 | 15 | 16 | 20 | 21 | 22 |
    23 | 24 |