PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / trunk
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant vtrunk
2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 All 59 releases
merchant / assets / js / admin / analytics.js

analytics.js in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant trunk, at assets/js/admin/analytics.js

1,437 lines 61.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 'use strict';
2
3 function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4 function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5 function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6 function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
7 function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
8 function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
9 function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
10 function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
11 function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
12 function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
13 function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
14 function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
15 function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
16 function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
17 function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
18 function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
19 (function ($) {
20 /**
21 * Main object for managing merchant analytics charts.
22 * @namespace merchantAnalyticsChart
23 */
24 var merchantAnalyticsChart = {
25 AJAX_URL: merchant_analytics.ajax_url,
26 NONCE: merchant_analytics.nonce,
27 impressionsChart: null,
28 revenueChart: null,
29 avgOrderValChart: null,
30 /**
31 * Options for the impressions chart (bar chart).
32 * @type {Object}
33 */
34 columnChartOptions: {
35 series: [{
36 data: []
37 }],
38 noData: {
39 text: 'No data available',
40 align: 'center',
41 verticalAlign: 'middle',
42 offsetX: 0,
43 offsetY: 0,
44 style: {
45 color: '#686868',
46 fontSize: '18px'
47 }
48 },
49 chart: {
50 type: 'bar',
51 height: 350,
52 stacked: false,
53 toolbar: {
54 show: false,
55 offsetX: -10,
56 offsetY: 10,
57 tools: {
58 download: false,
59 selection: true,
60 zoom: true,
61 zoomin: true,
62 zoomout: true,
63 pan: false,
64 reset: true
65 }
66 },
67 zoom: {
68 enabled: false,
69 allowMouseWheelZoom: false
70 }
71 },
72 plotOptions: {
73 bar: {
74 columnWidth: '20%',
75 borderRadius: 5,
76 borderRadiusApplication: 'end',
77 colors: {
78 backgroundBarColors: ['#ebeffd'],
79 backgroundBarRadius: 4
80 }
81 }
82 },
83 colors: ['#3A63E9'],
84 dataLabels: {
85 enabled: false
86 },
87 grid: {
88 show: true,
89 borderColor: '#D8D8D8',
90 strokeDashArray: 5,
91 position: 'back',
92 xaxis: {
93 lines: {
94 show: true,
95 offsetX: 60,
96 style: {
97 dashArray: 5
98 }
99 }
100 },
101 yaxis: {
102 lines: {
103 show: false
104 }
105 }
106 },
107 xaxis: {
108 axisTicks: {
109 show: false
110 },
111 axisBorder: {
112 show: true,
113 color: '#D8D8D8',
114 height: 1
115 }
116 },
117 tooltip: {
118 enabled: false
119 }
120 },
121 /**
122 * Options for the revenue chart (area chart).
123 * @type {Object}
124 */
125 revenueChartOptions: {
126 series: [{
127 data: []
128 }],
129 noData: {
130 text: 'No data available',
131 align: 'center',
132 verticalAlign: 'middle',
133 offsetX: 0,
134 offsetY: 0,
135 style: {
136 color: '#686868',
137 fontSize: '18px'
138 }
139 },
140 legend: {
141 show: false // This hides the legend
142 },
143 chart: {
144 type: 'area',
145 height: 350,
146 stacked: false,
147 toolbar: {
148 show: false,
149 offsetX: -10,
150 offsetY: 10,
151 tools: {
152 download: false,
153 selection: true,
154 zoom: true,
155 zoomin: true,
156 zoomout: true,
157 pan: false,
158 reset: true
159 }
160 },
161 zoom: {
162 enabled: false,
163 allowMouseWheelZoom: false
164 }
165 },
166 stroke: {
167 curve: 'smooth',
168 dashArray: 6,
169 width: 2,
170 lineCap: 'round'
171 },
172 fill: {
173 type: 'gradient',
174 gradient: {
175 inverseColors: false,
176 opacityFrom: 0.55,
177 opacityTo: 0.05,
178 stops: [10, 100]
179 }
180 },
181 markers: {
182 size: 5,
183 colors: ['#fff'],
184 strokeColors: '#3A63E9',
185 strokeWidth: 2,
186 hover: {
187 size: 6
188 }
189 },
190 colors: ['#3A63E9', '#393939'],
191 dataLabels: {
192 enabled: false
193 },
194 grid: {
195 show: true,
196 borderColor: '#D8D8D8',
197 strokeDashArray: 5,
198 position: 'back',
199 xaxis: {
200 lines: {
201 show: true,
202 offsetX: 60,
203 style: {
204 dashArray: 5
205 }
206 }
207 },
208 yaxis: {
209 lines: {
210 show: false
211 }
212 }
213 },
214 xaxis: {
215 axisTicks: {
216 show: false
217 },
218 axisBorder: {
219 show: true,
220 color: '#D8D8D8',
221 height: 1
222 },
223 tooltip: {
224 enabled: false
225 }
226 },
227 tooltip: {
228 fixed: {
229 offsetX: 0,
230 offsetY: 0
231 },
232 enabled: true,
233 theme: false,
234 custom: function custom(_ref) {
235 var series = _ref.series,
236 seriesIndex = _ref.seriesIndex,
237 dataPointIndex = _ref.dataPointIndex,
238 w = _ref.w;
239 var current_data = w.globals.initialSeries[seriesIndex].data[dataPointIndex];
240 return "\n <div class=\"arrow-box\">\n <div class=\"box-wrapper\">\n <div class=\"box-column big\">\n <div class=\"head\">\n <div class=\"box-title\">Total Income</div>\n <div class=\"box-value\">".concat(current_data.number_currency, "</div>\n </div>\n <div class=\"orders-count\">\n <strong>").concat(current_data.orders_count, "</strong> ").concat(merchant_analytics.labels.orders, "\n </div>\n </div>\n <div class=\"separator\"></div>\n <div class=\"box-column small\">\n <div class=\"head\">\n <svg width=\"64\" height=\"47\" viewBox=\"0 0 64 41\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- SVG content -->\n </svg>\n </div>\n <div class=\"change-percentage ").concat(current_data.diff_type, "\">\n <strong>").concat(current_data.difference, "%</strong>\n </div>\n </div>\n </div>\n </div>");
241 }
242 }
243 },
244 /**
245 * Options for the revenue chart (area chart).
246 * @type {Object}
247 */
248 widgetChartOptions: {
249 series: [{
250 data: []
251 }],
252 noData: {
253 text: 'No data available',
254 align: 'center',
255 verticalAlign: 'middle',
256 offsetX: 0,
257 offsetY: 0,
258 style: {
259 color: '#686868',
260 fontSize: '18px'
261 }
262 },
263 legend: {
264 show: false // This hides the legend
265 },
266 chart: {
267 type: 'area',
268 height: 350,
269 stacked: false,
270 toolbar: {
271 show: false,
272 offsetX: -10,
273 offsetY: 10,
274 tools: {
275 download: false,
276 selection: true,
277 zoom: true,
278 zoomin: true,
279 zoomout: true,
280 pan: false,
281 reset: true
282 }
283 },
284 zoom: {
285 enabled: false,
286 allowMouseWheelZoom: false
287 }
288 },
289 stroke: {
290 curve: 'smooth',
291 // dashArray: 6,
292 width: 2,
293 lineCap: 'round'
294 },
295 fill: {
296 type: 'gradient',
297 colors: ['#3A63E9'],
298 gradient: {
299 inverseColors: false,
300 opacityFrom: 0.55,
301 opacityTo: 0.15,
302 stops: [10, 100]
303 }
304 },
305 colors: ['#3A63E9'],
306 dataLabels: {
307 enabled: false
308 },
309 grid: {
310 show: true,
311 borderColor: '#D8D8D8',
312 strokeDashArray: 5,
313 position: 'back',
314 xaxis: {
315 lines: {
316 show: true,
317 offsetX: 60,
318 style: {
319 dashArray: 5
320 }
321 }
322 },
323 yaxis: {
324 lines: {
325 show: false
326 }
327 }
328 },
329 xaxis: {
330 axisTicks: {
331 show: false
332 },
333 axisBorder: {
334 show: true,
335 color: '#D8D8D8',
336 height: 1
337 },
338 tooltip: {
339 enabled: false
340 }
341 },
342 tooltip: {
343 enabled: false
344 }
345 },
346 /**
347 * Options for the average order value (AOV) chart (area chart).
348 * @type {Object}
349 */
350 avgOrderValChartOptions: {
351 series: [{
352 data: []
353 }],
354 noData: {
355 text: 'No data available',
356 align: 'center',
357 verticalAlign: 'middle',
358 offsetX: 0,
359 offsetY: 0,
360 style: {
361 color: '#686868',
362 fontSize: '18px'
363 }
364 },
365 chart: {
366 type: 'area',
367 height: 350,
368 stacked: false,
369 toolbar: {
370 show: false,
371 offsetX: -10,
372 offsetY: 10,
373 tools: {
374 download: false,
375 selection: true,
376 zoom: true,
377 zoomin: true,
378 zoomout: true,
379 pan: false,
380 reset: true
381 }
382 },
383 zoom: {
384 enabled: false,
385 allowMouseWheelZoom: false
386 }
387 },
388 stroke: {
389 curve: 'straight',
390 dashArray: 6,
391 width: 2
392 },
393 fill: {
394 type: 'gradient',
395 gradient: {
396 inverseColors: false,
397 opacityFrom: 0.55,
398 opacityTo: 0.05,
399 stops: [10, 100]
400 }
401 },
402 markers: {
403 size: 5,
404 colors: ['#fff'],
405 strokeColors: '#7880CA',
406 strokeWidth: 2,
407 hover: {
408 size: 6
409 }
410 },
411 colors: ['#7880CA'],
412 dataLabels: {
413 enabled: false
414 },
415 grid: {
416 show: true,
417 borderColor: '#D8D8D8',
418 strokeDashArray: 5,
419 position: 'back',
420 xaxis: {
421 lines: {
422 show: true,
423 offsetX: 60,
424 style: {
425 dashArray: 5
426 }
427 }
428 },
429 yaxis: {
430 lines: {
431 show: false
432 }
433 }
434 },
435 xaxis: {
436 axisTicks: {
437 show: false
438 },
439 axisBorder: {
440 show: true,
441 color: '#D8D8D8',
442 height: 1
443 },
444 tooltip: {
445 enabled: false
446 }
447 },
448 tooltip: {
449 enabled: true,
450 theme: false,
451 custom: function custom(_ref2) {
452 var series = _ref2.series,
453 seriesIndex = _ref2.seriesIndex,
454 dataPointIndex = _ref2.dataPointIndex,
455 w = _ref2.w;
456 var current_data = w.globals.initialSeries[seriesIndex].data[dataPointIndex];
457 return "\n <div class=\"arrow-box-aov\">\n <div class=\"box-title\">".concat(merchant_analytics.labels.orders_aov, "</div>\n <div class=\"box-value\">").concat(current_data.number_currency, " <span class=\"diff ").concat(current_data.diff_type, "\">").concat(current_data.difference, "%</span></div>\n </div>");
458 }
459 }
460 },
461 /**
462 * Sends an AJAX request and returns the response.
463 * @param {Object} data - The data to send with the request.
464 * @param {string} [loadingIndicatorSelector] - Selector for the loading indicator element.
465 * @param method - The HTTP method to use for the request.
466 * @returns {Promise} - The resolved response or rejected error.
467 */
468 sendAjaxRequest: function () {
469 var _sendAjaxRequest = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(data) {
470 var loadingIndicatorSelector,
471 method,
472 _args = arguments,
473 _t;
474 return _regenerator().w(function (_context) {
475 while (1) switch (_context.p = _context.n) {
476 case 0:
477 loadingIndicatorSelector = _args.length > 1 && _args[1] !== undefined ? _args[1] : '';
478 method = _args.length > 2 && _args[2] !== undefined ? _args[2] : 'GET';
479 _context.p = 1;
480 if (loadingIndicatorSelector) {
481 $(loadingIndicatorSelector).addClass('show');
482 }
483 _context.n = 2;
484 return $.ajax({
485 url: this.AJAX_URL,
486 method: method,
487 data: data
488 });
489 case 2:
490 return _context.a(2, _context.v);
491 case 3:
492 _context.p = 3;
493 _t = _context.v;
494 console.error('AJAX request failed:', _t);
495 throw _t;
496 case 4:
497 _context.p = 4;
498 if (loadingIndicatorSelector) {
499 $(loadingIndicatorSelector).removeClass('show');
500 }
501 return _context.f(4);
502 case 5:
503 return _context.a(2);
504 }
505 }, _callee, this, [[1, 3, 4, 5]]);
506 }));
507 function sendAjaxRequest(_x) {
508 return _sendAjaxRequest.apply(this, arguments);
509 }
510 return sendAjaxRequest;
511 }(),
512 /**
513 * Prepares data for an AJAX request.
514 * @param {string} action - The action to perform.
515 * @param {string} startDate - The start date for the data range.
516 * @param {string} endDate - The end date for the data range.
517 * @param {string} compareStartDate - The start date for the comparison range.
518 * @param {string} compareEndDate - The end date for the comparison range.
519 * @returns {Object} - The prepared data object.
520 */
521 prepareAjaxData: function prepareAjaxData(action, startDate, endDate) {
522 var compareStartDate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
523 var compareEndDate = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '';
524 return {
525 action: action,
526 nonce: this.NONCE,
527 start_date: startDate,
528 end_date: endDate,
529 compare_start_date: compareStartDate,
530 compare_end_date: compareEndDate
531 };
532 },
533 /**
534 * Updates the impressions chart with new data.
535 * @param {object} data - The selected date.
536 */
537 updateImpressionsChart: function () {
538 var _updateImpressionsChart = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(data) {
539 var _data$formattedDate, startDate, endDate, response, _t2;
540 return _regenerator().w(function (_context2) {
541 while (1) switch (_context2.p = _context2.n) {
542 case 0:
543 _data$formattedDate = _slicedToArray(data.formattedDate, 2), startDate = _data$formattedDate[0], endDate = _data$formattedDate[1];
544 _context2.p = 1;
545 _context2.n = 2;
546 return this.sendAjaxRequest(this.prepareAjaxData('merchant_get_impressions_chart_data', startDate, endDate), '.impressions-chart-section .merchant-analytics-loading-spinner');
547 case 2:
548 response = _context2.v;
549 if (response.success) {
550 this.impressionsChart.updateSeries([{
551 data: response.data
552 }]);
553 }
554 _context2.n = 4;
555 break;
556 case 3:
557 _context2.p = 3;
558 _t2 = _context2.v;
559 console.error('Error fetching impressions data:', _t2);
560 case 4:
561 return _context2.a(2);
562 }
563 }, _callee2, this, [[1, 3]]);
564 }));
565 function updateImpressionsChart(_x2) {
566 return _updateImpressionsChart.apply(this, arguments);
567 }
568 return updateImpressionsChart;
569 }(),
570 /**
571 * Updates the revenue chart with new data.
572 * @param {object} data - The selected date.
573 */
574 updateRevenueChart: function () {
575 var _updateRevenueChart = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(data) {
576 var _data$formattedDate2, startDate, endDate, response, _t3;
577 return _regenerator().w(function (_context3) {
578 while (1) switch (_context3.p = _context3.n) {
579 case 0:
580 _data$formattedDate2 = _slicedToArray(data.formattedDate, 2), startDate = _data$formattedDate2[0], endDate = _data$formattedDate2[1];
581 _context3.p = 1;
582 _context3.n = 2;
583 return this.sendAjaxRequest(this.prepareAjaxData('merchant_get_revenue_chart_data', startDate, endDate), '.revenue-chart-section .merchant-analytics-loading-spinner');
584 case 2:
585 response = _context3.v;
586 if (response.success) {
587 this.revenueChart.updateSeries([{
588 data: response.data
589 }]);
590 }
591 _context3.n = 4;
592 break;
593 case 3:
594 _context3.p = 3;
595 _t3 = _context3.v;
596 console.error('Error fetching revenue data:', _t3);
597 case 4:
598 return _context3.a(2);
599 }
600 }, _callee3, this, [[1, 3]]);
601 }));
602 function updateRevenueChart(_x3) {
603 return _updateRevenueChart.apply(this, arguments);
604 }
605 return updateRevenueChart;
606 }(),
607 /**
608 * Updates the average order value (AOV) chart with new data.
609 * @param {object} data - The selected date.
610 */
611 updateAOVChart: function () {
612 var _updateAOVChart = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(data) {
613 var _data$formattedDate3, startDate, endDate, response, _t4;
614 return _regenerator().w(function (_context4) {
615 while (1) switch (_context4.p = _context4.n) {
616 case 0:
617 _data$formattedDate3 = _slicedToArray(data.formattedDate, 2), startDate = _data$formattedDate3[0], endDate = _data$formattedDate3[1];
618 _context4.p = 1;
619 _context4.n = 2;
620 return this.sendAjaxRequest(this.prepareAjaxData('merchant_get_avg_order_value_chart_data', startDate, endDate), '.aov-chart-section .merchant-analytics-loading-spinner');
621 case 2:
622 response = _context4.v;
623 if (response.success) {
624 this.avgOrderValChart.updateSeries([{
625 data: response.data
626 }]);
627 }
628 _context4.n = 4;
629 break;
630 case 3:
631 _context4.p = 3;
632 _t4 = _context4.v;
633 console.error('Error fetching AOV data:', _t4);
634 case 4:
635 return _context4.a(2);
636 }
637 }, _callee4, this, [[1, 3]]);
638 }));
639 function updateAOVChart(_x4) {
640 return _updateAOVChart.apply(this, arguments);
641 }
642 return updateAOVChart;
643 }(),
644 /**
645 * Updates the overview cards with new data.
646 * @param {Object} dates - The selected date ranges.
647 * @returns {Promise<void>}
648 */
649 updateOverviewCards: function () {
650 var _updateOverviewCards = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(dates) {
651 var response, _t5;
652 return _regenerator().w(function (_context5) {
653 while (1) switch (_context5.p = _context5.n) {
654 case 0:
655 _context5.p = 0;
656 _context5.n = 1;
657 return this.sendAjaxRequest(this.prepareAjaxData($('.merchant-analytics-overview-section').attr('data-action'), dates.startDate, dates.endDate, dates.compareStartDate, dates.compareEndDate), '.merchant-analytics-overview-section .merchant-analytics-loading-spinner');
658 case 1:
659 response = _context5.v;
660 if (response.success) {
661 // Update the cards with the new data
662 this.updateCardsWithData(response.data);
663 }
664 _context5.n = 3;
665 break;
666 case 2:
667 _context5.p = 2;
668 _t5 = _context5.v;
669 console.error('Error fetching cards data:', _t5);
670 case 3:
671 return _context5.a(2);
672 }
673 }, _callee5, this, [[0, 2]]);
674 }));
675 function updateOverviewCards(_x5) {
676 return _updateOverviewCards.apply(this, arguments);
677 }
678 return updateOverviewCards;
679 }(),
680 /**
681 * Updates the overview cards with new data.
682 * @param {Object} data - The data to update the cards with.
683 */
684 updateCardsWithData: function updateCardsWithData(data) {
685 var container = $('.merchant-analytics-overview-section');
686 var cards = container.find('.overview-cards');
687 cards.html(data);
688 },
689 /**
690 * Updates the performing campaigns table with new data.
691 *
692 * @param {Object} dates - The selected date ranges.
693 *
694 * @returns {Promise<void>}
695 */
696 updatePerformingCampaignsTable: function () {
697 var _updatePerformingCampaignsTable = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(dates) {
698 var response, _t6;
699 return _regenerator().w(function (_context6) {
700 while (1) switch (_context6.p = _context6.n) {
701 case 0:
702 _context6.p = 0;
703 _context6.n = 1;
704 return this.sendAjaxRequest(this.prepareAjaxData('merchant_get_top_performing_campaigns_table_data', dates.startDate, dates.endDate, '', ''), '.merchant-analytics-overview-section .merchant-analytics-loading-spinner');
705 case 1:
706 response = _context6.v;
707 if (response.success) {
708 // Update the cards with the new data
709 this.updateTopCampaignsWithData(response.data, dates.container);
710 }
711 _context6.n = 3;
712 break;
713 case 2:
714 _context6.p = 2;
715 _t6 = _context6.v;
716 console.error('Error fetching cards data:', _t6);
717 case 3:
718 return _context6.a(2);
719 }
720 }, _callee6, this, [[0, 2]]);
721 }));
722 function updatePerformingCampaignsTable(_x6) {
723 return _updatePerformingCampaignsTable.apply(this, arguments);
724 }
725 return updatePerformingCampaignsTable;
726 }(),
727 /**
728 * Updates the all campaigns table with new data.
729 * @param dates - The selected date ranges.
730 * @returns {Promise<void>} - The resolved promise.
731 */
732 updateAllCampaignsTable: function () {
733 var _updateAllCampaignsTable = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(dates) {
734 var response, _t7;
735 return _regenerator().w(function (_context7) {
736 while (1) switch (_context7.p = _context7.n) {
737 case 0:
738 _context7.p = 0;
739 _context7.n = 1;
740 return this.sendAjaxRequest(this.prepareAjaxData('merchant_get_all_campaigns_table_data', dates.startDate, dates.endDate, '', ''), '.merchant-page-campaigns .merchant-analytics-loading-spinner');
741 case 1:
742 response = _context7.v;
743 if (response.success) {
744 // Update the cards with the new data
745 this.updateAllCampaignsWithData(response.data, dates.container);
746 this.populateFilterSelect(dates.container);
747 }
748 _context7.n = 3;
749 break;
750 case 2:
751 _context7.p = 2;
752 _t7 = _context7.v;
753 console.error('Error fetching cards data:', _t7);
754 case 3:
755 return _context7.a(2);
756 }
757 }, _callee7, this, [[0, 2]]);
758 }));
759 function updateAllCampaignsTable(_x7) {
760 return _updateAllCampaignsTable.apply(this, arguments);
761 }
762 return updateAllCampaignsTable;
763 }(),
764 /**
765 * Updates the top campaigns table with new data.
766 * @param data
767 * @param container
768 */
769 updateTopCampaignsWithData: function updateTopCampaignsWithData(data, container) {
770 var table_body = container.find('tbody');
771 container.find('table th').removeClass('asc desc');
772 table_body.empty();
773 $.each(data, function (campaignId, campaign) {
774 // Create the HTML for each row using template literals
775 var rowHTML = "\n\t\t <tr>\n\t\t <td>".concat(campaign.campaign_info.module_name, ": ").concat(campaign.campaign_info.campaign_title, "</td>\n\t\t <td>").concat(campaign.impressions, "</td>\n\t\t <td>").concat(campaign.clicks, "</td>\n\t\t <td class=\"ctr\">").concat(campaign.ctr, "</td>\n\t\t <td>").concat(campaign.orders, "</td>\n\t\t <td>").concat(campaign.revenue, "</td>\n\t\t </tr>\n\t\t ");
776
777 // Append the row HTML to the container
778 $(table_body).append(rowHTML);
779 });
780 },
781 /**
782 * Updates all campaigns table with new data.
783 * @param data - The data to update the table with.
784 * @param container - The container element for the table.
785 */
786 updateAllCampaignsWithData: function updateAllCampaignsWithData(data, container) {
787 var self = this;
788 var rowsHTML = [];
789 var table_body = container.find('tbody');
790 table_body.empty();
791 container.find('table th').removeClass('asc desc');
792 container.find('.js-campaign-search').val('');
793 container.find('.no-results-message').hide();
794 var count = 0;
795 var $pagination = container.find('.js-pagination');
796 var rowsPerPage = parseInt($pagination.attr('data-rows-per-page'));
797 $.each(data, function (moduleIndex, module_object) {
798 // Extract module and campaign info
799 var moduleId = module_object.module_id;
800 // check if module_object.campaigns is not empty
801 if (module_object.campaigns.length > 0) {
802 // Loop through each campaign
803 module_object.campaigns.forEach(function (campaign, index) {
804 var _campaign$revenue;
805 count++;
806 var switcherId = "".concat(moduleId, "-campaign-").concat(moduleIndex, "-").concat(index);
807 rowsHTML.push("\n\t\t\t\t <tr\n\t\t\t\t \tclass=\"".concat(count > rowsPerPage ? 'is-hidden' : '', "\"\n\t\t\t\t \t").concat(count > rowsPerPage ? 'style="display: none;"' : '', "\n\t\t\t\t data-module-id=\"").concat(moduleId, "\"\n\t\t\t\t data-campaign-key=\"").concat(campaign.campaign_key, "\"\n\t\t\t\t data-campaign-id=\"").concat(campaign.campaign_id, "\"\n\t\t\t\t data-row-count=\"").concat(count, "\">\n\t\t\t\t <td><input type=\"checkbox\" name=\"campaign_select[]\" value=\"").concat(campaign.title, "\" /></td>\n\t\t\t\t <td class=\"merchant__campaign-name js-campaign-name\">").concat(campaign.title, "</td>\n\t\t\t\t <td class=\"merchant__module-name js-module-name\" data-module-id=\"").concat(module_object.module_id, "\">").concat(module_object.module_name, "</td>\n\t\t\t\t <td class=\"merchant__status merchant-module-page-setting-field-switcher js-status\">\n\t\t\t\t ").concat(campaign.status === 'active' || campaign.status === 'inactive' ? "<div class=\"merchant-toggle-switch\">\n\t\t\t\t\t\t\t\t <input type=\"checkbox\" id=\"".concat(switcherId, "\" name=\"merchant[").concat(switcherId, "]\" value=\"").concat(campaign.status === 'active' ? '1' : '', "\" ").concat(campaign.status === 'active' ? 'checked ' : '', "class=\"toggle-switch-checkbox\">\n\t\t\t\t\t\t\t\t <label class=\"toggle-switch-label\" for=\"").concat(switcherId, "\">\n\t\t\t\t\t\t\t\t <span class=\"toggle-switch-inner\"></span>\n\t\t\t\t\t\t\t\t <span class=\"toggle-switch-switch\"></span>\n\t\t\t\t\t\t\t\t </label>\n\t\t\t\t\t\t\t\t\t\t\t</div>") : '-', "\n\t\t\t\t </td>\n\t\t\t\t <td class=\"merchant__impressions\">").concat(campaign.impression, "</td>\n\t\t\t\t <td class=\"merchant__clicks\">").concat(campaign.clicks, "</td>\n\t\t\t\t <td class=\"merchant__revenue\">").concat((_campaign$revenue = campaign.revenue) !== null && _campaign$revenue !== void 0 ? _campaign$revenue : '-', "</td>\n\t\t\t\t <td class=\"merchant__ctr\">").concat(campaign.ctr, "</td>\n\t\t\t\t <td class=\"merchant__orders\">").concat(campaign.orders, "</td>\n\t\t\t\t <td class=\"merchant__edit\">\n\t\t\t\t <a href=\"").concat(module_object.edit_url || '#', "\" target=\"_blank\">\n\t\t\t\t <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n\t\t\t\t <path d=\"M8.30399 1.00174C8.90067 0.405063 9.8596 0.405063 10.4563 1.00174L10.7333 1.27876C11.33 1.87543 11.33 2.83437 10.7333 3.43104L6.51398 7.65037C6.3435 7.82085 6.10909 7.97001 5.85338 8.03394L3.7224 8.65192C3.55193 8.69454 3.36014 8.65192 3.23228 8.50276C3.08311 8.3749 3.04049 8.18311 3.08311 8.01263L3.70109 5.88166C3.76502 5.62594 3.91419 5.39154 4.08467 5.22106L8.30399 1.00174ZM9.73175 1.72627C9.53996 1.53448 9.22031 1.53448 9.02852 1.72627L8.38923 2.34425L9.39079 3.3458L10.0088 2.70651C10.2006 2.51473 10.2006 2.19508 10.0088 2.00329L9.73175 1.72627ZM4.68134 6.15869L4.31908 7.41596L5.57635 7.0537C5.66159 7.03239 5.72552 6.98977 5.78945 6.92584L8.66626 4.04903L7.68601 3.06878L4.8092 5.94559C4.74527 6.00952 4.70265 6.07345 4.68134 6.15869ZM4.61741 1.83281C4.89444 1.83281 5.12885 2.06722 5.12885 2.34425C5.12885 2.64258 4.89444 2.85568 4.61741 2.85568H2.23072C1.7406 2.85568 1.37834 3.23926 1.37834 3.70807V9.50431C1.37834 9.99444 1.7406 10.3567 2.23072 10.3567H8.02697C8.49578 10.3567 8.87936 9.99444 8.87936 9.50431V7.11763C8.87936 6.8406 9.09245 6.60619 9.39079 6.60619C9.66782 6.60619 9.90222 6.8406 9.90222 7.11763V9.50431C9.90222 10.5485 9.04983 11.3796 8.02697 11.3796H2.23072C1.18655 11.3796 0.355469 10.5485 0.355469 9.50431V3.70807C0.355469 2.6852 1.18655 1.83281 2.23072 1.83281H4.61741Z\" fill=\"#565865\"/>\n\t\t\t\t </svg>\n\t\t\t\t Edit\n\t\t\t\t </a>\n\t\t\t\t </td>\n\t\t\t\t </tr>\n\t\t\t\t "));
808 });
809 }
810 });
811 $(table_body).append(rowsHTML.join(''));
812
813 // Reset pagination initial state
814 self.updatePaginationButtons(1, parseInt($pagination.attr('data-total-pages-initial')), parseInt($pagination.attr('data-total-rows-initial')));
815 },
816 /**
817 * Initializes the date picker for a chart container.
818 * @param {jQuery} container - The container element for the chart.
819 * @param {Object} options - Options for the date picker.
820 * @param {Function} options.onSelectHandler - Callback function for date selection.
821 * @param {Object} options.datePickerArgs - Additional arguments for the date picker.
822 */
823 datePickerInit: function datePickerInit(container, _ref3) {
824 var onSelectHandler = _ref3.onSelectHandler,
825 datePickerArgs = _ref3.datePickerArgs;
826 var inputs = container.find('.date-range-input');
827 if (!inputs.length) {
828 return;
829 }
830 inputs.each(function () {
831 var datePicker = $(this);
832 var initialValue = datePicker.val();
833 var selectedDates = [];
834 if (initialValue) {
835 selectedDates = initialValue.split(' - ').map(function (dateStr) {
836 return new Date(dateStr.trim());
837 });
838 }
839 var dpArgs = _objectSpread(_objectSpread({}, {
840 maxDate: new Date(),
841 locale: JSON.parse(merchant_datepicker_locale),
842 range: true,
843 position: 'bottom right',
844 dateFormat: 'MM/dd/yy',
845 selectedDates: selectedDates,
846 // Set the selected dates
847 multipleDatesSeparator: ' - ',
848 onSelect: function onSelect(data) {
849 if (typeof onSelectHandler === 'function') {
850 onSelectHandler(data);
851 }
852 }
853 }), datePickerArgs);
854 new AirDatepicker(datePicker.get(0), dpArgs);
855 });
856 },
857 /**
858 * Initializes the overview cards.
859 */
860 initOverviewCards: function initOverviewCards() {
861 var _this = this;
862 var container = $('.merchant-analytics-overview-section');
863
864 // Initialize the date picker
865 this.datePickerInit(container, {
866 onSelectHandler: function onSelectHandler() {
867 // Get both date range inputs
868 var firstInput = container.find('.first-date-range .date-range-input');
869 var secondInput = container.find('.second-date-range .date-range-input');
870 var firstDateRange = firstInput.val().split(' - ').map(function (dateStr) {
871 return dateStr.trim();
872 });
873 var secondDateRange = secondInput.val().split(' - ').map(function (dateStr) {
874 return dateStr.trim();
875 });
876
877 // Ensure both date ranges have exactly two dates
878 if (firstDateRange.length === 2 && secondDateRange.length === 2) {
879 _this.updateOverviewCards({
880 startDate: firstDateRange[0],
881 endDate: firstDateRange[1],
882 compareStartDate: secondDateRange[0],
883 compareEndDate: secondDateRange[1]
884 });
885 }
886 }
887 });
888 },
889 /**
890 * Renders a chart and initializes its date picker.
891 * @param {jQuery} container - The container element for the chart.
892 * @param {Object} chartOptions - Options for the ApexCharts instance.
893 * @param {Function} updateFunction - Function to call when the date is selected.
894 * @param {string} loadingIndicatorSelector - Selector for the loading indicator.
895 * @param datePickerArgs
896 * @returns {ApexCharts} - The rendered chart instance.
897 */
898 renderChart: function renderChart(container, chartOptions, updateFunction, loadingIndicatorSelector) {
899 var datePickerArgs = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
900 var chartEl = container.find('.chart');
901 if (!chartEl.length) {
902 return;
903 }
904 var chart = new ApexCharts(chartEl.get(0), chartOptions);
905 chart.render();
906 chart.updateSeries([{
907 data: JSON.parse(chartEl.attr('data-period'))
908 }]);
909 this.datePickerInit(container, {
910 onSelectHandler: function onSelectHandler(data) {
911 if (data.formattedDate.length === 2) {
912 updateFunction(data);
913 }
914 },
915 datePickerArgs: datePickerArgs
916 });
917 return chart;
918 },
919 /**
920 * Renders the revenue chart.
921 */
922 widgetChartRender: function widgetChartRender() {
923 var _this2 = this;
924 var container = $('.widget-chart-section');
925 var isRTL = $('body').hasClass('rtl');
926 merchantAnalyticsChart.revenueChart = this.renderChart(container, this.widgetChartOptions, function (data) {
927 return _this2.updateRevenueChart(data);
928 }, '.widget-chart-section .merchant-analytics-loading-spinner', {
929 position: isRTL ? 'top right' : 'top left'
930 });
931 },
932 /**
933 * Renders the revenue chart.
934 */
935 revenueChartRender: function revenueChartRender() {
936 var _this3 = this;
937 var container = $('.revenue-chart-section');
938 if (container.length) {
939 this.revenueChart = this.renderChart(container, this.revenueChartOptions, function (data) {
940 return _this3.updateRevenueChart(data);
941 }, '.revenue-chart-section .merchant-analytics-loading-spinner');
942 }
943 },
944 /**
945 * Renders the average order value (AOV) chart.
946 */
947 avgOrderValChartRender: function avgOrderValChartRender() {
948 var _this4 = this;
949 var container = $('.aov-chart-section');
950 if (container.length) {
951 this.avgOrderValChart = this.renderChart(container, this.avgOrderValChartOptions, function (data) {
952 return _this4.updateAOVChart(data);
953 }, '.aov-chart-section .merchant-analytics-loading-spinner');
954 }
955 },
956 /**
957 * Renders the impressions chart.
958 */
959 impressionsChartRender: function impressionsChartRender() {
960 var _this5 = this;
961 var container = $('.impressions-chart-section');
962 if (container.length) {
963 this.impressionsChart = this.renderChart(container, this.columnChartOptions, function (data) {
964 return _this5.updateImpressionsChart(data);
965 }, '.impressions-chart-section .merchant-analytics-loading-spinner');
966 }
967 },
968 /**
969 * Initializes the top campaigns table.
970 */
971 initTopCampaignsTable: function initTopCampaignsTable() {
972 var container = $('.merchant-analytics-section.campaigns-table');
973 var self = this;
974 if (container.length) {
975 // Initialize the date picker
976 this.datePickerInit(container, {
977 onSelectHandler: function onSelectHandler() {
978 // Get both date range inputs
979 var firstInput = container.find('.first-date-range .date-range-input');
980 var firstDateRange = firstInput.val().split(' - ').map(function (dateStr) {
981 return dateStr.trim();
982 });
983
984 // Ensure both date ranges have exactly two dates
985 if (firstDateRange.length === 2) {
986 self.updatePerformingCampaignsTable({
987 startDate: firstDateRange[0],
988 endDate: firstDateRange[1],
989 container: container
990 });
991 }
992 },
993 datePickerArgs: {
994 position: 'top right'
995 }
996 });
997 this.setupSortableTableEventListeners(container);
998 }
999 },
1000 /**
1001 * Initializes the all campaigns table.
1002 */
1003 initAllCampaignsTable: function initAllCampaignsTable() {
1004 var container = $('.merchant-analytics-section.all-campaigns-table');
1005 var self = this;
1006 if (container.length) {
1007 // Initialize the date picker
1008 this.datePickerInit(container, {
1009 onSelectHandler: function onSelectHandler() {
1010 // Get both date range inputs
1011 var firstInput = container.find('.first-date-range .date-range-input');
1012 var firstDateRange = firstInput.val().split(' - ').map(function (dateStr) {
1013 return dateStr.trim();
1014 });
1015
1016 // Ensure both date ranges have exactly two dates
1017 if (firstDateRange.length === 2) {
1018 self.updateAllCampaignsTable({
1019 startDate: firstDateRange[0],
1020 endDate: firstDateRange[1],
1021 container: container
1022 });
1023 }
1024 }
1025 });
1026 self.setupSortableTableEventListeners(container);
1027 self.populateFilterSelect(container);
1028 }
1029 },
1030 /**
1031 * Filters the table based on the the available module in the table
1032 *
1033 * @param container - The table container element.
1034 */
1035 populateFilterSelect: function populateFilterSelect(container) {
1036 var table = container.find('.js-campaigns-table');
1037 var selectorField = $('.filter-campaign select');
1038 // Clear all options except the first one
1039 $(selectorField).find('option:not(:first)').remove();
1040
1041 // Get unique values from the specified table column
1042 var values = [];
1043 $(table).find('tr .js-module-name').each(function () {
1044 var value = $(this).attr('data-module-id');
1045 var label = $(this).text().trim();
1046
1047 // Check if the value is not already in the values array
1048 if (value && !values.some(function (item) {
1049 return item.value === value;
1050 })) {
1051 values.push({
1052 value: value,
1053 label: label
1054 });
1055 }
1056 });
1057
1058 // Sort the values alphabetically (optional)
1059 values.sort();
1060
1061 // Append new options to the select field
1062 $.each(values, function (index, item) {
1063 $(selectorField).append($('<option>', {
1064 value: item.value,
1065 text: item.label
1066 }));
1067 });
1068 },
1069 /**
1070 * Add event listeners to the sortable table.
1071 * @param container
1072 */
1073 setupSortableTableEventListeners: function setupSortableTableEventListeners(container) {
1074 var self = this;
1075 container.find('th:not(.no-sort)').on('click', function (event) {
1076 self.sortableTable($(event.currentTarget), container);
1077 });
1078 var table = $('.js-campaigns-table');
1079 var searchInput = $('.js-campaign-search');
1080 var filterSelect = $('.js-filter-module');
1081 var bulkActionBtn = $('.js-bulk-action');
1082 var $pagination = $('.js-pagination');
1083
1084 // "Select All" checkbox
1085 table.find('thead th:first-child input[type="checkbox"]').on('change', function () {
1086 var isChecked = $(this).prop('checked');
1087 table.find('tbody tr:not(.is-hidden) input[type="checkbox"]:not(.toggle-switch-checkbox)').prop('checked', isChecked);
1088 });
1089
1090 // Status - Single row
1091 table.on('change', '.js-status input[type="checkbox"]', function () {
1092 var checkbox = $(this);
1093 var row = checkbox.closest('tr');
1094 var moduleId = row.attr('data-module-id');
1095 var campaignData = _defineProperty({}, moduleId, {
1096 campaign_key: row.attr('data-campaign-key'),
1097 campaigns: [{
1098 campaign_id: row.attr('data-campaign-id'),
1099 status: checkbox.prop('checked') ? 'active' : 'inactive'
1100 }]
1101 });
1102 self.updateCampaignStatus(campaignData, checkbox, [checkbox], true);
1103 });
1104
1105 // Status - Bulk action
1106 bulkActionBtn.on('click', function (e) {
1107 e.preventDefault();
1108 var $select = $(this).closest('.bulk-action').find('select');
1109 var statusAction = $select.val();
1110 if (!statusAction) {
1111 alert('Please select an action.');
1112 return;
1113 }
1114 var $checkboxes = table.find('tbody tr:not(.is-hidden) input[type="checkbox"]:not(.toggle-switch-checkbox):checked');
1115 if (!$checkboxes.length) {
1116 alert('Please select campaigns.');
1117 return;
1118 }
1119 var campaignData = {};
1120 $checkboxes.each(function () {
1121 var $row = $(this).closest('tr');
1122 var moduleId = $row.attr('data-module-id');
1123 if (!campaignData[moduleId]) {
1124 campaignData[moduleId] = {
1125 campaign_key: $row.attr('data-campaign-key'),
1126 campaigns: []
1127 };
1128 }
1129 campaignData[moduleId].campaigns.push({
1130 campaign_id: $row.attr('data-campaign-id'),
1131 status: statusAction
1132 });
1133 });
1134 self.updateCampaignStatus(campaignData, $(this), $checkboxes);
1135 });
1136
1137 // Search input
1138 searchInput.on('input', self.debounce(function () {
1139 self.filterTableTable(filterSelect.val(), table, $(this).val());
1140 }, 300));
1141
1142 // Module filter
1143 filterSelect.on('change', function () {
1144 self.filterTableTable($(this).val(), table, '');
1145 searchInput.val('');
1146 });
1147
1148 // Pagination clicks
1149 $pagination.on('click', '.pagination-button', function (e) {
1150 e.preventDefault();
1151 var currentPage = parseInt($(this).attr('data-current-page'));
1152 var nextPage = parseInt($(this).attr('data-page'));
1153 if (isNaN(nextPage) || nextPage === currentPage) {
1154 return;
1155 }
1156 currentPage = nextPage;
1157 self.paginateRows(currentPage, table.find('tbody tr'));
1158 self.updatePaginationButtons(currentPage);
1159 });
1160 },
1161 /**
1162 * Make the table sortable by the selected column.
1163 * @param header - The header element that was clicked.
1164 * @param container - The table container element.
1165 */
1166 sortableTable: function sortableTable(header, container) {
1167 var self = this;
1168 var column = header.index();
1169 var type = header.data('sort');
1170 var currentOrder = header.hasClass('asc') ? 'desc' : 'asc';
1171
1172 // Remove previous sorting classes
1173 container.find('th').removeClass('asc desc');
1174
1175 // Add class to indicate current sorting order
1176 header.addClass(currentOrder);
1177 var tbody = container.find('tbody');
1178 var rows = tbody.find('tr').toArray();
1179 rows.sort(function (a, b) {
1180 var keyA = $(a).find('td').eq(column).text();
1181 var keyB = $(b).find('td').eq(column).text();
1182 var valueA, valueB;
1183 if (type === 'int') {
1184 valueA = parseInt(keyA.replace(/[^0-9]/g, ''), 10);
1185 valueB = parseInt(keyB.replace(/[^0-9]/g, ''), 10);
1186 } else if (type === 'float') {
1187 valueA = parseFloat(keyA.replace(/[^0-9.]/g, ''));
1188 valueB = parseFloat(keyB.replace(/[^0-9.]/g, ''));
1189 } else {
1190 valueA = keyA;
1191 valueB = keyB;
1192 }
1193 if (currentOrder === 'asc') {
1194 return valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
1195 } else {
1196 return valueA > valueB ? -1 : valueA < valueB ? 1 : 0;
1197 }
1198 });
1199
1200 // Append sorted rows back to the tbody
1201 tbody.append(rows);
1202 },
1203 /**
1204 * Filter the table rows based on the selected module and search term.
1205 * @param moduleId
1206 * @param $table
1207 * @param searchTerm
1208 */
1209 filterTableTable: function filterTableTable(moduleId, $table) {
1210 var searchTerm = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
1211 if (!$table.length) {
1212 return;
1213 }
1214 var self = this;
1215 var visibleCount = 0;
1216 var $rows = $table.find('tbody tr');
1217 $rows.each(function () {
1218 var $row = $(this);
1219 var rowModuleId = $row.attr('data-module-id');
1220 var campaignName = $row.find('.js-campaign-name').text().toLowerCase();
1221 var moduleName = $row.find('.js-module-name').text().toLowerCase();
1222 var moduleMatch = !moduleId || rowModuleId === moduleId;
1223 var searchMatch = !searchTerm || campaignName.includes(searchTerm) || moduleName.includes(searchTerm);
1224 if (moduleMatch && searchMatch) {
1225 $row.show().removeClass('filtered-out is-hidden');
1226 visibleCount++;
1227 } else {
1228 $row.hide().addClass('filtered-out');
1229 }
1230 });
1231 var currentPage = 1;
1232 var totalRows = visibleCount;
1233 var rowsPerPage = parseInt($table.closest('.merchant-page-campaigns').find('.js-pagination').attr('data-rows-per-page'));
1234 var totalPages = Math.max(1, Math.ceil(totalRows / rowsPerPage));
1235
1236 // Update after filtering
1237 self.paginateRows(currentPage, $rows);
1238 self.updateNoResults(visibleCount === 0, $table);
1239 self.updatePaginationButtons(currentPage, totalPages, totalRows);
1240 },
1241 /**
1242 * Update the table to show rows for the selected page.
1243 *
1244 * @param currentPage
1245 * @param $rows
1246 */
1247 paginateRows: function paginateRows() {
1248 var currentPage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
1249 var $rows = arguments.length > 1 ? arguments[1] : undefined;
1250 var $pagination = $('.js-pagination');
1251 var rowsPerPage = parseInt($pagination.attr('data-rows-per-page'));
1252 var startIndex = (currentPage - 1) * rowsPerPage;
1253 var endIndex = startIndex + rowsPerPage;
1254 $rows.hide().addClass('is-hidden');
1255 $rows.filter(':not(.filtered-out)').each(function (index) {
1256 if (index >= startIndex && index < endIndex) {
1257 $(this).show().removeClass('is-hidden');
1258 }
1259 });
1260 },
1261 /**
1262 * Show no rows found message.
1263 *
1264 * @param show
1265 * @param $table
1266 */
1267 updateNoResults: function updateNoResults(show, $table) {
1268 var $noResults = $table.next('.no-results-message');
1269 if (show) {
1270 if (!$noResults.length) {
1271 $noResults = $('<div class="no-results-message" style="">No matching campaigns found</div>');
1272 $table.after($noResults);
1273 }
1274 $noResults.show();
1275 } else if ($noResults.length) {
1276 $noResults.hide();
1277 }
1278 },
1279 /**
1280 * Update the pagination buttons.
1281 *
1282 * @param currentPage
1283 * @param totalPages
1284 * @param totalRows
1285 */
1286 updatePaginationButtons: function updatePaginationButtons(currentPage, totalPages, totalRows) {
1287 var $pagination = $('.js-pagination');
1288 $pagination.attr('data-current-page', currentPage);
1289
1290 // If totalPages provided, update it to use the latest value
1291 if (totalPages) {
1292 $pagination.attr('data-total-pages', totalPages);
1293 }
1294 if (totalRows) {
1295 $pagination.attr('data-total-rows', totalRows);
1296 }
1297
1298 // Get the latest value
1299 totalPages = parseInt($pagination.attr('data-total-pages'));
1300 var html = '';
1301 if (currentPage > 1) {
1302 html += "\n\t\t <button class=\"pagination-button prev-page\" data-page=\"".concat(currentPage - 1, "\">\n\t\t <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"7\" height=\"12\" viewBox=\"0 0 7 12\" fill=\"#565865\">\n\t\t <path d=\"M5.16797 11.3301L0.521484 6.48047C0.394531 6.32812 0.34375 6.17578 0.34375 6.02344C0.34375 5.89648 0.394531 5.74414 0.496094 5.61719L5.14258 0.767578C5.37109 0.513672 5.77734 0.513672 6.00586 0.742188C6.25977 0.970703 6.25977 1.35156 6.03125 1.60547L1.79102 6.02344L6.05664 10.4922C6.28516 10.7207 6.28516 11.127 6.03125 11.3555C5.80273 11.584 5.39648 11.584 5.16797 11.3301Z\"/>\n\t\t </svg>\n\t\t </button>\n\t\t\t\t");
1303 }
1304 if (totalPages > 1) {
1305 for (var i = 1; i <= totalPages; i++) {
1306 html += "\n \t\t\t<button class=\"pagination-button".concat(i === currentPage ? ' pagination-active' : '', "\" data-page=\"").concat(i, "\">").concat(i, "</button>\n\t\t\t\t");
1307 }
1308 }
1309 if (currentPage < totalPages) {
1310 html += "\n\t\t <button class=\"pagination-button next-page\" data-page=\"".concat(currentPage + 1, "\">\n\t\t <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"7\" height=\"12\" viewBox=\"0 0 7 12\" fill=\"#565865\">\n\t\t <path d=\"M1.80664 0.742188L6.45312 5.5918C6.55469 5.71875 6.63086 5.87109 6.63086 6.02344C6.63086 6.17578 6.55469 6.32812 6.45312 6.42969L1.80664 11.2793C1.57812 11.5332 1.17188 11.5332 0.943359 11.3047C0.689453 11.0762 0.689453 10.6953 0.917969 10.4414L5.18359 5.99805L0.917969 1.58008C0.689453 1.35156 0.689453 0.945312 0.943359 0.716797C1.17188 0.488281 1.57812 0.488281 1.80664 0.742188Z\"/>\n\t\t </svg>\n\t\t </button>\n\t\t\t\t");
1311 }
1312 $pagination.html(html);
1313
1314 // Update results
1315 var $paginationNotice = $('.js-pagination-results');
1316 if (totalPages > 1) {
1317 var _totalRows = parseInt($pagination.attr('data-total-rows'));
1318 var rowsPerPage = parseInt($pagination.attr('data-rows-per-page'));
1319 var startIndex = (currentPage - 1) * rowsPerPage;
1320 var endIndex = startIndex + rowsPerPage;
1321 $paginationNotice.find('.pagination-start-row').text(startIndex ? startIndex : 1);
1322 $paginationNotice.find('.pagination-end-row').text(endIndex > _totalRows ? _totalRows : endIndex);
1323 $paginationNotice.find('.pagination-total-rows').text(totalRows);
1324 $paginationNotice.show();
1325 } else {
1326 $paginationNotice.hide();
1327 }
1328 },
1329 /**
1330 * Update the campaign status.
1331 * @param campaignData - The campaign data to update.
1332 * @param el - The element that triggered the update.
1333 * @param checkboxes - The checkboxes to update.
1334 * @param singleRow - Whether to update a single row or multiple rows.
1335 */
1336 updateCampaignStatus: function () {
1337 var _updateCampaignStatus = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8(campaignData, el, checkboxes) {
1338 var singleRow,
1339 self,
1340 $table,
1341 $loader,
1342 _args8 = arguments,
1343 _t8;
1344 return _regenerator().w(function (_context8) {
1345 while (1) switch (_context8.p = _context8.n) {
1346 case 0:
1347 singleRow = _args8.length > 3 && _args8[3] !== undefined ? _args8[3] : false;
1348 self = this;
1349 $table = el.closest('.all-campaigns-table').find('.js-campaigns-table'); // $ sign is used to indicate that it is a jQuery object
1350 $loader = '<span class="spinner is-active"></span>';
1351 el.prop('disabled', true);
1352 if (singleRow) {
1353 el.closest('.merchant-toggle-switch').append($loader);
1354 el.closest('tr').css('opacity', '.7');
1355 } else {
1356 $table.css('opacity', '.7');
1357 el.closest('.bulk-action').append($loader);
1358 }
1359 _context8.p = 1;
1360 _context8.n = 2;
1361 return this.sendAjaxRequest({
1362 action: 'merchant_update_campaign_status',
1363 nonce: self.NONCE,
1364 campaign_data: campaignData
1365 }, '', 'POST').then(function (response) {
1366 if (response.success) {
1367 if (!singleRow) {
1368 // Change the toggle of the selected campaigns
1369 checkboxes === null || checkboxes === void 0 || checkboxes.each(function () {
1370 $(this).closest('tr').find('.js-status input[type="checkbox"]').prop('checked', response.data.status === 'active');
1371 });
1372 }
1373 $(document).trigger('merchant_campaign_status_updated', [response.data, el, checkboxes, singleRow, campaignData]);
1374 }
1375 $('.spinner').remove();
1376 el.prop('disabled', false);
1377
1378 // Uncheck checkboxes & remove opacity
1379 if (singleRow) {
1380 el.closest('tr').css('opacity', '');
1381 } else {
1382 checkboxes === null || checkboxes === void 0 || checkboxes.each(function () {
1383 $table.find('thead th:first-child input[type="checkbox"]').prop('checked', false);
1384 $(this).prop('checked', false);
1385 });
1386 $table.css('opacity', '');
1387 }
1388 });
1389 case 2:
1390 _context8.n = 4;
1391 break;
1392 case 3:
1393 _context8.p = 3;
1394 _t8 = _context8.v;
1395 console.error('Error fetching campaign status data:', _t8);
1396 case 4:
1397 return _context8.a(2);
1398 }
1399 }, _callee8, this, [[1, 3]]);
1400 }));
1401 function updateCampaignStatus(_x8, _x9, _x0) {
1402 return _updateCampaignStatus.apply(this, arguments);
1403 }
1404 return updateCampaignStatus;
1405 }(),
1406 /**
1407 * Debounce function to limit the number of times a function is called.
1408 * @param func - The function to debounce.
1409 * @param wait - The time to wait before calling the function.
1410 * @returns {(function(...[*]): void)|*} - The debounced function.
1411 */
1412 debounce: function debounce(func, wait) {
1413 var timeout;
1414 return function () {
1415 var _this6 = this;
1416 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1417 args[_key] = arguments[_key];
1418 }
1419 clearTimeout(timeout);
1420 timeout = setTimeout(function () {
1421 return func.apply(_this6, args);
1422 }, wait);
1423 };
1424 }
1425 };
1426
1427 // Initialize charts when the document is ready
1428 $(document).ready(function () {
1429 merchantAnalyticsChart.initOverviewCards();
1430 merchantAnalyticsChart.widgetChartRender();
1431 merchantAnalyticsChart.revenueChartRender();
1432 merchantAnalyticsChart.avgOrderValChartRender();
1433 merchantAnalyticsChart.impressionsChartRender();
1434 merchantAnalyticsChart.initTopCampaignsTable();
1435 merchantAnalyticsChart.initAllCampaignsTable();
1436 });
1437 })(jQuery);