Features Added: - Queue display showing all assigned queues for the current user - Real-time queue statistics (waiting calls, capacity) - Visual indicators for queues with waiting calls (green border, pulse animation) - Queue selection with click interaction - Accept next call from selected queue functionality - Auto-refresh of queue data every 30 seconds - Mobile-responsive queue interface Backend Changes: - New ajax_get_agent_queues() handler to fetch user's assigned queues - Enhanced ajax_get_waiting_calls() to return structured data - Proper permission checking for twp_access_agent_queue capability Frontend Enhancements: - Interactive queue list with selection states - Queue controls panel showing selected queue info - Refresh button for manual queue updates - Visual feedback for queues with active calls - Mobile-optimized layout for smaller screens UI/UX Improvements: - Queues with waiting calls highlighted with green accent - Pulsing indicator for active queues - Auto-selection of first queue with calls - Responsive design for mobile devices - Dark mode support for queue elements 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
194 lines
8.1 KiB
PHP
194 lines
8.1 KiB
PHP
<?php
|
||
/**
|
||
* Handle plugin shortcodes
|
||
*/
|
||
class TWP_Shortcodes {
|
||
|
||
/**
|
||
* Initialize shortcodes
|
||
*/
|
||
public static function init() {
|
||
add_action('init', array(__CLASS__, 'register_shortcodes'));
|
||
add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_frontend_assets'));
|
||
}
|
||
|
||
/**
|
||
* Register all shortcodes
|
||
*/
|
||
public static function register_shortcodes() {
|
||
add_shortcode('twp_browser_phone', array(__CLASS__, 'browser_phone_shortcode'));
|
||
}
|
||
|
||
/**
|
||
* Enqueue frontend assets when shortcode is present
|
||
*/
|
||
public static function enqueue_frontend_assets() {
|
||
global $post;
|
||
|
||
if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'twp_browser_phone')) {
|
||
// Enqueue Twilio Voice SDK
|
||
wp_enqueue_script(
|
||
'twilio-voice-sdk',
|
||
'https://sdk.twilio.com/js/voice/2.11.1/twilio.min.js',
|
||
array(),
|
||
'2.11.1',
|
||
true
|
||
);
|
||
|
||
// Enqueue our browser phone script
|
||
wp_enqueue_script(
|
||
'twp-browser-phone-frontend',
|
||
TWP_PLUGIN_URL . 'assets/js/browser-phone-frontend.js',
|
||
array('jquery', 'twilio-voice-sdk'),
|
||
TWP_VERSION,
|
||
true
|
||
);
|
||
|
||
// Enqueue mobile-friendly styles
|
||
wp_enqueue_style(
|
||
'twp-browser-phone-frontend',
|
||
TWP_PLUGIN_URL . 'assets/css/browser-phone-frontend.css',
|
||
array(),
|
||
TWP_VERSION
|
||
);
|
||
|
||
// Localize script with AJAX data
|
||
wp_localize_script('twp-browser-phone-frontend', 'twp_frontend_ajax', array(
|
||
'ajax_url' => admin_url('admin-ajax.php'),
|
||
'nonce' => wp_create_nonce('twp_frontend_nonce'),
|
||
'user_id' => get_current_user_id(),
|
||
'is_logged_in' => is_user_logged_in()
|
||
));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Browser phone shortcode handler
|
||
*/
|
||
public static function browser_phone_shortcode($atts) {
|
||
// Check if user is logged in
|
||
if (!is_user_logged_in()) {
|
||
return '<div class="twp-error">You must be logged in to access the browser phone.</div>';
|
||
}
|
||
|
||
// Check if user has permission
|
||
if (!current_user_can('twp_access_browser_phone') && !current_user_can('manage_options')) {
|
||
return '<div class="twp-error">You don\'t have permission to access the browser phone.</div>';
|
||
}
|
||
|
||
// Parse shortcode attributes
|
||
$atts = shortcode_atts(array(
|
||
'title' => 'Browser Phone',
|
||
'show_title' => 'true',
|
||
'compact' => 'false'
|
||
), $atts, 'twp_browser_phone');
|
||
|
||
$show_title = ($atts['show_title'] === 'true');
|
||
$compact_mode = ($atts['compact'] === 'true');
|
||
|
||
ob_start();
|
||
?>
|
||
<div id="twp-frontend-browser-phone" class="twp-browser-phone-container <?php echo $compact_mode ? 'compact' : ''; ?>">
|
||
<?php if ($show_title): ?>
|
||
<h3 class="twp-browser-phone-title"><?php echo esc_html($atts['title']); ?></h3>
|
||
<?php endif; ?>
|
||
|
||
<!-- Connection Status -->
|
||
<div class="twp-connection-status">
|
||
<span class="status-indicator offline" id="twp-status-indicator"></span>
|
||
<span class="status-text" id="twp-status-text">Connecting...</span>
|
||
</div>
|
||
|
||
<!-- Phone Number Selection -->
|
||
<div class="twp-phone-selection">
|
||
<label for="twp-caller-id">Caller ID:</label>
|
||
<select id="twp-caller-id" class="twp-select">
|
||
<option value="">Loading...</option>
|
||
</select>
|
||
</div>
|
||
|
||
<!-- Dial Pad -->
|
||
<div class="twp-dialpad">
|
||
<div class="twp-number-display">
|
||
<input type="tel" id="twp-dial-number" placeholder="Enter number to dial" />
|
||
<button id="twp-clear-number" class="twp-btn-clear" title="Clear">×</button>
|
||
</div>
|
||
|
||
<div class="twp-dial-grid">
|
||
<button class="twp-dial-btn" data-digit="1">1<span></span></button>
|
||
<button class="twp-dial-btn" data-digit="2">2<span>ABC</span></button>
|
||
<button class="twp-dial-btn" data-digit="3">3<span>DEF</span></button>
|
||
<button class="twp-dial-btn" data-digit="4">4<span>GHI</span></button>
|
||
<button class="twp-dial-btn" data-digit="5">5<span>JKL</span></button>
|
||
<button class="twp-dial-btn" data-digit="6">6<span>MNO</span></button>
|
||
<button class="twp-dial-btn" data-digit="7">7<span>PQRS</span></button>
|
||
<button class="twp-dial-btn" data-digit="8">8<span>TUV</span></button>
|
||
<button class="twp-dial-btn" data-digit="9">9<span>WXYZ</span></button>
|
||
<button class="twp-dial-btn" data-digit="*">*</button>
|
||
<button class="twp-dial-btn" data-digit="0">0<span>+</span></button>
|
||
<button class="twp-dial-btn" data-digit="#">#</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Call Controls -->
|
||
<div class="twp-call-controls">
|
||
<button id="twp-call-btn" class="twp-btn twp-btn-primary">
|
||
<span class="call-icon">📞</span>
|
||
<span class="call-text">Call</span>
|
||
</button>
|
||
<button id="twp-hangup-btn" class="twp-btn twp-btn-danger" style="display: none;">
|
||
<span class="hangup-icon">📞</span>
|
||
<span class="hangup-text">Hang Up</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Call Info -->
|
||
<div class="twp-call-info" id="twp-call-info" style="display: none;">
|
||
<div class="call-timer">
|
||
<span class="timer-label">Call Duration:</span>
|
||
<span class="timer-value" id="twp-call-timer">00:00</span>
|
||
</div>
|
||
<div class="call-status">
|
||
<span id="twp-call-status">Connecting...</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Queue Management Section -->
|
||
<div class="twp-queue-section" id="twp-queue-section">
|
||
<h4>Your Queues</h4>
|
||
<div class="twp-queue-list" id="twp-queue-list">
|
||
<div class="queue-loading">Loading queues...</div>
|
||
</div>
|
||
|
||
<!-- Queue Controls -->
|
||
<div class="twp-queue-controls" id="twp-queue-controls" style="display: none;">
|
||
<div class="selected-queue-info">
|
||
<h5 id="selected-queue-name">No queue selected</h5>
|
||
<div class="queue-stats">
|
||
<span class="waiting-count">Waiting: <span id="twp-waiting-count">0</span></span>
|
||
<span class="queue-size">Max: <span id="twp-queue-max-size">-</span></span>
|
||
</div>
|
||
</div>
|
||
<div class="queue-actions">
|
||
<button id="twp-accept-queue-call" class="twp-btn twp-btn-success">
|
||
Accept Next Call
|
||
</button>
|
||
<button id="twp-refresh-queues" class="twp-btn twp-btn-secondary">
|
||
Refresh
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Audio elements -->
|
||
<audio id="twp-ringtone" preload="auto" loop>
|
||
<source src="<?php echo TWP_PLUGIN_URL; ?>assets/audio/ringtone.mp3" type="audio/mpeg">
|
||
</audio>
|
||
|
||
<!-- Error/Success Messages -->
|
||
<div class="twp-messages" id="twp-messages"></div>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
}
|