jQuery(document).ready(function($) { // Schedule Management window.openScheduleModal = function() { $('#schedule-modal').show(); $('#schedule-form')[0].reset(); $('#schedule-id').val(''); $('#schedule-modal-title').text('Add New Schedule'); // Reset form fields to defaults $('[name="days_of_week[]"]').prop('checked', false); $('[name="is_active"]').prop('checked', true); $('#after-hours-forward').hide(); $('#after-hours-workflow').hide(); }; window.closeScheduleModal = function() { $('#schedule-modal').hide(); }; window.editSchedule = function(id) { // Load schedule data and populate form $.post(twp_ajax.ajax_url, { action: 'twp_get_schedule', schedule_id: id, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var schedule = response.data; $('#schedule-modal-title').text('Edit Schedule'); $('#schedule-id').val(schedule.id); $('[name="schedule_name"]').val(schedule.schedule_name); $('[name="start_time"]').val(schedule.start_time); $('[name="end_time"]').val(schedule.end_time); $('[name="workflow_id"]').val(schedule.workflow_id); $('[name="is_active"]').prop('checked', schedule.is_active == '1'); // Set days of week checkboxes var days = schedule.days_of_week ? schedule.days_of_week.split(',') : []; $('[name="days_of_week[]"]').prop('checked', false); days.forEach(function(day) { $('[name="days_of_week[]"][value="' + day.trim() + '"]').prop('checked', true); }); // Set after hours action if (schedule.after_hours_action) { $('[name="after_hours_action"]').val(schedule.after_hours_action); toggleAfterHoursFields($('[name="after_hours_action"]')[0]); if (schedule.after_hours_action === 'forward' && schedule.after_hours_forward_number) { $('[name="after_hours_forward_number"]').val(schedule.after_hours_forward_number); } else if (schedule.after_hours_action === 'workflow' && schedule.after_hours_workflow_id) { $('[name="after_hours_workflow_id"]').val(schedule.after_hours_workflow_id); } } else if (schedule.forward_number) { // Legacy support for old forward_number field $('[name="after_hours_action"]').val('forward'); $('[name="after_hours_forward_number"]').val(schedule.forward_number); toggleAfterHoursFields($('[name="after_hours_action"]')[0]); } else { $('[name="after_hours_action"]').val('workflow'); toggleAfterHoursFields($('[name="after_hours_action"]')[0]); } $('#schedule-modal').show(); } else { alert('Error loading schedule data'); } }); }; window.deleteSchedule = function(id) { if (confirm('Are you sure you want to delete this schedule?')) { $.post(twp_ajax.ajax_url, { action: 'twp_delete_schedule', schedule_id: id, nonce: twp_ajax.nonce }, function(response) { if (response.success) { location.reload(); } }); } }; $('#schedule-form').on('submit', function(e) { e.preventDefault(); var formData = $(this).serialize(); // Collect days of week checkboxes var daysOfWeek = []; $('.days-checkbox:checked').each(function() { daysOfWeek.push($(this).val()); }); // Add days to form data if any selected if (daysOfWeek.length > 0) { formData += '&days_of_week[]=' + daysOfWeek.join('&days_of_week[]='); } // Add after-hours fields var afterHoursAction = $('select[name="after_hours_action"]').val(); if (afterHoursAction) { formData += '&after_hours_action=' + encodeURIComponent(afterHoursAction); if (afterHoursAction === 'workflow') { var afterHoursWorkflow = $('select[name="after_hours_workflow_id"]').val(); if (afterHoursWorkflow) { formData += '&after_hours_workflow_id=' + encodeURIComponent(afterHoursWorkflow); } } else if (afterHoursAction === 'forward') { var afterHoursForward = $('input[name="after_hours_forward_number"]').val(); if (afterHoursForward) { formData += '&after_hours_forward_number=' + encodeURIComponent(afterHoursForward); } } } formData += '&action=twp_save_schedule&nonce=' + twp_ajax.nonce; $.post(twp_ajax.ajax_url, formData, function(response) { if (response.success) { closeScheduleModal(); location.reload(); } else { alert('Error saving schedule: ' + (response.data || 'Unknown error')); } }); }); // Toggle after hours fields window.toggleAfterHoursFields = function(select) { var value = $(select).val(); $('#after-hours-forward').hide(); $('#after-hours-workflow').hide(); if (value === 'forward') { $('#after-hours-forward').show(); } else if (value === 'workflow') { $('#after-hours-workflow').show(); } }; window.toggleActionFields = function(select) { if ($(select).val() === 'forward') { $('#forward-fields').show(); $('#workflow-fields').hide(); } else { $('#forward-fields').hide(); $('#workflow-fields').show(); } }; // Workflow Builder var workflowSteps = []; var currentWorkflowId = null; window.openWorkflowBuilder = function() { $('#workflow-builder').show(); $('#workflow-modal-title').text('Create New Workflow'); workflowSteps = []; currentWorkflowId = null; $('#workflow-basic-info')[0].reset(); loadPhoneNumbers(); updateWorkflowDisplay(); }; window.closeWorkflowBuilder = function() { $('#workflow-builder').hide(); }; window.closeStepConfigModal = function() { $('#step-config-modal').hide(); }; function loadPhoneNumbers() { $.post(twp_ajax.ajax_url, { action: 'twp_get_phone_numbers', nonce: twp_ajax.nonce }, function(response) { if (response.success) { var options = ''; response.data.forEach(function(number) { options += ''; }); $('#workflow-phone').html(options); } }); } // Step type button handlers $(document).on('click', '.step-btn', function() { var stepType = $(this).data('step-type'); addWorkflowStep(stepType); }); function addWorkflowStep(stepType) { var step = { id: Date.now(), type: stepType, data: getDefaultStepData(stepType) }; workflowSteps.push(step); updateWorkflowDisplay(); // Open configuration modal openStepConfigModal(step.id, stepType); } function getDefaultStepData(stepType) { switch(stepType) { case 'greeting': return { message: '', use_tts: true }; case 'ivr_menu': return { message: '', options: {}, num_digits: 1, timeout: 10 }; case 'forward': return { forward_number: '', timeout: 30 }; case 'queue': return { queue_name: '', announce_message: '' }; case 'voicemail': return { greeting_message: '', max_length: 120 }; case 'schedule_check': return { schedule_id: '', in_hours_action: {}, after_hours_action: {} }; case 'sms': return { to_number: '', message: '' }; default: return {}; } } function openStepConfigModal(stepId, stepType) { var step = workflowSteps.find(function(s) { return s.id === stepId; }); if (!step) return; $('#step-id').val(stepId); $('#step-type').val(stepType); $('#step-config-title').text('Configure ' + getStepTypeName(stepType) + ' Step'); var configContent = generateStepConfigForm(stepType, step.data); $('#step-config-content').html(configContent); $('#step-config-modal').show(); } function getStepTypeName(stepType) { var names = { 'greeting': 'Greeting', 'ivr_menu': 'IVR Menu', 'forward': 'Forward Call', 'queue': 'Call Queue', 'voicemail': 'Voicemail', 'schedule_check': 'Schedule Check', 'sms': 'SMS Notification' }; return names[stepType] || stepType; } function generateStepConfigForm(stepType, data) { var html = ''; switch(stepType) { case 'greeting': html += '
'; html += '

Greeting Message

'; html += ''; html += ''; html += ''; html += '
'; html += ''; html += ''; html += ''; html += '
'; html += '
'; break; case 'ivr_menu': html += '
'; html += '

Menu Settings

'; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += '
'; html += ''; html += ''; html += ''; html += '
'; html += '
'; html += '
'; html += '

Menu Options

'; html += '
'; if (data.options && Object.keys(data.options).length > 0) { Object.keys(data.options).forEach(function(digit) { html += generateIvrOptionHtml(digit, data.options[digit]); }); } else { html += generateIvrOptionHtml('1', { action: 'forward', number: '' }); } html += '
'; html += '
+ Add Option
'; html += '
'; break; case 'forward': html += '
'; html += '

Forward Settings

'; html += ''; html += ''; html += ''; html += ''; html += '
'; break; case 'queue': html += '
'; html += '

Queue Settings

'; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += '
'; html += ''; html += ''; html += ''; html += '
'; html += '
'; break; case 'voicemail': html += '
'; html += '

Voicemail Settings

'; html += ''; html += ''; html += ''; html += ''; html += ''; html += '
'; html += ''; html += ''; html += ''; html += '
'; html += '
'; break; case 'sms': html += '
'; html += '

SMS Notification

'; html += ''; html += ''; html += ''; html += ''; html += '

Use {from}, {to}, {time} as placeholders

'; html += '
'; break; } return html; } function generateIvrOptionHtml(digit, option) { var html = '
'; html += ''; html += ''; html += ''; html += ''; html += '
'; return html; } window.addIvrOption = function() { var nextDigit = $('#ivr-options-list .ivr-option').length + 1; var newOptionHtml = generateIvrOptionHtml(nextDigit.toString(), { action: 'forward', number: '' }); $('#ivr-options-list').append(newOptionHtml); }; // Save step configuration $('#save-step-btn').on('click', function() { var stepId = parseInt($('#step-id').val()); var stepType = $('#step-type').val(); var formData = $('#step-config-form').serializeArray(); var step = workflowSteps.find(function(s) { return s.id === stepId; }); if (!step) return; // Parse form data into step data step.data = parseStepFormData(stepType, formData); updateWorkflowDisplay(); closeStepConfigModal(); }); function parseStepFormData(stepType, formData) { var data = {}; formData.forEach(function(field) { if (field.name === 'use_tts') { data.use_tts = true; } else if (field.name === 'voice_id') { data.voice_id = field.value; } else if (field.name.endsWith('[]')) { var key = field.name.replace('[]', ''); if (!data[key]) data[key] = []; data[key].push(field.value); } else { data[field.name] = field.value; } }); // Handle IVR options specially if (stepType === 'ivr_menu' && data.digit) { data.options = {}; for (var i = 0; i < data.digit.length; i++) { data.options[data.digit[i]] = { action: data.action[i], description: data.description[i], number: data.target[i], queue_name: data.target[i], message: data.target[i] }; } delete data.digit; delete data.action; delete data.description; delete data.target; } return data; } window.removeWorkflowStep = function(stepId) { workflowSteps = workflowSteps.filter(function(step) { return step.id !== stepId; }); updateWorkflowDisplay(); }; window.editWorkflowStep = function(stepId) { var step = workflowSteps.find(function(s) { return s.id === stepId; }); if (step) { openStepConfigModal(stepId, step.type); } }; function updateWorkflowDisplay() { var stepsHtml = ''; workflowSteps.forEach(function(step, index) { stepsHtml += '
'; stepsHtml += '
'; stepsHtml += '
'; stepsHtml += '' + (index + 1) + ''; stepsHtml += getStepTypeName(step.type); stepsHtml += '
'; stepsHtml += '
'; stepsHtml += ''; stepsHtml += ''; stepsHtml += '
'; stepsHtml += '
'; var description = getStepDescription(step); if (description) { stepsHtml += '
' + description + '
'; } stepsHtml += '
'; }); $('#workflow-steps-list').html(stepsHtml); // Update preview updateWorkflowPreview(); } function updateWorkflowPreview() { var previewHtml = ''; workflowSteps.forEach(function(step, index) { previewHtml += '
'; previewHtml += '' + (index + 1) + '. ' + getStepTypeName(step.type) + '
'; previewHtml += '' + getStepDescription(step) + ''; previewHtml += '
'; }); $('#flow-steps').html(previewHtml); } function getStepDescription(step) { switch(step.type) { case 'greeting': return step.data.message ? '"' + step.data.message.substring(0, 50) + '..."' : 'No message set'; case 'ivr_menu': var optionCount = step.data.options ? Object.keys(step.data.options).length : 0; return 'Menu with ' + optionCount + ' options'; case 'forward': return step.data.forward_number ? 'Forward to ' + step.data.forward_number : 'No number set'; case 'queue': return step.data.queue_name ? 'Add to queue: ' + step.data.queue_name : 'No queue selected'; case 'voicemail': return 'Record voicemail (max ' + (step.data.max_length || 120) + 's)'; case 'schedule_check': return 'Route based on business hours'; case 'sms': return step.data.to_number ? 'Send SMS to ' + step.data.to_number : 'No recipient set'; default: return ''; } } // Save workflow $('#save-workflow-btn').on('click', function() { var formData = $('#workflow-basic-info').serializeArray(); var workflowData = {}; formData.forEach(function(field) { if (field.name === 'is_active') { workflowData.is_active = true; } else { workflowData[field.name] = field.value; } }); if (!workflowData.workflow_name) { alert('Please enter a workflow name'); return; } if (!workflowData.phone_number) { alert('Please select a phone number'); return; } if (workflowSteps.length === 0) { alert('Please add at least one step to the workflow'); return; } var payload = { action: currentWorkflowId ? 'twp_update_workflow' : 'twp_save_workflow', workflow_name: workflowData.workflow_name, phone_number: workflowData.phone_number, workflow_data: JSON.stringify({ steps: workflowSteps, conditions: [], actions: [] }), is_active: workflowData.is_active ? 1 : 0, nonce: twp_ajax.nonce }; if (currentWorkflowId) { payload.workflow_id = currentWorkflowId; } $.post(twp_ajax.ajax_url, payload, function(response) { if (response.success) { closeWorkflowBuilder(); location.reload(); } else { alert('Error saving workflow: ' + (response.data || 'Unknown error')); } }); }); window.editWorkflow = function(workflowId) { // Load workflow data and open builder $.post(twp_ajax.ajax_url, { action: 'twp_get_workflow', workflow_id: workflowId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var workflow = response.data; $('#workflow-builder').show(); $('#workflow-modal-title').text('Edit Workflow: ' + workflow.workflow_name); // Set basic info $('#workflow-basic-info')[0].reset(); $('[name="workflow_name"]').val(workflow.workflow_name); $('[name="phone_number"]').val(workflow.phone_number); $('[name="is_active"]').prop('checked', workflow.is_active == '1'); // Load workflow data currentWorkflowId = workflowId; if (workflow.workflow_data) { try { var workflowData = JSON.parse(workflow.workflow_data); workflowSteps = workflowData.steps || []; } catch (e) { console.error('Error parsing workflow data:', e); workflowSteps = []; } } else { workflowSteps = []; } loadPhoneNumbers(); updateWorkflowDisplay(); } else { alert('Error loading workflow: ' + (response.data || 'Unknown error')); } }); }; window.testWorkflow = function(workflowId) { var testNumber = prompt('Enter phone number to test (e.g., +1234567890):'); if (testNumber) { $.post(twp_ajax.ajax_url, { action: 'twp_test_call', to_number: testNumber, workflow_id: workflowId, nonce: twp_ajax.nonce }, function(response) { if (response.success && response.data.success) { alert('Test call initiated successfully!'); } else { alert('Error initiating test call: ' + (response.data.error || 'Unknown error')); } }); } }; window.deleteWorkflow = function(workflowId) { if (confirm('Are you sure you want to delete this workflow?')) { $.post(twp_ajax.ajax_url, { action: 'twp_delete_workflow', workflow_id: workflowId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { location.reload(); } }); } }; // Queue Management window.openQueueModal = function() { $('#queue-modal').show(); $('#queue-form')[0].reset(); $('#queue-id').val(''); }; window.closeQueueModal = function() { $('#queue-modal').hide(); }; window.editQueue = function(queueId) { // Load queue data $.post(twp_ajax.ajax_url, { action: 'twp_get_queue', queue_id: queueId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var queue = response.data; $('#queue-id').val(queue.id); $('[name="queue_name"]').val(queue.queue_name); $('[name="max_size"]').val(queue.max_size); $('[name="timeout_seconds"]').val(queue.timeout_seconds); $('[name="wait_music_url"]').val(queue.wait_music_url); $('[name="tts_message"]').val(queue.tts_message); $('#queue-modal').show(); } }); }; window.viewQueueDetails = function(queueId) { // Show queue details in a proper modal $.post(twp_ajax.ajax_url, { action: 'twp_get_queue_details', queue_id: queueId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var details = response.data; var queue = details.queue; var waiting_calls = details.waiting_calls; var avg_wait_time = details.avg_wait_time; var calls = details.calls; var detailsHtml = '
'; detailsHtml += '

' + queue.queue_name + ' Details

'; detailsHtml += '
'; detailsHtml += '
' + waiting_calls + '
'; detailsHtml += '
' + avg_wait_time + '
'; detailsHtml += '
' + queue.max_size + '
'; detailsHtml += '
' + queue.timeout_seconds + ' seconds
'; detailsHtml += '
'; if (calls && calls.length > 0) { detailsHtml += '

Current Calls in Queue

'; detailsHtml += ''; detailsHtml += ''; detailsHtml += ''; calls.forEach(function(call, index) { detailsHtml += ''; detailsHtml += ''; detailsHtml += ''; detailsHtml += ''; detailsHtml += ''; detailsHtml += ''; }); detailsHtml += '
PositionFromWait TimeStatus
' + call.position + '' + call.from_number + '' + call.wait_time + '' + call.status + '
'; } else { detailsHtml += '

No calls currently in queue.

'; } detailsHtml += '
'; // Create and show modal showQueueDetailsModal(detailsHtml); } else { alert('Error loading queue details: ' + (response.data || 'Unknown error')); } }); }; function showQueueDetailsModal(content) { // Remove existing modal if present $('#queue-details-modal').remove(); // Create modal HTML var modalHtml = '
'; modalHtml += '
'; modalHtml += '
'; modalHtml += ''; modalHtml += '
'; modalHtml += '
' + content + '
'; modalHtml += ''; modalHtml += '
'; modalHtml += '
'; // Add modal to page $('body').append(modalHtml); } window.closeQueueDetailsModal = function() { $('#queue-details-modal').remove(); }; window.deleteQueue = function(queueId) { if (confirm('Are you sure you want to delete this queue? All waiting calls will be removed from the queue.')) { $.post(twp_ajax.ajax_url, { action: 'twp_delete_queue', queue_id: queueId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { location.reload(); } else { alert('Error deleting queue: ' + (response.data || 'Unknown error')); } }); } }; $('#queue-form').on('submit', function(e) { e.preventDefault(); var formData = $(this).serialize(); formData += '&action=twp_save_queue&nonce=' + twp_ajax.nonce; $.post(twp_ajax.ajax_url, formData, function(response) { if (response.success) { closeQueueModal(); location.reload(); } else { alert('Error saving queue'); } }); }); // Dashboard Auto-refresh if ($('#active-calls').length) { setInterval(function() { updateDashboardStats(); }, 5000); // Update every 5 seconds } function updateDashboardStats() { $.post(twp_ajax.ajax_url, { action: 'twp_get_dashboard_stats', nonce: twp_ajax.nonce }, function(response) { if (response.success) { $('#active-calls').text(response.data.active_calls); $('#queued-calls').text(response.data.queued_calls); // Update recent calls table if (response.data.recent_calls) { var tableHtml = ''; response.data.recent_calls.forEach(function(call) { tableHtml += ''; tableHtml += '' + call.time + ''; tableHtml += '' + call.from + ''; tableHtml += '' + call.to + ''; tableHtml += '' + call.status + ''; tableHtml += '' + call.duration + ''; tableHtml += ''; }); if (tableHtml === '') { tableHtml = 'No recent calls'; } $('#recent-calls').html(tableHtml); } } }); } // Phone Numbers Management window.refreshNumbers = function() { $('#twp-numbers-list').html('

Loading phone numbers...

'); $.post(twp_ajax.ajax_url, { action: 'twp_get_phone_numbers', nonce: twp_ajax.nonce }, function(response) { if (response.success) { displayPhoneNumbers(response.data); } else { $('#twp-numbers-list').html('

Error loading phone numbers: ' + response.data + '

'); } }); }; window.searchAvailableNumbers = function() { $('#twp-available-numbers').show(); $('#search-results').html(''); }; window.searchNumbers = function() { var countryCode = $('#country-code').val(); var areaCode = $('#area-code').val(); var contains = $('#contains').val(); $('#search-results').html('

Searching available numbers...

'); $.post(twp_ajax.ajax_url, { action: 'twp_search_available_numbers', country_code: countryCode, area_code: areaCode, contains: contains, nonce: twp_ajax.nonce }, function(response) { if (response.success) { displayAvailableNumbers(response.data); } else { $('#search-results').html('

Error searching numbers: ' + response.data + '

'); } }); }; function displayPhoneNumbers(numbers) { if (numbers.length === 0) { $('#twp-numbers-list').html('

No phone numbers found. Buy your first number

'); return; } var html = '
'; numbers.forEach(function(number) { html += '
'; html += '
' + number.phone_number + '
'; html += '
'; html += '
Friendly Name:' + (number.friendly_name || 'N/A') + '
'; html += '
Voice URL:' + (number.voice_url ? 'Configured' : 'Not set') + '
'; html += '
SMS URL:' + (number.sms_url ? 'Configured' : 'Not set') + '
'; html += '
Capabilities:'; var capabilities = []; if (number.capabilities.voice) capabilities.push('Voice'); if (number.capabilities.sms) capabilities.push('SMS'); if (number.capabilities.mms) capabilities.push('MMS'); html += capabilities.join(', ') + '
'; html += '
'; html += '
'; html += ''; html += ''; html += '
'; html += '
'; }); html += '
'; $('#twp-numbers-list').html(html); } function displayAvailableNumbers(numbers) { if (numbers.length === 0) { $('#search-results').html('

No numbers found matching your criteria. Try different search terms.

'); return; } var html = ''; numbers.forEach(function(number) { html += '
'; html += '
'; html += '
' + number.phone_number + '
'; html += '
'; var capabilities = []; if (number.capabilities.voice) capabilities.push('Voice'); if (number.capabilities.sms) capabilities.push('SMS'); if (number.capabilities.mms) capabilities.push('MMS'); html += capabilities.join(', '); html += '
'; html += '
'; html += '
$1.00/month
'; html += ''; html += '
'; }); $('#search-results').html(html); } window.purchaseNumber = function(phoneNumber) { if (confirm('Purchase ' + phoneNumber + ' for $1.00/month?')) { $.post(twp_ajax.ajax_url, { action: 'twp_purchase_number', phone_number: phoneNumber, voice_url: twp_ajax.rest_url + 'twilio-webhook/v1/voice', sms_url: twp_ajax.rest_url + 'twilio-webhook/v1/sms', nonce: twp_ajax.nonce }, function(response) { if (response.success) { alert('Phone number purchased successfully!'); refreshNumbers(); $('#twp-available-numbers').hide(); } else { alert('Error purchasing number: ' + response.error); } }); } }; window.configureNumber = function(numberSid, phoneNumber) { $('#number-sid').val(numberSid); $('#phone-number').val(phoneNumber); $('#number-config-modal').show(); }; window.closeNumberConfigModal = function() { $('#number-config-modal').hide(); }; $('#number-config-form').on('submit', function(e) { e.preventDefault(); var formData = $(this).serialize(); formData += '&action=twp_configure_number&nonce=' + twp_ajax.nonce; $.post(twp_ajax.ajax_url, formData, function(response) { if (response.success) { alert('Phone number configured successfully!'); closeNumberConfigModal(); refreshNumbers(); } else { alert('Error configuring number: ' + response.error); } }); }); window.releaseNumber = function(numberSid, phoneNumber) { if (confirm('Are you sure you want to release ' + phoneNumber + '? This action cannot be undone and you will lose this phone number.')) { $.post(twp_ajax.ajax_url, { action: 'twp_release_number', number_sid: numberSid, nonce: twp_ajax.nonce }, function(response) { if (response.success) { alert('Phone number released successfully!'); refreshNumbers(); } else { alert('Error releasing number: ' + response.error); } }); } }; // Initialize phone numbers if on that page if ($('#twp-numbers-list').length) { refreshNumbers(); } // Queue management for workflow steps window.loadQueues = function(button) { var $button = $(button); var $select = $button.prev('select.queue-select'); var currentValue = $select.data('current'); $button.text('Loading...').prop('disabled', true); $.post(twp_ajax.ajax_url, { action: 'twp_get_all_queues', nonce: twp_ajax.nonce }, function(response) { $button.text('Load Queues').prop('disabled', false); if (response.success) { var options = ''; response.data.forEach(function(queue) { var selected = queue.queue_name === currentValue ? ' selected' : ''; options += ''; }); $select.html(options); } else { alert('Error loading queues: ' + (response.data || 'Unknown error')); } }).fail(function() { $button.text('Load Queues').prop('disabled', false); alert('Failed to load queues'); }); }; // Voice management for workflow steps window.loadWorkflowVoices = function(button) { var $button = $(button); var $select = $button.prev('select.voice-select'); var currentValue = $select.data('current'); $button.text('Loading...').prop('disabled', true); $.post(twp_ajax.ajax_url, { action: 'twp_get_elevenlabs_voices', nonce: twp_ajax.nonce }, function(response) { $button.text('Load Voices').prop('disabled', false); if (response.success) { var options = ''; response.data.forEach(function(voice) { var selected = voice.voice_id === currentValue ? ' selected' : ''; var description = voice.labels ? Object.values(voice.labels).join(', ') : ''; var optionText = voice.name + (description ? ' (' + description + ')' : ''); options += ''; }); $select.html(options); } else { var errorMessage = 'Error loading voices: '; if (typeof response.data === 'string') { errorMessage += response.data; } else if (response.data && response.data.detail) { errorMessage += response.data.detail; } else if (response.data && response.data.error) { errorMessage += response.data.error; } else { errorMessage += 'Unknown error occurred'; } alert(errorMessage); } }).fail(function() { $button.text('Load Voices').prop('disabled', false); alert('Failed to load voices. Please check your API key.'); }); }; // Toggle TTS options visibility $(document).on('change', 'input[name="use_tts"]', function() { var $ttsOptions = $(this).closest('.step-config-section').find('.tts-options'); if ($(this).is(':checked')) { $ttsOptions.show(); } else { $ttsOptions.hide(); } }); // Auto-load voices when step config modal opens if API key exists $(document).on('click', '.step-btn', function() { setTimeout(function() { // Check if API key exists in main settings if (twp_ajax.has_elevenlabs_key) { $('.voice-select').each(function() { if ($(this).find('option').length <= 1) { var button = $(this).next('button'); if (button.length) { loadWorkflowVoices(button[0]); } } }); } }, 500); }); // Voicemail Management window.playVoicemail = function(voicemailId, recordingUrl) { var audio = document.getElementById('voicemail-audio'); if (audio) { audio.src = recordingUrl; audio.play(); // Show voicemail modal and load transcription showVoicemail(voicemailId, recordingUrl); } }; window.viewVoicemail = function(voicemailId) { // Load voicemail details via AJAX $.post(twp_ajax.ajax_url, { action: 'twp_get_voicemail', voicemail_id: voicemailId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var voicemail = response.data; showVoicemail(voicemail.id, voicemail.recording_url, voicemail.transcription); } else { alert('Error loading voicemail details'); } }); }; function showVoicemail(voicemailId, recordingUrl, transcription) { // Set the audio source var audio = document.getElementById('voicemail-audio'); if (audio && recordingUrl) { audio.src = recordingUrl; } // Set transcription text var transcriptionDiv = document.getElementById('voicemail-transcription-text'); if (transcriptionDiv) { if (transcription && transcription !== 'Transcription pending...' && transcription !== 'Transcription failed') { transcriptionDiv.innerHTML = '

' + transcription + '

'; // Hide the generate transcription button if we have a transcription var transcribeBtn = document.getElementById('transcribe-btn'); if (transcribeBtn) { transcribeBtn.style.display = 'none'; } } else if (transcription === 'Transcription failed') { transcriptionDiv.innerHTML = '

Transcription failed. Please try again.

'; } else { transcriptionDiv.innerHTML = 'Transcription pending... This will be updated automatically when ready.'; // Show the generate transcription button var transcribeBtn = document.getElementById('transcribe-btn'); if (transcribeBtn) { transcribeBtn.style.display = 'inline-block'; } } } // Store current voicemail ID for actions window.currentVoicemailId = voicemailId; window.currentRecordingUrl = recordingUrl; // Show modal var modal = document.getElementById('voicemail-modal'); if (modal) { modal.style.display = 'flex'; } } window.closeVoicemailModal = function() { var modal = document.getElementById('voicemail-modal'); if (modal) { modal.style.display = 'none'; } // Stop audio playback var audio = document.getElementById('voicemail-audio'); if (audio) { audio.pause(); audio.currentTime = 0; } }; window.downloadVoicemail = function() { if (window.currentRecordingUrl) { window.open(window.currentRecordingUrl, '_blank'); } }; window.deleteVoicemail = function() { if (confirm('Are you sure you want to delete this voicemail?')) { $.post(twp_ajax.ajax_url, { action: 'twp_delete_voicemail', voicemail_id: window.currentVoicemailId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { closeVoicemailModal(); location.reload(); } else { alert('Error deleting voicemail'); } }); } }; window.deleteVoicemailConfirm = function(voicemailId) { if (confirm('Are you sure you want to delete this voicemail?')) { $.post(twp_ajax.ajax_url, { action: 'twp_delete_voicemail', voicemail_id: voicemailId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { location.reload(); } else { alert('Error deleting voicemail'); } }); } }; window.transcribeVoicemail = function() { if (window.currentVoicemailId) { var transcribeBtn = document.getElementById('transcribe-btn'); if (transcribeBtn) { transcribeBtn.innerHTML = 'Generating...'; transcribeBtn.disabled = true; } $.post(twp_ajax.ajax_url, { action: 'twp_transcribe_voicemail', voicemail_id: window.currentVoicemailId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var transcriptionDiv = document.getElementById('voicemail-transcription-text'); if (transcriptionDiv) { transcriptionDiv.innerHTML = '

' + response.data.transcription + '

'; } if (transcribeBtn) { transcribeBtn.style.display = 'none'; } } else { alert('Error generating transcription: ' + response.data); if (transcribeBtn) { transcribeBtn.innerHTML = 'Generate Transcription'; transcribeBtn.disabled = false; } } }); } }; // Close modal when clicking outside $(document).on('click', '#voicemail-modal', function(e) { if (e.target.id === 'voicemail-modal') { closeVoicemailModal(); } }); // Agent Group Management Functions window.openGroupModal = function() { $('#group-modal').show(); $('#group-form')[0].reset(); $('#group-id').val(''); $('#group-modal-title').text('Add New Group'); }; window.closeGroupModal = function() { $('#group-modal').hide(); }; window.saveGroup = function() { var formData = $('#group-form').serialize(); formData += '&action=twp_save_group&nonce=' + twp_ajax.nonce; $.post(twp_ajax.ajax_url, formData, function(response) { if (response.success) { closeGroupModal(); location.reload(); } else { alert('Error saving group: ' + (response.data || 'Unknown error')); } }); }; window.editGroup = function(groupId) { $.post(twp_ajax.ajax_url, { action: 'twp_get_group', group_id: groupId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var group = response.data; $('#group-modal-title').text('Edit Group'); $('#group-id').val(group.id); $('[name="group_name"]').val(group.group_name); $('[name="description"]').val(group.description); $('[name="ring_strategy"]').val(group.ring_strategy); $('[name="timeout_seconds"]').val(group.timeout_seconds); $('#group-modal').show(); } else { alert('Error loading group: ' + (response.data || 'Unknown error')); } }); }; window.deleteGroup = function(groupId) { if (confirm('Are you sure you want to delete this group? All members will be removed.')) { $.post(twp_ajax.ajax_url, { action: 'twp_delete_group', group_id: groupId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { location.reload(); } else { alert('Error deleting group: ' + (response.data || 'Unknown error')); } }); } }; window.manageGroupMembers = function(groupId) { $('#current-group-id').val(groupId); loadGroupMembers(groupId); $('#members-modal').show(); }; window.closeMembersModal = function() { $('#members-modal').hide(); }; function loadGroupMembers(groupId) { $.post(twp_ajax.ajax_url, { action: 'twp_get_group_members', group_id: groupId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { var html = ''; response.data.forEach(function(member) { html += ''; html += '' + member.display_name + ''; html += '' + (member.phone_number || 'No phone set') + ''; html += '' + member.priority + ''; html += '' + (member.is_active ? 'Active' : 'Inactive') + ''; html += ''; html += ''; }); if (html === '') { html = 'No members in this group'; } $('#group-members-list').html(html); } }); } window.addGroupMember = function() { var groupId = $('#current-group-id').val(); var userId = $('#add-member-select').val(); var priority = $('#add-member-priority').val() || 0; if (!userId) { alert('Please select a user to add'); return; } $.post(twp_ajax.ajax_url, { action: 'twp_add_group_member', group_id: groupId, user_id: userId, priority: priority, nonce: twp_ajax.nonce }, function(response) { if (response.success) { $('#add-member-select').val(''); $('#add-member-priority').val(0); loadGroupMembers(groupId); } else { alert('Error adding member: ' + (response.data || 'Unknown error')); } }); }; window.removeGroupMember = function(userId) { var groupId = $('#current-group-id').val(); if (confirm('Remove this member from the group?')) { $.post(twp_ajax.ajax_url, { action: 'twp_remove_group_member', group_id: groupId, user_id: userId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { loadGroupMembers(groupId); } else { alert('Error removing member: ' + (response.data || 'Unknown error')); } }); } }; // Agent Queue Functions window.updateAgentStatus = function(status) { $.post(twp_ajax.ajax_url, { action: 'twp_set_agent_status', status: status, nonce: twp_ajax.nonce }, function(response) { if (!response.success) { alert('Error updating status: ' + (response.data || 'Unknown error')); } }); }; window.acceptCall = function(callId) { var button = $('[onclick="acceptCall(' + callId + ')"]'); button.prop('disabled', true).text('Accepting...'); $.post(twp_ajax.ajax_url, { action: 'twp_accept_call', call_id: callId, nonce: twp_ajax.nonce }, function(response) { if (response.success) { alert('Call accepted! You should receive the call shortly.'); refreshWaitingCalls(); } else { alert('Error accepting call: ' + response.data); button.prop('disabled', false).text('Accept'); } }).fail(function() { alert('Failed to accept call. Please try again.'); button.prop('disabled', false).text('Accept'); }); }; window.refreshWaitingCalls = function() { if (!$('#waiting-calls-list').length) return; $.post(twp_ajax.ajax_url, { action: 'twp_get_waiting_calls', nonce: twp_ajax.nonce }, function(response) { if (response.success) { var html = ''; if (response.data.length === 0) { html = 'No calls waiting'; } else { response.data.forEach(function(call) { var waitMinutes = Math.floor(call.wait_seconds / 60); var waitSeconds = call.wait_seconds % 60; var waitTime = waitMinutes > 0 ? waitMinutes + 'm ' + waitSeconds + 's' : waitSeconds + 's'; html += ''; html += '' + call.position + ''; html += '' + call.queue_name + ''; html += '' + call.from_number + ''; html += '' + waitTime + ''; html += ''; html += ''; }); } $('#waiting-calls-list').html(html); } }); }; // Auto-refresh waiting calls every 5 seconds on agent queue page if ($('#waiting-calls-list').length) { setInterval(refreshWaitingCalls, 5000); refreshWaitingCalls(); // Initial load } // Click-to-Call Functions window.initiateCall = function() { var toNumber = prompt('Enter number to call (e.g., +1234567890):'); if (toNumber) { $.post(twp_ajax.ajax_url, { action: 'twp_initiate_outbound_call', to_number: toNumber, nonce: twp_ajax.nonce }, function(response) { if (response.success) { alert('Call initiated! You should receive a call on your phone shortly, then the call will connect to ' + toNumber); } else { alert('Error initiating call: ' + (response.data || 'Unknown error')); } }); } }; // Callback Management Functions window.requestCallback = function() { var phoneNumber = prompt('Enter phone number for callback (e.g., +1234567890):'); if (phoneNumber) { $.post(twp_ajax.ajax_url, { action: 'twp_request_callback', phone_number: phoneNumber, nonce: twp_ajax.nonce }, function(response) { if (response.success) { alert('Callback requested successfully! The customer will be called back soon.'); refreshCallbacks(); } else { alert('Error requesting callback: ' + (response.data.message || 'Unknown error')); } }); } }; window.refreshCallbacks = function() { if (!$('#callbacks-list').length) return; $.post(twp_ajax.ajax_url, { action: 'twp_get_callbacks', nonce: twp_ajax.nonce }, function(response) { if (response.success) { var html = ''; var callbacks = response.data.callbacks; var stats = response.data.stats; if (callbacks.length === 0) { html = 'No pending callbacks'; } else { callbacks.forEach(function(callback) { var statusClass = 'status-' + callback.status; var queueName = callback.queue_name || 'Direct'; html += ''; html += '' + callback.phone_number + ''; html += '' + queueName + ''; html += '' + callback.requested_at + ''; html += '' + callback.wait_minutes + ' min'; html += '' + callback.status + ''; html += '' + callback.attempts + ''; html += ''; }); } $('#callbacks-list').html(html); // Update stats if available if (stats) { $('#callback-stats-total').text(stats.total_requests); $('#callback-stats-completed').text(stats.completed); $('#callback-stats-pending').text(stats.pending); $('#callback-stats-success-rate').text(stats.success_rate + '%'); if (stats.avg_completion_time) { $('#callback-stats-avg-time').text(Math.round(stats.avg_completion_time) + ' min'); } } } }); }; // Auto-refresh callbacks every 10 seconds on callbacks page if ($('#callbacks-list').length) { setInterval(refreshCallbacks, 10000); refreshCallbacks(); // Initial load } // Initialize on load updateDashboardStats(); });