Skip to content

Instantly share code, notes, and snippets.

@ldco2016
Created July 15, 2019 02:13
Show Gist options
  • Save ldco2016/b832750bb23d9c6888e86570f5950e03 to your computer and use it in GitHub Desktop.
Save ldco2016/b832750bb23d9c6888e86570f5950e03 to your computer and use it in GitHub Desktop.
SettingsPage
import React from "react";
import PropTypes from "prop-types";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import glamorous from "glamorous";
import { Button } from "../../../../common/components";
import { Card, CardText } from "react-toolbox/lib/card";
import { getCurrentUser } from "../../../../redux-modules/current-user";
import { withLoading } from "../../../../redux-modules/loading-overlay";
import PreferencesActions from "../../actions/customers/preferences";
import { getPreferences } from "../../selectors/customers/preferences";
import ActionHandler from "../ActionHandler";
import SwitchList from "../SwitchList";
import styles from "./styles.css";
export const SwitchListHeader = glamorous.h2(
{
fontWeight: "normal",
textTransform: "capitalize",
marginBottom: 20
},
props => ({
color: props.color
})
);
class SettingsPage extends React.Component {
static propTypes = {
isLoading: PropTypes.bool,
currentUser: PropTypes.shape({
id: PropTypes.string
}),
pageColor: PropTypes.shape({
name: PropTypes.string,
value: PropTypes.string
}),
headerText: PropTypes.string,
renderSaveButton: PropTypes.func,
handleSaveResults: PropTypes.func,
category: PropTypes.oneOf([
"None",
"CommunicationPreferences",
"MemberPrivacy",
"GetInvolved",
"TopicsOfConcern",
"MemberBenefitInterests"
]),
preferences: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.string,
displayText: PropTypes.string,
category: PropTypes.oneOf([
"None",
"CommunicationPreferences",
"MemberPrivacy",
"GetInvolved",
"TopicsOfConcern",
"MemberBenefitInterests"
]),
isSelected: PropTypes.bool
})
),
actions: PropTypes.shape({
preferences: PropTypes.objectOf(PropTypes.func)
})
};
static promises = {
includePromises: [
{ type: "ENTITY/ENTITY_GET", meta: { namespace: "preferences" } },
{ type: "ENTITY/ENTITY_PUT", meta: { namespace: "preferences" } }
]
};
constructor(props) {
super(props);
this.state = {
form: this.loadPreferencesFromProps(props),
save: {
shouldSave: false,
data: []
}
};
}
// getDisplayTextByCategory() {
// return this.props.preferences.map((item, index) => {
// if (this.props.preferences[index].category === this.props.category) {
// return (
// <div
// key={item.key + item.category}
// dangerouslySetInnerHTML={{
// __html: this.props.preferences[index].description
// }}
// />
// );
// }
// });
// }
componentWillReceiveProps(nextProps) {
if (nextProps.isLoading) {
return;
}
this.setState(prevState => {
return {
...prevState,
form: {
...prevState.form,
...this.loadPreferencesFromProps(nextProps)
}
};
});
}
setFormValue = formProps => {
this.setState(prevState => {
return {
...prevState,
form: {
...prevState.form,
...formProps
}
};
});
};
loadPreferencesFromProps = props => {
console.log(props);
const { preferences } = props;
return {
...preferences.reduce((acc, curr) => {
return {
...acc,
[curr.key]: curr.isSelected
};
}, {})
};
};
handleChecked = key => value => {
this.setFormValue({ [key]: value });
};
handleSubmit = () => {
const { ...preferences } = this.state.form;
const data = {
items: this.props.preferences.map(i => {
return {
...i,
isSelected: preferences[i.key]
};
})
};
return this.updateSave({ shouldSave: true, data });
};
updateSave = ({ shouldSave, data = [] }) => {
this.setState(prevState => ({
...prevState,
save: {
shouldSave,
data
}
}));
};
handleAction = data => {
this.updateSave({ shouldSave: false });
return this.props.actions.preferences.put(data);
};
render() {
const {
preferences,
category,
headerText,
renderSaveButton,
handleSaveResults
} = this.props;
const filteredPreferences = preferences.filter(
i => i.category === category && i.key
);
return (
<div>
<Card className={styles.card}>
<CardText>
{this.getDisplayTextByCategory()}
{headerText ? (
<SwitchListHeader>{headerText}</SwitchListHeader>
) : null}
<ActionHandler
condition={
!!this.props.currentUser.id &&
(!preferences || !preferences.length)
}
action={this.props.actions.preferences.get}
name="get-preferences"
/>
<ActionHandler
condition={!this.props.isLoading && this.state.save.shouldSave}
action={this.handleAction}
data={[this.state.save.data]}
>
{results => {
return results &&
handleSaveResults &&
typeof handleSaveResults === "function"
? handleSaveResults(results)
: null;
}}
</ActionHandler>
<SwitchList
items={filteredPreferences}
data={this.state.form}
onChange={this.handleChecked}
sortKey="order"
>
<h4 style={{ textAlign: "center" }}>Loading...</h4>
</SwitchList>
</CardText>
</Card>
{typeof renderSaveButton === "function" ? (
renderSaveButton(this.handleSubmit)
) : (
<Button
onClick={this.handleSubmit}
label="Save"
className={styles["save-button"]}
/>
)}
</div>
);
}
}
const mapStateToProps = state => {
const currentUser = getCurrentUser(state);
return {
currentUser,
...(currentUser.settings || {}).contactPreferences,
preferences: getPreferences(state)
};
};
// return dispatch to be used in mergeProps where binding will take place
const mapDispatchToProps = dispatch => {
return { dispatch };
};
const mergeProps = (stateProps, dispatchProps, ownProps) => {
return {
...ownProps,
...stateProps,
actions: {
preferences: bindActionCreators(
PreferencesActions(stateProps.currentUser.id),
dispatchProps.dispatch
)
}
};
};
export default withLoading(
connect(
mapStateToProps,
mapDispatchToProps,
mergeProps
)(SettingsPage)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment