| 1 |
/** |
| 2 |
* Load Lasso Lite click snapshot |
| 3 |
* Shows today, week, and month clicks in a bottom-right notification |
| 4 |
*/ |
| 5 |
var lassoLiteRealtimeToastAutoHideTimer = null; |
| 6 |
|
| 7 |
function get_use_cache_param() { |
| 8 |
var useCache = lasso_lite_helper.get_url_parameter('use_cache'); |
| 9 |
if (useCache === null || useCache === undefined || useCache === '') { |
| 10 |
return '1'; |
| 11 |
} |
| 12 |
return useCache; |
| 13 |
} |
| 14 |
|
| 15 |
function load_lasso_lite_click_snapshot() { |
| 16 |
var useCache = get_use_cache_param(); |
| 17 |
// Only show the first time the user visits today |
| 18 |
var seenDate = localStorage.getItem('lasso_lite_snapshot_seen'); |
| 19 |
var today = new Date().toDateString(); |
| 20 |
|
| 21 |
if (seenDate === today) { |
| 22 |
return; |
| 23 |
} |
| 24 |
localStorage.setItem('lasso_lite_snapshot_seen', today); |
| 25 |
|
| 26 |
jQuery.ajax({ |
| 27 |
url: lassoLiteOptionsData.ajax_url, |
| 28 |
type: 'post', |
| 29 |
data: { |
| 30 |
action: 'lasso_lite_get_click_snapshot', |
| 31 |
nonce: lassoLiteOptionsData.optionsNonce, |
| 32 |
use_cache: useCache |
| 33 |
}, |
| 34 |
success: function(res) { |
| 35 |
if (res && res.success && res.data) { |
| 36 |
var snapshotData = res.data.data ? res.data.data : res.data; |
| 37 |
var todayClicks = Number(snapshotData.today_clicks || 0); |
| 38 |
var weekClicks = Number(snapshotData.week_clicks || 0); |
| 39 |
var monthClicks = Number(snapshotData.month_clicks || 0); |
| 40 |
var clickCount = 0; |
| 41 |
var periodLabel = ''; |
| 42 |
|
| 43 |
if (todayClicks > 0) { |
| 44 |
clickCount = todayClicks; |
| 45 |
periodLabel = 'today'; |
| 46 |
} else if (weekClicks > 0) { |
| 47 |
clickCount = weekClicks; |
| 48 |
periodLabel = 'this week'; |
| 49 |
} else if (monthClicks > 0) { |
| 50 |
clickCount = monthClicks; |
| 51 |
periodLabel = 'this month'; |
| 52 |
} else { |
| 53 |
return; |
| 54 |
} |
| 55 |
|
| 56 |
jQuery('#snapshot-click-count').text(clickCount); |
| 57 |
jQuery('#snapshot-period').text(periodLabel); |
| 58 |
jQuery('#lasso-lite-click-snapshot-box').fadeIn(); |
| 59 |
} |
| 60 |
}, |
| 61 |
error: function(xhr, status, error) { |
| 62 |
console.error('Lasso Lite Snapshot Error:', error); |
| 63 |
} |
| 64 |
}); |
| 65 |
} |
| 66 |
|
| 67 |
/** |
| 68 |
* Load Lasso Lite link issues snapshot |
| 69 |
* Shows broken/out-of-stock/international clicks in the last 30 days |
| 70 |
*/ |
| 71 |
function load_lasso_lite_link_issues_snapshot(onComplete) { |
| 72 |
var useCache = get_use_cache_param(); |
| 73 |
var now = new Date(); |
| 74 |
var monthKey = now.getFullYear() + '-' + (now.getMonth() + 1); |
| 75 |
var seenMonth = localStorage.getItem('lasso_lite_link_issues_snapshot_seen'); |
| 76 |
|
| 77 |
if (seenMonth === monthKey) { |
| 78 |
if (typeof onComplete === 'function') { |
| 79 |
onComplete(false); |
| 80 |
} |
| 81 |
return; |
| 82 |
} |
| 83 |
|
| 84 |
jQuery.ajax({ |
| 85 |
url: lassoLiteOptionsData.ajax_url, |
| 86 |
type: 'post', |
| 87 |
data: { |
| 88 |
action: 'lasso_lite_get_link_issues_snapshot', |
| 89 |
nonce: lassoLiteOptionsData.optionsNonce, |
| 90 |
use_cache: useCache |
| 91 |
}, |
| 92 |
success: function(res) { |
| 93 |
if (res && res.success && res.data) { |
| 94 |
var snapshotData = res.data.data ? res.data.data : res.data; |
| 95 |
var brokenClicks = Number(snapshotData.broken_clicks || 0); |
| 96 |
var outOfStockClicks = Number(snapshotData.out_of_stock_clicks || 0); |
| 97 |
var internationalClicks = Number(snapshotData.international_clicks || 0); |
| 98 |
var showPotential = !!snapshotData.show_potential_earnings; |
| 99 |
var potentialEarnings = snapshotData.potential_earnings_lost; |
| 100 |
|
| 101 |
if (brokenClicks <= 0 && outOfStockClicks <= 0 && internationalClicks <= 0 && !showPotential) { |
| 102 |
if (typeof onComplete === 'function') { |
| 103 |
onComplete(false); |
| 104 |
} |
| 105 |
return; |
| 106 |
} |
| 107 |
|
| 108 |
var monthLabel = now.toLocaleString('default', { month: 'long' }); |
| 109 |
jQuery('#link-issues-snapshot-title').text(monthLabel + ' Snapshot:'); |
| 110 |
jQuery('#link-issues-broken-clicks').text(brokenClicks); |
| 111 |
jQuery('#link-issues-out-of-stock-clicks').text(outOfStockClicks); |
| 112 |
jQuery('#link-issues-international-clicks').text(internationalClicks); |
| 113 |
|
| 114 |
if (showPotential && potentialEarnings !== null && potentialEarnings !== undefined) { |
| 115 |
jQuery('#link-issues-potential-earnings').text('$' + Number(potentialEarnings).toFixed(2)); |
| 116 |
jQuery('#link-issues-potential-earnings-row').show(); |
| 117 |
} else { |
| 118 |
jQuery('#link-issues-potential-earnings-row').hide(); |
| 119 |
} |
| 120 |
|
| 121 |
localStorage.setItem('lasso_lite_link_issues_snapshot_seen', monthKey); |
| 122 |
jQuery('#lasso-lite-link-issues-snapshot-box').fadeIn(); |
| 123 |
|
| 124 |
if (typeof onComplete === 'function') { |
| 125 |
onComplete(true); |
| 126 |
} |
| 127 |
} else if (typeof onComplete === 'function') { |
| 128 |
onComplete(false); |
| 129 |
} |
| 130 |
}, |
| 131 |
error: function(xhr, status, error) { |
| 132 |
if (typeof onComplete === 'function') { |
| 133 |
onComplete(false); |
| 134 |
} |
| 135 |
console.error('Lasso Lite Link Issues Snapshot Error:', error); |
| 136 |
} |
| 137 |
}); |
| 138 |
} |
| 139 |
|
| 140 |
/** |
| 141 |
* Load dashboard alert totals (broken/out-of-stock/opportunities) |
| 142 |
*/ |
| 143 |
function load_lasso_lite_links_issues_totals() { |
| 144 |
var useCache = get_use_cache_param(); |
| 145 |
|
| 146 |
function numberWithCommas(x) { |
| 147 |
return String(x).replace(/\B(?=(\d{3})+(?!\d))/g, ','); |
| 148 |
} |
| 149 |
|
| 150 |
function renderTotals(totals) { |
| 151 |
var broken = Number((totals && totals.totalBrokenLinks) || 0); |
| 152 |
var outOfStock = Number((totals && totals.totalOutOfStock) || 0); |
| 153 |
var opportunities = Number((totals && totals.totalOpportunities) || 0); |
| 154 |
|
| 155 |
jQuery('#total-broken-links').html('<i class="far fa-unlink"></i> ' + numberWithCommas(broken)); |
| 156 |
jQuery('#total-out-of-stock').html('<i class="far fa-box-open"></i> ' + numberWithCommas(outOfStock)); |
| 157 |
jQuery('#total-opportunities').html('<i class="far fa-lightbulb-on"></i> ' + numberWithCommas(opportunities)); |
| 158 |
|
| 159 |
// Always show these pills for consistency, even if counts are zero |
| 160 |
jQuery('#total-broken-links-li').removeClass('d-none'); |
| 161 |
jQuery('#total-out-of-stock-li').removeClass('d-none'); |
| 162 |
jQuery('#total-opportunities-li').removeClass('d-none'); |
| 163 |
} |
| 164 |
|
| 165 |
// Default state: show pills with 0 before API returns |
| 166 |
renderTotals({ totalBrokenLinks: 0, totalOutOfStock: 0, totalOpportunities: 0 }); |
| 167 |
|
| 168 |
jQuery.ajax({ |
| 169 |
url: lassoLiteOptionsData.ajax_url, |
| 170 |
type: 'post', |
| 171 |
data: { |
| 172 |
action: 'lasso_lite_get_links_issues_totals', |
| 173 |
nonce: lassoLiteOptionsData.optionsNonce, |
| 174 |
use_cache: useCache |
| 175 |
}, |
| 176 |
success: function(res) { |
| 177 |
if (!res || !res.success || !res.data) { |
| 178 |
return; |
| 179 |
} |
| 180 |
|
| 181 |
var totals = res.data.data ? res.data.data : res.data; |
| 182 |
renderTotals(totals); |
| 183 |
}, |
| 184 |
error: function(xhr, status, error) { |
| 185 |
console.error('Lasso Lite Link Issues Totals Error:', error); |
| 186 |
} |
| 187 |
}); |
| 188 |
} |
| 189 |
|
| 190 |
function load_dashboard( page = '', keyword = '') { |
| 191 |
let container = jQuery('#report-content'); |
| 192 |
if ( keyword === '' ) { |
| 193 |
keyword = lasso_lite_helper.get_url_parameter('link-search-input'); |
| 194 |
} |
| 195 |
|
| 196 |
if ( page === '' ) { |
| 197 |
page = lasso_lite_helper.get_page_from_current_url(); |
| 198 |
} |
| 199 |
|
| 200 |
jQuery.ajax({ |
| 201 |
url: lassoLiteOptionsData.ajax_url, |
| 202 |
type: 'post', |
| 203 |
data: { |
| 204 |
action: 'lasso_lite_dashboard_get_list', |
| 205 |
nonce: lassoLiteOptionsData.optionsNonce, |
| 206 |
page: page, |
| 207 |
keyword: keyword |
| 208 |
}, |
| 209 |
beforeSend: function () { |
| 210 |
container.html(lasso_lite_helper.get_loading_image()); |
| 211 |
} |
| 212 |
}) |
| 213 |
.done(function (res) { |
| 214 |
if ( res.success === true ) { |
| 215 |
let data = res.data; |
| 216 |
let json_data = data.output; |
| 217 |
|
| 218 |
lasso_lite_helper.inject_to_template(jQuery("#report-content"), 'dashboard-list', json_data); |
| 219 |
lasso_lite_helper.generate_paging( jQuery('.dashboard-pagination'), data.page, data.total, function (page_number) { |
| 220 |
load_dashboard(page_number); |
| 221 |
}, data.limit_on_page); |
| 222 |
|
| 223 |
if ( data.total === 0 || json_data.length == 0 ) { |
| 224 |
container.html(lasso_lite_helper.default_empty_data); |
| 225 |
} |
| 226 |
} else { |
| 227 |
container.html(lasso_lite_helper.default_empty_data); |
| 228 |
} |
| 229 |
}) |
| 230 |
.fail(function (xhr, status, error) { |
| 231 |
container.html(lasso_lite_helper.default_empty_data); |
| 232 |
}); |
| 233 |
} |
| 234 |
|
| 235 |
/** |
| 236 |
* Show the teal bottom-right toast when new live clicks arrive (same style as click snapshot). |
| 237 |
*/ |
| 238 |
function lasso_lite_show_realtime_click_toast() { |
| 239 |
var $toast = jQuery('#lasso-lite-realtime-click-toast'); |
| 240 |
if (!$toast.length) { |
| 241 |
return; |
| 242 |
} |
| 243 |
if (lassoLiteRealtimeToastAutoHideTimer) { |
| 244 |
window.clearTimeout(lassoLiteRealtimeToastAutoHideTimer); |
| 245 |
lassoLiteRealtimeToastAutoHideTimer = null; |
| 246 |
} |
| 247 |
$toast.stop(true, true).fadeIn(200); |
| 248 |
lassoLiteRealtimeToastAutoHideTimer = window.setTimeout(function () { |
| 249 |
lassoLiteRealtimeToastAutoHideTimer = null; |
| 250 |
$toast.fadeOut(200); |
| 251 |
}, 10000); |
| 252 |
} |
| 253 |
|
| 254 |
/** |
| 255 |
* Poll WordPress for click events when Advanced Click Tracking is enabled. |
| 256 |
*/ |
| 257 |
function init_lasso_lite_dashboard_realtime() { |
| 258 |
if (typeof window.lassoLiteOptionsData === 'undefined' || !lassoLiteOptionsData.realtime) { |
| 259 |
return; |
| 260 |
} |
| 261 |
var rt = lassoLiteOptionsData.realtime; |
| 262 |
if (!rt || rt.mode !== 'poll' || !rt.pullAction) { |
| 263 |
return; |
| 264 |
} |
| 265 |
var ajaxUrl = lassoLiteOptionsData.ajax_url; |
| 266 |
var nonce = lassoLiteOptionsData.optionsNonce; |
| 267 |
if (!ajaxUrl || !nonce) { |
| 268 |
return; |
| 269 |
} |
| 270 |
var $wrap = jQuery('#lasso-lite-realtime-live'); |
| 271 |
var $count = jQuery('#lasso-lite-realtime-click-count'); |
| 272 |
if (!$wrap.length || !$count.length) { |
| 273 |
return; |
| 274 |
} |
| 275 |
|
| 276 |
$wrap.removeClass('d-none'); |
| 277 |
|
| 278 |
var total = 0; |
| 279 |
function bump(n) { |
| 280 |
var add = typeof n === 'number' && n > 0 ? n : 1; |
| 281 |
total += add; |
| 282 |
$count.text(total); |
| 283 |
lasso_lite_show_realtime_click_toast(); |
| 284 |
} |
| 285 |
|
| 286 |
var since = typeof rt.startSeq === 'number' ? rt.startSeq : parseInt(rt.startSeq, 10) || 0; |
| 287 |
var pollMs = rt.pollInterval || 12000; |
| 288 |
|
| 289 |
function pull() { |
| 290 |
jQuery.post(ajaxUrl, { |
| 291 |
action: rt.pullAction, |
| 292 |
nonce: nonce, |
| 293 |
since: since |
| 294 |
}).done(function (res) { |
| 295 |
if (!res || !res.success || !res.data) { |
| 296 |
return; |
| 297 |
} |
| 298 |
var evs = res.data.events || []; |
| 299 |
if (evs.length) { |
| 300 |
bump(evs.length); |
| 301 |
} |
| 302 |
if (typeof res.data.max_seq === 'number') { |
| 303 |
since = res.data.max_seq; |
| 304 |
} |
| 305 |
}); |
| 306 |
} |
| 307 |
window.setInterval(pull, pollMs); |
| 308 |
pull(); |
| 309 |
} |
| 310 |
|
| 311 |
jQuery(document).ready(function () { |
| 312 |
if (typeof window.go_to_next_step_action !== 'function') { |
| 313 |
window.go_to_next_step_action = function() { |
| 314 |
jQuery('#lasso-lite-analytics-modal').modal('hide'); |
| 315 |
}; |
| 316 |
} |
| 317 |
|
| 318 |
var $liteProModal = jQuery('#lasso-lite-pro-modal'); |
| 319 |
if ($liteProModal.length) { |
| 320 |
var copyMap = { |
| 321 |
'broken-links': { |
| 322 |
title: 'Broken link alerts are currently disabled' |
| 323 |
}, |
| 324 |
'out-of-stock': { |
| 325 |
title: 'Out-of-stock alerts are currently disabled' |
| 326 |
}, |
| 327 |
'opportunities': { |
| 328 |
title: 'Opportunities are currently disabled' |
| 329 |
} |
| 330 |
}; |
| 331 |
|
| 332 |
$liteProModal.on('show.bs.modal', function() { |
| 333 |
jQuery('body').addClass('lasso-lite-pro-modal-open'); |
| 334 |
}); |
| 335 |
$liteProModal.on('hidden.bs.modal', function() { |
| 336 |
jQuery('body').removeClass('lasso-lite-pro-modal-open'); |
| 337 |
}); |
| 338 |
|
| 339 |
jQuery(document).on('click', '.lasso-lite-pro-trigger', function(e) { |
| 340 |
e.preventDefault(); |
| 341 |
var key = jQuery(this).data('feature'); |
| 342 |
var copy = copyMap[key] || copyMap['opportunities']; |
| 343 |
jQuery('#lasso-lite-pro-modal-title').text(copy.title); |
| 344 |
$liteProModal.modal('show'); |
| 345 |
}); |
| 346 |
} |
| 347 |
|
| 348 |
// Load dashboard content |
| 349 |
load_dashboard(); |
| 350 |
|
| 351 |
init_lasso_lite_dashboard_realtime(); |
| 352 |
|
| 353 |
// Load dashboard alert totals |
| 354 |
load_lasso_lite_links_issues_totals(); |
| 355 |
|
| 356 |
// Load link issues snapshot first, fallback to click snapshot |
| 357 |
load_lasso_lite_link_issues_snapshot(function(didShow) { |
| 358 |
if (!didShow) { |
| 359 |
load_lasso_lite_click_snapshot(); |
| 360 |
} |
| 361 |
}); |
| 362 |
|
| 363 |
// Handle snapshot close button |
| 364 |
jQuery(document).on('click', '.close-snapshot', function() { |
| 365 |
jQuery('#lasso-lite-click-snapshot-box').fadeOut(); |
| 366 |
jQuery('#lasso-lite-link-issues-snapshot-box').fadeOut(); |
| 367 |
}); |
| 368 |
|
| 369 |
jQuery(document).on('click', '.close-realtime-live-toast', function() { |
| 370 |
if (lassoLiteRealtimeToastAutoHideTimer) { |
| 371 |
window.clearTimeout(lassoLiteRealtimeToastAutoHideTimer); |
| 372 |
lassoLiteRealtimeToastAutoHideTimer = null; |
| 373 |
} |
| 374 |
jQuery('#lasso-lite-realtime-click-toast').fadeOut(200); |
| 375 |
}); |
| 376 |
|
| 377 |
// Open Connect to Lasso modal only — no redirect or new tab. |
| 378 |
jQuery(document).on('click', '.lasso-lite-dashboard-connect-cta', function(e) { |
| 379 |
e.preventDefault(); |
| 380 |
var $modal = jQuery('#lasso-lite-analytics-modal'); |
| 381 |
if ($modal.length) { |
| 382 |
$modal.modal('show'); |
| 383 |
} |
| 384 |
}); |
| 385 |
|
| 386 |
// Handle search form |
| 387 |
jQuery("#links-filter").submit(function (e) { |
| 388 |
e.preventDefault(); |
| 389 |
let keyword = jQuery("#link-search-input").val().trim(); |
| 390 |
lasso_lite_helper.update_url_parameter('link-search-input', keyword); |
| 391 |
load_dashboard('', keyword ); |
| 392 |
}); |
| 393 |
}); |
| 394 |
|