@@ -0,0 +1,34 @@
import React from 'react';
import * as mdl from 'react-mdl'


export default class Option extends React.Component {
render() {
let { name, label, value, disabled,
onChange, onBlur } = this.props

return (
<mdl.RadioGroup
name={name}
value={value || ''}
onBlur={(e) => onBlur(e.target.value)}
onChange={e => onChange(e.target.value)}>

{
_.map(options,
(value, name) => (
<mdl.Radio
key={name}
disabled={disabled}
name={name}
value={name}
ripple>
{value}
</mdl.Radio>
)
)
}
</mdl.RadioGroup>
);
}
}
@@ -0,0 +1,25 @@
import React from 'react';
import * as mdl from 'react-mdl'


export default class Text extends React.Component {
render() {
let { name, label, value, disabled,
onChange, onBlur } = this.props

return (
<div className='textfield'>
<div className='auto-size'>{value || label}</div>
<mdl.Textfield
className={['field-' + name, (value !== undefined) ? 'is-dirty' : ''].join(' ')}
label={label}
name={name}
value={value}
disabled={disabled}
onBlur={(e) => onBlur(e.target.value)}
onChange={e => onChange(e.target.value)}
floatingLabel/>
</div>
);
}
}

This file was deleted.

@@ -1,22 +1,8 @@
import fields from './fields'
import group from './group'
import member from './member'
import permissions from './permissions'
import view from './view'

import App from './app'
import Auth from './auth'
import HeaderBar from './headerBar'

import Field from './field'
import ItemEdit from './itemEdit'
import List from './list'

export {
fields,
group,
member,
permissions,
view,

App,
Auth,
HeaderBar
Field,
ItemEdit
}
File renamed without changes.
File renamed without changes.

This file was deleted.

This file was deleted.

@@ -7,7 +7,6 @@ import { syncHistory } from 'redux-simple-router'
import persistState from 'redux-localstorage';
import { createHistory } from 'history'

import DevTools from './components/devTools';
import rootReducer from './reducers'

export const history = createHistory();
@@ -22,7 +21,8 @@ const finalCreateStore = compose(
createLogger()
),
// Required! Enable Redux DevTools with the monitors you chose
DevTools.instrument()
window.devToolsExtension ? window.devToolsExtension() : f => f

)(createStore);


File renamed without changes.
File renamed without changes.
@@ -3,7 +3,8 @@ import React from 'react'
import { connect } from 'react-redux'

import actions from 'actions'
import ItemEdit from 'components/view/itemEdit'

import { ItemEdit } from 'components'


class FieldsEdit extends React.Component {
File renamed without changes.
@@ -7,7 +7,7 @@ import {Link} from 'react-router';
import { connect } from 'react-redux';
import _ from 'lodash';

import {List, Head, Row} from 'components/view/list';
import {List, Head, Row} from 'components/list';

import { DragSource, DropTarget, DragDropContext } from 'react-dnd';
// import Backend from 'react-dnd-touch-backend';
@@ -5,7 +5,7 @@ import * as mdl from 'react-mdl'

import { connect } from 'react-redux';

import ItemEdit from 'components/view/itemEdit';
import {ItemEdit} from 'components';

import actions from 'actions'

File renamed without changes.
@@ -2,7 +2,7 @@
import React from 'react'
import * as mdl from 'react-mdl'

import {List, Head, Row} from 'components/view/list'
import {List, Head, Row} from 'components/list'
import {Link} from 'react-router'

import { connect } from 'react-redux'
@@ -0,0 +1,33 @@

import React from 'react';
import * as mdl from 'react-mdl';
import { connect } from 'react-redux';

class HeaderBar extends React.Component {
render() {
let {members, groups, fields} = this.props

let changed = !_.isEmpty(members.updates) || !_.isEmpty(groups.updates) || !_.isEmpty(fields.updates)

return (
<div className='headerBar'>
{ changed && (
<mdl.Button ripple>
Save
<mdl.Icon name='more_vert' />
</mdl.Button>
)}
</div>
);
}
}

function mapStateToProps(state) {
return {
...state
}
}



export default connect(mapStateToProps)(HeaderBar);
@@ -0,0 +1,19 @@
import fields from './fields'
import group from './group'
import member from './member'
import permissions from './permissions'
import HeaderBar from './headerBar'

import App from './app'
import Auth from './auth'

export {
fields,
group,
member,
HeaderBar,
permissions,

App,
Auth
}
@@ -3,7 +3,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import * as mdl from 'react-mdl'

import ItemEdit from '../view/itemEdit';
import {ItemEdit} from 'components';

import { connect } from 'react-redux';

@@ -0,0 +1,7 @@
import Edit from './edit'
import View from './view'

export default {
Edit,
View
}
@@ -2,7 +2,7 @@
import React from 'react';
import * as mdl from 'react-mdl'

import {List, Head, Row} from '../view/list';
import {List, Head, Row} from 'components/list';
import { Link } from 'react-router';
import { Navigation } from 'react-router'
import { connect } from 'react-redux';
File renamed without changes.
File renamed without changes.

This file was deleted.

@@ -10,7 +10,6 @@ import injectTapEventPlugin from "react-tap-event-plugin";

import routes from 'routes'
import {history, configureStore} from 'configureStore'
import DevTools from 'components/devTools'

// Reference static files so they are loaded with webpack.
import 'app.less';
@@ -27,15 +26,14 @@ injectTapEventPlugin();
const store = configureStore()


ReactDOM.render(

ReactDOM.render((
<Provider store={store}>
<div>
<Router history={history}>
{ routes(store) }
</Router>
<DevTools />
</div>
</Provider>,
</Provider>
),
document.getElementById('app')
);
@@ -2,6 +2,10 @@ import update from 'react-addons-update';
import constants from 'constants'
import initialState from './fields.state.json'
import _ from 'lodash'
import Immutable from 'immutable'


initialState = Immutable.Map(initialState)


// Index depths
@@ -166,4 +170,4 @@ function fieldreducer(state = initialState, action) {
}


export default fieldreducer
export default fieldreducer
@@ -25,6 +25,14 @@ const initialState = {

function groupsReducer(state = initialState, action) {
switch (action.type) {
case constants.GROUPS_CREATE:
return update(state, {
items: {
$merge: {
[action.id]: {}
}
}
})
case constants.GROUPS_UPDATE:
return update(state, {
items: {
@@ -4,27 +4,36 @@ import constants from 'constants'

const initialState = {
items: {},
updates: {},
dirty: false
}

function memberReducer(state = initialState, action) {
switch (action.type) {
case constants.MEMBERS_RECEIVE:
return Object.assign({}, state, {
items: _.keyBy(action.members, 'id'),
dirty: false
items: _.indexBy(action.members, 'id'),
})
case constants.MEMBERS_UPDATE:
return update(state, {
items: {
[action.id]: {
$merge: action.member
}
},
dirty: {
$set: true
}
})
if (!_.matches(action.member)(state.items[action.id])) {
// changed
return update(state, {
items: {
[action.id]: {
$merge: action.member
}
},
updates: {
$merge: {
[action.id]: action.member
}
},
dirty: {
$set: true
}
})
}
break;
case constants.FIELDS_CREATE_MEMBERS_COMMIT:
return update(state, {
dirty: false
@@ -42,9 +51,8 @@ function memberReducer(state = initialState, action) {
$set: true
}
})
default:
return state;
}
return state;
}


@@ -1,15 +1,18 @@
import React from 'react';
import { Route, IndexRoute } from 'react-router'

import {
HeaderBar
} from 'containers'

import {
group,
member,
fields,
permissions,
Auth,
App,
HeaderBar
} from 'components'
App
} from 'containers'

import actions from 'actions'

@@ -0,0 +1,33 @@
var path = require('path');
var express = require('express');
var webpack = require('webpack');
var proxy = require('express-http-proxy');
var config = require('./webpack.config.dev');

var app = express();
var compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath,
stats: {
colors: true
}
}));

app.use(require('webpack-hot-middleware')(compiler));

app.use('/api', proxy('localhost:4242'));

app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
if (err) {
console.log(err);
return;
}

console.log('Listening at http://localhost:3000');
});
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
module.exports = __webpack_public_path__ + "4e9ae9995ec3e2f6b9cbaca845707bdb.ttf";
@@ -0,0 +1 @@
module.exports = __webpack_public_path__ + "72bdc1d57a7ac33df5f8e8bbeae2db6a.ttf";
@@ -0,0 +1 @@
module.exports = __webpack_public_path__ + "e7ad421525fdd80f74880440c4dae08d.woff";
@@ -0,0 +1 @@
module.exports = __webpack_public_path__ + "e2f35f2d8bb12d4d3407ebe3683adaa1.woff";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
module.exports = __webpack_public_path__ + "1050ce7c9422d070887dbdb04b24c30b.woff";
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
module.exports = __webpack_public_path__ + "9ac46d2eb22f2f00090a73ed943b9522.ttf";

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,21 @@

<!doctype html>
<html>
<title>Wolbodo:ledenlijst</title>
<link rel="icon" type="image/png" href="favicon.png" sizes="256x256">


<link href="/styles.css" rel="stylesheet"></link>


<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<body>
<div id="app"></div>
</body>


<script src="/bundle.js"></script>

</html>
@@ -4,10 +4,11 @@
"description": "The react frontend for the membership management system",
"main": "index.jsx",
"scripts": {
"build": "webpack --progress --profile --colors",
"start": "npm run dev",
"serve": "./node_modules/.bin/http-server -p 8080",
"dev": "webpack-dev-server --hot --progress --inline --colors --port 8090"
"clean": "rimraf dist",
"build:webpack": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
"build": "npm run clean && npm run build:webpack",
"start": "node devServer.js",
"lint": "eslint src"
},
"author": "Dexter",
"license": "ISC",
@@ -28,8 +29,9 @@
"classnames": "^2.2.3",
"fetch": "^1.0.0",
"history": "^1.17.0",
"immutable": "^3.7.6",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.0.0",
"lodash": "^3.10.0",
"material-design-icons": "^2.1.3",
"material-design-lite": "^1.0.6",
"material-ui": "^0.14.2",
@@ -43,53 +45,42 @@
"react-mdl": "^1.2.0",
"react-redux": "^4.0.6",
"react-router": "^1.0.3",
"react-router-redux": "*",
"react-tap-event-plugin": "^0.2.1",
"react-ui-datepicker": "^0.1.0",
"redux": "^3.0.5",
"redux-localstorage": "*",
"redux-simple-router": "^2.0.4",
"redux-thunk": "^1.0.3",
"resolve-url-loader": "^1.4.3",
"webpack-dev-server": "^1.14.1"
"redux-thunk": "^1.0.3"
},
"devDependencies": {
"babel-core": "^6.3.15",
"babel-eslint": "^5.0.0-beta4",
"babel-loader": "^6.2.0",
"babel-plugin-react-transform": "^2.0.0",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-react-hmre": "^1.0.0",
"babel-preset-stage-0": "*",
"babel-preset-stage-1": "*",
"babel-preset-stage-1": "^6.3.13",
"cross-env": "^1.0.6",
"css-loader": "*",
"css-loader": "^0.23.1",
"eslint": "^1.10.3",
"eslint-plugin-babel": "^3.0.0",
"eslint-plugin-react": "^3.11.3",
"eventsource-polyfill": "^0.9.6",
"express": "^4.13.4",
"extract-text-webpack-plugin": "*",
"file-loader": "*",
"font-loader": "*",
"html-webpack-plugin": "*",
"http-server": "*",
"json-loader": "*",
"jsx-loader": "*",
"less": "*",
"less-loader": "*",
"react-hot-loader": "*",
"react-transform-catch-errors": "^1.0.1",
"redbox-react": "^1.2.0",
"redux-devtools": "*",
"redux-devtools-dock-monitor": "*",
"redux-devtools-log-monitor": "*",
"redux-logger": "*",
"express": "^4.13.3",
"express-http-proxy": "^0.6.0",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"html-webpack-plugin": "^2.7.2",
"json-loader": "^0.5.4",
"less": "^2.5.3",
"less-loader": "^2.2.2",
"redux-devtools": "^3.0.1",
"redux-devtools-dock-monitor": "^1.0.1",
"redux-devtools-log-monitor": "^1.0.2",
"redux-logger": "^2.4.0",
"rimraf": "^2.4.3",
"serviceworker-loader": "*",
"style-loader": "*",
"url-loader": "*",
"webpack": "^1.12.12",
"url-loader": "^0.5.7",
"webpack": "^1.12.9",
"webpack-dev-middleware": "^1.4.0",
"webpack-hot-middleware": "^2.6.0"
}
@@ -0,0 +1,65 @@
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin')
var srcPath = path.join(__dirname, 'app');

module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
'eventsource-polyfill', // necessary for hot reloading with IE
'webpack-hot-middleware/client',
'./app/index.jsx'
],
resolve: {
root: srcPath,
extensions: ['', '.js', '.jsx'],
modulesDirectories: ['node_modules', 'src'],

alias: {
'material' : "../node_modules/react-mdl/extra/material.js",
'material.css' : "../node_modules/react-mdl/extra/material.css"
// 'material-icons': "../"
}
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: ''
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin('styles.css'),
new HtmlWebpackPlugin({
inject: false,
template: 'index.html',
favicon: 'app/favicon.png'
})
],
module: {
loaders: [{
test: /\.jsx?/,
loaders: ['babel'],
include: srcPath
},{
test: /\.json$/,
loader: "json-loader"
}, {
test: /\.less$/,
loader: ExtractTextPlugin.extract('css?sourceMap!' + 'less?sourceMap')
}, {
test: /\.css$/,
loader: ExtractTextPlugin.extract('css?sourceMap')
}, {
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/,
loader: "file"
}, {
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
}, {
test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
}]
}
};

This file was deleted.

@@ -0,0 +1,64 @@
var path = require('path');
var webpack = require('webpack');
var srcPath = path.join(__dirname, 'app');

module.exports = {
devtool: 'source-map',
entry: [
'./app/index.jsx'
],
resolve: {
root: srcPath,
extensions: ['', '.js', '.jsx'],
modulesDirectories: ['node_modules', 'src'],

alias: {
'material' : "../node_modules/react-mdl/extra/material.js",
'material.css' : "../node_modules/react-mdl/extra/material.css"
// 'material-icons': "../"
}
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: ''
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
],
module: {
loaders: [{
test: /\.jsx?/,
loaders: ['babel'],
include: srcPath
},{
test: /\.json$/,
loader: "json-loader"
}, {
test: /\.less$/,
loader: 'css?sourceMap!less?sourceMap'
}, {
test: /\.css$/,
loader: 'css?sourceMap'
}, {
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/,
loader: "file"
}, {
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
}, {
test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
}]
}
};