Created skeleton

This commit is contained in:
Chris Blanchard 2015-07-20 10:41:58 +01:00
parent b0287fbb77
commit 397b3042a5
22 changed files with 828 additions and 4 deletions

10
config/config.js Normal file
View file

@ -0,0 +1,10 @@
"use strict";
var env = process.env.NODE_ENV || "development";
var fs = require("fs");
var path = require("path");
var baseConfig = require(path.join(__dirname, path.join("environments/" + env)));
module.exports = baseConfig;

View file

@ -0,0 +1,7 @@
"use strict";
var config = {
port: 8000
};
module.exports = config;

View file

@ -0,0 +1,7 @@
"use strict";
var config = {
port: 8080
};
module.exports = config;

View file

@ -0,0 +1,7 @@
"use strict";
var config = {
port: 9000
};
module.exports = config;

41
config/express.js Normal file
View file

@ -0,0 +1,41 @@
"use strict";
var fs = require("fs");
var path = require("path");
var morgan = require("morgan");
var express = require("express");
var winston = require("winston");
var config = require("./config.js");
var exphbs = require('express-handlebars');
var env = process.env.NODE_ENV || "development";
var pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json")));
module.exports = function (app) {
app.use(express.static(path.join(__dirname, '../public')));
// Use winston on production
var log;
if (env !== 'development') {
log = {
stream: {
write: function (message, encoding) {
winston.info(message);
}
}
};
} else {
log = 'dev';
}
if (env !== 'test') app.use(morgan(log));
var hbs = exphbs({
defaultLayout: 'main',
extname: '.hbs'
});
app.engine('.hbs', hbs);
app.set('view engine', '.hbs');
};

13
config/routes.js Normal file
View file

@ -0,0 +1,13 @@
"use strict";
var config = require("./config.js");
module.exports = function (app) {
app.get("/", function (request, response) {
response.render("index.hbs");
});
app.get("*", function (request, response) {
response.status(404).render("404.hbs");
});
};

13
config/socketio.js Normal file
View file

@ -0,0 +1,13 @@
"use strict";
module.exports = function (io) {
io.on('connection', function (socket) {
socket.emit('welcome', { hello: 'world' });
// socket.on('my other event', function (data) {
// console.log(data);
// });
socket.on('disconnect', function () {
io.emit('user disconnected');
});
});
};

View file

@ -0,0 +1,22 @@
"use strict";
var express = require("express");
var app = express();
var fs = require("fs");
var path = require("path");
var config = require(path.join(__dirname, "config/config.js"));
var server = require('http').Server(app);
var io = require('socket.io')(server);
// Configure express
require(path.join(__dirname, "config/express"))(app);
// Add routes
require(path.join(__dirname, "config/routes"))(app);
// Configure socket.io server
require(path.join(__dirname, "config/socketio"))(io);
console.log("Listening on port", config.port);
module.exports = app;

View file

@ -3,8 +3,13 @@
"version": "1.0.0",
"description": "ENSL Gather Service for Skulks with Shotguns",
"main": "index.js",
"keywords": [
"NS2",
"Skulks with Shotguns"
],
"scripts": {
"test": "NODE_ENV=test mocha spec/"
"test": "NODE_ENV=test mocha spec/",
"start": "node index.js"
},
"repository": {
"type": "git",
@ -17,8 +22,14 @@
},
"homepage": "https://github.com/cblanc/sws_gathers",
"dependencies": {
"express": "^4.13.1",
"node-mysql": "^0.4.2",
"socket.io": "^1.3.5"
"chai": "~3.1.0",
"express": "~4.13.1",
"express-handlebars": "~2.0.1",
"mocha": "~2.2.5",
"morgan": "~1.6.1",
"node-mysql": "~0.4.2",
"socket.io": "~1.3.5",
"supertest": "~1.0.1",
"winston": "~1.0.1"
}
}

0
public/css/app.css Normal file
View file

354
public/css/theme.css Executable file
View file

@ -0,0 +1,354 @@
/*!
* Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com)
* Code licensed under the Apache License v2.0.
* For details, see http://www.apache.org/licenses/LICENSE-2.0.
*/
body {
background-color: #f8f8f8;
}
#wrapper {
width: 100%;
}
#page-wrapper {
padding: 0 15px;
min-height: 568px;
background-color: #fff;
}
@media(min-width:768px) {
#page-wrapper {
position: inherit;
margin: 0 0 0 250px;
padding: 0 30px;
border-left: 1px solid #e7e7e7;
}
}
.navbar-top-links {
margin-right: 0;
}
.navbar-top-links li {
display: inline-block;
}
.navbar-top-links li:last-child {
margin-right: 15px;
}
.navbar-top-links li a {
padding: 15px;
min-height: 50px;
}
.navbar-top-links .dropdown-menu li {
display: block;
}
.navbar-top-links .dropdown-menu li:last-child {
margin-right: 0;
}
.navbar-top-links .dropdown-menu li a {
padding: 3px 20px;
min-height: 0;
}
.navbar-top-links .dropdown-menu li a div {
white-space: normal;
}
.navbar-top-links .dropdown-messages,
.navbar-top-links .dropdown-tasks,
.navbar-top-links .dropdown-alerts {
width: 310px;
min-width: 0;
}
.navbar-top-links .dropdown-messages {
margin-left: 5px;
}
.navbar-top-links .dropdown-tasks {
margin-left: -59px;
}
.navbar-top-links .dropdown-alerts {
margin-left: -123px;
}
.navbar-top-links .dropdown-user {
right: 0;
left: auto;
}
.sidebar .sidebar-nav.navbar-collapse {
padding-right: 0;
padding-left: 0;
}
.sidebar .sidebar-search {
padding: 15px;
}
.sidebar ul li {
border-bottom: 1px solid #e7e7e7;
}
.sidebar ul li a.active {
background-color: #eee;
}
.sidebar .arrow {
float: right;
}
.sidebar .fa.arrow:before {
content: "\f104";
}
.sidebar .active>a>.fa.arrow:before {
content: "\f107";
}
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a {
padding-left: 37px;
}
.sidebar .nav-third-level li a {
padding-left: 52px;
}
@media(min-width:768px) {
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
margin-top: 51px;
}
.navbar-top-links .dropdown-messages,
.navbar-top-links .dropdown-tasks,
.navbar-top-links .dropdown-alerts {
margin-left: auto;
}
}
.btn-outline {
color: inherit;
background-color: transparent;
transition: all .5s;
}
.btn-primary.btn-outline {
color: #428bca;
}
.btn-success.btn-outline {
color: #5cb85c;
}
.btn-info.btn-outline {
color: #5bc0de;
}
.btn-warning.btn-outline {
color: #f0ad4e;
}
.btn-danger.btn-outline {
color: #d9534f;
}
.btn-primary.btn-outline:hover,
.btn-success.btn-outline:hover,
.btn-info.btn-outline:hover,
.btn-warning.btn-outline:hover,
.btn-danger.btn-outline:hover {
color: #fff;
}
.chat {
margin: 0;
padding: 0;
list-style: none;
}
.chat li {
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px dotted #999;
}
.chat li.left .chat-body {
margin-left: 60px;
}
.chat li.right .chat-body {
margin-right: 60px;
}
.chat li .chat-body p {
margin: 0;
}
.panel .slidedown .glyphicon,
.chat .glyphicon {
margin-right: 5px;
}
.chat-panel .panel-body {
height: 350px;
overflow-y: scroll;
}
.login-panel {
margin-top: 25%;
}
.flot-chart {
display: block;
height: 400px;
}
.flot-chart-content {
width: 100%;
height: 100%;
}
.dataTables_wrapper {
position: relative;
clear: both;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
background: 0 0;
}
table.dataTable thead .sorting_asc:after {
content: "\f0de";
float: right;
font-family: fontawesome;
}
table.dataTable thead .sorting_desc:after {
content: "\f0dd";
float: right;
font-family: fontawesome;
}
table.dataTable thead .sorting:after {
content: "\f0dc";
float: right;
font-family: fontawesome;
color: rgba(50,50,50,.5);
}
.btn-circle {
width: 30px;
height: 30px;
padding: 6px 0;
border-radius: 15px;
text-align: center;
font-size: 12px;
line-height: 1.428571429;
}
.btn-circle.btn-lg {
width: 50px;
height: 50px;
padding: 10px 16px;
border-radius: 25px;
font-size: 18px;
line-height: 1.33;
}
.btn-circle.btn-xl {
width: 70px;
height: 70px;
padding: 10px 16px;
border-radius: 35px;
font-size: 24px;
line-height: 1.33;
}
.show-grid [class^=col-] {
padding-top: 10px;
padding-bottom: 10px;
border: 1px solid #ddd;
background-color: #eee!important;
}
.show-grid {
margin: 15px 0;
}
.huge {
font-size: 40px;
}
.panel-green {
border-color: #5cb85c;
}
.panel-green .panel-heading {
border-color: #5cb85c;
color: #fff;
background-color: #5cb85c;
}
.panel-green a {
color: #5cb85c;
}
.panel-green a:hover {
color: #3d8b3d;
}
.panel-red {
border-color: #d9534f;
}
.panel-red .panel-heading {
border-color: #d9534f;
color: #fff;
background-color: #d9534f;
}
.panel-red a {
color: #d9534f;
}
.panel-red a:hover {
color: #b52b27;
}
.panel-yellow {
border-color: #f0ad4e;
}
.panel-yellow .panel-heading {
border-color: #f0ad4e;
color: #fff;
background-color: #f0ad4e;
}
.panel-yellow a {
color: #f0ad4e;
}
.panel-yellow a:hover {
color: #df8a13;
}

180
public/css/timeline.css Executable file
View file

@ -0,0 +1,180 @@
.timeline {
position: relative;
padding: 20px 0 20px;
list-style: none;
}
.timeline:before {
content: " ";
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 3px;
margin-left: -1.5px;
background-color: #eeeeee;
}
.timeline > li {
position: relative;
margin-bottom: 20px;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li > .timeline-panel {
float: left;
position: relative;
width: 46%;
padding: 20px;
border: 1px solid #d4d4d4;
border-radius: 2px;
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.175);
box-shadow: 0 1px 6px rgba(0,0,0,0.175);
}
.timeline > li > .timeline-panel:before {
content: " ";
display: inline-block;
position: absolute;
top: 26px;
right: -15px;
border-top: 15px solid transparent;
border-right: 0 solid #ccc;
border-bottom: 15px solid transparent;
border-left: 15px solid #ccc;
}
.timeline > li > .timeline-panel:after {
content: " ";
display: inline-block;
position: absolute;
top: 27px;
right: -14px;
border-top: 14px solid transparent;
border-right: 0 solid #fff;
border-bottom: 14px solid transparent;
border-left: 14px solid #fff;
}
.timeline > li > .timeline-badge {
z-index: 100;
position: absolute;
top: 16px;
left: 50%;
width: 50px;
height: 50px;
margin-left: -25px;
border-radius: 50% 50% 50% 50%;
text-align: center;
font-size: 1.4em;
line-height: 50px;
color: #fff;
background-color: #999999;
}
.timeline > li.timeline-inverted > .timeline-panel {
float: right;
}
.timeline > li.timeline-inverted > .timeline-panel:before {
right: auto;
left: -15px;
border-right-width: 15px;
border-left-width: 0;
}
.timeline > li.timeline-inverted > .timeline-panel:after {
right: auto;
left: -14px;
border-right-width: 14px;
border-left-width: 0;
}
.timeline-badge.primary {
background-color: #2e6da4 !important;
}
.timeline-badge.success {
background-color: #3f903f !important;
}
.timeline-badge.warning {
background-color: #f0ad4e !important;
}
.timeline-badge.danger {
background-color: #d9534f !important;
}
.timeline-badge.info {
background-color: #5bc0de !important;
}
.timeline-title {
margin-top: 0;
color: inherit;
}
.timeline-body > p,
.timeline-body > ul {
margin-bottom: 0;
}
.timeline-body > p + p {
margin-top: 5px;
}
@media(max-width:767px) {
ul.timeline:before {
left: 40px;
}
ul.timeline > li > .timeline-panel {
width: calc(100% - 90px);
width: -moz-calc(100% - 90px);
width: -webkit-calc(100% - 90px);
}
ul.timeline > li > .timeline-badge {
top: 16px;
left: 15px;
margin-left: 0;
}
ul.timeline > li > .timeline-panel {
float: right;
}
ul.timeline > li > .timeline-panel:before {
right: auto;
left: -15px;
border-right-width: 15px;
border-left-width: 0;
}
ul.timeline > li > .timeline-panel:after {
right: auto;
left: -14px;
border-right-width: 14px;
border-left-width: 0;
}
}

0
public/js/app.js Normal file
View file

3
public/js/socketio.js Normal file
View file

@ -0,0 +1,3 @@
$(function () {
});

36
public/js/theme.js Executable file
View file

@ -0,0 +1,36 @@
$(function() {
$('#side-menu').metisMenu();
});
//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
$(window).bind("load resize", function() {
topOffset = 50;
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
if (width < 768) {
$('div.navbar-collapse').addClass('collapse');
topOffset = 100; // 2-row-menu
} else {
$('div.navbar-collapse').removeClass('collapse');
}
height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1;
height = height - topOffset;
if (height < 1) height = 1;
if (height > topOffset) {
$("#page-wrapper").css("min-height", (height) + "px");
}
});
var url = window.location;
var element = $('ul.nav a').filter(function() {
return this.href == url || url.href.indexOf(this.href) == 0;
}).addClass('active').parent().parent().addClass('in').parent();
if (element.is('li')) {
element.addClass('active');
}
});

10
spec/helpers/index.js Normal file
View file

@ -0,0 +1,10 @@
"use strict";
var fs = require("fs");
var path = require("path");
var helpers = {}
helpers.app = require(path.join(__dirname, "../../index.js"));
module.exports = helpers;

21
spec/integration.js Normal file
View file

@ -0,0 +1,21 @@
"use strict";
var helper = require("./helpers/index.js");
var request = require("supertest");
var app = helper.app;
describe("Basic Spec", function () {
it ("returns 200", function (done) {
request(app)
.get("/")
.expect(200)
.end(done);
});
it ("returns 404 if page not found", function (done) {
request(app)
.get("/foo")
.expect(404)
.end(done);
});
});

10
views/404.hbs Normal file
View file

@ -0,0 +1,10 @@
<div id="page-wrapper" style="min-height: 750px;">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Four Oh Four</h1>
<p>Page not found</p>
</div>
</div>
</div>
</div>

14
views/index.hbs Normal file
View file

@ -0,0 +1,14 @@
<div id="page-wrapper" style="min-height: 750px;">
<div class="container-fluid">
<div class="row">
</div>
<div class="row">
<div class="col-lg-6">
<h3 class="page-header">Current Gather</h3>
</div>
<div class="col-lg-6">
<h3 class="page-header">Chat</h3>
</div>
</div>
</div>
</div>

9
views/layouts/main.hbs Normal file
View file

@ -0,0 +1,9 @@
<html>
{{>head}}
<body>
<div id="wrapper">
{{>menu}}
{{{ body }}}
</div>
</body>
</html>

20
views/partials/head.hbs Normal file
View file

@ -0,0 +1,20 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Skulks with Shotguns</title>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/theme.css">
<link rel="stylesheet" href="/css/timeline.css">
<link rel="stylesheet" href="/css/app.css">
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src="/js/theme.js"></script>
<script src="/js/app.js"></script>
<script src="/js/socketio.js"></script>
</head>

36
views/partials/menu.hbs Normal file
View file

@ -0,0 +1,36 @@
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ENSL SWS Gathers</a>
</div>
<ul class="nav navbar-top-links navbar-right">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#"><i class="fa fa-gear fa-fw"></i> Settings</a>
</li>
<li class="divider"></li>
<li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
</li>
</ul>
</li>
</ul>
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<a href="/"><i class="fa fa-dashboard fa-fw"></i> Gathers</a>
</li>
</ul>
</div>
</div>
</nav>