Files
myAi/web/wwwroot/js/utils/api.js
T
claude 98979b58f8 refactor: Extract shared JavaScript utilities (Step 1 of 6)
Create reusable utility modules to eliminate duplication across main.js,
cv-matcher.js, and legal.js:

- js/utils/form-helpers.js: showFieldError, clearFieldErrors, isValidEmail,
  extractApiError — shared form validation and error handling
- js/utils/i18n.js: currentLang, t, applyLanguage, updateLegalLinks,
  browserLang — shared translation and language switching
- js/utils/api.js: checkApiLive, getRecaptchaWebKey, getGoogleTagManagerId,
  loadGoogleTagManager — shared API configuration loading
- js/modules/cookie-consent.js: getConsent, setConsent, initConsent,
  setupConsentHandlers — cookie banner and consent management

All utilities exposed on window.MyAi namespace for use by existing pages.
Full JSDoc headers and inline comments for maintainability.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-29 09:05:51 +03:00

122 lines
3.9 KiB
JavaScript

/**
* API & Configuration Loading Utilities
*
* Shared helpers for API health checks and configuration retrieval.
* Handles reCaptcha key loading, Google Tag Manager setup, and API health checks.
*/
var reCaptchaSiteKey = null;
var gTagManagerId = null;
/**
* Check API /health/live endpoint and update status indicator if present.
* Updates #api-status element with "API: {status}" (green if OK, red if down).
* Logs result to console if element not found.
*
* @returns {object} - jQuery AJAX promise
*/
function checkApiLive() {
var $statusEl = $('#api-status');
return $.ajax({
url: '/api/health/live',
method: 'GET',
dataType: 'json',
timeout: 5000
}).done(function (data) {
var status = (data && data.status) ? data.status : 'unknown';
if ($statusEl.length) {
$statusEl.text('API: ' + status).removeClass('text-danger').addClass('text-success');
} else {
console.log('API live status:', status);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
if ($statusEl.length) {
$statusEl.text('API: offline').removeClass('text-success').addClass('text-danger');
}
console.error('API health check failed:', textStatus, errorThrown);
});
}
/**
* Load reCaptcha public site key from /api/captcha endpoint.
* Dynamically injects reCaptcha script if not already loaded.
* Stores key on window for use by grecaptcha.execute().
*
* @returns {object} - jQuery AJAX promise
*/
function getRecaptchaWebKey() {
return $.get('/api/captcha').done(function (res) {
reCaptchaSiteKey = res;
if (reCaptchaSiteKey && !window.__recaptcha_loaded) {
window.__recaptcha_loaded = true;
var script = document.createElement('script');
script.setAttribute('src', 'https://www.google.com/recaptcha/api.js?render=' + reCaptchaSiteKey);
document.head.appendChild(script);
}
}).fail(function () {
console.warn('Could not load reCaptcha site key from /api/captcha');
});
}
/**
* Load Google Tag Manager ID from /api/google/tagmanager endpoint.
* Does not load GTM script—that happens in loadGoogleTagManager() once consent is given.
*
* @returns {object} - jQuery AJAX promise
*/
function getGoogleTagManagerId() {
return $.get('/api/google/tagmanager').done(function (res) {
gTagManagerId = res;
}).fail(function () {
console.warn('Could not load Google Tag Manager id from /api/google/tagmanager');
});
}
/**
* Load and inject Google Tag Manager script if consent is given and not already loaded.
* Sets up dataLayer and injects GTM script from googleapis.com.
* Called only after user accepts analytics consent.
*
* Requires gTagManagerId to be loaded first via getGoogleTagManagerId().
*/
function loadGoogleTagManager() {
if (window.__gtm_loaded || !gTagManagerId) return;
window.__gtm_loaded = true;
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'gtm.start': new Date().getTime(),
event: 'gtm.js'
});
var script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtm/js?id=' + gTagManagerId;
document.head.appendChild(script);
}
/**
* Get the currently loaded reCaptcha site key.
* @returns {string|null} - reCaptcha site key or null if not yet loaded
*/
function getReCaptchaSiteKey() {
return reCaptchaSiteKey;
}
/**
* Get the currently loaded Google Tag Manager ID.
* @returns {string|null} - GTM ID or null if not yet loaded
*/
function getGoogleTagManagerId() {
return gTagManagerId;
}
// Expose API utilities on window.MyAi for use by other scripts
window.MyAi = window.MyAi || {};
window.MyAi.checkApiLive = checkApiLive;
window.MyAi.getRecaptchaWebKey = getRecaptchaWebKey;
window.MyAi.getGoogleTagManagerId = getGoogleTagManagerId;
window.MyAi.loadGoogleTagManager = loadGoogleTagManager;
window.MyAi.getReCaptchaSiteKey = getReCaptchaSiteKey;
window.MyAi.applyConsent = function(consent) {
if (consent && consent.analytics === true) loadGoogleTagManager();
};