Skip to content

Instantly share code, notes, and snippets.

@fauxparse
Last active September 11, 2018 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fauxparse/c888875bc333da7f81a377df15aef8ba to your computer and use it in GitHub Desktop.
Save fauxparse/c888875bc333da7f81a377df15aef8ba to your computer and use it in GitHub Desktop.
Permissions HOC
export const setAdmin = admin => ({
type: 'SET_ADMIN',
admin,
});
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import withPermissions from './withPermissions';
import Permissions from './Permissions';
class Actions extends Component {
render() {
const { user: { name, id }, permissions } = this.props;
return (
<section>
<h2>Things {name} can do:</h2>
<ul>
<li>
<button disabled={!permissions.canAddNote()}>
Add a note
</button>
</li>
<li>
<button disabled={!permissions.canDeleteNote({ ownerId: id })}>
Delete a note
</button>
</li>
<li>
<button disabled={!permissions.canDeleteNote({ ownerId: id + 1 })}>
Delete somebody else’s note
</button>
</li>
<li>
<button disabled={!permissions.canWipeProductionDatabase()}>
Wipe the production database
</button>
</li>
</ul>
</section>
);
}
}
Actions.propTypes = {
user:
PropTypes.shape({
name: PropTypes.string.isRequired,
id: PropTypes.number.isRequired,
}).isRequired,
permissions: PropTypes.instanceOf(Permissions).isRequired,
}
const mapStateToProps = ({ user }) => ({ user })
export default connect(mapStateToProps)(withPermissions(Actions));
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { setAdmin } from './actions/admin';
class AdminToggle extends Component {
adminChanged = e => this.props.setAdmin(e.target.checked)
render() {
const { admin } = this.props;
return (
<label>
<input type="checkbox" checked={admin} onChange={this.adminChanged} />
&nbsp;Admin
</label>
);
}
}
const mapStateToProps = ({ user: { admin } }) => ({ admin })
const mapDispatchToProps = dispatch => ({
setAdmin: admin => dispatch(setAdmin(admin))
});
export default connect(mapStateToProps, mapDispatchToProps)(AdminToggle);
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './reducers';
import App from './App';
import './index.css';
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
import { combineReducers } from 'redux';
import user from './user';
export default combineReducers({
user,
});
export default (state = { name: 'Powelly', id: 1, admin: false }, action) => {
switch(action.type) {
case 'SET_ADMIN':
return { ...state, admin: action.admin };
default:
return state;
}
}
import React from 'react';
import { connect } from 'react-redux';
import Permissions from './Permissions';
const fetchPermissions = ({ user }) => ({
permissions: new Permissions(user),
});
export default (WrappedComponent) =>
connect(fetchPermissions)(WrappedComponent)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment