(function () { function initSelect2() { if (!window.jQuery || !jQuery.fn.select2) { return; } document.querySelectorAll('.js-select2').forEach(function (el) { if (jQuery(el).data('select2')) { return; } var placeholder = el.getAttribute('data-placeholder'); if (!placeholder) { var emptyOption = el.querySelector('option[value=""]'); placeholder = emptyOption ? emptyOption.textContent : ''; } jQuery(el).select2({ width: '100%', placeholder: placeholder, allowClear: true }); }); } function initFlatpickr() { if (typeof flatpickr === 'undefined') { return; } document.querySelectorAll('.js-date-picker').forEach(function (el) { if (el._flatpickr) { return; } flatpickr(el, { dateFormat: 'd/m/Y', allowInput: true }); }); } function initFlashAlerts() { document.querySelectorAll('.flash-alert').forEach(function (alertEl) { if (alertEl.dataset.tsInit === '1') { return; } alertEl.dataset.tsInit = '1'; var timeout = parseInt(alertEl.getAttribute('data-timeout') || '5', 10); var remaining = timeout; var countdownEl = alertEl.querySelector('.flash-countdown'); var updateCountdown = function () { if (countdownEl) { countdownEl.textContent = '[' + remaining + ']'; } }; updateCountdown(); var intervalId = setInterval(function () { remaining -= 1; if (remaining <= 0) { clearInterval(intervalId); alertEl.style.display = 'none'; } else { updateCountdown(); } }, 1000); }); } function initPasswordToggles() { document.querySelectorAll('.js-password-toggle').forEach(function (btn) { if (btn.dataset.tsInit === '1') { return; } btn.dataset.tsInit = '1'; var targetId = btn.getAttribute('data-target'); if (!targetId) { return; } var input = document.getElementById(targetId); if (!input) { return; } var openIcon = btn.querySelector('[data-icon="open"]'); var closedIcon = btn.querySelector('[data-icon="closed"]'); var applyState = function (showPassword) { if (!openIcon || !closedIcon) { return; } if (showPassword) { openIcon.classList.add('d-none'); closedIcon.classList.remove('d-none'); closedIcon.classList.add('text-danger'); openIcon.classList.remove('text-primary'); } else { closedIcon.classList.add('d-none'); openIcon.classList.remove('d-none'); openIcon.classList.add('text-primary'); closedIcon.classList.remove('text-danger'); } }; applyState(input.getAttribute('type') === 'text'); btn.addEventListener('click', function () { var isPassword = input.getAttribute('type') === 'password'; input.setAttribute('type', isPassword ? 'text' : 'password'); applyState(!isPassword); }); }); } function initStrengthMeters() { document.querySelectorAll('[data-password-input]').forEach(function (input) { if (input.dataset.tsInit === '1') { return; } input.dataset.tsInit = '1'; var key = input.getAttribute('data-password-input'); if (!key) { return; } var bar = document.querySelector('[data-strength-bar="' + key + '"]'); var confirm = document.querySelector('[data-password-confirm="' + key + '"]'); var matchHint = document.querySelector('[data-password-match="' + key + '"]'); var updateStrength = function () { if (!bar) { return; } var value = input.value || ''; var score = 0; if (value.length >= 12) score += 1; if (/[A-Z]/.test(value)) score += 1; if (/[a-z]/.test(value)) score += 1; if (/\d/.test(value)) score += 1; if (/[^A-Za-z0-9]/.test(value)) score += 1; var percent = (score / 5) * 100; bar.style.width = percent + '%'; bar.classList.remove('bg-danger', 'bg-warning', 'bg-success'); if (percent < 40) { bar.classList.add('bg-danger'); } else if (percent < 80) { bar.classList.add('bg-warning'); } else { bar.classList.add('bg-success'); } }; var updateMatch = function () { if (!confirm || !matchHint) { return; } if (!confirm.value && !input.value) { matchHint.classList.add('d-none'); return; } if (confirm.value === input.value) { matchHint.classList.add('d-none'); } else { matchHint.classList.remove('d-none'); } }; input.addEventListener('input', function () { updateStrength(); updateMatch(); }); if (confirm) { confirm.addEventListener('input', updateMatch); } updateStrength(); }); } function initBulkSelectors() { document.querySelectorAll('[data-bulk-select-root]').forEach(function (root) { if (root.dataset.tsInit === '1') { return; } root.dataset.tsInit = '1'; var selectAll = root.querySelector('[data-bulk-select-all]'); if (!selectAll) { return; } var checkboxes = root.querySelectorAll('[data-bulk-select-item]'); selectAll.addEventListener('change', function () { checkboxes.forEach(function (cb) { cb.checked = selectAll.checked; }); }); }); } function initEmailSelectedConfirm() { document.querySelectorAll('form[data-confirm-email-selected]').forEach(function (form) { if (form.dataset.tsConfirmInit === '1') { return; } form.dataset.tsConfirmInit = '1'; form.addEventListener('submit', function (event) { var selected = form.querySelectorAll('[data-bulk-select-item]:checked'); if (!selected.length) { // No selected jobs; let the normal server-side handling decide what to do. return; } var message = 'Are you sure you want to email selected job(s) summary?'; if (!window.confirm(message)) { event.preventDefault(); } }); }); } function initUiCore() { initSelect2(); initFlatpickr(); initFlashAlerts(); initPasswordToggles(); initStrengthMeters(); initBulkSelectors(); initEmailSelectedConfirm(); } window.__tsInitUiCore = initUiCore; window.__tsPageInits = window.__tsPageInits || []; window.__tsPageInits.push(initUiCore); })();