Skip to content

Commit

Permalink
Working demo
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielpoca committed Apr 15, 2016
0 parents commit 7f71ae2
Show file tree
Hide file tree
Showing 25 changed files with 424 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "airbnb",
"parser": "babel-eslint",
"rules": {
"id-length": [2, {
"exceptions": ["_"]
}],
"arrow-body-style": 0,
"camelcase": 0,
"consistent-return": 0,
"curly": 0,
"func-names": 0,
"new-cap": 0,
"no-param-reassign": 0,
"prefer-arrow-callback": 0,
"space-before-function-paren": 0,
"react/no-multi-comp": [2, {
"ignoreStateless": true
}],
"react/prefer-stateless-function": 0,
"react/jsx-no-bind": 0
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
13 changes: 13 additions & 0 deletions .meteor/.finished-upgraders
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This file contains information which helps Meteor properly upgrade your
# app when you run 'meteor update'. You should check it into version control
# with your project.

notices-for-0.9.0
notices-for-0.9.1
0.9.4-platform-file
notices-for-facebook-graph-api-2
1.2.0-standard-minifiers-package
1.2.0-meteor-platform-split
1.2.0-cordova-changes
1.2.0-breaking-changes
1.3.0-split-minifiers-package
1 change: 1 addition & 0 deletions .meteor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
local
7 changes: 7 additions & 0 deletions .meteor/.id
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file contains a token that is unique to your project.
# Check it into your repository along with the rest of this directory.
# It can be used for purposes such as:
# - ensuring you don't accidentally deploy one app on top of another
# - providing package authors with aggregated statistics

vq6rq61988jma1l59dr2
20 changes: 20 additions & 0 deletions .meteor/packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.

meteor-base # Packages every Meteor app needs to have
mobile-experience # Packages for a great mobile UX
mongo # The database Meteor supports right now
blaze-html-templates # Compile .html files into Meteor Blaze views
reactive-var # Reactive variable for tracker
jquery # Helpful client-side library
tracker # Meteor's client-side reactive programming library

standard-minifier-css # CSS minifier run for production mode
standard-minifier-js # JS minifier run for production mode
es5-shim # ECMAScript 5 compatibility for older browsers.
ecmascript # Enable ECMAScript2015+ syntax in app code

simple:dev-error-overlay
2 changes: 2 additions & 0 deletions .meteor/platforms
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
server
browser
1 change: 1 addition & 0 deletions .meteor/release
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[email protected]
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Meteor Redux Demo
=================

This repository contains a demonstration application for the article [A bridge between React and Meteor](https://subvisual.co/blog/posts/79-working-with-meteor-react-and-redux). In this application you can write and see messages. If you try to write an empty message you'll see an error.

The purpose of this application is to demonstrate a possible setup for Redux on Meteor, most code written here is not acceptable on production application.
14 changes: 14 additions & 0 deletions client/actions/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Meteor } from 'meteor/meteor';

export const createMessage = params => {
return dispatch => {
Meteor.call('createMessage', params, (error) => {
if (!error) return;

dispatch({
type: 'ADD_ERROR',
error,
});
});
};
};
17 changes: 17 additions & 0 deletions client/components/Errors/Errors.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { Component, PropTypes } from 'react';

class ErrorsList extends Component {
renderError(error, index) {
return <li key={index}>{error.message}</li>;
}

render() {
return <ul>{this.props.errors.map(this.renderError)}</ul>;
}
}

ErrorsList.propTypes = {
errors: PropTypes.array.isRequired,
};

export default ErrorsList;
27 changes: 27 additions & 0 deletions client/components/MessagesEditor/MessagesEditor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { Component, PropTypes } from 'react';
import { reduxForm } from 'redux-form';

const fields = ['text'];

class MessagesEditor extends Component {
render() {
const { fields: { text }, handleSubmit } = this.props;

return (
<form onSubmit={handleSubmit}>
<input {...text} />
<button type="submit">Create</button>
</form>
);
}
}

MessagesEditor.propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
};

export default reduxForm({
fields,
form: 'new-message',
})(MessagesEditor);
17 changes: 17 additions & 0 deletions client/components/MessagesList/MessagesList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { Component, PropTypes } from 'react';

class MessagesList extends Component {
renderMessage(message, index) {
return <li key={index}>{message.text}</li>;
}

render() {
return <ul>{this.props.messages.map(this.renderMessage)}</ul>;
}
}

MessagesList.propTypes = {
messages: PropTypes.array.isRequired,
};

export default MessagesList;
51 changes: 51 additions & 0 deletions client/containers/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { createMessage } from '../actions/actions';
import { reset } from 'redux-form';

import SubscribeComponent from '../helpers/SubscribeComponent';
import MessagesList from '../components/MessagesList/MessagesList';
import MessagesEditor from '../components/MessagesEditor/MessagesEditor';
import Errors from '../components/Errors/Errors';

class App extends Component {
componentWillMount() {
this.props.subscribe('messages');
}

handleSubmit(fields) {
this.props.createMessage(fields);
this.props.reset('new-message');
}

render() {
return (
<div>
<MessagesList {...this.props} />
<MessagesEditor
onSubmit={this.handleSubmit.bind(this)}
/>
<Errors {...this.props} />
</div>
);
}
}

App.propTypes = {
subscribe: PropTypes.func.isRequired,
createMessage: PropTypes.func.isRequired,
reset: PropTypes.func.isRequired,
messages: PropTypes.array.isRequired,
errors: PropTypes.array.isRequired,
};

const mapStateToProps = state => {
return { messages: state.messages, errors: state.errors };
};

const mapDispatchToProps = dispatch => {
return bindActionCreators({ createMessage, reset }, dispatch);
};

export default connect(mapStateToProps, mapDispatchToProps)(SubscribeComponent(App));
35 changes: 35 additions & 0 deletions client/helpers/SubscribeComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Meteor } from 'meteor/meteor';
import React, { Component } from 'react';

export default ComposedComponent => class extends Component {
constructor() {
super();
this.subs = {};
}

subscribe(name, ...args) {
if (this.subs[name])
this.subs[name].stop();

this.subs[name] = Meteor.subscribe(name, ...args);
}

subscriptionReady(name) {
if (this.subs[name].ready())
return this.subs[name].ready();
}

componentWillUnmount() {
Object.keys(this.subs).map(key => this.subs[key].stop());
}

render() {
return (
<ComposedComponent
{...this.props}
subscribe={this.subscribe.bind(this)}
subscriptionReady={this.subscriptionReady.bind(this)}
/>
);
}
};
6 changes: 6 additions & 0 deletions client/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<head>
<title>Meteor Redux Demo</title>
</head>
<body>
<div id="app"></div>
</body>
18 changes: 18 additions & 0 deletions client/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Meteor } from 'meteor/meteor';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route, browserHistory } from 'react-router';

import createStore from './store/createStore';
import App from './containers/App';

Meteor.startup(() => {
render((
<Provider store={createStore()}>
<Router history={browserHistory}>
<Route path="/" component={App} />
</Router>
</Provider>
), document.getElementById('app'));
});
26 changes: 26 additions & 0 deletions client/reducers/reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';

const messagesReducer = (state = [], action) => {
switch (action.type) {
case 'SET_MESSAGES':
return action.messages;
default:
return state;
}
};

const errorsReducer = (state = [], action) => {
switch (action.type) {
case 'ADD_ERROR':
return [...state, action.error];
default:
return state;
}
};

export default combineReducers({
messages: messagesReducer,
errors: errorsReducer,
form: formReducer,
});
19 changes: 19 additions & 0 deletions client/store/createStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Tracker } from 'meteor/tracker';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import reducers from '../reducers/reducers';
import Messages from '../../lib/messages';

export default () => {
const store = createStore(reducers, applyMiddleware(thunk));

Tracker.autorun(() => {
store.dispatch({
type: 'SET_MESSAGES',
messages: Messages.find().fetch(),
});
});

return store;
};
5 changes: 5 additions & 0 deletions lib/messages.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Mongo } from 'meteor/mongo';

Messages = new Mongo.Collection('messages');

export default Messages;
Loading

0 comments on commit 7f71ae2

Please sign in to comment.