PageSourceSearch

https://inverterservicecenter.com/scripts/initializers/cart-alert.js

js inverterservicecenter.com collected 2026-10-07 08:05:41 UTC 4,381 bytes, 133 lines download raw bytes

1import { events } from '@dropins/tools/event-bus.js';
2import { InLineAlert, Icon, provider as UI } from '@dropins/tools/components.js';
3import { h, Fragment } from '@dropins/tools/preact.js';
4import { initializeDropin } from './index.js';
5import { fetchPlaceholders, rootLink } from '../commerce.js';
6import { loadCSS } from '../aem.js';
7import { insertAlertAfterBreadcrumbs } from '../utils/insert-alert-after-breadcrumbs.js';
8
9await initializeDropin(async () => {
10  // Load cart alert styles
11  await loadCSS(`${window.hlx.codeBasePath}/styles/cart-alert.css`);
12
13  const placeholders = await fetchPlaceholders();
14  const main = document.querySelector('main');
15  if (!main) return;
16
17  let currentAlert = null;
18  // Track whether alert should be shown for the next cart operation
19  let shouldShowAlert = false;
20
21  /**
22   * Builds heading: links the phrase "shopping cart" to the cart URL (placeholder or default).
23   * @param {string} productName
24   * @param {string} [placeholderTemplate]
25   * @param {string} cartURL
26   */
27  const buildCartAddedHeading = (productName, placeholderTemplate, cartURL) => {
28    const text = placeholderTemplate
29      ? placeholderTemplate.replace('{product}', productName)
30      : `You added ${productName} to your shopping cart.`;
31
32    const match = text.match(/shopping cart/i);
33    if (!match || match.index === undefined) {
34      return text;
35    }
36
37    const start = match.index;
38    const end = start + match[0].length;
39    const linkLabel = text.slice(start, end);
40
41    return h(
42      Fragment,
43      null,
44      text.slice(0, start),
45      h('a', {
46        href: cartURL,
47        className: 'cart-alert__link',
48      }, linkLabel),
49      text.slice(end),
50    );
51  };
52
53  /**
54   * Creates and displays a cart success alert
55   * @param {Array} items - Array of cart items that were added or updated
56   */
57  const showCartAlert = async (items) => {
58    // Only show alert if explicitly requested
59    if (!shouldShowAlert) {
60      return;
61    }
62
63    // Reset flag after checking
64    shouldShowAlert = false;
65    if (!items || items.length === 0) return;
66
67    // Get the first item's product name
68    const productName = items[0]?.name || items[0]?.product?.name || 'Product';
69    const cartURL = rootLink('/cart');
70
71    // Remove any existing alert
72    const existingAlert = main.querySelector('.cart-alert-container');
73    if (existingAlert) {
74      existingAlert.remove();
75      currentAlert = null;
76    }
77
78    // Create alert container after breadcrumbs (or first in main as fallback)
79    const alertContainer = document.createElement('div');
80    alertContainer.className = 'cart-alert-container';
81    alertContainer.setAttribute('role', 'region');
82    alertContainer.setAttribute('aria-live', 'polite');
83
84    insertAlertAfterBreadcrumbs(main, alertContainer);
85
86    const heading = buildCartAddedHeading(
87      productName,
88      placeholders?.Global?.CartAddedMessage,
89      cartURL,
90    );
91
92    currentAlert = await UI.render(InLineAlert, {
93      heading,
94      type: 'success',
95      variant: 'primary',
96      icon: h(Icon, { source: 'CheckWithCircle' }),
97      'aria-live': 'assertive',
98      role: 'alert',
99      onDismiss: () => {
100        if (currentAlert && alertContainer.parentNode) {
101          alertContainer.remove();
102          currentAlert = null;
103        }
104      },
105    })(alertContainer);
106
107    // Scroll so the breadcrumb alert is visible (same pattern as wishlist-alert).
108    setTimeout(() => {
109      window.scrollTo({ top: 0, behavior: 'smooth' });
110    }, 100);
111
112    // Auto-dismiss after 5 seconds
113    setTimeout(() => {
114      if (currentAlert && alertContainer.parentNode) {
115        alertContainer.remove();
116        currentAlert = null;
117      }
118    }, 5000);
119  };
120
121  // Listen for custom event that indicates whether alert should be shown
122  // This event should be emitted BEFORE calling cart API
123  // (addProductsToCart or updateProductsFromCart)
124  events.on('cart/action/before', (metadata) => {
125    // Set flag based on showAlert property (defaults to false if not specified)
126    shouldShowAlert = metadata?.showAlert === true;
127  }, { eager: false });
128
129  // Listen for both cart product added and updated events
130  // Alert will only show if shouldShowAlert flag was set to true
131  events.on('cart/product/added', showCartAlert, { eager: false });
132  events.on('cart/product/updated', showCartAlert, { eager: false });
133})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.