/** * Load message bank data into selection dropdowns * @param {Function || null} cbOK callback when complete */ function load_messagebank(cbOK = null) { $("#input_GOP").empty(); $("#input_GBD").empty(); $("#input_GFC").empty(); $("#input_FLD").empty(); // get messagebank data from server, which contains [FLIGHT_NUMBER] let messageData = [...new Set(window.messagebankdata.filter(mb => mb.message_Detail.includes('[FLIGHT_NUMBER]')).map(mb => `${mb.description} [${mb.aNN_ID}]`))]; messageData.forEach((item) => { $("#input_GOP").append($("").attr("value", item).text(item)); $("#input_GBD").append($("").attr("value", item).text(item)); $("#input_GFC").append($("").attr("value", item).text(item)); $("#input_FLD").append($("").attr("value", item).text(item)); }); if (window.messagebankdata.length > 0) { if (cbOK) cbOK(); } } function load_remark_selection() { fetchAPI("Settings/FISCode", "GET", {}, null, (okdata) => { $("#input_GOP").val(okdata.gop) $("#input_GBD").val(okdata.gbd); $("#input_GFC").val(okdata.gfc); $("#input_FLD").val(okdata.fld); $("#input_defaultvoice").val(okdata.defaultvoice); }, (errdata) => { alert("Error getting FIS codes : " + errdata.message); }); } function Get_OldResultDays(){ fetchAPI("Settings/OldResultDays", "GET", {}, null, (okdata) => { let days = parseInt(okdata.message); if(isNaN(days) || days < 0){ days = 3; } $("#oldresultdays").val(days); }, (errdata) => { alert("Error getting Old Result Days : " + errdata.message); }); } function Set_OldResultDays(){ let days = parseInt($("#oldresultdays").val()); if(isNaN(days) || days < 0){ alert("Please enter a valid number of days (0 or more)."); return; } fetchAPI("Settings/OldResultDays", "POST", {}, { days: days }, (okdata) => { alert("Old Result Days updated successfully."); }, (errdata) => { alert("Error updating Old Result Days : " + errdata.message); }); } function load_default_voice(){ $("#input_defaultvoice").empty(); window.voiceTypes.forEach((voice) => { $("#input_defaultvoice").append($("").attr("value", voice).text(voice)); }); } function ValidLatitude(lat){ const num = parseFloat(lat); return !isNaN(num) && num >= -90 && num <= 90; } function ValidLongitude(lon){ const num = parseFloat(lon); return !isNaN(num) && num >= -180 && num <= 180; } function ValidTimezone(tz){ try{ Intl.DateTimeFormat(undefined, { timeZone: tz }); return true; } catch(e){ return false; } } function ValidHHMM(time){ const regex = /^([01]\d|2[0-3]):([0-5]\d)$/; return regex.test(time); } /** * Check if a date string is valid in DD/MM/YYYY format * @param {string} dateStr date to check in DD/MM/YYYY format * @returns {boolean} true if valid date in DD/MM/YYYY format, false otherwise */ function ValidDateDDMMYYYY(dateStr){ const regex = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/; if (!regex.test(dateStr)) return false; const [day, month, year] = dateStr.split('/').map(Number); const date = new Date(year, month - 1, day); return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day; } function ValidFilePath(path){ if (typeof path !== 'string' || path.trim() === '') return false; // test if ends with .wav or .mp3 const regex = /\.(wav|mp3)$/i; return regex.test(path); } function IsEnabled(value){ // accept "true", "false", true, false, 1, 0 // detect if value is null or undefined if (value === null || value === undefined) return false; if (typeof value === 'boolean') return value; if (typeof value === 'number') return value === 1; if (typeof value === 'string') return value.toLowerCase() === "true" || value === "1"; return false; } /** * @typedef {Object} AdzanSetting * @property {string} latitude * @property {string} longitude * @property {string} timezone * @property {string} fajar_sound * @property {string} dzuhur_sound * @property {string} ashar_sound * @property {string} maghrib_sound * @property {string} isya_sound * @property {string} fajar_time * @property {string} dzuhur_time * @property {string} ashar_time * @property {string} maghrib_time * @property {string} isya_time * @property {boolean} fajar_enable * @property {boolean} dzuhur_enable * @property {boolean} ashar_enable * @property {boolean} maghrib_enable * @property {boolean} isya_enable */ function Get_AdzanSetting(){ fetchAPI("Settings/AdzanSetting", "GET", {}, null, /** * returned AdzanSetting data * @param {AdzanSetting} okdata */ (okdata) => { // text input for latitude, longitude, timezone if (ValidLatitude(okdata.latitude)) { $('#adzanlatitude').val(okdata.latitude); } else { $('#adzanlatitude').val("N/A"); } if (ValidLongitude(okdata.longitude)) { $('#adzanlongitude').val(okdata.longitude); } else { $('#adzanlongitude').val("N/A"); } if (ValidTimezone(okdata.timezone)) { $('#adzantimezone').val(okdata.timezone); } else { $('#adzantimezone').val("N/A"); } // text input for adzan sound file for each prayer time if (ValidFilePath(okdata.fajar_sound)) { $('#fajar .adzanfile').val(okdata.fajar_sound); } else { $('#fajar .adzanfile').val("N/A"); } if (ValidFilePath(okdata.dzuhur_sound)) { $('#dzuhur .adzanfile').val(okdata.dzuhur_sound); } else { $('#dzuhur .adzanfile').val("N/A"); } if (ValidFilePath(okdata.ashar_sound)) { $('#ashar .adzanfile').val(okdata.ashar_sound); } else { $('#ashar .adzanfile').val("N/A"); } if (ValidFilePath(okdata.maghrib_sound)) { $('#maghrib .adzanfile').val(okdata.maghrib_sound); } else { $('#maghrib .adzanfile').val("N/A"); } if (ValidFilePath(okdata.isya_sound)) { $('#isya .adzanfile').val(okdata.isya_sound); } else { $('#isya .adzanfile').val("N/A"); } // checkbox adzanenable for each prayer time $('#fajar .adzanenable').prop('checked', IsEnabled(okdata.fajar_enable)); $('#dzuhur .adzanenable').prop('checked', IsEnabled(okdata.dzuhur_enable)); $('#ashar .adzanenable').prop('checked', IsEnabled(okdata.ashar_enable)); $('#maghrib .adzanenable').prop('checked', IsEnabled(okdata.maghrib_enable)); $('#isya .adzanenable').prop('checked', IsEnabled(okdata.isya_enable)); // adzantime for each prayer time // if valid HH:MM will set value, else set to undefined if (ValidHHMM(okdata.fajar_time)) { $('#fajar .adzantime').val(okdata.fajar_time); } else { $('#fajar .adzantime').val(""); } if (ValidHHMM(okdata.dzuhur_time)) { $('#dzuhur .adzantime').val(okdata.dzuhur_time); } else { $('#dzuhur .adzantime').val(""); } if (ValidHHMM(okdata.ashar_time)) { $('#ashar .adzantime').val(okdata.ashar_time); } else { $('#ashar .adzantime').val(""); } if (ValidHHMM(okdata.maghrib_time)) { $('#maghrib .adzantime').val(okdata.maghrib_time); } else { $('#maghrib .adzantime').val(""); } if (ValidHHMM(okdata.isya_time)) { $('#isya .adzantime').val(okdata.isya_time); } else { $('#isya .adzantime').val(""); } }, (errdata) => { alert("Error getting Adzan settings : " + errdata.message); }); } function Set_AdzanSetting(){ let latitude = $('#adzanlatitude').val(); if (!ValidLatitude(latitude)){ alert("Please enter a valid latitude between -90 and 90."); return; } let longitude = $('#adzanlongitude').val(); if (!ValidLongitude(longitude)){ alert("Please enter a valid longitude between -180 and 180."); return; } let timezone = $('#adzantimezone').val(); if (!ValidTimezone(timezone)){ alert("Please enter a valid timezone."); return; } let fajar_sound = $('#fajar .adzanfile').val(); if (!ValidFilePath(fajar_sound)){ alert("Please enter a valid file path for Fajar adzan sound (must end with .wav or .mp3)."); return; } let dzuhur_sound = $('#dzuhur .adzanfile').val(); if (!ValidFilePath(dzuhur_sound)){ alert("Please enter a valid file path for Dzuhur adzan sound (must end with .wav or .mp3)."); return; } let ashar_sound = $('#ashar .adzanfile').val(); if (!ValidFilePath(ashar_sound)){ alert("Please enter a valid file path for Ashar adzan sound (must end with .wav or .mp3)."); return; } let maghrib_sound = $('#maghrib .adzanfile').val(); if (!ValidFilePath(maghrib_sound)){ alert("Please enter a valid file path for Maghrib adzan sound (must end with .wav or .mp3)."); return; } let isya_sound = $('#isya .adzanfile').val(); if (!ValidFilePath(isya_sound)){ alert("Please enter a valid file path for Isya adzan sound (must end with .wav or .mp3)."); return; } let fajar_enable = $('#fajar .adzanenable').prop('checked'); let dzuhur_enable = $('#dzuhur .adzanenable').prop('checked'); let ashar_enable = $('#ashar .adzanenable').prop('checked'); let maghrib_enable = $('#maghrib .adzanenable').prop('checked'); let isya_enable = $('#isya .adzanenable').prop('checked'); let fajar_time = $('#fajar .adzantime').val(); if (!ValidHHMM(fajar_time)){ alert("Please enter a valid time for Fajar adzan (HH:MM)."); return; } let dzuhur_time = $('#dzuhur .adzantime').val(); if (!ValidHHMM(dzuhur_time)){ alert("Please enter a valid time for Dzuhur adzan (HH:MM)."); return; } let ashar_time = $('#ashar .adzantime').val(); if (!ValidHHMM(ashar_time)){ alert("Please enter a valid time for Ashar adzan (HH:MM)."); return; } let maghrib_time = $('#maghrib .adzantime').val(); if (!ValidHHMM(maghrib_time)){ alert("Please enter a valid time for Maghrib adzan (HH:MM)."); return; } let isya_time = $('#isya .adzantime').val(); if (!ValidHHMM(isya_time)){ alert("Please enter a valid time for Isya adzan (HH:MM)."); return; } /** * @type {AdzanSetting} */ let data = { latitude: latitude, longitude: longitude, timezone: timezone, fajar_sound: fajar_sound, dzuhur_sound: dzuhur_sound, ashar_sound: ashar_sound, maghrib_sound: maghrib_sound, isya_sound: isya_sound, fajar_enable: fajar_enable, dzuhur_enable: dzuhur_enable, ashar_enable: ashar_enable, maghrib_enable: maghrib_enable, isya_enable: isya_enable, fajar_time: fajar_time, dzuhur_time: dzuhur_time, ashar_time: ashar_time, maghrib_time: maghrib_time, isya_time: isya_time }; fetchAPI("Settings/AdzanSetting", "POST", {}, data, (okdata) => { alert("Adzan settings updated successfully."); }, (errdata) => { alert("Error updating Adzan settings : " + errdata.message); }); } function Get_WebAccessSetting(){ fetchAPI("Settings/WebAccess", "GET", {}, null, (okdata) => { let adminpass = okdata.adminpass || "password"; let viewerpass = okdata.userpass || "password"; $("#adminpassword1").val(adminpass); $("#adminpassword2").val(adminpass); $("#viewerpassword1").val(viewerpass); $("#viewerpassword2").val(viewerpass); }, (errdata) => { alert("Error getting Web Access settings : " + errdata.message); }); } function Set_WebAccessSetting(){ let adminpass1 = $("#adminpassword1").val(); let adminpass2 = $("#adminpassword2").val(); let viewerpass1 = $("#viewerpassword1").val(); let viewerpass2 = $("#viewerpassword2").val(); if(adminpass1 !== adminpass2){ alert("Admin passwords do not match."); return; } if(viewerpass1 !== viewerpass2){ alert("Viewer passwords do not match."); return; } let data = { adminpass: adminpass1, viewerpass: viewerpass1 }; fetchAPI("Settings/WebAccess", "POST", {}, data, (okdata) => { alert("Web Access settings updated successfully."); }, (errdata) => { alert("Error updating Web Access settings : " + errdata.message); }); } $(document).ready(function () { console.log("setting.js loaded"); load_default_voice(); Get_OldResultDays(); Get_WebAccessSetting(); Get_AdzanSetting(); load_messagebank(() => load_remark_selection()); $('#fiscodesave').click(function () { Set_OldResultDays(); let gop = $("#input_GOP").val(); let gbd = $("#input_GBD").val(); let gfc = $("#input_GFC").val(); let fld = $("#input_FLD").val(); let voice = $("#input_defaultvoice").val(); if (gop && gbd && gfc && fld && voice) { let data = { GOP: gop, GBD: gbd, GFC: gfc, FLD: fld, defaultvoice: voice }; fetchAPI("Settings/FISCode", "POST", {}, data, (okdata) => { alert("FIS codes saved successfully."); }, (errdata) => { alert("Error saving FIS codes : " + errdata.message); }); } else { alert("Please select all FIS codes (GOP, GBD, GFC, FLD) and Default Voice before saving."); } }); $('#webaccesssave').click(function () { Set_WebAccessSetting(); }); $('#adzansave').click(function () { Set_AdzanSetting(); }); });