diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx
index 295fa9bf6..fb5f9ade7 100644
--- a/client/admin/admin.jsx
+++ b/client/admin/admin.jsx
@@ -1,38 +1,35 @@
const React = require('react');
const createClass = require('create-react-class');
-const _ = require('lodash');
-const cx = require('classnames');
-const HomebrewAdmin = require('./homebrewAdmin/homebrewAdmin.jsx');
+
+const BrewCleanup = require('./brewCleanup/brewCleanup.jsx');
+const BrewLookup = require('./brewLookup/brewLookup.jsx');
+const Stats = require('./stats/stats.jsx');
const Admin = createClass({
getDefaultProps : function() {
return {
- url : '',
- admin_key : '',
- homebrews : [],
+ adminKey : ''
};
},
render : function(){
- return (
-
-
-
-
-
- naturalcrit admin
-
-
+ return
}
});
diff --git a/client/admin/admin.less b/client/admin/admin.less
index c13063a01..84ffc9838 100644
--- a/client/admin/admin.less
+++ b/client/admin/admin.less
@@ -36,4 +36,60 @@ body{
}
}
-}
\ No newline at end of file
+
+
+}
+
+/*.homebrewAdmin{
+ margin-bottom: 80px;
+ .brewTable{
+ table{
+
+ th{
+ padding : 10px;
+ font-weight : 800;
+ }
+ tr:nth-child(even){
+ background-color : fade(@green, 10%);
+ }
+ tr.isEmpty{
+ background-color : fade(@red, 30%);
+ }
+ td{
+ min-width : 100px;
+ padding : 10px;
+ text-align : center;
+
+ &.preview{
+ position : relative;
+ &:hover{
+ .content{
+ display : block;
+ }
+ }
+ .content{
+ position : absolute;
+ display : none;
+ top : 100%;
+ left : 0px;
+ z-index : 1000;
+ max-height : 500px;
+ width : 300px;
+ padding : 30px;
+ background-color : white;
+ font-family : monospace;
+ text-align : left;
+ pointer-events : none;
+ }
+ }
+ }
+ }
+ }
+ .deleteButton{
+ cursor: pointer;
+ }
+ button.clearOldButton{
+ float : right;
+ }
+}
+*/
\ No newline at end of file
diff --git a/client/admin/brewCleanup/brewCleanup.jsx b/client/admin/brewCleanup/brewCleanup.jsx
new file mode 100644
index 000000000..b70fbdb1f
--- /dev/null
+++ b/client/admin/brewCleanup/brewCleanup.jsx
@@ -0,0 +1,19 @@
+const React = require('react');
+const createClass = require('create-react-class');
+const cx = require('classnames');
+
+
+const BrewCleanup = createClass({
+ displayName : 'BrewCleanup',
+ getDefaultProps(){
+ return {
+ };
+ },
+ render(){
+ return
+ BrewCleanup Component Ready.
+
;
+ }
+});
+
+module.exports = BrewCleanup;
\ No newline at end of file
diff --git a/client/admin/brewCleanup/brewCleanup.less b/client/admin/brewCleanup/brewCleanup.less
new file mode 100644
index 000000000..d3313d4c0
--- /dev/null
+++ b/client/admin/brewCleanup/brewCleanup.less
@@ -0,0 +1,3 @@
+.BrewCleanup{
+
+}
\ No newline at end of file
diff --git a/client/admin/brewLookup/brewLookup.jsx b/client/admin/brewLookup/brewLookup.jsx
new file mode 100644
index 000000000..80016b50a
--- /dev/null
+++ b/client/admin/brewLookup/brewLookup.jsx
@@ -0,0 +1,86 @@
+const React = require('react');
+const createClass = require('create-react-class');
+const _ = require('lodash');
+const cx = require('classnames');
+
+const request = require('superagent');
+const Moment = require('moment');
+
+
+const BrewLookup = createClass({
+ getDefaultProps() {
+ return {
+ adminKey : '',
+ };
+ },
+ getInitialState() {
+ return {
+ query : '',
+ foundBrew : null,
+ searching : false,
+ error : null
+ };
+ },
+
+ handleChange(e){
+ this.setState({ query : e.target.value });
+ },
+ lookup(){
+ this.setState({ searching: true, error: null });
+
+ request.get(`/admin/lookup/${this.state.query}`)
+ .query({ admin_key: this.props.adminKey })
+ .then((res)=> this.setState({foundBrew : res.body}))
+ .catch((err)=>this.setState({ error : err }))
+ .finally(()=>this.setState({ searching : false }))
+ },
+
+ renderFoundBrew(){
+ const brew = this.state.foundBrew;
+ return
+
+ - Title
+ - {brew.title}
+
+ - Authors
+ - {brew.authors.join(', ')}
+
+ - Edit Link
+ - /edit/{brew.editId}
+
+ - Share Link
+ - /share/{brew.shareId}
+
+ - Last Updated
+ - {Moment(brew.updatedAt).fromNow()}
+
+ - Num of Views
+ - {brew.views}
+
+
;
+ },
+
+ render(){
+ return
+
Brew Lookup
+
+
+
+ {this.state.error
+ &&
{this.state.error}
+ }
+
+ {this.state.foundBrew
+ ? this.renderFoundBrew()
+ :
No brew found.
+ }
+
;
+ }
+});
+
+module.exports = BrewLookup;
diff --git a/client/admin/brewLookup/brewLookup.less b/client/admin/brewLookup/brewLookup.less
new file mode 100644
index 000000000..61eeec424
--- /dev/null
+++ b/client/admin/brewLookup/brewLookup.less
@@ -0,0 +1,30 @@
+
+.brewLookup{
+ input{
+ height : 33px;
+ margin-bottom : 20px;
+ padding : 0px 10px;
+ font-family : monospace;
+ }
+ button{
+ vertical-align : middle;
+ height : 37px;
+ }
+ dl{
+ @maxItemWidth : 132px;
+ dt{
+ float : left;
+ clear : left;
+ width : @maxItemWidth;
+ text-align : right;
+ &::after {
+ content: " : ";
+ }
+ }
+ dd{
+ height : 1em;
+ margin-left : @maxItemWidth + 6px;
+ padding : 0 0 0.5em 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/client/admin/homebrewAdmin/brewLookup/brewLookup.jsx b/client/admin/homebrewAdmin/brewLookup/brewLookup.jsx
deleted file mode 100644
index 15f01286d..000000000
--- a/client/admin/homebrewAdmin/brewLookup/brewLookup.jsx
+++ /dev/null
@@ -1,68 +0,0 @@
-const React = require('react');
-const createClass = require('create-react-class');
-const _ = require('lodash');
-const cx = require('classnames');
-
-const request = require('superagent');
-const Moment = require('moment');
-
-
-const BrewLookup = createClass({
- getDefaultProps : function() {
- return {
- adminKey : '',
- };
- },
- getInitialState : function() {
- return {
- query : '',
- resultBrew : null,
- searching : false
- };
- },
-
- handleChange : function(e){
- this.setState({
- query : e.target.value
- });
- },
- lookup : function(){
- this.setState({ searching: true });
-
- request.get(`/admin/lookup/${this.state.query}`)
- .query({ admin_key: this.props.adminKey })
- .end((err, res)=>{
- this.setState({
- searching : false,
- resultBrew : (err ? null : res.body)
- });
- });
- },
-
- renderFoundBrew : function(){
- if(this.state.searching) return
;
- if(!this.state.resultBrew) return
No brew found.
;
-
- const brew = this.state.resultBrew;
- return
-
{brew.title}
-
{brew.authors.join(', ')}
-
-
-
{Moment(brew.updatedAt).fromNow()}
-
{brew.views}
-
;
- },
-
- render : function(){
- return
-
Brew Lookup
-
-
-
- {this.renderFoundBrew()}
- ;
- }
-});
-
-module.exports = BrewLookup;
diff --git a/client/admin/homebrewAdmin/brewLookup/brewLookup.less b/client/admin/homebrewAdmin/brewLookup/brewLookup.less
deleted file mode 100644
index 071028c20..000000000
--- a/client/admin/homebrewAdmin/brewLookup/brewLookup.less
+++ /dev/null
@@ -1,8 +0,0 @@
-.brewLookup{
- height : 200px;
- input{
- height : 33px;
- padding : 0px 10px;
- margin-bottom: 20px;
- }
-}
\ No newline at end of file
diff --git a/client/admin/homebrewAdmin/brewSearch.jsx b/client/admin/homebrewAdmin/brewSearch.jsx
deleted file mode 100644
index 365f61a05..000000000
--- a/client/admin/homebrewAdmin/brewSearch.jsx
+++ /dev/null
@@ -1,66 +0,0 @@
-const React = require('react');
-const createClass = require('create-react-class');
-const _ = require('lodash');
-const cx = require('classnames');
-
-const request = require('superagent');
-
-const BrewSearch = createClass({
-
- getDefaultProps : function() {
- return {
- admin_key : ''
- };
- },
-
- getInitialState : function() {
- return {
- searchTerm : '',
- brew : null,
- };
- },
-
-
- search : function(){
- request.get(`/homebrew/api/search?id=${this.state.searchTerm}`)
- .query({
- admin_key : this.props.admin_key,
- })
- .end((err, res)=>{
- console.log(err, res, res.body.brews[0]);
- this.setState({
- brew : res.body.brews[0],
- });
- });
- },
-
- handleChange : function(e){
- this.setState({
- searchTerm : e.target.value
- });
- },
- handleSearchClick : function(){
- this.search();
- },
-
- renderBrew : function(){
- if(!this.state.brew) return null;
- return
-
Edit id : {this.state.brew.editId}
-
Share id : {this.state.brew.shareId}
-
;
- },
-
- render : function(){
- return
-
-
-
-
- {this.renderBrew()}
-
;
- },
-
-});
-
-module.exports = BrewSearch;
\ No newline at end of file
diff --git a/client/admin/homebrewAdmin/homebrewAdmin.jsx b/client/admin/homebrewAdmin/homebrewAdmin.jsx
deleted file mode 100644
index 218793141..000000000
--- a/client/admin/homebrewAdmin/homebrewAdmin.jsx
+++ /dev/null
@@ -1,170 +0,0 @@
-const React = require('react');
-const createClass = require('create-react-class');
-const _ = require('lodash');
-const cx = require('classnames');
-const request = require('superagent');
-
-const Moment = require('moment');
-
-
-const BrewLookup = require('./brewLookup/brewLookup.jsx');
-
-
-const HomebrewAdmin = createClass({
- getDefaultProps : function() {
- return {
- admin_key : ''
- };
- },
-
- getInitialState : function() {
- return {
- page : 0,
- count : 20,
- brewCache : {},
- total : 0,
- };
- },
-
-
- fetchBrews : function(page){
- request.get('/api/search')
- .query({
- admin_key : this.props.admin_key,
- count : this.state.count,
- page : page
- })
- .end((err, res)=>{
- if(err || !res.body || !res.body.brews) return;
- const newCache = _.extend({}, this.state.brewCache);
- newCache[page] = res.body.brews;
- this.setState({
- brewCache : newCache,
- total : res.body.total,
- count : res.body.count
- });
- });
- },
-
- componentDidMount : function() {
- this.fetchBrews(this.state.page);
- },
-
- changePageTo : function(page){
- if(!this.state.brewCache[page]){
- this.fetchBrews(page);
- }
- this.setState({
- page : page
- });
- },
-
-
- clearInvalidBrews : function(){
- request.get('/api/invalid')
- .query({ admin_key: this.props.admin_key })
- .end((err, res)=>{
- if(!confirm(`This will remove ${res.body.count} brews. Are you sure?`)) return;
- request.get('/api/invalid')
- .query({ admin_key: this.props.admin_key, do_it: true })
- .end((err, res)=>{
- alert('Done!');
- });
- });
- },
-
-
- deleteBrew : function(brewId){
- if(!confirm(`Are you sure you want to delete '${brewId}'?`)) return;
- request.get(`/api/remove/${brewId}`)
- .query({ admin_key: this.props.admin_key })
- .end(function(err, res){
- window.location.reload();
- });
- },
-
- handlePageChange : function(dir){
- this.changePageTo(this.state.page + dir);
- },
-
-
- renderPagnination : function(){
- let outOf;
- if(this.state.total){
- outOf = `${this.state.page} / ${Math.round(this.state.total/this.state.count)}`;
- }
- return
- this.handlePageChange(-1)}/>
- {outOf}
- this.handlePageChange(1)}/>
-
;
- },
-
-
- renderBrews : function(){
- const brews = this.state.brewCache[this.state.page] || _.times(this.state.count);
- return _.map(brews, (brew)=>{
- return
- | {brew.editId} |
- {brew.shareId} |
- {Moment(brew.createdAt).fromNow()} |
- {Moment(brew.updatedAt).fromNow()} |
- {Moment(brew.lastViewed).fromNow()} |
- {brew.views} |
-
- this.deleteBrew(brew.editId)}>
-
-
- |
-
;
- });
- },
-
- renderBrewTable : function(){
- return
-
-
-
- | Edit Id |
- Share Id |
- Created At |
- Last Updated |
- Last Viewed |
- Views |
-
-
-
- {this.renderBrews()}
-
-
-
;
- },
-
- render : function(){
- return
-
-
-
- {/*
-
- Homebrews - {this.state.total}
-
-
-
-
-
-
- {this.renderPagnination()}
- {this.renderBrewTable()}
-
-
-
-
- */}
- ;
- }
-});
-
-module.exports = HomebrewAdmin;
diff --git a/client/admin/homebrewAdmin/homebrewAdmin.less b/client/admin/homebrewAdmin/homebrewAdmin.less
deleted file mode 100644
index 6cfc3d5a0..000000000
--- a/client/admin/homebrewAdmin/homebrewAdmin.less
+++ /dev/null
@@ -1,53 +0,0 @@
-
-.homebrewAdmin{
- margin-bottom: 80px;
- .brewTable{
- table{
-
- th{
- padding : 10px;
- font-weight : 800;
- }
- tr:nth-child(even){
- background-color : fade(@green, 10%);
- }
- tr.isEmpty{
- background-color : fade(@red, 30%);
- }
- td{
- min-width : 100px;
- padding : 10px;
- text-align : center;
-
- &.preview{
- position : relative;
- &:hover{
- .content{
- display : block;
- }
- }
- .content{
- position : absolute;
- display : none;
- top : 100%;
- left : 0px;
- z-index : 1000;
- max-height : 500px;
- width : 300px;
- padding : 30px;
- background-color : white;
- font-family : monospace;
- text-align : left;
- pointer-events : none;
- }
- }
- }
- }
- }
- .deleteButton{
- cursor: pointer;
- }
- button.clearOldButton{
- float : right;
- }
-}
\ No newline at end of file
diff --git a/client/admin/stats/stats.jsx b/client/admin/stats/stats.jsx
new file mode 100644
index 000000000..cf67bd1d1
--- /dev/null
+++ b/client/admin/stats/stats.jsx
@@ -0,0 +1,48 @@
+const React = require('react');
+const createClass = require('create-react-class');
+const cx = require('classnames');
+
+const request = require('superagent');
+
+
+const Stats = createClass({
+ displayName : 'Stats',
+ getDefaultProps(){
+ return {
+ adminKey : ''
+ };
+ },
+ getInitialState(){
+ return {
+ stats : {
+ totalBrews : 0
+ },
+ fetching : false
+ }
+ },
+ componentDidMount(){
+ this.fetchStats();
+ },
+ fetchStats(){
+ this.setState({ fetching : true})
+ request.get('/admin/stats')
+ .query({ admin_key : this.props.adminKey })
+ .then((res)=> this.setState({ stats : res.body }))
+ .finally(()=>this.setState({fetching : false}));
+ },
+ render(){
+ return
+
Stats
+
+ - Total Brew Count
+ - {this.state.stats.totalBrews}
+
+
+ {this.state.fetching
+ &&
+ }
+
;
+ }
+});
+
+module.exports = Stats;
\ No newline at end of file
diff --git a/client/admin/stats/stats.less b/client/admin/stats/stats.less
new file mode 100644
index 000000000..5337bf671
--- /dev/null
+++ b/client/admin/stats/stats.less
@@ -0,0 +1,28 @@
+
+.Stats{
+ position : relative;
+ .pending{
+ position : absolute;
+ top : 0px;
+ left : 0px;
+ height : 100%;
+ width : 100%;
+ background-color : rgba(238,238,238, 0.5);
+ }
+ dl{
+ @maxItemWidth : 132px;
+ dt{
+ float : left;
+ clear : left;
+ width : @maxItemWidth;
+ text-align : right;
+ &::after {
+ content: " : ";
+ }
+ }
+ dd{
+ margin : 0 0 0 @maxItemWidth + 10px;
+ padding : 0 0 0.5em 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/server/admin.api.js b/server/admin.api.js
index e171f9381..40798f4fa 100644
--- a/server/admin.api.js
+++ b/server/admin.api.js
@@ -17,8 +17,8 @@ process.env.ADMIN_KEY = process.env.ADMIN_KEY || 'admin_key';
-//Removes all empty brews that are older than 3 days and that are shorter than a tweet
-router.get('/api/invalid', mw.adminOnly, (req, res)=>{
+/* Removes all empty brews that are older than 3 days and that are shorter than a tweet */
+router.get('/admin/clear_invalid', mw.adminOnly, (req, res)=>{
const invalidBrewQuery = HomebrewModel.find({
'$where' : 'this.text.length < 140',
createdAt : {
@@ -28,12 +28,12 @@ router.get('/api/invalid', mw.adminOnly, (req, res)=>{
if(req.query.do_it){
invalidBrewQuery.remove().exec((err, objs)=>{
- refreshCount();
+ if(err) return res.status(500).send(err);
return res.send(200);
});
} else {
invalidBrewQuery.exec((err, objs)=>{
- if(err) console.log(err);
+ if(err) return res.status(500).send(err);
return res.json({
count : objs.length
});
@@ -41,10 +41,11 @@ router.get('/api/invalid', mw.adminOnly, (req, res)=>{
}
});
+/* Searches for matching edit or share id, also attempts to partial match */
router.get('/admin/lookup/:id', mw.adminOnly, (req, res, next)=>{
- //search for mathcing edit id
- //search for matching share id
- // search for partial match
+
+ console.log('lookup');
+
HomebrewModel.findOne({ $or : [
{ editId: { '$regex': req.params.id, '$options': 'i' } },
@@ -54,6 +55,17 @@ router.get('/admin/lookup/:id', mw.adminOnly, (req, res, next)=>{
});
});
+router.get('/admin/stats', mw.adminOnly, (req, res)=>{
+ console.log('hittting stats');
+
+ HomebrewModel.count({}, (err, count)=>{
+ return res.json({
+ totalBrews : count
+ })
+ })
+
+});
+
//Admin route
@@ -68,7 +80,7 @@ router.get('/admin', function(req, res){
}
render('admin', templateFn, {
url : req.originalUrl,
- admin_key : process.env.ADMIN_KEY,
+ adminKey : process.env.ADMIN_KEY
})
.then((page)=>{
return res.send(page);