Skip to content

Instantly share code, notes, and snippets.

@RyanCCollins
Last active October 12, 2016 01:51
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 RyanCCollins/2e0a10370762f6db91ff4a801f3fe519 to your computer and use it in GitHub Desktop.
Save RyanCCollins/2e0a10370762f6db91ff4a801f3fe519 to your computer and use it in GitHub Desktop.
User profile container, with mutations
class Profile extends Component {
// Removed for brevity. View the whole component
// here: https://github.com/RyanCCollins/meetup-event-planner/tree/master/client/app/src/containers/ProfileContainer
handleSaving() {
const {
updateProfile,
bioInput,
avatarInput,
employerInput,
actions,
user,
refetch,
} = this.props;
const profile = {
bio: bioInput,
avatar: avatarInput,
employer: employerInput,
};
const variables = {
authToken: user.authToken,
profile,
};
actions.profileSubmissionInitiation();
updateProfile(variables)
.then(() => {
refetch();
actions.profileSubmissionSuccess();
})
.catch(err => {
actions.profileSubmissionFailure(err.message);
});
}
render() {
const {
user,
loading,
submissionError,
bioInput,
avatarInput,
isEditing,
employerInput,
} = this.props;
return (
<Box>
{loading &&
<LoadingIndicator isLoading={loading} />
}
{submissionError &&
<ToastMessage
status="critical"
message={submissionError}
onClose={this.handleClearError}
/>
}
{user &&
<Box className={styles.profile}>
<UserProfile
user={user}
isEditing={isEditing}
onEditEmail={this.handleEditingEmail}
onCancel={this.handleCancelEditing}
onEditBio={this.handleEditingBio}
onClickToEdit={this.handleClick}
onSaveEdit={this.handleSaving}
bioInput={bioInput}
onEditAvatar={this.handleEditingAvatar}
avatarInput={avatarInput}
onEditEmployer={this.handleEditingEmployer}
employerInput={employerInput}
/>
</Box>
}
</Box>
);
}
}
Profile.propTypes = {
actions: PropTypes.object.isRequired,
updateProfile: PropTypes.func.isRequired,
user: PropTypes.object,
error: PropTypes.string,
loading: PropTypes.bool.isRequired,
isEditing: PropTypes.bool.isRequired,
bioInput: PropTypes.string,
submissionError: PropTypes.string,
updateQueries: PropTypes.func.isRequired,
refetch: PropTypes.func.isRequired,
avatarInput: PropTypes.string,
employerInput: PropTypes.string,
};
// mapStateToProps :: {State} -> {Props}
const mapStateToProps = (state) => ({
user: state.authReducer.user,
bioInput: state.profileContainer.bioInput,
submissionError: state.profileContainer.error,
isEditing: state.profileContainer.isEditing,
avatarInput: state.profileContainer.avatarInput,
emailInput: state.profileContainer.emailInput,
employerInput: state.profileContainer.employerInput,
});
// mapDispatchToProps :: Dispatch -> {Action}
const mapDispatchToProps = (dispatch) => ({
actions: bindActionCreators(
Object.assign({},
AppActions,
ProfileActionCreators
),
dispatch
),
});
const Container = cssModules(Profile, styles);
const authUserDataFragment = createFragment(
gql`
fragment authUserData on AuthUser {
id
bio
email
name
avatar
employer
events {
name
id
}
}
`
);
const fetchUserData = gql`
query getAuthUser($token:String!) {
authUser(auth_token: $token) {
...authUserData
}
}
`;
const ContainerWithData = graphql(fetchUserData, {
options: (ownProps) => ({
skip: !ownProps.user.authToken,
variables: {
token: ownProps.user.authToken,
},
fragments: [authUserDataFragment],
}),
props: ({ data: { loading, authUser, error, refetch } }) => ({
loading,
error,
authUser,
refetch,
}),
})(Container);
const updateProfileMutation = gql`
mutation updateProfile($profile: ProfileInput, $authToken: String!) {
UpdateProfile(input: { profile: $profile, auth_token: $authToken }) {
user {
...authUserData
}
}
}
`;
const ContainerWithMutation = graphql(updateProfileMutation, {
options: () => ({
fragments: [authUserDataFragment],
}),
props: ({ ownProps, mutate }) => ({
updateProfile({ authToken, profile }) {
return new Promise((resolve, reject) =>
mutate({
variables: { authToken, profile },
})
.then(mutationResult => {
ownProps.actions.setPersistentUser(mutationResult.data.UpdateProfile.user);
resolve(mutationResult);
})
.catch(err => reject(err))
);
},
}),
})(ContainerWithData);
export default connect(
mapStateToProps,
mapDispatchToProps
)(ContainerWithMutation);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment