Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat): New Profile Address page #499

Merged
merged 42 commits into from
Feb 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
240f047
add ProfileImage component to context
kieckhafer Oct 8, 2018
d55a5dc
Create new Profile Address Book page
kieckhafer Oct 8, 2018
d78378b
add new profileAddressBook page to routes
kieckhafer Oct 8, 2018
868a8ac
update components version
kieckhafer Oct 8, 2018
b88e2fe
Merge branch 'develop' into feat-kieckhafer-newAccountPage
kieckhafer Oct 11, 2018
cadb988
Merge branch 'develop' into feat-kieckhafer-newAccountPage
kieckhafer Oct 15, 2018
ca5f487
update appComponent to include new components from library
kieckhafer Oct 15, 2018
9d3c6e7
add addressBook data to gql query
kieckhafer Oct 15, 2018
ff018a4
remove placeholder info
kieckhafer Oct 15, 2018
4f9b419
add icon contextual components
kieckhafer Oct 16, 2018
494c55b
rename profileAddressBook page to profile
kieckhafer Oct 16, 2018
706c8f4
add routes for addressBook and orders on profile
kieckhafer Oct 16, 2018
d2cec12
add placeholder route for payment options
kieckhafer Oct 16, 2018
09d39bb
add styles to component
kieckhafer Oct 16, 2018
92a8762
add helmet for meta data
kieckhafer Oct 16, 2018
de3f11a
fix import directory
kieckhafer Oct 16, 2018
3e28052
remove errant logs
kieckhafer Oct 16, 2018
e912192
rearrange code for better readability
kieckhafer Oct 16, 2018
20b7f87
Merge branch 'develop' into feat-kieckhafer-newAccountPage
kieckhafer Nov 26, 2018
2029221
Merge branch 'develop' into feat-kieckhafer-newAccountPage
kieckhafer Nov 26, 2018
6a20b2e
Merge branch 'feat-kieckhafer-newAccountPage' of github.com:reactionc…
kieckhafer Nov 26, 2018
1ccee08
temporary fix for AddressBook component error
kieckhafer Nov 26, 2018
68db5cf
chore: added AccordionFormList to components context
nnnnat Dec 7, 2018
1c1509c
chore: ask for address _id in viewer query
nnnnat Dec 7, 2018
bd9fc7e
feat: started creating address gql fragment and mutation
nnnnat Dec 7, 2018
3029761
feat: started a withAddressBook apollo container
nnnnat Dec 7, 2018
a6134dc
feat: connecting the profile AddressBook with gql data
nnnnat Dec 7, 2018
9ee6ffc
Merge branch 'develop' into feat-kieckhafer-newAccountPage
nnnnat Dec 7, 2018
a02ccf2
fix: pull from latest develop & fix merge conflicts
dancastellon Feb 1, 2019
62e09de
fix: profile - edit address, update cache on add/delete, add profile …
dancastellon Feb 4, 2019
7eec3c3
fix: lint fix: remove duplicate key
kieckhafer Feb 4, 2019
39d2ba5
Merge remote-tracking branch 'origin/develop' into feat-kieckhafer-ne…
kieckhafer Feb 8, 2019
c93d705
refactor: move ProfileAddressBook into its' own component
kieckhafer Feb 8, 2019
975a6b9
Merge remote-tracking branch 'origin/develop' into feat-kieckhafer-ne…
kieckhafer Feb 11, 2019
8546264
lint fixes
kieckhafer Feb 13, 2019
d2739de
test snapshot
kieckhafer Feb 13, 2019
b32e487
lint fixes
kieckhafer Feb 13, 2019
7b8cc79
Merge branch 'develop' into feat-kieckhafer-profileAddressPage
kieckhafer Feb 13, 2019
df198dc
add jest test default reporter
kieckhafer Feb 13, 2019
d2be9b8
remove failing test (fixed in #393)
kieckhafer Feb 13, 2019
539b163
add primaryShopId to withOrder
kieckhafer Feb 13, 2019
3ca97eb
Merge branch 'feat-kieckhafer-profileAddressPage' of github.com:/reac…
kieckhafer Feb 13, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
],
"coverageDirectory": "reports/coverage",
"reporters": [
"default",
"jest-junit"
],
"roots": [
Expand Down
7 changes: 6 additions & 1 deletion src/components/AccountDropdown/AccountDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const styles = (theme) => ({
width: 320,
padding: theme.spacing.unit * 2
},
authContent: {
marginBottom: {
marginBottom: theme.spacing.unit * 2
}
});
Expand Down Expand Up @@ -73,6 +73,11 @@ class AccountDropdown extends Component {
<div className={classes.accountDropdown}>
{authStore.isAuthenticated ?
<Fragment>
<div className={classes.marginBottom}>
<Button color="primary" fullWidth href="/profile/address">
Profile
</Button>
</div>
<Button color="primary" fullWidth href={`/logout/${account._id}`} variant="contained">
Sign Out
</Button>
Expand Down
75 changes: 75 additions & 0 deletions src/components/ProfileAddressBook/ProfileAddressBook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { inject, observer } from "mobx-react";
import Grid from "@material-ui/core/Grid";
import { withStyles } from "@material-ui/core/styles";
import AddressBook from "@reactioncommerce/components/AddressBook/v1";
import withAddressBook from "containers/address/withAddressBook";
import relayConnectionToArray from "lib/utils/relayConnectionToArray";
import ErrorPage from "../../pages/_error";

const styles = (theme) => ({
accountProfileInfoContainer: {
marginBottom: theme.spacing.unit * 4
}
});

@withStyles(styles)
@withAddressBook
@inject("authStore")
@inject("uiStore")
@observer
class ProfileAddressBook extends Component {
static propTypes = {
authStore: PropTypes.shape({
account: PropTypes.object.isRequired
}),
classes: PropTypes.object,
onAddressAdded: PropTypes.func.isRequired,
onAddressDeleted: PropTypes.func.isRequired,
onAddressEdited: PropTypes.func.isRequired,
shop: PropTypes.shape({
name: PropTypes.string.isRequired,
description: PropTypes.string
})
};

renderAddressBook() {
const {
authStore: { account: { addressBook } },
onAddressAdded,
onAddressEdited,
onAddressDeleted
} = this.props;
// Use relayConnectionToArray to remove edges / nodes levels from addressBook object
const addresses = (addressBook && relayConnectionToArray(addressBook)) || [];

// Create data object to pass to AddressBook component
const accountAddressBook = {
addressBook: addresses
};

return (
<AddressBook
account={accountAddressBook}
onAddressAdded={onAddressAdded}
onAddressEdited={onAddressEdited}
onAddressDeleted={onAddressDeleted}
/>
);
}

render() {
const { authStore: { account }, shop } = this.props;

if (account && !account._id) return <ErrorPage shop={shop} subtitle="Not Found" />;

return (
<Grid item xs={12} md={12}>
{this.renderAddressBook()}
</Grid>
);
}
}

export default ProfileAddressBook;
1 change: 1 addition & 0 deletions src/components/ProfileAddressBook/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./ProfileAddressBook";
19 changes: 19 additions & 0 deletions src/containers/account/viewer.gql
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
query viewer {
viewer {
_id
addressBook {
edges {
node {
_id
address1
address2
city
company
country
fullName
isBillingDefault
isCommercial
isShippingDefault
phone
postal
region
}
}
}
emailRecords {
address
}
Expand Down
20 changes: 20 additions & 0 deletions src/containers/address/fragments.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
fragment AddressCommon on Address {
address1
address2
city
postal
country
region
}

fragment FullAddressCommon on Address {
...AddressCommon
_id
fullName
company
isBillingDefault
isCommercial
isShippingDefault
metafields
phone
}
59 changes: 59 additions & 0 deletions src/containers/address/mutations.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
mutation addAccountAddressBookEntry($input: AddAccountAddressBookEntryInput!) {
addAccountAddressBookEntry(input: $input) {
address {
_id
address1
address2
city
company
country
fullName
isBillingDefault
isCommercial
isShippingDefault
phone
postal
region
}
}
}

mutation updateAccountAddressBookEntry($input: UpdateAccountAddressBookEntryInput!) {
updateAccountAddressBookEntry(input: $input) {
address {
_id
address1
address2
city
company
country
fullName
isBillingDefault
isCommercial
isShippingDefault
phone
postal
region
}
}
}

mutation removeAccountAddressBookEntry($input: RemoveAccountAddressBookEntryInput!) {
removeAccountAddressBookEntry(input: $input) {
address {
_id
address1
address2
city
company
country
fullName
isBillingDefault
isCommercial
isShippingDefault
phone
postal
region
}
}
}
160 changes: 160 additions & 0 deletions src/containers/address/withAddressBook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import React, { Component, Fragment } from "react";
import PropTypes from "prop-types";
import hoistNonReactStatic from "hoist-non-react-statics";
import { withApollo } from "react-apollo";
import { inject, observer } from "mobx-react";
import relayConnectionToArray from "lib/utils/relayConnectionToArray";
import viewerQuery from "../account/viewer.gql";
import {
addAccountAddressBookEntry,
updateAccountAddressBookEntry,
removeAccountAddressBookEntry
} from "./mutations.gql";

export default function withAddressBook(Comp) {
@withApollo
@inject("authStore")
@observer
class WithAddressBook extends Component {
static propTypes = {
authStore: PropTypes.shape({
account: PropTypes.object.isRequired
}),
client: PropTypes.shape({
query: PropTypes.func.isRequired
})
};

state = {};

get accountId() {
const { authStore } = this.props;
return authStore && authStore.account && authStore.account._id;
}

get accountAddressBook() {
const { authStore: { account: { addressBook } } } = this.props;
return (addressBook && relayConnectionToArray(addressBook)) || [];
}

/**
* @name handleAddAccountAddressBookEntry
* @summary Adds an address to current user's address book
* @param {Object} address Address to add
* @return {Undefined} undefined
*/
handleAddAccountAddressBookEntry = (address) => {
const { client: apolloClient } = this.props;

// TEMP delete `addressName` prop until API supports it.
delete address.addressName;

apolloClient.mutate({
mutation: addAccountAddressBookEntry,
variables: {
input: {
address,
accountId: this.accountId
}
},
update: (cache, { data: mutationData }) => {
if (mutationData && mutationData.addAccountAddressBookEntry) {
const { address: newAddressEntry } = mutationData.addAccountAddressBookEntry;
if (newAddressEntry) {
const cacheData = cache.readQuery({ query: viewerQuery });
if (!cacheData.viewer.addressBook) {
cacheData.viewer.addressBook = { edges: [] };
}
cacheData.viewer.addressBook.edges.push({
__typename: "AddressEdge",
node: newAddressEntry
});
// Update Apollo cache
cache.writeQuery({
query: viewerQuery,
data: cacheData
});
}
}
}
});
};

/**
* @name handleEditAccountAddressBookEntry
* @summary Updates an address in current user's address book
* @param {String} addressId _id of address to update
* @param {Object} updates Field updates
* @return {Undefined} undefined
*/
handleEditAccountAddressBookEntry = (addressId, updates) => {
const { client: apolloClient } = this.props;
apolloClient.mutate({
mutation: updateAccountAddressBookEntry,
variables: {
input: {
addressId,
accountId: this.accountId,
updates
}
}
});
};

/**
* @name handleRemoveAccountAddressBookEntry
* @summary Asks user to confirm, then deletes address from current user's address book
* @param {String} addressId _id of address to delete
* @return {Undefined} undefined
*/
handleRemoveAccountAddressBookEntry = (addressId) => {
const { client: apolloClient } = this.props;

if (!confirm("Delete this address?")) {
return;
}

apolloClient.mutate({
mutation: removeAccountAddressBookEntry,
variables: {
input: {
addressId,
accountId: this.accountId
}
},
update: (cache, { data: mutationData }) => {
if (mutationData && mutationData.removeAccountAddressBookEntry) {
const { address: removedAddressEntry } = mutationData.removeAccountAddressBookEntry;
if (removedAddressEntry) {
const cacheData = cache.readQuery({ query: viewerQuery });
const removedIndex = cacheData.viewer.addressBook.edges.findIndex((edge) => edge.node._id === addressId);
cacheData.viewer.addressBook.edges.splice(removedIndex, 1);
// Update Apollo cache
cache.writeQuery({
query: viewerQuery,
data: cacheData
});
}
}
}
});
};

render() {
return (
<Fragment>
<Comp
{...this.props}
onAddressAdded={this.handleAddAccountAddressBookEntry}
onAddressEdited={this.handleEditAccountAddressBookEntry}
onAddressDeleted={this.handleRemoveAccountAddressBookEntry}
/>
</Fragment>
);
}
}

hoistNonReactStatic(WithAddressBook, Comp);

return WithAddressBook;
}
Loading