Added article history view page
parent
c3efeb4adc
commit
e55733c951
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
This file contains all endpoints related to archives
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Articles = require('../models/article.js');
|
||||||
|
var Topics = require('../models/topic.js');
|
||||||
|
var Archives = require('../models/archive.js');
|
||||||
|
var Users = require('../models/user.js');
|
||||||
|
|
||||||
|
var db = require('../db.js'); //this file contains the knex file import. it's equal to knex=require('knex')
|
||||||
|
|
||||||
|
module.exports = function(app){
|
||||||
|
app.get('/archives/:id/',function(req,res){
|
||||||
|
/*
|
||||||
|
This is a GET endpoint that responds with one article of the specific ID (identified through the ID param)
|
||||||
|
the article is present in the data object in the returning object.
|
||||||
|
the error key in the returning object is a boolen which is false if there is no error and true otherwise
|
||||||
|
*/
|
||||||
|
Archives.forge({id: req.params.id})
|
||||||
|
.fetch()
|
||||||
|
.then(function (archive) {
|
||||||
|
console.log("ARCHIVE=================================");
|
||||||
|
console.log(archive);
|
||||||
|
Users.forge({id: archive.attributes.user_id}).fetch().then(function(user){
|
||||||
|
archiveObj = archive.toJSON();
|
||||||
|
userObj = user.toJSON();
|
||||||
|
archiveObj.user = {
|
||||||
|
id: userObj.id,
|
||||||
|
name: userObj.name,
|
||||||
|
email: userObj.email,
|
||||||
|
about: userObj.about
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.then(function(){
|
||||||
|
res.json({
|
||||||
|
error: {
|
||||||
|
error: false,
|
||||||
|
message: ''
|
||||||
|
},
|
||||||
|
code: 'B113',
|
||||||
|
data: archiveObj
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
error: {
|
||||||
|
error: true,
|
||||||
|
message: error.message
|
||||||
|
},
|
||||||
|
code: 'B114',
|
||||||
|
data: {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Error from './error.jsx';
|
||||||
|
import Loader from './loader.jsx';
|
||||||
|
import {hashHistory} from 'react-router';
|
||||||
|
|
||||||
|
class BrowseArchives extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.archiveSelect = this.archiveSelect.bind(this);
|
||||||
|
this.state = {error: "", archives: []};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
console.log("Component Mounted!");
|
||||||
|
var myHeaders = new Headers({
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
"x-access-token": localStorage.getItem('userToken')
|
||||||
|
});
|
||||||
|
var myInit = { method: 'GET',
|
||||||
|
headers: myHeaders,
|
||||||
|
};
|
||||||
|
var that = this;
|
||||||
|
var url = '/api/articles/'+this.props.articleId+'/history';
|
||||||
|
fetch(url,myInit)
|
||||||
|
.then(function(response) {
|
||||||
|
console.log(response);
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(response) {
|
||||||
|
if(response.error.error)
|
||||||
|
that.setState({error: response.error.message})
|
||||||
|
else {
|
||||||
|
that.setState({archives: response.data})
|
||||||
|
console.log(that.state.archives);
|
||||||
|
}
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
archiveSelect(id,e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.archiveChange(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if(this.state.error) {
|
||||||
|
return <Error error={this.state.error} />
|
||||||
|
}
|
||||||
|
if(this.state.archives.length<1) {
|
||||||
|
return <Loader />;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return(
|
||||||
|
<div className="custom-collapse">
|
||||||
|
<div className="visible-xs">
|
||||||
|
<button className="collapse-toggle btn btn-default" type="button" data-toggle="collapse" data-parent="custom-collapse" data-target="#side-menu-collapse">
|
||||||
|
View Topics
|
||||||
|
</button>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div className="list-group collapse" id="side-menu-collapse">
|
||||||
|
{this.state.archives.map(archive => (
|
||||||
|
<a key={archive.id} href="#" className="list-group-item dropdown-toggle" onClick={(e) => this.archiveSelect(archive.id,e)}>
|
||||||
|
<h4 className="list-group-item-heading">{new Date(archive.updated_at).toDateString()}</h4>
|
||||||
|
<p className="list-group-item-text">{archive.what_changed}</p>
|
||||||
|
</a>
|
||||||
|
))}</div>
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BrowseArchives;
|
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {Link} from 'react-router';
|
||||||
|
import Loader from './loader.jsx';
|
||||||
|
import Error from './error.jsx';
|
||||||
|
import BrowseArchives from './browse_archives.jsx';
|
||||||
|
import SimpleArticle from './simple_article.jsx';
|
||||||
|
var Remarkable = require('remarkable');
|
||||||
|
|
||||||
|
class ArticleHistory extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.archiveUpdate = this.archiveUpdate.bind(this);
|
||||||
|
this.state = {archive_id: ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
archiveUpdate(id) {
|
||||||
|
this.setState({archive_id: id});
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return(
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<label>Archives</label>
|
||||||
|
<BrowseArchives archiveChange={this.archiveUpdate} articleId={this.props.params.articleId} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9">
|
||||||
|
<label>View Article</label>
|
||||||
|
<SimpleArticle archiveId={this.state.archive_id} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ArticleHistory;
|
@ -0,0 +1,70 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {Link} from 'react-router';
|
||||||
|
import Loader from './loader.jsx';
|
||||||
|
import Error from './error.jsx';
|
||||||
|
var Remarkable = require('remarkable');
|
||||||
|
|
||||||
|
class SimpleArticle extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {error: "", article: {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps){
|
||||||
|
var myHeaders = new Headers({
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
"x-access-token": localStorage.getItem('userToken')
|
||||||
|
});
|
||||||
|
var myInit = { method: 'GET',
|
||||||
|
headers: myHeaders,
|
||||||
|
};
|
||||||
|
var that = this;
|
||||||
|
fetch('/api/archives/'+nextProps.archiveId,myInit)
|
||||||
|
.then(function(response) {
|
||||||
|
console.log(response);
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(response) {
|
||||||
|
if(response.error.error)
|
||||||
|
that.setState({error: response.error.message})
|
||||||
|
else {
|
||||||
|
that.setState({article: response.data})
|
||||||
|
}
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getRawMarkupBody() {
|
||||||
|
var md = new Remarkable();
|
||||||
|
return { __html: md.render(this.state.article.body) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if(this.state.error) {
|
||||||
|
return <Error error={this.state.error} />
|
||||||
|
}
|
||||||
|
if(this.state.article && this.state.article.user) {
|
||||||
|
return(<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="article-heading">
|
||||||
|
<h1 className="single-article-title">{this.state.article.title}
|
||||||
|
</h1>
|
||||||
|
<div className="single-article-meta">
|
||||||
|
Edited by <b>{this.state.article.user.name}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="single-article-body"
|
||||||
|
dangerouslySetInnerHTML={this.getRawMarkupBody()}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return <center><p className="help-block">Please select the archive</p></center>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SimpleArticle;
|
Loading…
Reference in New Issue