diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx
index f2f2667a4..c24f7f176 100644
--- a/client/admin/admin.jsx
+++ b/client/admin/admin.jsx
@@ -4,8 +4,9 @@ const createClass = require('create-react-class');
const BrewUtils = require('./brewUtils/brewUtils.jsx');
const NotificationUtils = require('./notificationUtils/notificationUtils.jsx');
+import AuthorUtils from './authorUtils/authorUtils.jsx';
-const tabGroups = ['brew', 'notifications'];
+const tabGroups = ['brew', 'notifications', 'authors'];
const Admin = createClass({
getDefaultProps : function() {
@@ -39,6 +40,7 @@ const Admin = createClass({
{this.state.currentTab==='brew' && }
{this.state.currentTab==='notifications' && }
+ {this.state.currentTab==='authors' && }
;
}
diff --git a/client/admin/authorUtils/authorLookup/authorLookup.jsx b/client/admin/authorUtils/authorLookup/authorLookup.jsx
new file mode 100644
index 000000000..50226d93d
--- /dev/null
+++ b/client/admin/authorUtils/authorLookup/authorLookup.jsx
@@ -0,0 +1,90 @@
+import './authorLookup.less';
+
+import React from 'react';
+import request from 'superagent';
+
+const authorLookup = ()=>{
+ const [author, setAuthor] = React.useState('');
+ const [searching, setSearching] = React.useState(false);
+ const [results, setResults] = React.useState([]);
+
+ const lookup = async ()=>{
+ if(!author) return;
+
+ setSearching(true);
+ setResults([]);
+
+ await request.get(`/admin/user/list/${author}`)
+ .then((brews)=>{
+ setResults(brews.body);
+ setSearching(false);
+ });
+ };
+
+ const renderResults = ()=>{
+ if(results.length == 0) return <>
+
Results
+ None found.
+ >;
+
+ return <>
+ {`Results - ${results.length}`}
+
+
+
+ | Title |
+ Share |
+ Edit |
+ Last Update |
+ Storage |
+
+
+
+ {results
+ .sort((a, b)=>{ // Sort brews from most recently updated
+ if(a.updatedAt > b.updatedAt) return -1;
+ if(a.updatedAt < b.updatedAt) return 1;
+ return 0;
+ })
+ .map((brew, idx)=>{
+ return
+ | {brew.title} |
+ {brew.shareId} |
+ {brew.editId} |
+ {brew.updatedAt} |
+ {brew.googleId ? 'Google' : 'Homebrewery'} |
+
;
+ })}
+
+
+ >;
+ };
+
+ const handleKeyPress = (evt)=>{
+ if(evt.key === 'Enter') return lookup();
+ };
+
+ const handleChange = (evt)=>{
+ setAuthor(evt.target.value);
+ };
+
+ return (
+
+
+
Author Lookup
+
+
+
+ {renderResults()}
+
+
+ );
+};
+
+module.exports = authorLookup;
diff --git a/client/admin/authorUtils/authorLookup/authorLookup.less b/client/admin/authorUtils/authorLookup/authorLookup.less
new file mode 100644
index 000000000..7f6903aa5
--- /dev/null
+++ b/client/admin/authorUtils/authorLookup/authorLookup.less
@@ -0,0 +1,48 @@
+.authorLookup {
+ position : relative;
+ display : flex;
+ flex-direction : column;
+
+ .field {
+ display : flex;
+ gap : 5px;
+ align-items : center;
+ justify-items : stretch;
+ width : 100%;
+ margin-bottom : 20px;
+
+
+ input {
+ height : 33px;
+ padding : 0px 10px;
+ margin-bottom : unset;
+ font-family : monospace;
+ }
+
+ button {
+ width: 50px;
+
+ i { margin-right : 10px; }
+ }
+ }
+
+ table.resultsTable {
+ * {
+ border: 1px solid black;
+ vertical-align: middle;
+ padding: 5px;
+ }
+
+ th {
+ font-weight: bold;
+ }
+
+ th, td {
+ text-align: center;
+
+ &:first-of-type {
+ text-align: left;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/client/admin/authorUtils/authorUtils.jsx b/client/admin/authorUtils/authorUtils.jsx
new file mode 100644
index 000000000..a96eea528
--- /dev/null
+++ b/client/admin/authorUtils/authorUtils.jsx
@@ -0,0 +1,13 @@
+import React from 'react';
+
+import AuthorLookup from './authorLookup/authorLookup.jsx';
+
+const authorUtils = ()=>{
+ return (
+
+ );
+};
+
+module.exports = authorUtils;
\ No newline at end of file