$(document).ready(function () {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
'Accept': 'application/json'
}
});
// --- PHONE INPUT LOGIC ---
const phoneInstances = {};
function initPhoneInput(selector) {
const input = document.querySelector(selector);
if (!input) return null;
if (phoneInstances[selector]) return phoneInstances[selector];
phoneInstances[selector] = window.intlTelInput(input, {
initialCountry: "gh",
onlyCountries: ["gh"],
nationalMode: true,
autoPlaceholder: "polite",
utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.19/js/utils.js"
});
input.addEventListener("blur", function () {
if (phoneInstances[selector].isValidNumber()) {
phoneInstances[selector].setNumber(phoneInstances[selector].getNumber());
}
});
return phoneInstances[selector];
}
$('#editUserModal').on('shown.bs.modal', () => initPhoneInput("#editPhone"));
$('#addUserModal').on('shown.bs.modal', () => initPhoneInput("#addUserphone"));
// --- SELECT2 LOGIC ---
$('#editAllowedApps, #inputPermissions').select2({
dropdownParent: $('#editUserModal'),
placeholder: "Select options, multiple allowed"
});
$('#allowedApps').select2({
dropdownParent: $('#addUserModal'),
placeholder: "Select options, multiple allowed"
});
// --- DYNAMIC POSITIONS MAP LOGIC ---
let optionsMap = {}; // Start empty
function populatePositions(userType, targetDropdown) {
targetDropdown.empty().append('');
if (optionsMap[userType]) {
$.each(optionsMap[userType], function(index, value) {
targetDropdown.append($("").attr("value", value.toLowerCase()).text(toTitleCase(value)));
});
}
}
function toSentenceCase(value) {
value = value
.replace(/_+/g, ' ')
.replace(/\s+/g, ' ')
.trim()
.toLowerCase();
return value
? value.charAt(0).toUpperCase() + value.slice(1)
: '';
}
function toTitleCase(value) {
return value
.replace(/_+/g, ' ')
.replace(/\s+/g, ' ')
.trim()
.toLowerCase()
.replace(/\b\w/g, char => char.toUpperCase());
}
// Fetch the map from the backend on load
$.ajax({
url: base_url + '/users/positions-map',
type: 'GET',
success: function(response) {
let mapData = response.data || response;
if (mapData && Object.keys(mapData).length > 0) {
optionsMap = mapData;
// Populate if a radio is already checked
let initialUserType = $("input[name='user_type']:checked").val();
if(initialUserType) {
populatePositions(initialUserType, $("#uaPostionAdd"));
}
} else {
console.warn("The map data is empty or formatted incorrectly.");
}
},
error: function(xhr, status, error) {
console.error("Failed to load positions map:", error);
console.log(xhr.responseText); // Shows PHP errors if the route crashed
}
});
$("input[name='user_type']").change(function() {
let userType = $(this).val();
let isDistrict = (userType === 'district_user');
let isRegional = (userType === 'regional_luspa');
populatePositions(userType, $("#uaPostionAdd"));
});
// --- DEPENDENT DROPDOWNS ---
$('.regionIDD').change(function() {
let region_id = $(this).val();
let $districtSelect = $('.districtIDD');
$districtSelect.empty().append('');
if(!region_id) return;
$.ajax({
url: base_url + '/admin/districts/' + region_id,
type: 'GET',
success: function(data) {
if(data.districts) {
$.each(data.districts, function(id, row) {
$districtSelect.append($("").val(row.districtid).text(row.district_name));
});
}
}
});
});
// --- EDIT USER LOGIC ---
let lastTrigger = null;
$(document).on('click', '.editUserBtn', function(evnt) {
evnt.preventDefault();
lastTrigger = this;
const row = $(this).closest('.user-row');
let selectedUserId = row.data('id');
let phoneIti = initPhoneInput("#editPhone");
$.ajax({
url: base_url + '/users/edit/' + selectedUserId,
type: 'GET',
beforeSend: function() {
$('#editSuccessArea').addClass('d-none');
$('#editInfoArea').removeClass('d-none').text("Please wait ... loading user details!!");
},
success: function(response) {
$('#editErrorArea').addClass('d-none').text('');
$('#editInfoArea').addClass('d-none').text('');
if (response.success) {
let user = response.data;
let allowedAppsArray = user.allowed_apps ? user.allowed_apps.split(",") : [];
$('#editFullName').val(user.full_name);
$('#editEmail').val(user.email);
$('#editUsername').val(user.username);
$('#editGender').val(user.gender);
$('#editTitle').val(user.title);
$('#editRegionID').val(user.region_id);
$('#editDistrictId').val(user.district_id);
$("input[name='user_id']").val(user.user_id);
$('#editAllowedApps').val(allowedAppsArray).trigger('change');
if (user.user_type === 'district_user') {
$('#editUserTypeDistrict').prop('checked', true);
}
else if(user.user_type === 'regional_luspa'){
$('#editUserTypeLuspaRegion').prop('checked', true);
}
else{
$('#editUserTypeLuspaNational').prop('checked', true);
}
// Populate positions based on the loaded user_type
if(user.user_type) {
populatePositions(user.user_type, $("#editUaPostion"));
}
$('#editUaPostion').val(user.ua_position);
if (phoneIti && user.phone) {
phoneIti.setNumber(user.phone);
} else {
$('#editPhone').val(user.phone);
}
}
},
error: function(xhr, status, error) {
$('#editErrorArea').removeClass('d-none').text("Failed to load user: " + error);
}
});
});
$('#editUserModal').on('hidden.bs.modal', function(){
if (lastTrigger && document.contains(lastTrigger)) lastTrigger.focus();
lastTrigger = null;
});
// --- FORM SUBMISSION LOGIC ---
function handleFormSubmission(formElement, url, successMessage, phoneInstanceSelector) {
const $form = $(formElement);
const isEdit = formElement.id === 'editUserForm';
const prefix = isEdit ? '#edit' : '#newUser';
const $successArea = $(`${prefix}SuccessArea`);
const $errorArea = $(`${prefix}ErrorArea`);
const itiInstance = phoneInstances[phoneInstanceSelector];
$successArea.addClass('d-none').text("");
$errorArea.addClass('d-none').text("");
const formData = new FormData(formElement);
let errors = [];
if (itiInstance) {
if (!itiInstance.isValidNumber()) {
errors.push("01|Please enter a valid Ghana phone number.");
} else {
formData.set("phone", itiInstance.getNumber());
}
}
const fullName = $form.find('input[name="full_name"], [id*="FullName"], [id*="Fullname"]').val().trim();
const username = $form.find('input[name="username"], [id*="Username"]').val().trim();
const email = $form.find('input[type="email"], [id*="Email"]').val().trim();
if (!fullName) errors.push("Full name is required.");
if (!username) errors.push("Username is required.");
if (!email) {
errors.push("Email is required.");
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
errors.push("Invalid email format.");
}
if (errors.length > 0) {
$errorArea.removeClass("d-none").html(errors.join("
"));
return;
}
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false,
beforeSend: function() {
$successArea.removeClass('d-none').addClass('text-info').text("Processing request, please wait...");
},
success: function(data) {
$successArea.removeClass('text-info');
if (data.success) {
$successArea.removeClass('d-none').text(successMessage);
$.alert({ title: 'Success!', content: successMessage });
setTimeout(() => location.reload(), 2000);
} else {
$successArea.addClass('d-none');
$errorArea.removeClass('d-none').text(data.msg || "An error occurred.");
$.alert({ title: 'Error!', content: data.msg || "An error occurred." });
}
},
error: function(xhr, status, error) {
$successArea.addClass("d-none");
if (xhr.status === 422 && xhr.responseJSON && xhr.responseJSON.errors) {
let messages = [];
$.each(xhr.responseJSON.errors, function (field, msgs) {
messages.push(msgs.join("
"));
});
$errorArea.removeClass("d-none").html(messages.join("
"));
$.alert({ title: "Validation Error", content: messages.join("
") });
} else {
$errorArea.removeClass("d-none").text("Request failed: " + error);
$.alert({ title: "Error", content: "Request failed: " + error });
}
}
});
}
$("#editUserForm").on("submit", function (evt) {
evt.preventDefault();
handleFormSubmission(this, base_url + '/userupdate', "User details successfully updated!", "#editPhone");
});
$("#newUserForm").on("submit", function (evt) {
evt.preventDefault();
handleFormSubmission(this, base_url + '/users', "User successfully created!", "#addUserphone");
});
});