PageSourceSearch

https://www.tauntonleisure.com/SiteSpecific/CustomContent/assets/pdp-rewards/rewards.js?=v1

js tauntonleisure.com collected 2026-10-04 20:42:13 UTC 5,791 bytes, 144 lines download raw bytes

1/**
2 * Rewards Points — standalone module
3 *
4 * Fetches rewards points for the current product and injects a static
5 * (non-accordion) rewards card above the sidepanel accordions.
6 *
7 * Depends on: universal_product (platform global), #seconddetails being
8 * present in the DOM (injected by pdp-sidepanel.js).
9 */
10(function () {
11  'use strict';
12
13  // ---------------------------------------------------------------------------
14  // Configuration — update per deployment
15  // ---------------------------------------------------------------------------
16  var CONFIG = {
17    endpoint:  '/wsCitrusStore.asmx/RewardsPointsFull',
18
19    // Selector for the element the rewards card is inserted before
20    insertBefore: '#ModularLongDescription',
21
22    // Only show the card when the rewards percentage meets or exceeds this value
23    threshold: 5,
24
25    text: {
26      // {name} → product name, {value} → £ value string, {pct} → percentage integer
27      earnLabel: 'Earn {pct}% Back in Reward Points',
28      intro:     'Purchase this {name} and receive <strong>{value}</strong> ({pct}%) of its value back in Reward Points, ready to use on a future purchase. You must be signed in to your account at the time of purchase to receive points. Points will not be added if you checkout as a guest.',
29      // Set to '' to hide
30      note:      '',
31      linkUrl:   '/ssl/customerrewardslogin.aspx',
32      linkText:  'Learn more',
33    }
34  };
35
36  // ---------------------------------------------------------------------------
37  // Icon
38  // ---------------------------------------------------------------------------
39  var ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M11.245 4.174c.317-.938 1.593-.938 1.91 0l1.387 4.104a1 1 0 0 0 .95.692h4.31c.985 0 1.394 1.26.598 1.838l-3.486 2.536a1 1 0 0 0-.364 1.117l1.387 4.103c.317.938-.77 1.716-1.567 1.117l-3.487-2.537a1 1 0 0 0-1.182 0l-3.487 2.537c-.797.599-1.884-.18-1.567-1.117l1.387-4.103a1 1 0 0 0-.364-1.117L3.6 10.808c-.796-.578-.387-1.838.598-1.838h4.31a1 1 0 0 0 .95-.692z"/></svg>';
40
41  // ---------------------------------------------------------------------------
42  // Percentage calculation
43  // ---------------------------------------------------------------------------
44  function calcRewards(rewardsPounds, salePrice) {
45    var pct      = salePrice > 0 ? Math.round((rewardsPounds / salePrice) * 100) : 0;
46    var cssClass = '';
47
48    if (pct >= 3) {
49      cssClass = 'pdpRewards--triple';
50    } else if (pct === 2) {
51      cssClass = 'pdpRewards--double';
52    }
53
54    return { pct: pct, cssClass: cssClass };
55  }
56
57  // ---------------------------------------------------------------------------
58  // Render
59  // ---------------------------------------------------------------------------
60  function render(productName, valueStr, pct, cssClass) {
61    var target = document.querySelector(CONFIG.insertBefore);
62    if (!target) return;
63
64    var earnLabel = CONFIG.text.earnLabel.replace('{pct}', pct);
65
66    var introText = CONFIG.text.intro
67      .replace('{name}', productName)
68      .replace('{value}', valueStr)
69      .replace('{pct}', pct);
70
71    var noteHtml = CONFIG.text.note
72      ? '<p class="pdpRewards-note">' + CONFIG.text.note + '</p>'
73      : '';
74
75    var linkHtml = CONFIG.text.linkUrl
76      ? '<a href="' + CONFIG.text.linkUrl + '" class="pdpRewards-link" target="_blank" rel="noopener">' + CONFIG.text.linkText + '</a>'
77      : '';
78
79    var html =
80      '<div id="pdpRewards" class="pdpRewards ' + cssClass + '">' +
81        '<div class="pdpRewards-header">' +
82          '<span class="pdpRewards-icon">' + ICON + '</span>' +
83          '<span class="pdpRewards-earn">' + earnLabel + '</span>' +
84          linkHtml +
85        '</div>' +
86        '<div class="pdpRewards-body">' +
87          '<p class="pdpRewards-intro">' + introText + '</p>' +
88          noteHtml +
89        '</div>' +
90      '</div>';
91
92    target.insertAdjacentHTML('beforebegin', html);
93  }
94
95  // ---------------------------------------------------------------------------
96  // Fetch
97  // ---------------------------------------------------------------------------
98  function init() {
99    if (typeof universal_product === 'undefined' || !universal_product) return;
100
101    var productName = universal_product.name || '';
102    var salePrice   = universal_product.unit_sale_price || 0;
103
104    var xhr = new XMLHttpRequest();
105    xhr.open('POST', CONFIG.endpoint, true);
106    xhr.setRequestHeader('Content-Type', 'application/json');
107
108    xhr.onreadystatechange = function () {
109      if (xhr.readyState !== 4) return;
110
111      if (xhr.status >= 200 && xhr.status < 300) {
112        try {
113          var result   = JSON.parse(xhr.responseText);
114          var valueStr = (result && result.d) ? result.d : null;
115
116          if (!valueStr) return;
117
118          var valuePounds = parseFloat(valueStr.replace('\u00A3', '').trim()) || 0;
119          var calc        = calcRewards(valuePounds, salePrice);
120
121          if (calc.pct < CONFIG.threshold) return;
122
123          render(productName, valueStr, calc.pct, calc.cssClass);
124        } catch (e) {
125          console.error('PDP Rewards: failed to parse response', e);
126        }
127      } else {
128        console.error('PDP Rewards: request failed with status ' + xhr.status);
129      }
130    };
131
132    xhr.send(JSON.stringify({ productId: universal_product.id, attributeDetailId: null }));
133  }
134
135  // ---------------------------------------------------------------------------
136  // Boot
137  // ---------------------------------------------------------------------------
138  if (document.readyState === 'loading') {
139    document.addEventListener('DOMContentLoaded', init);
140  } else {
141    init();
142  }
143
144}());

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.