Add initial journal app with library menu on left

This commit is contained in:
Joey Payne 2016-02-15 21:28:21 -07:00
commit c5c75efc23
13 changed files with 838 additions and 0 deletions

1
.babelrc Normal file
View file

@ -0,0 +1 @@
{ "presets": ["es2015", "react", "stage-0", "stage-1", "stage-2", "stage-3"] }

1
.gitignore vendored
View file

@ -32,3 +32,4 @@ jspm_packages
# Optional REPL history
.node_repl_history
dist

72
app/main.jsx Normal file
View file

@ -0,0 +1,72 @@
import React from 'react'
import injectTapEventPlugin from "react-tap-event-plugin"
injectTapEventPlugin()
import ThemeManager from 'material-ui/lib/styles/theme-manager'
import ReactDOM from 'react-dom'
import LibraryNav from 'LibraryNav'
import Styles from 'material-ui/lib/styles'
import Rethink from 'rethinkdbdash'
import moment from 'moment'
const DefaultRawTheme = Styles.LightRawTheme
let r = Rethink({
db: 'technote',
servers: [
{host: '162.243.255.144',
port: 28015}
]})
function createTables(){
r.tableCreate('notes').run()
.then(function(){
r.table('notes').indexCreate('account_id').run()
})
.error(function(){})
r.tableCreate('accounts').run().error(function(){})
}
class Main extends React.Component {
constructor(props){
super(props)
createTables()
this.state = {entries: []}
}
static get childContextTypes(){
return {muiTheme: React.PropTypes.object}
}
getChildContext() {
return {
muiTheme: ThemeManager.getMuiTheme(DefaultRawTheme)
}
}
entriesTapped = () => {
r.table('notes').getAll('jyapayne@gmail.com', {index: 'account_id'}).run().then(
function(notes){
console.log(notes)
}
)
};
render() {
return (
<LibraryNav
id="library-nav"
entriesTapped={this.entriesTapped}
className="left inline fill-height"/>
)
}
}
ReactDOM.render(
<Main />,
document.getElementById('main')
);

View file

@ -0,0 +1,65 @@
import React from 'react'
import mui from 'material-ui'
import ThemeManager from 'material-ui/lib/styles/theme-manager'
import List from 'material-ui/lib/lists/list'
import ListItem from 'material-ui/lib/lists/list-item'
import ActionGrade from 'material-ui/lib/svg-icons/action/grade'
import History from 'material-ui/lib/svg-icons/action/history'
import AddCircleOutline from 'material-ui/lib/svg-icons/content/add-circle-outline'
import Folder from 'material-ui/lib/svg-icons/file/folder'
import Delete from 'material-ui/lib/svg-icons/action/delete'
import Divider from 'material-ui/lib/divider'
const {AppBar,
AppCanvas,
FontIcon,
IconButton,
EnhancedButton,
NavigationClose,
Menu,
Mixins,
RaisedButton,
FlatButton,
Dialog,
Styles,
Tab,
Tabs,
Paper} = mui
const colors = Styles.Colors
const DefaultRawTheme = Styles.LightRawTheme
export default class EntrySelector extends React.Component {
constructor(props){
super(props)
this.state = {entries: []}
}
static get childContextTypes(){
return {muiTheme: React.PropTypes.object}
}
getChildContext() {
return {
muiTheme: ThemeManager.getMuiTheme(DefaultRawTheme)
}
}
blank(){
}
render(){
return (
)
}
}

134
app/modules/LibraryNav.jsx Normal file
View file

@ -0,0 +1,134 @@
import React from 'react'
import mui from 'material-ui'
import ThemeManager from 'material-ui/lib/styles/theme-manager'
import styles from 'material-ui/lib/styles'
import List from 'material-ui/lib/lists/list'
import ListItem from 'material-ui/lib/lists/list-item'
import ActionGrade from 'material-ui/lib/svg-icons/action/grade'
import History from 'material-ui/lib/svg-icons/action/history'
import AddCircleOutline from 'material-ui/lib/svg-icons/content/add-circle-outline'
import Folder from 'material-ui/lib/svg-icons/file/folder'
import Delete from 'material-ui/lib/svg-icons/action/delete'
import Divider from 'material-ui/lib/divider'
const colors = styles.Colors
const {AppBar,
AppCanvas,
FontIcon,
IconButton,
EnhancedButton,
NavigationClose,
Menu,
Mixins,
RaisedButton,
FlatButton,
Dialog,
Styles,
Tab,
Tabs,
Paper} = mui
const DefaultRawTheme = Styles.LightRawTheme
export default class LibraryNav extends React.Component {
constructor(props){
super(props)
this.state = {open: false, items: []}
}
static get childContextTypes(){
return {muiTheme: React.PropTypes.object}
}
handleOpen = () => {
console.log(this);
this.setState({open: true})
};
handleClose = () => {
this.setState({open: false})
};
getChildContext() {
return {
muiTheme: ThemeManager.getMuiTheme(DefaultRawTheme)
}
}
displayDialog(){
console.log(this)
}
readDir = () => {
console.log(fs.readdirSync('.'))
};
entriesTapped = () => {
var items = this.state.items
items.push({name: 'Stuff '+(items.length+1), id: items.length})
this.setState({items: items})
};
blank(){
}
render(){
return (
<div id={this.props.id} className={this.props.className || ""}>
<List subheader="Library">
<ListItem
primaryText="Entries"
onTouchTap={this.props.entriesTapped || this.blank}
leftIcon={<img src="images/note.svg"/>}
className="noselect"/>
<ListItem
primaryText="Starred"
onTouchTap={this.props.starredTapped || this.blank}
leftIcon={<ActionGrade color={colors.amberA700}/>}
className="noselect" />
<ListItem
primaryText="Recents"
onTouchTap={this.props.recentsTapped || this.blank}
leftIcon={<History color="#4BAE4E"/>}
className="noselect" />
<ListItem
primaryText="Trash"
onTouchTap={this.props.trashTapped || this.blank}
leftIcon={<Delete color={colors.grey500}/>}
className="noselect" />
<ListItem
primaryText="All Notes"
onTouchTap={this.props.allNotesTapped || this.blank}
leftIcon={<Folder color="#FFCC5F" />}
className="noselect" />
{this.state.items.map(function(item){
return <ListItem
primaryText={item.name}
key={item.id}
className="noselect"/>;
})}
</List>
<Divider />
<List subheader={<div>
<div className="inline">NoteBooks</div>
<IconButton
touch={true}
onTouchTap={this.props.addNotebookTapped || this.blank}
tooltip="Add New Notebook"
className="right inline">
<AddCircleOutline
color={colors.grey500}/>
</IconButton>
</div>}>
</List>
</div>
)
}
}

View file

@ -0,0 +1,60 @@
import React from 'react';
import {StylePropable} from 'material-ui/lib/mixins';
const MobileTearSheet = React.createClass({
propTypes: {
children: React.PropTypes.node,
height: React.PropTypes.number,
},
contextTypes: {
muiTheme: React.PropTypes.object,
},
mixins: [
StylePropable,
],
getDefaultProps() {
return {
height: 500,
};
},
render() {
const styles = {
root: {
float: 'left',
marginBottom: 24,
marginRight: 24,
width: 360,
height: "100%",
},
container: {
border: 'solid 1px #d9d9d9',
borderBottom: 'none',
height: '100%',
overflow: 'hidden',
},
bottomTear: {
display: 'block',
position: 'relative',
marginTop: -10,
width: 360,
},
};
return (
<div style={this.prepareStyles(styles.root)} className="tearsheet">
<div style={this.prepareStyles(styles.container)}>
{this.props.children}
</div>
<img style={this.prepareStyles(styles.bottomTear)} src="images/bottom-tear.svg" />
</div>
);
},
});
export default MobileTearSheet;

12
images/bottom-tear.svg Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 360 10" enable-background="new 0 0 360 10" xml:space="preserve">
<polygon fill="#DAD9D9" points="359,0 359,7.5 352.5,0.5 345,8.5 337.5,0.5 330,8.5 322.5,0.5 315,8.5 307.5,0.5 300,8.5 292.5,0.5
285,8.5 277.5,0.5 270,8.5 262.5,0.5 255,8.5 247.5,0.5 240,8.5 232.5,0.5 225,8.5 217.5,0.5 210,8.5 202.5,0.5 195,8.5 187.5,0.5
180,8.5 172.5,0.5 165,8.5 157.5,0.5 150,8.5 142.5,0.5 135,8.5 127.5,0.5 120,8.5 112.5,0.5 105,8.5 97.5,0.5 90,8.5 82.5,0.5
75,8.5 67.5,0.5 60,8.5 52.5,0.5 45,8.5 37.5,0.5 30,8.5 22.5,0.5 15,8.5 7.5,0.5 1,7.5 1,0 0,0 0,10 7.5,2 15,10 22.5,2 30,10
37.5,2 45,10 52.5,2 60,10 67.5,2 75,10 82.5,2 90,10 97.5,2 105,10 112.5,2 120,10 127.5,2 135,10 142.5,2 150,10 157.5,2 165,10
172.5,2 180,10 187.5,2 195,10 202.5,2 210,10 217.5,2 225,10 232.5,2 240,10 247.5,2 255,10 262.5,2 270,10 277.5,2 285,10
292.5,2 300,10 307.5,2 315,10 322.5,2 330,10 337.5,2 345,10 352.5,2 360,10 360,0 "/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

162
images/note.svg Normal file
View file

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128px"
height="128px"
viewBox="0 0 128 128"
version="1.1"
id="SVGRoot"
inkscape:version="0.91+devel r"
sodipodi:docname="note.svg">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="140.71213"
inkscape:cy="72.575592"
inkscape:document-units="px"
inkscape:current-layer="g4975"
showgrid="false"
inkscape:window-width="1855"
inkscape:window-height="1056"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:grid-bbox="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:locked="false" />
<defs
id="defs4214" />
<metadata
id="metadata4217">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<g
id="g4975">
<g
id="g5019"
transform="translate(1.1490417,0.0428853)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#9e9e9f;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.94117647"
id="rect4773"
width="88.14122"
height="115.57799"
x="18.782757"
y="6.1681209"
ry="10.881775" />
<rect
style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4795"
width="88.134224"
height="10.392586"
x="13.633903"
y="39.731781"
ry="0" />
<rect
ry="0"
y="58.528904"
x="13.633903"
height="10.392574"
width="88.134224"
id="rect4802"
style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4804"
width="88.134224"
height="10.392578"
x="13.633903"
y="77.326027"
ry="0" />
<rect
ry="0"
y="96.123146"
x="13.624446"
height="10.392578"
width="88.143684"
id="rect4806"
style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#f8bbd0;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4793"
width="8.1023436"
height="105.27682"
x="36.383701"
y="11.31977" />
<rect
ry="0"
y="21.911697"
x="13.633903"
height="10.39666"
width="22.745701"
id="rect4808"
style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#bdbdbd;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4819"
width="22.749798"
height="10.39666"
x="13.633903"
y="39.727707"
ry="0" />
<rect
style="opacity:1;fill:#bdbdbd;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4819-0"
width="22.745701"
height="10.39666"
x="13.633903"
y="58.524826"
ry="0" />
<rect
style="opacity:1;fill:#bdbdbd;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4819-9"
width="22.749798"
height="10.396652"
x="13.633903"
y="77.321945"
ry="0" />
<rect
style="opacity:1;fill:#bdbdbd;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4819-3"
width="22.749798"
height="10.39666"
x="13.633903"
y="96.123146"
ry="0" />
<rect
style="opacity:1;fill:#bdbdbd;fill-opacity:1;stroke:none;stroke-width:10.30698776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4819-38"
width="22.749798"
height="10.39666"
x="13.633903"
y="21.911697"
ry="0" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

26
index.html Normal file
View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,500' rel='stylesheet' type='text/css'>
<link href='style.css' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
font-family: 'Roboto', sans-serif;
};
</style>
</head>
<body style="width:100%; height:100%">
<div id="main" style="height:100%">
</div>
<script>
document.addEventListener("keydown", function (e) {
if (e.which === 123) {
require('remote').getCurrentWindow().toggleDevTools();
} else if (e.which === 116) {
location.reload();
}
});
</script>
<script type="text/javascript" src="dist/bundle.js"></script>
</body>
</html>

93
main.js Normal file
View file

@ -0,0 +1,93 @@
var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.
app.commandLine.appendSwitch("no-proxy-server");
// Report crashes to our server.
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;
// Quit when all windows are closed.
app.on('window-all-closed', function() {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform != 'darwin') {
app.quit();
}
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
// Create the browser window.
var mainWindow = new BrowserWindow({
"resizable": true,
"macIcon": "",
"titleBarStyle": "default",
"minHeight": "",
"frame": true,
"enableLargerThanScreen": false,
"height": 768,
"maxHeight": "",
"autoHideMenuBar": false,
"useContentSize": false,
"skipTaskbar": false,
"fullscreen": false,
"icon": "",
"acceptFirstMouse": false,
"transparent": false,
"minWidth": "",
"x": "",
"maxWidth": "",
"width": 1024,
"type": "",
"alwaysOnTop": false,
"darkTheme": false,
"show": true,
"y": "",
"kiosk": false,
"exeIcon": "",
"backgroundColor": "#000000",
"webPreferences": {
"preload": "",
"nodeIntegration": true,
"javascript": true,
"images": true,
"plugins": false,
"experimentalCanvasFeatures": false,
"webgl": true,
"allowRunningInsecureContent": false,
"webaudio": true,
"zoomFactor": 1.0,
"blinkFeatures": "",
"experimentalFeatures": false,
"allowDisplayingInsecureContent": false,
"textAreasAreResizable": true,
"directWrite": true,
"partition": "",
"webSecurity": true
},
"title": "Electrify",
"disableAutoHideCursor": false,
"center": true
});
// and load the index.html of the app.
mainWindow.loadURL('file://' + __dirname + '/index.html');
mainWindow.webContents.setUserAgent("");
mainWindow.webContents.on('did-finish-load',function(){
mainWindow.setTitle("Electrify");
});
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
});

157
package.json Normal file
View file

@ -0,0 +1,157 @@
{
"inject_js_start": "",
"chromium_args": "",
"host_resolver_rules": "",
"remote_debugging_port": "",
"js_flags": "",
"js-flags": "",
"main": "main.js",
"additional_trust_anchors": [
""
],
"disable_http_cache": false,
"web_preferences": {},
"node-main": "",
"chromium-args": "",
"user_agent": "",
"webkit": {
"java": false,
"page-cache": false,
"plugin": false
},
"client_certificate": "",
"scripts": {
"dev": "webpack-dev-server --progress --colors --port 8090",
"serve": "./node_modules/.bin/http-server -p 8080",
"start": "npm run serve | npm run dev",
"webpack": "webpack --progress --colors --watch"
},
"single-instance": true,
"app_name": "Electrify",
"name": "Electrify",
"node-remote": "",
"host_rules": "",
"proxy_pac_url": "",
"cipher_suite_blacklist": "",
"ignore_connections_limit": "",
"ppapi_flash_path": "",
"inject-js-end": "",
"no_proxy_server": "False",
"inject-js-start": "",
"description": "A web/node app to desktop exporter using Electron.",
"webexe_settings": {
"electron_version": "0.36.7",
"linux-x32": false,
"force_download": false,
"mac-x64": false,
"nw_version": "0.12.2",
"download_dir": "/home/joey/Downloads/nwdls",
"windows-x64": false,
"export_dir": "output",
"custom_script": "",
"nw_compression_level": 0,
"electron_compression_level": 0,
"uncompressed_folder": false,
"windows-x32": false,
"mac-x32": false,
"linux-x64": true
},
"dependencies": {
"material-ui": "^0.14.4",
"materialize-css": "^0.97.5",
"moment": "^2.11.2",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"react-quill": "^0.4.1",
"react-tap-event-plugin": "^0.2.2",
"rethinkdbdash": "^2.2.17"
},
"ppapi_flash_version": "",
"nodejs": true,
"proxy_server": "",
"user-agent": "",
"version": "0.1.0",
"proxy_bypass_list": "",
"snapshot": "",
"author": "Joey Payne",
"license": "MIT",
"inject_js_end": "",
"window": {
"as_desktop": false,
"kiosk_emulation": false,
"resizable": true,
"max_width": "",
"always-on-top": false,
"title_bar_style": "default",
"enable_larger_than_screen": false,
"use_content_size": false,
"min_width": "",
"height": 480,
"background_color": "#000000",
"show_in_taskbar": true,
"max_height": "",
"toolbar": true,
"disable_auto_hide_cursor": false,
"fullscreen": false,
"icon": "",
"skip_taskbar": false,
"transparent": false,
"frame": true,
"x": "",
"always_on_top": false,
"accept_first_mouse": false,
"position": "",
"type": "",
"mac_icon": "",
"min_height": "",
"show": true,
"y": "",
"kiosk": false,
"exe_icon": "",
"width": 640,
"title": "Electrify",
"center": true,
"visible": true,
"dark_theme": false,
"auto_hide_menu_bar": false
},
"disable_renderer_backgrounding": false,
"ssl_version_fallback_min": "",
"web": {
"experimental_canvas_features": false,
"preload": "",
"allow_displaying_insecure_content": false,
"javascript": true,
"images": true,
"direct_write": true,
"text_areas_are_resizable": true,
"blink_features": "",
"webgl": true,
"plugins": false,
"webaudio": true,
"zoom_factor": 100,
"experimental_features": false,
"allow_running_insecure_content": false,
"web_security": true,
"partition": "",
"node_integration": true
},
"ignore_certificate_errors": false,
"log_net_log": "",
"main_html": "index.html",
"devDependencies": {
"babel-core": "^6.5.1",
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.5.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"babel-preset-stage-1": "^6.5.0",
"babel-preset-stage-2": "^6.5.0",
"babel-preset-stage-3": "^6.5.0",
"http-server": "^0.8.4",
"webpack": "*",
"webpack-dev-server": "^1.11.0"
},
"keywords": [],
"node_main": ""
}

26
style.css Normal file
View file

@ -0,0 +1,26 @@
body, html{
margin: 0px;
height: 100%;
}
#main{
min-height: 100%;
}
.fill-height{
height: 100%;
}
.noselect{
-webkit-user-select: none;
}
.inline{
display: inline-block;
vertical-align: top;
}
.left{
}
.right{
float: right;
}
#library-nav{
border-right: solid 1px #d9d9d9;
width: 200px;
}

29
webpack.config.js Normal file
View file

@ -0,0 +1,29 @@
var path = require('path');
module.exports = {
entry: './app/main.jsx',
output: {
path: __dirname + "/dist",
filename: "bundle.js",
sourceMapFilename: 'bundle.map'
},
target: 'node',
//devtool: 'source-map',
module:{
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {presets: ['react', 'es2015', 'stage-0',
'stage-1', 'stage-2', 'stage-3']}
}
]
},
resolve:{
extensions: ['', '.js', '.jsx'],
root: [
path.resolve('./app/modules')
]
}
};