$(document).ready(function () {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
'Accept': 'application/json'
}
});
const phoneInstances = {};
function initPhoneInput(selector) {
const input = document.querySelector(selector);
if (!input) return null;
// If it was already initialized, don't do it again
if (phoneInstances[selector]) return phoneInstances[selector];
phoneInstances[selector] = window.intlTelInput(input, {
initialCountry: "gh",
onlyCountries: ["gh"],
nationalMode: true, // ALLOW users to type 024... natively
autoPlaceholder: "polite",
utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.19/js/utils.js"
});
// Auto-format on blur using the plugin's built-in engine
input.addEventListener("blur", function () {
if (phoneInstances[selector].isValidNumber()) {
// Reformats to local standard (e.g., 024 123 4567) for UI
phoneInstances[selector].setNumber(phoneInstances[selector].getNumber());
}
});
return phoneInstances[selector];
}
// Initialize inputs when their respective modals open
$('#editUserModal').on('shown.bs.modal', () => initPhoneInput("#editPhone"));
$('#addUserModal').on('shown.bs.modal', () => initPhoneInput("#addUserphone"));
$('#editAllowedApps, #inputPermissions').select2({
dropdownParent: $('#editUserModal'),
placeholder: "Select options, multiple allowed"
});
$('#allowedApps').select2({
dropdownParent: $('#addUserModal'),
placeholder: "Select options, multiple allowed"
});
const optionsMap = {
district_user: [
"PPD Head", "Works Head", "MIS", "PPD Staff", "Works Staff",
"Devt Planning Officer", "MCE", "DCE", "Urban Roads Department Head",
"District Fire Officer", "District Disaster Prevention Department",
"Head of District Health Department", "Representative of the Lands Commission",
"Representative of the Environmental Protection Agency", "Rep from Traditional Council",
"Chairman of the Works Sub Committee", "Chairman of Development Sub Planning Committee",
"Nominated Elected Assembly Memebers"
],
national_luspa: ["Director", "IT Head", "Staff"],
regional_luspa: ["Director", "Staff"]
};
function populatePositions(userType, targetDropdown) {
targetDropdown.empty().append('');
if (optionsMap[userType]) {
$.each(optionsMap[userType], function(index, value) {
targetDropdown.append($("").attr("value", value.toLowerCase()).text(value));
});
}
}
let initialUserType = $("input[name='user_type']:checked").val();
if(initialUserType) populatePositions(initialUserType, $("#uaPostionAdd"));
// Handle Radio Changes
$("input[name='user_type']").change(function() {
let userType = $(this).val();
let isDistrict = (userType === 'district_user');
let isRegional = (userType === 'regional_luspa');
$('#regionID, #editRegionID').prop('disabled', !isDistrict && !isRegional);
$('#districtID, #editdistrictID').prop('disabled', !isDistrict);
populatePositions(userType, $("#uaPostionAdd"));
});
$('.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));
});
}
}
});
});
let lastTrigger = null;
$(document).on('click', '.editUserBtn', function(evnt) {
evnt.preventDefault();
lastTrigger = this;
const row = $(this).closest('.user-row');
let selectedUserId = row.data('id');
// Ensure phone instance exists before trying to set data into it
let phoneIti = initPhoneInput("#editPhone");
$.ajax({
url: base_url + '/users/edit/' + selectedUserId,
type: 'GET',
beforeSend: function() {
$('#editSuccessArea').addClass('d-none');
$('#editErrorArea').removeClass('d-none').text("Please wait ... loading user details!!");
},
success: function(response) {
$('#editErrorArea').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);
$('#editUaPostion').val(user.ua_position);
$('#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);
}
if (phoneIti && user.phone) {
phoneIti.setNumber(user.phone);
} else {
$('#editPhone').val(user.phone);
}
// $('#editUserModal').modal('show')
}
},
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;
});
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 = [];
// Validate Phone cleanly
if (itiInstance) {
if (!itiInstance.isValidNumber()) {
errors.push("01|Please enter a valid Ghana phone number.");
} else {
// Get the clean E.164 database format (e.g. +233241234567)
formData.set("phone", itiInstance.getNumber());
}
}
// Validate standard fields
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");
});
});