/** * Easy Invoice - Client Management * Handles all client-related functionality including selection, adding new clients, * and managing client data. */ (function($) { $(document).ready(function() { // Store client data in a JavaScript object var clientsData = {}; // Load clients data from the global object if available function initializeClientData() { if (typeof window.easyInvoiceClients !== 'undefined') { clientsData = window.easyInvoiceClients; } // Make clientsData available globally window.easyInvoiceClients = clientsData; } // Initialize client data initializeClientData(); // Handle client selection change function setupClientSelection() { var isInitialLoad = true; // Flag to prevent AJAX calls on initial load $("#select-client").on("change", function() { var clientId = $(this).val(); // Skip AJAX call if this is the initial load or if we're initializing client if (isInitialLoad || (typeof window.isInitializingClient !== 'undefined' && window.isInitializingClient)) { isInitialLoad = false; return; } if (clientId) { // Load client data via AJAX loadClientData(clientId); } else { // Clear client display clearClientDisplay(); } }); // Auto-select client if client-id field has a value (for existing invoices) var existingClientId = $("#client-id").val(); if (existingClientId && existingClientId !== '') { // Set the dropdown value without triggering change event $("#select-client").val(existingClientId); // Check if we have client data from PHP first if (typeof easyInvoice !== 'undefined' && easyInvoice.clientData && easyInvoice.clientData.id == existingClientId) { loadClientDataFromPHP(easyInvoice.clientData); } } // Reset the flag after a short delay to allow for user interactions setTimeout(function() { isInitialLoad = false; }, 1000); } // Load client data from PHP (no AJAX needed) function loadClientDataFromPHP(clientData) { // Set client ID $("#client-id").val(clientData.id); // Update display fields $("#display-client-name").text(clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name) || 'N/A'); $("#display-client-email").text(clientData.email || 'N/A'); $("#display-client-phone").text(clientData.phone || 'N/A'); $("#display-client-company").text(clientData.business_client_name || 'N/A'); $("#display-client-address").text(clientData.address || 'N/A'); $("#display-client-website").text(clientData.website || 'N/A'); // Show client info display and hide no-client message $("#client-info-display").removeClass("hidden"); $("#no-client-message").addClass("hidden"); // Update the new selected client display var clientName = clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name) || 'N/A'; $("#selected-client-name").text(clientName); $("#selected-client-email").text(clientData.email || 'N/A'); $("#selected-client-display").removeClass("hidden"); // Update the edit client link var editUrl = 'admin.php?page=easy-invoice-client-edit&client_id=' + clientData.id; $('#edit-selected-client').attr('href', editUrl).removeClass('hidden'); // Store client data for later use clientsData[clientData.id] = { name: clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name), email: clientData.email, phone: clientData.phone, address: clientData.address, website: clientData.website, business_name: clientData.business_client_name, first_name: clientData.first_name, last_name: clientData.last_name }; } // Load client data via AJAX function loadClientData(clientId) { $.ajax({ url: easyInvoice.ajaxUrl, type: 'POST', data: { action: 'easy_invoice_get_client', client_id: clientId, nonce: easyInvoice.nonce }, success: function(response) { if (response.success) { var client = response.data; // Set client ID $("#client-id").val(clientId); // Update display fields $("#display-client-name").text(client.business_client_name || (client.first_name + ' ' + client.last_name) || 'N/A'); $("#display-client-email").text(client.email || 'N/A'); $("#display-client-phone").text(client.phone || 'N/A'); $("#display-client-company").text(client.business_client_name || 'N/A'); $("#display-client-address").text(client.address || 'N/A'); $("#display-client-website").text(client.website || 'N/A'); // Show client info display and hide no-client message $("#client-info-display").removeClass("hidden"); $("#no-client-message").addClass("hidden"); // Update the new selected client display var clientName = client.business_client_name || (client.first_name + ' ' + client.last_name) || 'N/A'; $("#selected-client-name").text(clientName); $("#selected-client-email").text(client.email || 'N/A'); $("#selected-client-display").removeClass("hidden"); // Update the edit client link var editUrl = 'admin.php?page=easy-invoice-client-edit&client_id=' + clientId; $('#edit-selected-client').attr('href', editUrl).removeClass('hidden'); // Store client data for later use clientsData[clientId] = { name: client.business_client_name || (client.first_name + ' ' + client.last_name), email: client.email, phone: client.phone, address: client.address, website: client.website, business_name: client.business_client_name, first_name: client.first_name, last_name: client.last_name }; } else { clearClientDisplay(); } }, error: function(xhr, status, error) { clearClientDisplay(); } }); } // Clear client display function clearClientDisplay() { $("#client-id").val(""); $("#display-client-name").text("-"); $("#display-client-email").text("-"); $("#display-client-phone").text("-"); $("#display-client-company").text("-"); $("#display-client-address").text("-"); $("#display-client-website").text("-"); $("#client-info-display").addClass("hidden"); $("#no-client-message").removeClass("hidden"); $("#selected-client-display").addClass("hidden"); $("#edit-selected-client").addClass("hidden"); } // Clean up existing handlers to prevent duplicates function cleanUpExistingHandlers() { $("#add-new-client-btn").off("click"); $(document).off("click", "#add-new-client-btn"); $(".close-modal").off("click"); $(document).off("click", ".close-modal"); $(document).off("click", "#add-save-client-btn"); $(document).off("click", "#add-cancel-add-client"); } // Setup client modal functionality function setupClientModal() { // Clean up existing handlers first cleanUpExistingHandlers(); // Simple function to toggle modal visibility function toggleClientModal(show) { if (show) { $("#add_client_modal").removeClass("hidden"); } else { $("#add_client_modal").addClass("hidden"); // Reset form when closing $("#add-client-form")[0].reset(); } } // Simple button click handler $(document).on("click", "#add-new-client-btn", function(e) { e.preventDefault(); e.stopPropagation(); // Simple modal show $("#add_client_modal").removeClass("hidden"); return false; }); // Use event delegation for close buttons $(document).on("click", ".close-modal", function(e) { e.preventDefault(); e.stopPropagation(); toggleClientModal(false); return false; }); // Handle cancel button $(document).on("click", "#add-cancel-add-client", function(e) { e.preventDefault(); e.stopPropagation(); toggleClientModal(false); return false; }); // Close when clicking on the background $(document).on("click", "#add_client_modal", function(e) { if (e.target === this) { toggleClientModal(false); } }); // Handle client form submission via button click $(document).on("click", "#add-save-client-btn", function(e) { e.preventDefault(); e.stopPropagation(); // Prevent event bubbling to parent form // Check if we can find the form fields directly (since form tag might not be rendering) var $businessNameField = $("#add-client-business-name"); var $emailField = $("#add-client-email"); var $usernameField = $("#add-client-username"); var $passwordField = $("#add-client-password"); if ($businessNameField.length === 0 || $emailField.length === 0 || $usernameField.length === 0 || $passwordField.length === 0) { if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error("Client form fields not found! Please refresh the page and try again."); } else { console.error("Client form fields not found! Please refresh the page and try again."); } return; } // Check if easyInvoice object exists if (typeof easyInvoice === 'undefined') { if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error("Error: easyInvoice object is not defined. Please refresh the page."); } else { console.error("Error: easyInvoice object is not defined. Please refresh the page."); } return; } // Check if required fields are filled var businessName = $businessNameField.val(); var email = $emailField.val(); var username = $usernameField.val(); var password = $passwordField.val(); // Validate required fields if (!businessName || !email || !username ) { if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error("Please fill in all required fields (Business Name, Email, Username, Password)"); } else { console.error("Please fill in all required fields (Business Name, Email, Username, Password)"); } return; } // Get form data using new field names - ensure no conflicts with main form var clientData = { business_client_name: businessName, email: email, username: username, password: password, address: $("#add-client-address").val(), phone: $("#add-client-phone").val(), first_name: $("#add-client-first-name").val(), last_name: $("#add-client-last-name").val(), website: $("#add-client-website").val(), action: "easy_invoice_add_client", nonce: easyInvoice.nonce, suppress_global_toast: true, // Prevent global toasts is_client_form: true // Flag to identify this is client form data }; // Show loading state var submitBtn = $(this); var originalText = submitBtn.text(); submitBtn.prop("disabled", true).html(" Saving..."); // Send AJAX request $.ajax({ url: easyInvoice.ajaxUrl, type: "POST", data: clientData, timeout: 10000, // 10 second timeout success: function(response) { // Always reset the button and clear the form submitBtn.prop("disabled", false).html(originalText); $("#add-client-business-name, #add-client-email, #add-client-username, #add-client-password, #add-client-first-name, #add-client-last-name, #add-client-address, #add-client-phone, #add-client-website").val(""); if (response.success) { // Close modal $("#add_client_modal").addClass("hidden"); // If we're in an invoice or quote builder, select the new client if (typeof window.selectClientFromOption === 'function') { // Create client data object for selection var newClientData = { name: clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name), email: clientData.email, company: clientData.business_client_name, phone: clientData.phone, website: clientData.website, address: clientData.address }; // Select the new client in the main form window.selectClientFromOption({ getAttribute: function(attr) { if (attr === 'data-client-id') return response.data.client_id; if (attr === 'data-client-name') return newClientData.name; if (attr === 'data-client-email') return newClientData.email; if (attr === 'data-client-company') return newClientData.company; if (attr === 'data-client-phone') return newClientData.phone; if (attr === 'data-client-website') return newClientData.website; if (attr === 'data-client-address') return newClientData.address; return ''; } }); } // Add the new client to the table var clientName = clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name); if (clientName.trim() === '') { clientName = clientData.username; } // Create new table row var newRow = `
${response.data.client_id}
${clientName}
${clientData.email}
${clientData.username}
Client
View Edit
`; // Remove "No clients found" row if it exists $(".client-list-table tbody tr td[colspan='6']").closest("tr").remove(); // Add new row at the top of the table (since we order by ID DESC) $(".client-list-table tbody").prepend(newRow); // Update total clients count var currentCount = parseInt($("h3:contains('Total Clients')").next().text()) || 0; $("h3:contains('Total Clients')").next().text(currentCount + 1); // Show server's success message (don't add additional client-side message) if (typeof showToast === 'function' && response.data.message) { showToast(response.data.message, "success"); } } else { if (typeof showToast === 'function') { showToast(response.data.message || "Error adding client", "error"); } } }, error: function(xhr, status, error) { submitBtn.prop("disabled", false).html(originalText); if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error("Error connecting to server. Please try again."); } else if (typeof showToast === 'function') { showToast("Error connecting to server. Please try again.", "error"); } else { console.error("Error connecting to server. Please try again."); } }, timeout: function() { submitBtn.prop("disabled", false).html(originalText); if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error("Request timed out. Please try again."); } else if (typeof showToast === 'function') { showToast("Request timed out. Please try again.", "error"); } else { console.error("Request timed out. Please try again."); } } }); }); } // Setup password field functionality function setupPasswordFields() { // Show/hide password functionality for add client modal $(document).on('click', '#show-password', function() { const passwordInput = $('#client-password'); const icon = $(this).find('i'); if (passwordInput.attr('type') === 'password') { passwordInput.attr('type', 'text'); icon.removeClass('fa-eye').addClass('fa-eye-slash'); } else { passwordInput.attr('type', 'password'); icon.removeClass('fa-eye-slash').addClass('fa-eye'); } }); // Show/hide password functionality for edit client page $(document).on('click', '#edit-show-password', function() { const passwordInput = $('#edit-client-password'); const icon = $(this).find('i'); if (passwordInput.attr('type') === 'password') { passwordInput.attr('type', 'text'); icon.removeClass('fa-eye').addClass('fa-eye-slash'); } else { passwordInput.attr('type', 'password'); icon.removeClass('fa-eye-slash').addClass('fa-eye'); } }); // Generate password functionality for add client modal $(document).on('click', '#add-generate-password, #edit-generate-password', function() { const button = $(this); const isEditMode = button.attr('id') === 'edit-generate-password'; const passwordInput = isEditMode ? $('#edit-client-password') : $('#add-client-password'); const showPasswordBtn = isEditMode ? $('#edit-show-password') : $('#add-show-password'); button.prop('disabled', true); $.ajax({ url: easyInvoice.ajaxUrl, type: 'POST', data: { action: 'easy_invoice_generate_password', nonce: easyInvoice.nonce, suppress_global_toast: true // Prevent global success toast }, success: function(response) { if (response.success) { passwordInput.val(response.data.password); passwordInput.attr('type', 'text'); showPasswordBtn.find('i').removeClass('fa-eye').addClass('fa-eye-slash'); } else { } }, error: function() { if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error('Error connecting to server'); } else if (typeof showToast === 'function') { showToast('Error connecting to server', 'error'); } else { console.error('Error connecting to server'); } }, complete: function() { button.prop('disabled', false); } }); }); } // Setup client edit functionality function setupClientEdit() { // Disable HTML5 validation for password field in edit mode if ($("#edit-client-form").length) { $("#edit-client-password").removeAttr("required"); } // Handle client edit form submission $(document).on("submit", "#edit-client-form", function(e) { e.preventDefault(); let isSubmitting = false; if (isSubmitting) return; isSubmitting = true; const clientData = { client_id: $("#edit-client-id").val(), business_client_name: $("#edit-client-business-name").val(), email: $("#edit-client-email").val(), username: $("#edit-client-username").val(), password: $("#edit-client-password").val(), address: $("#edit-client-address").val(), phone: $("#edit-client-phone").val(), first_name: $("#edit-client-first-name").val(), last_name: $("#edit-client-last-name").val(), website: $("#edit-client-website").val(), action: "easy_invoice_update_client", nonce: easyInvoice.nonce }; const submitBtn = $("#edit-save-client-btn"); const originalText = submitBtn.text(); submitBtn.prop("disabled", true).html(" Saving..."); $.ajax({ url: easyInvoice.ajaxUrl, type: "POST", data: clientData, success: function(response) { // Re-enable the button regardless of success/failure submitBtn.prop("disabled", false).text(originalText); isSubmitting = false; }, error: function() { if (typeof EasyInvoiceToast !== 'undefined') { EasyInvoiceToast.error("Error connecting to server"); } else if (typeof showToast === 'function') { showToast("Error connecting to server", "error"); } else { console.error("Error connecting to server"); } submitBtn.prop("disabled", false).text(originalText); isSubmitting = false; } }); }); } // Initialize all client functionality function initializeClientManager() { // Prevent multiple initializations if (window.clientManagerInitialized) { return; } setupClientSelection(); setupClientModal(); setupPasswordFields(); setupClientEdit(); // Mark as initialized window.clientManagerInitialized = true; } // Initialize the client manager initializeClientManager(); // Expose client manager functions globally window.clientManager = { initializeClientData: initializeClientData, refreshClientList: function(newClientData) { clientsData = newClientData || clientsData; window.easyInvoiceClients = clientsData; }, setupModal: setupClientModal }; }); })(jQuery);