more fixes to ajaxify, updated /users blocks to sit flush to the left, started work on the ACP including basic templates, added a method to get active users in all rooms (socket connections), added more routes mostly pointing to admin, added a routing folder to start organizing routes better, starting with admin.
parent
8e1ee88878
commit
f3f08a9c94
@ -0,0 +1,75 @@
|
||||
|
||||
<h1>Categories</h1>
|
||||
|
||||
<hr />
|
||||
<ul class="nav nav-pills">
|
||||
<li class='active'><a href='/admin/categories/active'>Active</a></li>
|
||||
<li class=''><a href='/admin/categories/disabled'>Disabled</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<div class="row-fluid admin-categories">
|
||||
<ul class="span12" id="entry-container">
|
||||
<!-- BEGIN categories -->
|
||||
<li class="entry-row {categories.blockclass}">
|
||||
<form class="form-inline">
|
||||
<div class="icon">
|
||||
<i class="{categories.icon} icon-2x"></i>
|
||||
</div>
|
||||
<input value="{categories.name}" class="input-medium"></input>
|
||||
<select class="blockclass input-medium" data-value="{categories.blockclass}" onchange="update_blockclass(this);">
|
||||
<option value="category-purple">category-purple</option>
|
||||
<option value="category-darkblue">category-darkblue</option>
|
||||
<option value="category-blue">category-blue</option>
|
||||
<option value="category-darkgreen">category-darkgreen</option>
|
||||
<option value="category-orange">category-orange</option>
|
||||
</select>
|
||||
<input value="{categories.icon}" class="input-medium" onchange="update_icon(this);"></input>
|
||||
<!--<input value="{categories.description}" class="input-medium"></input>-->
|
||||
<!--<a target="_blank" href="../category/{categories.slug}">category/{categories.slug}</a>-->
|
||||
|
||||
<!--<div style="float: right">
|
||||
<button class="btn btn-large btn-inverse">Save</button>
|
||||
</div>-->
|
||||
</form>
|
||||
</li>
|
||||
|
||||
<!-- END categories -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function update_blockclass(el) {
|
||||
el.parentNode.parentNode.className = 'entry-row ' + el.value;
|
||||
}
|
||||
function update_icon(el) {
|
||||
jQuery(el.parentNode.parentNode);
|
||||
}
|
||||
|
||||
jQuery('#entry-container').sortable();
|
||||
jQuery('.blockclass').each(function() {
|
||||
jQuery(this).val(this.getAttribute('data-value'));
|
||||
});
|
||||
|
||||
|
||||
//DRY Failure. this needs to go into an ajaxify onready style fn. Currently is copy pasted into every single function so after ACP is off the ground fix asap
|
||||
(function() {
|
||||
jQuery('document').ready(function() {
|
||||
var url = window.location.href,
|
||||
parts = url.split('/'),
|
||||
active = parts[parts.length-1];
|
||||
|
||||
jQuery('.nav-pills li').removeClass('active');
|
||||
jQuery('.nav-pills li a').each(function() {
|
||||
if (this.getAttribute('href').match(active)) {
|
||||
jQuery(this.parentNode).addClass('active');
|
||||
return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
}());
|
||||
</script>
|
@ -0,0 +1,13 @@
|
||||
<h1>Facebook Social Authentication</h1>
|
||||
<hr />
|
||||
|
||||
<form>
|
||||
<div class="alert alert-notify">
|
||||
<p>Create a <strong>Facebook Application</strong> and then paste your application details here.</p><br />
|
||||
<input type="text" class="" placeholder="App Key"><br />
|
||||
<input type="text" class="" placeholder="App Secret"><br />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<button class="btn btn-large btn-primary" type="submit">Save</button>
|
||||
<button class="btn btn-large" type="submit" disabled>Delete</button>
|
@ -0,0 +1,31 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" class="container" style="padding-top: 50px; display:none;">
|
||||
<footer class="footer">Copyright © 2013 <a target="_blank" href="http://www.nodebb.com">NodeBB</a> by <a target="_blank" href="https://github.com/psychobunny">psychobunny</a>, <a href="https://github.com/julianlam" target="_blank">julianlam</a>, <a href="https://github.com/barisusakli" target="_blank">barisusakli</a> from <a target="_blank" href="http://www.designcreateplay.com">designcreateplay</a></footer>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
jQuery('document').ready(function() {
|
||||
// On menu click, change "active" state
|
||||
var menuEl = document.querySelector('.sidebar-nav'),
|
||||
liEls = menuEl.querySelectorAll('li')
|
||||
parentEl = null;
|
||||
|
||||
menuEl.addEventListener('click', function(e) {
|
||||
parentEl = e.target.parentNode;
|
||||
if (parentEl.nodeName === 'LI') {
|
||||
for(var x=0,numLis=liEls.length;x<numLis;x++) {
|
||||
if (liEls[x] !== parentEl) jQuery(liEls[x]).removeClass('active');
|
||||
else jQuery(parentEl).addClass('active');
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
|
||||
}())
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<h1>Google Plus Social Authentication</h1>
|
||||
<hr />
|
||||
|
||||
<form>
|
||||
<div class="alert alert-notify">
|
||||
<p>Create a <strong>Google+ Application</strong> and then paste your application details here.</p><br />
|
||||
<input type="text" class="" placeholder="App ID"><br />
|
||||
<input type="text" class="" placeholder="App Secret"><br />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<button class="btn btn-large btn-primary" type="submit">Save</button>
|
||||
<button class="btn btn-large" type="submit" disabled>Delete</button>
|
@ -0,0 +1,106 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
||||
<link href="/vendor/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet" media="screen">
|
||||
<link rel="stylesheet" href="/vendor/fontawesome/css/font-awesome.min.css">
|
||||
<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
|
||||
<script type="text/javascript" src="/vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
||||
<script type="text/javascript" src="/src/app.js"></script>
|
||||
<script type="text/javascript" src="/src/templates.js"></script>
|
||||
<script type="text/javascript" src="/src/ajaxify.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
|
||||
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/css/style.css" />
|
||||
<style type="text/css">
|
||||
.entry-row {
|
||||
border-radius: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
cursor: move;
|
||||
width: 555px;
|
||||
}
|
||||
.admin-categories form {
|
||||
margin: 0 0 0px;
|
||||
}
|
||||
|
||||
.admin-categories input {
|
||||
height: 20px;
|
||||
padding: 5px;
|
||||
margin-left: 10px;
|
||||
width: 150px;
|
||||
border: 0;
|
||||
border-radius: 5px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.admin-categories select {
|
||||
border: 0;
|
||||
margin-left: 10px;
|
||||
padding: 5px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.admin-categories button {
|
||||
margin-top: -7px;
|
||||
}
|
||||
.admin-categories .icon{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 35px;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="brand" href="/admin/index">NodeBB ACP</a>
|
||||
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li>
|
||||
<a href="/admin/index"><i class="icon-home"></i> Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/settings"><i class="icon-cogs"></i> Settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav pull-right" id="right-menu">
|
||||
<li><a href="/users" id="user_label"></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">NodeBB</li>
|
||||
<li class='active'><a href='/admin/index'><i class='icon-home'></i> Home</a></li>
|
||||
<li class=''><a href='/admin/categories'><i class='icon-folder-close-alt'></i> Categories</a></li>
|
||||
<li class=''><a href='/admin/users'><i class='icon-user'></i> Users</a></li>
|
||||
<li class=''><a href='/admin/topics'><i class='icon-book'></i> Topics</a></li>
|
||||
<li class=''><a href='/admin/themes'><i class='icon-th'></i> Themes</a></li>
|
||||
<li class=''><a href='/admin/settings'><i class='icon-cogs'></i> Settings</a></li>
|
||||
<li class="nav-header">Social Authentication</li>
|
||||
<li class=''><a href='/admin/twitter'><i class='icon-twitter'></i>Twitter</a></li>
|
||||
<li class=''><a href='/admin/facebook'><i class='icon-facebook'></i>Facebook</a></li>
|
||||
<li class=''><a href='/admin/gplus'><i class='icon-google-plus'></i>Google+</a></li>
|
||||
<li class="nav-header">Custom Modules</li>
|
||||
<li class=''><a href=''>Search</a></li>
|
||||
</ul>
|
||||
</div><!--/.well -->
|
||||
</div><!--/span-->
|
||||
<div class="span9" id="content">
|
@ -0,0 +1,42 @@
|
||||
|
||||
<div class="hero-unit">
|
||||
<h1>Welcome to NodeBB</h1>
|
||||
<br />
|
||||
<p>
|
||||
<a target="_blank" href="http://www.nodebb.org" class="btn btn-large"><i class="icon-comment"></i> NodeBB Forum</a>
|
||||
<a target="_blank" href="http://www.nodebb.org" class="btn btn-large"><i class="icon-github-alt"></i> Get Plugins</a>
|
||||
<a target="_blank" href="http://www.nodebb.org" class="btn btn-large"><i class="icon-github-alt"></i> Get Themes</a>
|
||||
<a target="_blank" href="http://www.nodebb.org" class="btn btn-large"><i class="icon-twitter"></i> dcplabs</a>
|
||||
</p>
|
||||
<p><small>You are running <strong>NodeBB v0.0.1</strong>. This is where we will check to make sure your <strong>NodeBB</strong> is latest, etc.</small></p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="">
|
||||
<h2>Active Users <small><span class="badge" id="connections"></span> socket connections</small></h2>
|
||||
<p id="active_users">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
ajaxify.register_events(['api:get_all_rooms']);
|
||||
socket.on('api:get_all_rooms', function(data) {
|
||||
var active_users = document.getElementById('active_users'),
|
||||
total = 0;
|
||||
|
||||
for(var room in data) {
|
||||
if (room !== '') {
|
||||
var count = data[room].length;
|
||||
total += count;
|
||||
active_users.innerHTML = active_users.innerHTML + "<div class='alert alert-success'><strong>" + room + "</strong> " + count + " active user" + (count > 1 ? "s" : "") + "</div><br />";
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('connections').innerHTML = total;
|
||||
});
|
||||
|
||||
socket.emit('api:get_all_rooms');
|
||||
</script>
|
@ -0,0 +1,24 @@
|
||||
<h1>Settings</h1>
|
||||
<hr />
|
||||
|
||||
<form>
|
||||
<h3>Privilege Thresholds</h3>
|
||||
<div class="alert alert-notify">
|
||||
<p>Use <strong>privilege thresholds</strong> to manage how much reputation a user must gain to receive moderator access.</p><br />
|
||||
<strong>Manage Thread</strong><br /> <input type="text" class="" value="1000"><br />
|
||||
<strong>Moderate Users</strong><br /> <input type="text" class="" value="10000"><br />
|
||||
<strong>Create Pinned Topics</strong><br /> <input type="text" class="" value="100000"><br />
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form>
|
||||
<h3>Email Settings</h3>
|
||||
<div class="alert alert-notify">
|
||||
<strong>Email Address</strong><br /> <input type="text" class="" value="info@localhost"><br />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<button class="btn btn-large btn-primary" type="submit">Save</button>
|
||||
<button class="btn btn-large" type="submit" disabled>Delete</button>
|
@ -0,0 +1,2 @@
|
||||
<h1>Themes</h1>
|
||||
<hr />
|
@ -0,0 +1,55 @@
|
||||
<h1>Topics</h1>
|
||||
<hr />
|
||||
|
||||
<ul class="nav nav-pills">
|
||||
<li class='active'><a href='/admin/topics'>All</a></li>
|
||||
<li class=''><a href='/admin/topics/latest'>Latest</a></li>
|
||||
<li class=''><a href='/admin/topics/active'>Active</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="topic-container">
|
||||
<!-- BEGIN topics -->
|
||||
<a href="../../topic/{topics.slug}"><li class="topic-row">
|
||||
<div class="row" style="margin: 0">
|
||||
<div class="span1 topic-row-icon">
|
||||
<i class="icon-lock icon-4x"></i>
|
||||
<i class="{topics.pin-icon}"></i><i class="{topics.lock-icon}"></i>
|
||||
</div>
|
||||
<div class="span11 topic-row-content">
|
||||
<div class="top-posters">
|
||||
<img src="http://www.gravatar.com/avatar/fd37ce111f863c6665045c2d72d199bf?s=60" class="img-polaroid" />
|
||||
<img src="http://www.gravatar.com/avatar/07c9c7170c3ac676c2561e3eeaee063c?s=60" class="img-polaroid" />
|
||||
<img src="http://www.gravatar.com/avatar/91050ce0072697b53380c6a03a1bc12a?s=60" class="img-polaroid" />
|
||||
</div>
|
||||
<div>
|
||||
<h3><span class="badge badge-important">3</span> {topics.title} <small>24<i class="icon-star"></i></small></h3>
|
||||
<p> Posted {topics.relativeTime} ago by
|
||||
<span class="username">{topics.username}</span>. {topics.post_count} posts.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li></a>
|
||||
<!-- END topics -->
|
||||
</ul>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
//DRY Failure. this needs to go into an ajaxify onready style fn. Currently is copy pasted into every single function so after ACP is off the ground fix asap
|
||||
(function() {
|
||||
jQuery('document').ready(function() {
|
||||
var url = window.location.href,
|
||||
parts = url.split('/'),
|
||||
active = parts[parts.length-1];
|
||||
|
||||
jQuery('.nav-pills li').removeClass('active');
|
||||
jQuery('.nav-pills li a').each(function() {
|
||||
if (this.getAttribute('href').match(active)) {
|
||||
jQuery(this.parentNode).addClass('active');
|
||||
return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
}());
|
||||
</script>
|
@ -0,0 +1,14 @@
|
||||
<h1>Twitter Social Authentication</h1>
|
||||
<hr />
|
||||
|
||||
<form>
|
||||
<div class="alert alert-notify">
|
||||
<p>Create a <strong>Twitter Application</strong> and then paste your application details here.</p><br />
|
||||
<input type="text" class="" placeholder="App Key"><br />
|
||||
<input type="text" class="" placeholder="App Secret"><br />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<button class="btn btn-large btn-primary" type="submit">Save</button>
|
||||
<button class="btn btn-large" type="submit" disabled>Delete</button>
|
@ -0,0 +1,55 @@
|
||||
<h1>Users</h1>
|
||||
<hr />
|
||||
<ul class="nav nav-pills">
|
||||
<li class='active'><a href='/admin/users'>Latest Users</a></li>
|
||||
<li class=''><a href='/admin/users/sort-posts'>Top Posters</a></li>
|
||||
<li class=''><a href='/admin/users/sort-reputation'>Most Reputation</a></li>
|
||||
<li class=''><a href='/admin/users/search'>Search</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="search {search_display} well">
|
||||
<input type="text" placeholder="Enter a username to search" onkeypress="jQuery('.icon-spinner').removeClass('none');" /><br />
|
||||
<i class="icon-spinner icon-spin none"></i>
|
||||
</div>
|
||||
|
||||
<!-- BEGIN users -->
|
||||
<div class="users-box well">
|
||||
<a href="/users/{users.username}">
|
||||
<img src="{users.picture}"/>
|
||||
</a>
|
||||
<br/>
|
||||
<a href="/users/{users.username}">{users.username}</a>
|
||||
<br/>
|
||||
<div title="reputation">
|
||||
<span id='reputation'>{users.reputation}</span>
|
||||
<i class='icon-star'></i>
|
||||
</div>
|
||||
<div title="post count">
|
||||
<span id='postcount'>{users.postcount}</span>
|
||||
<i class='icon-pencil'></i>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- END users -->
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
//DRY Failure. this needs to go into an ajaxify onready style fn. Currently is copy pasted into every single function so after ACP is off the ground fix asap
|
||||
(function() {
|
||||
jQuery('document').ready(function() {
|
||||
var url = window.location.href,
|
||||
parts = url.split('/'),
|
||||
active = parts[parts.length-1];
|
||||
|
||||
jQuery('.nav-pills li').removeClass('active');
|
||||
jQuery('.nav-pills li a').each(function() {
|
||||
if (this.getAttribute('href').match(active)) {
|
||||
jQuery(this.parentNode).addClass('active');
|
||||
return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
}());
|
||||
</script>
|
@ -0,0 +1,62 @@
|
||||
|
||||
(function(Admin) {
|
||||
Admin.create_routes = function(app) {
|
||||
|
||||
(function() {
|
||||
var routes = ['categories', 'users', 'topics', 'settings', 'themes', 'twitter', 'facebook', 'gplus'];
|
||||
|
||||
for (var i=0, ii=routes.length; i<ii; i++) {
|
||||
(function(route) {
|
||||
app.get('/admin/' + route, function(req, res) {
|
||||
res.send(templates['admin/header'] + app.create_route('admin/' + route) + templates['admin/footer']);
|
||||
});
|
||||
}(routes[i]));
|
||||
}
|
||||
}());
|
||||
|
||||
//todo consolidate.
|
||||
app.get('/admin', function(req, res) {
|
||||
res.send(templates['admin/header'] + app.create_route('admin/index') + templates['admin/footer']);
|
||||
});
|
||||
app.get('/admin/index', function(req, res) {
|
||||
res.send(templates['admin/header'] + app.create_route('admin/index') + templates['admin/footer']);
|
||||
});
|
||||
|
||||
|
||||
function api_method(req, res) {
|
||||
switch(req.params.method) {
|
||||
case 'users' :
|
||||
if (req.params.tab == 'search') {
|
||||
res.send(JSON.stringify({search_display: 'block', users: []}))
|
||||
} else {
|
||||
global.modules.user.getUserList(function(data){
|
||||
res.send(JSON.stringify({search_display: 'none', users:data}));
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'categories':
|
||||
if (req.params.tab == 'disabled') {
|
||||
res.send(JSON.stringify({categories: []}));
|
||||
} else {
|
||||
global.modules.categories.get(function(data) {
|
||||
res.send(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'topics' :
|
||||
global.modules.topics.get(function(data) {
|
||||
res.send(JSON.stringify(data));
|
||||
});
|
||||
break;
|
||||
default :
|
||||
res.send('{}');
|
||||
}
|
||||
}
|
||||
|
||||
app.get('/api/admin/:method/:tab?*', api_method);
|
||||
app.get('/api/admin/:method*', api_method);
|
||||
};
|
||||
|
||||
|
||||
}(exports));
|
Loading…
Reference in New Issue