diff --git a/blocks/product-details-custom/ProductDetailsCarousel.js b/blocks/product-details-custom/ProductDetailsCarousel.js
index 8264b28266..fc498eb026 100644
--- a/blocks/product-details-custom/ProductDetailsCarousel.js
+++ b/blocks/product-details-custom/ProductDetailsCarousel.js
@@ -87,16 +87,6 @@ export default class Carousel extends Component {
});
}
- renderLabel() {
- const amasty = this.props.product?.amasty;
- if (!amasty) {
- return null;
- }
- return html`
- ${this.renderLabel()}
${!this.props.loading && html`
diff --git a/blocks/product-details/product-details.css b/blocks/product-details/product-details.css
index 3d8a3f1b50..730a3bdc70 100644
--- a/blocks/product-details/product-details.css
+++ b/blocks/product-details/product-details.css
@@ -1 +1,7 @@
-/* stylelint-disable no-empty-source */
\ No newline at end of file
+.pdp-product__buttons { /* stylelint-disable-line selector-class-pattern */
+ display: flex;
+}
+
+.pdp-product__buttons > .dropin-button--primary { /* stylelint-disable-line selector-class-pattern */
+ flex-grow: 1;
+}
diff --git a/blocks/product-details/product-details.js b/blocks/product-details/product-details.js
index e2d0c44d4b..06ffae7731 100644
--- a/blocks/product-details/product-details.js
+++ b/blocks/product-details/product-details.js
@@ -249,6 +249,24 @@ export default async function decorate(block) {
},
};
});
+
+ ctx.appendButton((next, state) => {
+ const adding = state.get('adding');
+ return ({
+ disabled: adding,
+ icon: 'Heart',
+ variant: 'secondary',
+ onClick: async () => {
+ try {
+ state.set('adding', true);
+ const { addToWishlist } = await import('../../scripts/wishlist/api.js');
+ await addToWishlist(next.values.sku);
+ } finally {
+ state.set('adding', false);
+ }
+ },
+ });
+ });
},
},
useACDL: true,
diff --git a/blocks/product-list-page-custom/ProductList.js b/blocks/product-list-page-custom/ProductList.js
index feef14e2bb..5fa1c33ab8 100644
--- a/blocks/product-list-page-custom/ProductList.js
+++ b/blocks/product-list-page-custom/ProductList.js
@@ -8,6 +8,7 @@ import {
} from '../../scripts/commerce.js';
const html = htm.bind(h);
+const searchUnitId = 'livesearch-plp';
class ProductCard extends Component {
constructor(props) {
@@ -49,7 +50,7 @@ class ProductCard extends Component {
onProductClick(product) {
window.adobeDataLayer.push((dl) => {
// TODO: Remove eventInfo once collector is updated
- dl.push({ event: 'search-product-click', eventInfo: { ...dl.getState(), searchUnitId: 'searchUnitId', sku: product.sku } });
+ dl.push({ event: 'search-product-click', eventInfo: { ...dl.getState(), searchUnitId, sku: product.sku } });
});
}
diff --git a/blocks/product-recommendations/product-recommendations.js b/blocks/product-recommendations/product-recommendations.js
index e18d3b49ea..459e56a6a1 100644
--- a/blocks/product-recommendations/product-recommendations.js
+++ b/blocks/product-recommendations/product-recommendations.js
@@ -132,9 +132,10 @@ const mapUnit = (unit) => ({
rank: index,
score: 0,
productId: parseInt(product.externalId, 10) || 0,
- type: '?',
- queryType: product.__typename,
+ type: product.__typename,
+ queryType: 'primary',
})),
+ pagePlacement: '',
});
async function loadRecommendation(block, context, visibility, filters) {
diff --git a/scripts/scripts.js b/scripts/scripts.js
index 5e86e9bf13..7048e96272 100644
--- a/scripts/scripts.js
+++ b/scripts/scripts.js
@@ -201,6 +201,9 @@ async function loadEager(doc) {
minXOffset: 0,
minYOffset: 0,
},
+ shoppingCartContext: {
+ totalQuantity: 0,
+ },
});
if (pageType !== 'Product') {
window.adobeDataLayer.push((dl) => {
diff --git a/scripts/wishlist/api.js b/scripts/wishlist/api.js
new file mode 100644
index 0000000000..1a75eed08b
--- /dev/null
+++ b/scripts/wishlist/api.js
@@ -0,0 +1,103 @@
+import { getSignInToken, performMonolithGraphQLQuery } from '../commerce.js';
+
+const redirectToSignin = () => {
+ window.location = '/customer/login';
+};
+
+const getWishlistsQuery = `
+ query GetWishlists {
+ customer {
+ wishlists {
+ id
+ name
+ items_count
+ items_v2 {
+ items {
+ id
+ product {
+ uid
+ name
+ sku
+ }
+ }
+ }
+ }
+ }
+}
+`;
+
+const addProductToWishlistMutation = `
+mutation(
+ $wishlistId: ID!,
+ $sku: String!
+) {
+ addProductsToWishlist(
+ wishlistId: $wishlistId,
+ wishlistItems: [
+ {
+ sku: $sku
+ quantity: 1
+ }
+ ]
+ ) {
+ user_errors {
+ code
+ message
+ }
+ wishlist {
+ name
+ }
+ }
+}
+`;
+
+export async function getWishlists() {
+ const token = getSignInToken();
+ if (!token) {
+ redirectToSignin();
+ }
+
+ const wishlists = await performMonolithGraphQLQuery(
+ getWishlistsQuery,
+ {},
+ true,
+ token,
+ );
+
+ if (wishlists.errors?.find((error) => error.message === "The current customer isn't authorized.")) {
+ redirectToSignin();
+ }
+
+ return wishlists.data?.customer?.wishlists;
+}
+
+/**
+ * Adds a product to the specified wishlist
+ * @param product SKU of the product to add
+ * @param wishlistId Optionally pass a wishlist. If no option, the first wishlist will be used.
+ * @returns {Promise}
+ */
+export async function addToWishlist(product, wishlistId) {
+ const token = getSignInToken();
+ if (!token) {
+ redirectToSignin();
+ }
+
+ const toWishlist = wishlistId ?? (await getWishlists())[0].id;
+
+ const response = await performMonolithGraphQLQuery(
+ addProductToWishlistMutation,
+ {
+ wishlistId: toWishlist,
+ sku: product,
+ },
+ false,
+ token,
+ );
+
+ if (response.user_errors) {
+ console.error(response.user_errors);
+ } else {
+ window.location = `/customer/wishlist?wishlist_id=${toWishlist}`;
+ }
+}