├── .gitignore ├── .tern-project ├── .tmuxinator.yml ├── components ├── CategoriesWidget.js ├── CategoriesWidgetContainer.js ├── CommentForm.js ├── CommentsWidget.js ├── CommentsWidgetContainer.js ├── Footer.js ├── Head.js ├── Hero.js ├── Home.js ├── LoadMorePosts.js ├── Main.js ├── NoMorePosts.js ├── Post.js ├── PostPage.js ├── Posts.js ├── PostsWidget.js ├── Results.js ├── ScrollDown.js ├── Search.js ├── SearchPage.js ├── SearchWidget.js ├── Sidebar.js ├── SingleComment.js ├── SinglePost.js ├── SinglePostComments.js ├── SinglePostContainer.js ├── SinglePostFooter.js ├── SinglePostHeader.js └── Spinner.js ├── config.js ├── package.json ├── pages ├── index.js ├── post.js └── search.js ├── readme.md ├── redux ├── InitialState.js ├── actions.js ├── helpers.js ├── index.js ├── readme.md └── reducers.js ├── static ├── header.jpg ├── twentyNext.css └── twentyseventeen.css ├── wp.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .next/ 3 | yarn-error.log 4 | -------------------------------------------------------------------------------- /.tern-project: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": { 3 | "es_modules": {}, 4 | "node": {} 5 | }, 6 | "libs": [ 7 | "ecma5", 8 | "ecma6", 9 | "browser", 10 | "react" 11 | ], 12 | "ecmaVersion": 6 13 | } 14 | -------------------------------------------------------------------------------- /.tmuxinator.yml: -------------------------------------------------------------------------------- 1 | # ~/.tmuxinator/nextjs.yml 2 | 3 | name: nextjs 4 | root: ~/git/nextjs 5 | windows: 6 | - editor: vim 7 | - server: yarn run dev 8 | -------------------------------------------------------------------------------- /components/CategoriesWidget.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | class CategoriesWidget extends React.Component { 4 | render () { 5 | let { categories } = this.props 6 | return ( 7 |
8 |

Categories

9 | 16 |
17 | ) 18 | } 19 | } 20 | 21 | export default CategoriesWidget 22 | -------------------------------------------------------------------------------- /components/CategoriesWidgetContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import CategoriesWidget from './CategoriesWidget' 3 | import Spinner from './Spinner' 4 | import wp from '../wp' 5 | 6 | import { connect } from 'react-redux' 7 | import { receivedCategories } from '../redux/actions' 8 | 9 | function mapStateToProps (store) { 10 | return { 11 | isFetching: store.categories.isFetching, 12 | categories: store.categories.items 13 | } 14 | } 15 | 16 | const dispatchToProps = { receivedCategories } 17 | 18 | class CategoriesWidgetContainer extends React.Component { 19 | 20 | async componentDidMount () { 21 | const {receivedCategories} = this.props 22 | let categories = await wp.categories() 23 | receivedCategories(categories) 24 | } 25 | 26 | render () { 27 | let {categories, isFetching} = this.props 28 | if (!isFetching) { 29 | return ( 30 | 31 | ) 32 | } else { 33 | return ( 34 | 35 | ) 36 | } 37 | } 38 | } 39 | 40 | export default connect(mapStateToProps, dispatchToProps)(CategoriesWidgetContainer) 41 | -------------------------------------------------------------------------------- /components/CommentForm.js: -------------------------------------------------------------------------------- 1 | import {Component} from 'react' 2 | import wp from '../wp' 3 | import { connect } from 'react-redux' 4 | import { requestPostComments, receivePostComments } from '../redux/actions' 5 | 6 | const mapStoreToProps = (store) => { 7 | return { 8 | postID: store.post.data.id 9 | } 10 | } 11 | 12 | const actionCreators = { 13 | requestPostComments, 14 | receivePostComments 15 | } 16 | 17 | class CommentForm extends Component { 18 | // All of our fields displayed in the state 19 | state = { 20 | comment: '', 21 | name: '', 22 | email: '', 23 | website: '' 24 | } 25 | 26 | // Handlers to update the UI as we type 27 | commentHandler = ev => { this.setState({comment: ev.target.value}) } 28 | nameHandler = ev => { this.setState({name: ev.target.value}) } 29 | emailHandler = ev => { this.setState({email: ev.target.value}) } 30 | websiteHandler = ev => { this.setState({website: ev.target.value}) } 31 | 32 | // Handler to actually perform our submit logic 33 | submitHandler = (ev) => { 34 | ev.preventDefault() 35 | let { comment, name, email, website } = this.state 36 | let { postID, requestPostComments, receivePostComments } = this.props 37 | 38 | requestPostComments() 39 | 40 | wp.comments().create({ 41 | author_name: name, 42 | author_email: email, 43 | author_url: website, 44 | content: comment, 45 | post: postID, 46 | date: new Date() 47 | }) 48 | .then(res => { 49 | wp.comments().forPost(postID) 50 | .then(comments => { 51 | receivePostComments(comments) 52 | this.setState({ 53 | comment: '', 54 | name: '', 55 | email: '', 56 | website: '' 57 | }) 58 | }) 59 | }) 60 | } 61 | 62 | render () { 63 | return ( 64 |
65 |

66 | Leave a Reply 67 |

68 |
69 |

70 | 71 | Your email address will not be published. 72 | Required fields are marked * 73 |

74 |

75 | 76 |