diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx
new file mode 100644
index 000000000..c7c4d6f94
--- /dev/null
+++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.jsx
@@ -0,0 +1,144 @@
+require('./brewItem.less');
+const React = require('react');
+const createClass = require('create-react-class');
+const _ = require('lodash');
+const cx = require('classnames');
+const moment = require('moment');
+const request = require('superagent');
+
+const googleDriveIcon = require('../../../../googleDrive.png');
+const dedent = require('dedent-tabs').default;
+
+const BrewItem = createClass({
+ getDefaultProps : function() {
+ return {
+ brew : {
+ title : '',
+ description : '',
+
+ authors : []
+ }
+ };
+ },
+
+ deleteBrew : function(){
+ if(this.props.brew.authors.length <= 1){
+ if(!confirm('Are you sure you want to delete this brew? Because you are the only owner of this brew, the document will be deleted permanently.')) return;
+ if(!confirm('Are you REALLY sure? You will not be able to recover the document.')) return;
+ } else {
+ if(!confirm('Are you sure you want to remove this brew from your collection? This will remove you as an editor, but other owners will still be able to access the document.')) return;
+ if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return;
+ }
+
+ if(this.props.brew.googleId) {
+ request.get(`/api/removeGoogle/${this.props.brew.googleId}${this.props.brew.editId}`)
+ .send()
+ .end(function(err, res){
+ location.reload();
+ });
+ } else {
+ request.delete(`/api/${this.props.brew.editId}`)
+ .send()
+ .end(function(err, res){
+ location.reload();
+ });
+ }
+ },
+
+ renderDeleteBrewLink : function(){
+ if(!this.props.brew.editId) return;
+
+ return
+
+ ;
+ },
+
+ renderEditLink : function(){
+ if(!this.props.brew.editId) return;
+
+ let editLink = this.props.brew.editId;
+ if(this.props.brew.googleId) {
+ editLink = this.props.brew.googleId + editLink;
+ }
+
+ return
+
+ ;
+ },
+
+ renderShareLink : function(){
+ if(!this.props.brew.shareId) return;
+
+ let shareLink = this.props.brew.shareId;
+ if(this.props.brew.googleId) {
+ shareLink = this.props.brew.googleId + shareLink;
+ }
+
+ return
+
+ ;
+ },
+
+ renderDownloadLink : function(){
+ if(!this.props.brew.shareId) return;
+
+ let shareLink = this.props.brew.shareId;
+ if(this.props.brew.googleId) {
+ shareLink = this.props.brew.googleId + shareLink;
+ }
+
+ return
+
+ ;
+ },
+
+ renderGoogleDriveIcon : function(){
+ if(!this.props.brew.gDrive) return;
+
+ return
+
+ ;
+ },
+
+ render : function(){
+ const brew = this.props.brew;
+ const dateFormatString = 'YYYY-MM-DD HH:mm:ss';
+
+ return
+
+
{brew.title}
+
{brew.description}
+
+
+
+
+ {brew.authors.join(', ')}
+
+
+
+ {brew.views}
+
+ {brew.pageCount &&
+
+ {brew.pageCount}
+
+ }
+
+ {moment(brew.updatedAt).fromNow()}
+
+ {this.renderGoogleDriveIcon()}
+
+
+
+ {this.renderShareLink()}
+ {this.renderEditLink()}
+ {this.renderDownloadLink()}
+ {this.renderDeleteBrewLink()}
+
+
;
+ }
+});
+
+module.exports = BrewItem;
diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less
new file mode 100644
index 000000000..d323874f5
--- /dev/null
+++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less
@@ -0,0 +1,75 @@
+
+.brewItem{
+ position : relative;
+ display : inline-block;
+ vertical-align : top;
+ box-sizing : border-box;
+ box-sizing : border-box;
+ overflow : hidden;
+ width : 48%;
+ min-height : 105px;
+ margin-right : 15px;
+ margin-bottom : 15px;
+ padding : 5px 15px 2px 8px;
+ padding-right : 15px;
+ border : 1px solid #c9ad6a;
+ border-radius : 5px;
+ -webkit-column-break-inside : avoid;
+ page-break-inside : avoid;
+ break-inside : avoid;
+ .text {
+ min-height : 54px;
+ h4{
+ margin-bottom : 5px;
+ font-size : 2.2em;
+ }
+ }
+ .info{
+ position: initial;
+ bottom: 2px;
+ font-family : ScalySans;
+ font-size : 1.2em;
+ &>span{
+ margin-right : 12px;
+ line-height : 1.5em;
+ }
+ }
+ &:hover{
+ .links{
+ opacity : 1;
+ }
+ }
+ &:nth-child(2n + 1){
+ margin-right : 0px;
+ }
+ .links{
+ .animate(opacity);
+ position : absolute;
+ top : 0px;
+ right : 0px;
+ height : 100%;
+ width : 2em;
+ opacity : 0;
+ background-color : fade(black, 60%);
+ text-align : center;
+ a{
+ .animate(opacity);
+ display : block;
+ margin : 8px 0px;
+ opacity : 0.6;
+ font-size : 1.3em;
+ color : white;
+ &:hover{
+ opacity : 1;
+ }
+ i{
+ cursor : pointer;
+ }
+ }
+ }
+ .googleDriveIcon {
+ height : 20px;
+ padding : 0px;
+ margin : -5px;
+ }
+}
diff --git a/client/homebrew/pages/basePages/listPage/listPage.jsx b/client/homebrew/pages/basePages/listPage/listPage.jsx
new file mode 100644
index 000000000..e4beb4a94
--- /dev/null
+++ b/client/homebrew/pages/basePages/listPage/listPage.jsx
@@ -0,0 +1,189 @@
+require('./listPage.less');
+const React = require('react');
+const createClass = require('create-react-class');
+const _ = require('lodash');
+const cx = require('classnames');
+
+const moment = require('moment');
+
+const Nav = require('naturalcrit/nav/nav.jsx');
+const Navbar = require('../../../navbar/navbar.jsx');
+
+const RecentNavItem = require('../../../navbar/recent.navitem.jsx').both;
+const Account = require('../../../navbar/account.navitem.jsx');
+const NewBrew = require('../../../navbar/newbrew.navitem.jsx');
+const BrewItem = require('./brewItem/brewItem.jsx');
+const ReportIssue = require('../../../navbar/issue.navitem.jsx');
+
+// const brew = {
+// title : 'SUPER Long title woah now',
+// authors : []
+// };
+
+//const BREWS = _.times(25, ()=>{ return brew;});
+
+
+const ListPage = createClass({
+ getDefaultProps : function() {
+ return {
+ brewCollection : [
+ {
+ title : '',
+ class : '',
+ brews : []
+ }
+ ]
+ };
+ },
+ getInitialState : function() {
+ return {
+ sortType : 'alpha',
+ sortDir : 'asc',
+ filterString : ''
+ };
+ },
+
+ renderBrews : function(brews){
+ if(!brews || !brews.length) return No Brews.
;
+
+ const sortedBrews = this.sortBrews(brews);
+
+ return _.map(sortedBrews, (brew, idx)=>{
+ return ;
+ });
+ },
+
+ sortBrewOrder : function(brew){
+ if(!brew.title){brew.title = 'No Title';}
+ const mapping = {
+ 'alpha' : _.deburr(brew.title.toLowerCase()),
+ 'created' : moment(brew.createdAt).format(),
+ 'updated' : moment(brew.updatedAt).format(),
+ 'views' : brew.views,
+ 'latest' : moment(brew.lastViewed).format()
+ };
+ return mapping[this.state.sortType];
+ },
+
+ sortBrews : function(brews){
+ return _.orderBy(brews, (brew)=>{ return this.sortBrewOrder(brew); }, this.state.sortDir);
+ },
+
+ handleSortOptionChange : function(event){
+ this.setState({
+ sortType : event.target.value
+ });
+ },
+
+ handleSortDirChange : function(event){
+ this.setState({
+ sortDir : `${(this.state.sortDir == 'asc' ? 'desc' : 'asc')}`
+ });
+ },
+
+ renderSortOption : function(sortTitle, sortValue){
+ return
+
+ | ;
+ },
+
+ handleFilterTextChange : function(e){
+ this.setState({
+ filterString : e.target.value
+ });
+ return;
+ },
+
+ renderFilterOption : function(){
+ return
+
+ | ;
+ },
+
+ renderSortOptions : function(){
+ return
+
+
+
+
+ Sort by :
+ |
+ {this.renderSortOption('Title', 'alpha')}
+ {this.renderSortOption('Created Date', 'created')}
+ {this.renderSortOption('Updated Date', 'updated')}
+ {this.renderSortOption('Views', 'views')}
+ {/* {this.renderSortOption('Latest', 'latest')} */}
+
+ Direction :
+ |
+
+
+ |
+ {this.renderFilterOption()}
+
+
+
+
;
+ },
+
+ getSortedBrews : function(brewCollection){
+ const testString = _.deburr(this.state.filterString).toLowerCase();
+ const brews = this.state.filterString ? _.filter(brewCollection.brews, (brew)=>{
+ return (_.deburr(brew.title).toLowerCase().includes(testString)) ||
+ (_.deburr(brew.description).toLowerCase().includes(testString));
+ }) : this.props.brewCollection.brews;
+ return _.groupBy(brews, (brew)=>{
+ return (brew.published ? 'published' : 'private');
+ });
+ },
+
+ renderBrewCollection : function(brewCollection){
+ return _.map(brewCollection, (brewItem, idx)=>{
+ return
+
{brewItem.title || 'No Title'}
+ {this.renderBrews(brewItem.brews)}
+ ;
+ });
+ },
+
+ render : function(){
+ return
+
+
+
+
+
+
+
+
+
+
+
+
+ {this.renderSortOptions()}
+ {this.renderBrewCollection(this.props.brewCollection)}
+
+
+
;
+ }
+});
+
+module.exports = ListPage;
diff --git a/client/homebrew/pages/basePages/listPage/listPage.less b/client/homebrew/pages/basePages/listPage/listPage.less
new file mode 100644
index 000000000..6be946404
--- /dev/null
+++ b/client/homebrew/pages/basePages/listPage/listPage.less
@@ -0,0 +1,77 @@
+
+.noColumns(){
+ column-count : auto;
+ column-fill : auto;
+ column-gap : auto;
+ column-width : auto;
+ -webkit-column-count : auto;
+ -moz-column-count : auto;
+ -webkit-column-width : auto;
+ -moz-column-width : auto;
+ -webkit-column-gap : auto;
+ -moz-column-gap : auto;
+}
+.listPage{
+ .content{
+ overflow-y : scroll;
+ .phb{
+ .noColumns();
+ height : auto;
+ min-height : 279.4mm;
+ margin : 20px auto;
+ &::after{
+ display : none;
+ }
+ .noBrews{
+ margin : 10px 0px;
+ font-size : 1.3em;
+ font-style : italic;
+ }
+
+ }
+ }
+ .sort-container{
+ font-family : 'Open Sans', sans-serif;
+ position : fixed;
+ top : 35px;
+ left : calc(50vw - 408px);
+ border : 2px solid #58180D;
+ width : 800px;
+ background-color : #EEE5CE;
+ padding : 2px;
+ text-align : center;
+ z-index : 15;
+ h6{
+ text-transform : uppercase;
+ font-family : 'Open Sans', sans-serif;
+ font-size : 11px;
+ font-weight : bold;
+ color : #58180D;
+ }
+ table{
+ margin : 0px;
+ vertical-align : middle;
+ tbody tr{
+ background-color: transparent !important;
+ i{
+ padding-right : 5px
+ }
+ button{
+ background-color : transparent;
+ color : #58180D;
+ font-family : 'Open Sans', sans-serif;
+ font-size : 11px;
+ text-transform : uppercase;
+ font-weight : normal;
+ &.active{
+ font-weight : bold;
+ border : 2px solid #58180D;
+ }
+ &.sortDir{
+ width : 75px;
+ }
+ }
+ }
+ }
+ }
+}