|
@@ -1,6 +1,6 @@
|
|
|
import React, { Component } from 'react';
|
|
|
import logo from './logo.svg';
|
|
|
-import './App.css';
|
|
|
+import './1/1.js';
|
|
|
|
|
|
import {Router, Route, Link, Switch} from "react-router-dom";
|
|
|
import createHistory from "history/createBrowserHistory";
|
|
@@ -12,28 +12,45 @@ import { GraphQLClient } from 'graphql-request'
|
|
|
|
|
|
const gql = new GraphQLClient("http://localhost:4000/graphql", { headers: {} })
|
|
|
|
|
|
-gql.request(`query getPosts {
|
|
|
- posts {
|
|
|
- id
|
|
|
- title
|
|
|
- text
|
|
|
- timestamp
|
|
|
- tagz
|
|
|
- }
|
|
|
-}`).then(data => store.dispatch({type: "DATA", data}))
|
|
|
+
|
|
|
+function getFeed() {
|
|
|
+ store.dispatch({type: 'EMPTY'})
|
|
|
+ gql.request(`query getPosts {
|
|
|
+ posts {
|
|
|
+ id
|
|
|
+ title
|
|
|
+ text
|
|
|
+ timestamp
|
|
|
+ tagz
|
|
|
+ }
|
|
|
+ }`).then(data => store.dispatch({type: "DATA", data}))
|
|
|
+}
|
|
|
|
|
|
function postsReducer(state, action)
|
|
|
{
|
|
|
+ if (state === undefined || action.type == 'EMPTY'){
|
|
|
+ return {data: [], status: 'EMPTY'}
|
|
|
+ }
|
|
|
if (action.type === 'DATA'){
|
|
|
- console.log(action.data)
|
|
|
return {data: action.data.posts, status: 'DATA'}
|
|
|
}
|
|
|
- return {data: [], status: 'EMPTY'}
|
|
|
+ return state
|
|
|
+}
|
|
|
+
|
|
|
+function postReducer(state, action){
|
|
|
+ if (state === undefined){
|
|
|
+ return {data: {}, status: 'EMPTY'}
|
|
|
+ }
|
|
|
+ if (action.type === 'POST'){
|
|
|
+ return {data: action.data.post, status: 'DATA'}
|
|
|
+ }
|
|
|
+ return state;
|
|
|
}
|
|
|
|
|
|
|
|
|
const reducers = combineReducers({
|
|
|
posts: postsReducer,
|
|
|
+ post: postReducer,
|
|
|
})
|
|
|
|
|
|
var store = createStore(reducers);
|
|
@@ -44,9 +61,16 @@ var store = createStore(reducers);
|
|
|
|
|
|
class TagList extends Component {
|
|
|
render() {
|
|
|
+ if (this.props.tags){
|
|
|
+ return (
|
|
|
+ <div className="tagList">
|
|
|
+ {this.props.tags.map(tag => <span>{tag}</span>)}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
return (
|
|
|
<div className="tagList">
|
|
|
- {this.props.tags.map(tag => <span>{tag}</span>)}
|
|
|
+ Loading...
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
@@ -88,24 +112,127 @@ class Feed extends Component {
|
|
|
const mapStateToProps = function(store) {
|
|
|
return {
|
|
|
posts: store.posts,
|
|
|
+ post: store.post,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
Feed = connect(mapStateToProps)(Feed)
|
|
|
|
|
|
-let FeedPage = (props) => <Feed />
|
|
|
+class FeedPage extends Component {
|
|
|
+ render (){
|
|
|
+ getFeed();
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <Link to='/addPost'>Add post...</Link>
|
|
|
+ <Feed />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Comment extends Component {
|
|
|
+ render (){
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ {this.props.comment.text}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class CommentList extends Component {
|
|
|
+ render (){
|
|
|
+ if (this.props.comments){
|
|
|
+ return (
|
|
|
+ <div className='commentList'>
|
|
|
+ {this.props.comments.map( comment => <Comment comment={comment} key={comment.id}/>)}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <div className='commentList'>
|
|
|
+ Loading...
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
class Post extends Component {
|
|
|
render(){
|
|
|
+ console.log(this.props.post.data)
|
|
|
+ if (this.props.post.data.status === 'EMPTY'){
|
|
|
+ return (
|
|
|
+ <div className='post'>
|
|
|
+ Loading...
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <div className='post'>
|
|
|
+ <h1>{this.props.post.data.title}</h1>
|
|
|
+ <div>{this.props.post.data.text}</div>
|
|
|
+ <div>{(new Date(this.props.post.data.timestamp *1000)).toLocaleString()}</div>
|
|
|
+ <TagList tags={this.props.post.data.tagz} />
|
|
|
+ <CommentList comments={this.props.post.data.comments} />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Post = connect(mapStateToProps)(Post)
|
|
|
+
|
|
|
+
|
|
|
+class PostPage extends Component {
|
|
|
+ render(){
|
|
|
+ gql.request(`query getPostWithComments($postID: Int!){
|
|
|
+ post(id:$postID){
|
|
|
+ id
|
|
|
+ title
|
|
|
+ text
|
|
|
+ timestamp
|
|
|
+ tagz
|
|
|
+ comments {
|
|
|
+ id
|
|
|
+ text
|
|
|
+ age
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }`, {postID: this.props.match.params.id})
|
|
|
+ .then(data => store.dispatch({type: 'POST', data}))
|
|
|
+ return (
|
|
|
+ <Post id={this.props.match.params.id}/>
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class AddPostPage extends Component {
|
|
|
+
|
|
|
+ save(){
|
|
|
+ gql.request(
|
|
|
+ `mutation createPost($title: String!, $text:String!) {
|
|
|
+ createPost(title: $title, text: $text) {
|
|
|
+ title
|
|
|
+ text
|
|
|
+ }
|
|
|
+ }`,
|
|
|
+ {title: this.title.value,
|
|
|
+ text: this.text.value}
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ render (){
|
|
|
return (
|
|
|
<div>
|
|
|
- one post with id = {this.props.id}
|
|
|
+ <textarea ref={c => this.text = c}>
|
|
|
+ </textarea>
|
|
|
+ <input ref={c => this.title = c} />
|
|
|
+ <button onClick={this.save.bind(this)}>Save</button>
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-let PostPage = (props) => <Post id={props.match.params.id}/>
|
|
|
|
|
|
class App extends Component {
|
|
|
render() {
|
|
@@ -115,6 +242,7 @@ class App extends Component {
|
|
|
<Switch>
|
|
|
<Route path='/' component={FeedPage} exact />
|
|
|
<Route path='/post/:id' component={PostPage} />
|
|
|
+ <Route path='/addPost' component={AddPostPage} exact />
|
|
|
</Switch>
|
|
|
</Router>
|
|
|
</Provider>
|