PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.7.4
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.7.4
8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 All 533 releases
chatbot / includes / admin / templates / ai-actions.php

ai-actions.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.7.4, at includes/admin/templates/ai-actions.php

945 lines 57.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4 if ( isset( $_POST['submit'] ) && check_admin_referer( 'wp_chatbot_ai_actions', '_wpnonce' ) && current_user_can( 'manage_options' ) ) {
5
6 $ai_forms = array();
7 if ( isset( $_POST['ai_form_title'] ) && is_array( $_POST['ai_form_title'] ) ) {
8 $titles = $_POST['ai_form_title'];
9 $prompts = isset( $_POST['ai_form_prompt'] ) ? $_POST['ai_form_prompt'] : array();
10 $interactive = isset( $_POST['ai_form_interactive'] ) ? $_POST['ai_form_interactive'] : array();
11 $email = isset( $_POST['ai_form_email'] ) ? $_POST['ai_form_email'] : array();
12 $email_addresses = isset( $_POST['ai_form_email_addresses'] ) ? $_POST['ai_form_email_addresses'] : array();
13
14 for ( $i = 0; $i < count( $titles ); $i++ ) {
15 $title = sanitize_text_field( wp_unslash( $titles[$i] ) );
16 $prompt = isset( $prompts[$i] ) ? sanitize_textarea_field( wp_unslash( $prompts[$i] ) ) : '';
17 if ( ! empty( $title ) && ! empty( $prompt ) ) {
18 $ai_forms[] = array(
19 'title' => $title,
20 'prompt' => $prompt,
21 'interactive' => isset($interactive[$i]) ? intval($interactive[$i]) : 0,
22 'email' => isset($email[$i]) ? intval($email[$i]) : 1,
23 'email_addresses' => isset($email_addresses[$i]) ? sanitize_textarea_field( wp_unslash( $email_addresses[$i] ) ) : '',
24 );
25 }
26 }
27 }
28 update_option( 'wpbot_ai_forms', $ai_forms );
29
30 if ( isset( $_POST['qcld_ai_default_email'] ) ) {
31 $raw_emails = wp_unslash( $_POST['qcld_ai_default_email'] );
32 // Sanitize each email individually, preserving comma-separated list
33 $emails = array_map( 'sanitize_email', array_map( 'trim', explode( ',', $raw_emails ) ) );
34 $emails = array_filter( $emails ); // remove any invalid entries
35 update_option( 'qcld_ai_default_email', implode( ', ', $emails ) );
36 }
37
38 update_option( 'enable_ai_interactive_form', '1' );
39
40 echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Settings saved.', 'chatbot' ) . '</p></div>';
41 }
42
43 $saved_forms = get_option( 'wpbot_ai_forms', array() );
44
45 // One-time migration: Ensure all existing forms have email enabled by default.
46 $migrated = false;
47 if ( is_array( $saved_forms ) ) {
48 foreach ( $saved_forms as &$f ) {
49 if ( ! isset( $f['email_migrated'] ) ) {
50 $f['email'] = 1;
51 $f['email_migrated'] = 1;
52 $migrated = true;
53 }
54 }
55 if ( $migrated ) {
56 update_option( 'wpbot_ai_forms', $saved_forms );
57 }
58 }
59 if ( ! is_array( $saved_forms ) ) {
60 $saved_forms = array();
61 }
62 ?>
63 <div class="wrap qcld-main-wrapper">
64 <div class="qcld-wp-chatbot-wrap-header-aisection">
65 <div class="qcld-wp-chatbot-wrap-header">
66 <div class="qcld-wp-chatbot-wrap-header-logo">
67 <a href="#" class="qcld-wp-chatbot-wrap-site__logo">
68 <img style="width:100%" src="<?php echo esc_url( QCLD_wpCHATBOT_IMG_URL . '/chatbot.png' ); ?>" alt="Dialogflow CX"> WPBot Control Panel
69 </a>
70 <p><strong>Core Version:</strong> v<?php echo esc_html( QCLD_wpCHATBOT_VERSION ); ?></p>
71 </div>
72 <ul class="qcld-wp-chatbot-wrap-version-wrapper">
73 <li><a class="wpchatbot-Upgrade" href="https://www.wpbot.pro/" target="_blank">Upgrade To Pro</a></li>
74 </ul>
75 </div>
76 </div>
77
78 <div class="qcl-openai" style="margin-top: 20px;">
79 <div style="display: flex; gap: 20px; align-items: flex-start;">
80
81 <!-- LEFT SIDEBAR -->
82 <div style="width: 250px; flex-shrink: 0; background: #fff; border: 1px solid #ccd0d4; box-shadow: 0 1px 1px rgba(0,0,0,.04);">
83 <ul class="qcld-ai-sidebar-menu" style="margin: 0; padding: 0; list-style: none;">
84 <li style="border-bottom: 1px solid #eee;">
85 <a href="#ai-new-action-tab" class="ai-sidebar-link active" style="display: block; padding: 15px; text-decoration: none; color: #444; font-weight: 600; cursor: pointer; transition: 0.2s;">+ <?php esc_html_e('Add New Action', 'chatbot'); ?></a>
86 </li>
87
88 <li style="border-bottom: 1px solid #eee;">
89 <a href="#" class="ai-sidebar-parent-link" style="display: flex; justify-content: space-between; padding: 15px; text-decoration: none; color: #444; font-weight: 600; cursor: pointer; background: #fcfcfc;">
90 <?php esc_html_e('Saved Actions', 'chatbot'); ?>
91 <span class="dashicons dashicons-arrow-down-alt2" style="margin-top: 2px; transition: 0.2s;"></span>
92 </a>
93 <ul class="ai-saved-actions-submenu" style="margin: 0; padding: 0; list-style: none; display: block; border-top: 1px solid #eee;">
94 <?php
95 $counter = 1;
96 if ( ! empty( $saved_forms ) ) {
97 foreach ( $saved_forms as $form ) {
98 $tab_id = 'ai-action-tab-' . $counter;
99 echo '<li><a href="#' . esc_attr($tab_id) . '" class="ai-sidebar-link ai-sidebar-saved-link" data-id="'.esc_attr($tab_id).'" style="display: block; padding: 10px 15px 10px 30px; text-decoration: none; color: #555; font-size: 13px; border-bottom: 1px solid #f5f5f5;">' . esc_html( $form['title'] ) . '</a></li>';
100 $counter++;
101 }
102 } else {
103 echo '<li class="ai-no-saved-actions" style="padding: 10px 15px 10px 30px; color: #999; font-size: 12px; font-style: italic;">' . esc_html__('No saved actions', 'chatbot') . '</li>';
104 }
105 ?>
106 </ul>
107 </li>
108
109 </ul>
110 </div>
111
112 <!-- MAIN CONTENT AREA -->
113 <div style="flex-grow: 1; min-width: 0; background: #fff; border: 1px solid #ccd0d4; box-shadow: 0 1px 1px rgba(0,0,0,.04);">
114 <form action="" method="POST" id="ai-actions-main-form" style="margin: 0; padding: 0;">
115 <?php wp_nonce_field( 'wp_chatbot_ai_actions', '_wpnonce' ); ?>
116
117 <!-- NEW ACTION TAB -->
118 <div id="ai-new-action-tab" class="ai-content-pane active" style="padding: 20px;">
119 <?php
120 $no_ai_active = (get_option( 'ai_enabled' ) != 1 &&
121 get_option( 'qcld_openrouter_enabled' ) != 1 &&
122 get_option( 'qcld_gemini_enabled' ) != 1 &&
123 get_option( 'qcld_grok_enabled' ) != 1 &&
124 get_option( 'qcld_claude_enabled' ) != 1);
125 if($no_ai_active):
126 ?>
127 <div style="color: #fff; background: #e64340; padding: 12px 16px; border-radius: 6px; margin-bottom: 20px; display: flex; align-items: center; gap: 10px;">
128 <?php esc_html_e('No AI connection is active. Please enable AI integration.', 'chatbot'); ?>
129 </div>
130 <?php endif; ?>
131 <h3 style="margin-top: 0; font-size: 18px;"><?php esc_html_e('Choose a Template', 'chatbot'); ?></h3>
132 <p style="color: #666;"><?php esc_html_e('Select a template below to create a new AI Action. You can customize it on the next screen.', 'chatbot'); ?></p>
133
134 <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">
135 <!-- Blank -->
136 <div class="ai-template-card" data-title="" data-prompt="" style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
137 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-plus-alt2" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
138 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Blank Prompt</h4>
139 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Start from scratch and build your own custom AI action.</p>
140 </div>
141
142 <!-- 1. Web Agency Quote -->
143 <div class="ai-template-card" data-title="Web Agency Quote" data-prompt="You are a project discovery assistant for a web development agency.
144 Ask the user the following questions conversationally, one at a time:
145
146 1. What type of project are they planning (e.g., WordPress plugin, custom web app, WooCommerce store)?
147 2. What are the core features or problems they need solved?
148 3. What is their estimated budget range and target launch timeline?
149 4. What is their full name, work email, and preferred contact method?
150
151 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
152 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-desktop" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
153 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Web Agency Quote</h4>
154 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Software, agency, and freelance service inquiries.</p>
155 </div>
156
157 <!-- 2. Real Estate Inquiry -->
158 <div class="ai-template-card" data-title="Real Estate Inquiry" data-prompt="You are a real estate assistant helping visitors find their ideal property.
159 Collect these details step-by-step:
160
161 1. Are they looking to Buy, Rent, or Sell?
162 2. What property type and location/neighborhood are they interested in?
163 3. How many bedrooms and bathrooms do they require?
164 4. What is their target price or monthly budget range?
165 5. What is their full name, phone number, and email address to schedule a viewing?
166
167 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
168 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-building" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
169 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Real Estate Inquiry</h4>
170 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Qualifying buyers and renters for property showings.</p>
171 </div>
172
173 <!-- 3. Priority Support -->
174 <div class="ai-template-card" data-title="Priority Support" data-prompt="You are a technical support intake agent.
175 Guide the customer through collecting diagnostic details:
176
177 1. What plugin, product, or service is experiencing the issue?
178 2. Can they briefly describe the error or unexpected behavior?
179 3. What is the website URL where this occurs, and their environment specs (e.g., WP/PHP versions) if known?
180 4. What is the urgency level (Low, Medium, or Critical / Site Down)?
181 5. What is their full name and account email address?
182
183 Acknowledge issues empathetically.
184 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
185 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-sos" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
186 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Priority Support</h4>
187 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Bug triage and diagnostic data gathering for helpdesks.</p>
188 </div>
189
190 <!-- 4. SaaS Demo Booking -->
191 <div class="ai-template-card" data-title="SaaS Demo Booking" data-prompt="You are an onboarding specialist for a SaaS platform.
192 Qualify visitors requesting a product demo by asking:
193
194 1. What company do they represent, and what is their current team or company size?
195 2. What is the primary bottleneck or workflow they want our software to automate?
196 3. What CRM or marketing tools are in their current tech stack?
197 4. What is their full name, business email, and preferred day/time for a 15-minute demo?
198
199 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
200 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-chart-pie" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
201 <h4 style="margin: 0 0 10px 0; font-size: 15px;">SaaS Demo Booking</h4>
202 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Lead qualification and sales routing for software platforms.</p>
203 </div>
204
205 <!-- 5. E-Commerce Wholesale -->
206 <div class="ai-template-card" data-title="E-Commerce Wholesale" data-prompt="You are a sales assistant helping wholesale and bulk-order customers.
207 Gather order specifications:
208
209 1. What product SKU or item category are they interested in?
210 2. What estimated quantity or unit count do they plan to purchase?
211 3. Do they require custom branding/labels or standard packaging?
212 4. What is their target delivery deadline and destination country/postal code?
213 5. What is their company name, contact person, and billing email?
214
215 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
216 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-cart" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
217 <h4 style="margin: 0 0 10px 0; font-size: 15px;">E-Commerce Wholesale</h4>
218 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">B2B wholesale pricing and custom merchandise for WooCommerce.</p>
219 </div>
220
221 <!-- 6. Legal Case Intake -->
222 <div class="ai-template-card" data-title="Legal Case Intake" data-prompt="You are a legal intake assistant for a law firm.
223 State clearly that this chat does not establish an attorney-client relationship, then collect:
224
225 1. What area of law do they need assistance with (e.g., Personal Injury, Family Law, Business Dispute, Estate Planning)?
226 2. A brief summary of the situation and approximately when it occurred.
227 3. Are there any upcoming deadlines, court dates, or active lawsuits already filed?
228 4. What is their full name, phone number, and email address?
229
230 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
231 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-portfolio" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
232 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Legal Case Intake</h4>
233 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Pre-screening legal leads for practice area viability and deadlines.</p>
234 </div>
235
236 <!-- 7. Healthcare Booking -->
237 <div class="ai-template-card" data-title="Healthcare Booking" data-prompt="You are a patient coordinator assistant for a dental and medical clinic.
238 Collect scheduling details without providing medical advice:
239
240 1. Are they a new or existing patient, and what is the primary reason for their visit?
241 2. Do they have medical/dental insurance, and if so, who is the provider?
242 3. What days of the week and times of day work best for their appointment?
243 4. What is their full name, date of birth, phone number, and email address?
244
245 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
246 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-heart" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
247 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Healthcare Booking</h4>
248 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Clinic patient scheduling, primary symptoms, and insurance check.</p>
249 </div>
250
251 <!-- 8. Event Planning -->
252 <div class="ai-template-card" data-title="Event Planning" data-prompt="You are an event specialist assisting clients with catering and planning inquiries.
253 Guide them through these questions:
254
255 1. What type of event are they planning (e.g., Wedding, Corporate Gala, Birthday)?
256 2. What is the estimated event date, venue location, and expected guest count?
257 3. What dining/service style do they prefer (e.g., Plated Multi-Course, Buffet, Cocktail/Hors d'oeuvres)?
258 4. What is their approximate overall budget?
259 5. What is their contact name, organization (if applicable), phone number, and email?
260
261 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
262 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-calendar-alt" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
263 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Event Planning</h4>
264 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Event venue, banquet, and catering inquiries.</p>
265 </div>
266
267 <!-- 9. Auto Dealership -->
268 <div class="ai-template-card" data-title="Auto Dealership" data-prompt="You are a sales concierge for an automotive dealership.
269 Collect test drive details:
270
271 1. Which vehicle model, trim, or year are they interested in test-driving?
272 2. Do they have a trade-in vehicle? If yes, ask for the Year, Make, Model, and approximate mileage.
273 3. What is their preferred payment path (Financing, Leasing, or Cash purchase)?
274 4. What date and time would they like to schedule their test drive?
275 5. What is their full name, mobile number, and email address?
276
277 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
278 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-car" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
279 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Auto Dealership</h4>
280 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Test-drive bookings and vehicle trade-in estimates.</p>
281 </div>
282
283 <!-- 10. Education Admissions -->
284 <div class="ai-template-card" data-title="Education Admissions" data-prompt="You are an admissions advisor for an educational training academy.
285 Ask the prospective student:
286
287 1. Which program or certification do they want to enroll in?
288 2. What is their current background or experience level (Beginner, Intermediate, Advanced)?
289 3. Are they looking for Full-Time (Immersive) or Part-Time study?
290 4. What is their target cohort start date?
291 5. What is their full name, WhatsApp/phone number, and email address?
292
293 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
294 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-welcome-learn-more" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
295 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Education Admissions</h4>
296 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Online course and bootcamp enrollment qualification.</p>
297 </div>
298
299 <!-- 11. Senior PHP Programmer Assessment -->
300 <div class="ai-template-card" data-title="Senior PHP Programmer Assessment" data-prompt="You are an expert technical interviewer screening candidates for an in-house Senior PHP Developer position specializing in Laravel and WordPress core architecture.
301
302 Role Prerequisites:
303 - Degree: Must hold a Bachelor's degree in Computer Science (CSC) or Computer Information Systems (CIS).
304 - Experience: Minimum 2 years of professional PHP development with hands-on Laravel and WordPress plugin engineering.
305
306 CRITICAL EXECUTION RULES:
307 - Ask exactly ONE question per turn.
308 - NEVER combine multiple questions, items, or prompts into a single message.
309 - Await the candidate's answer before moving to the next item.
310 - Do not provide code solutions, hints, or technical corrections during the interview.
311
312 Sequential Interview Steps (Strict 1-by-1 Flow):
313 Step 1: &quot;To get started, what is your full name?&quot;
314 Step 2: &quot;What is your primary email address?&quot;
315 Step 3: &quot;What is the best phone number to reach you?&quot;
316 Step 4: &quot;Could you share the link to your GitHub, GitLab, or portfolio profile?&quot;
317 Step 5: &quot;What is your exact degree title, major, and graduating university?&quot;
318 Step 6: &quot;How many total years of professional PHP development experience do you have?&quot;
319 Step 7: &quot;What commercial projects have you built using Laravel and custom WordPress plugins?&quot;
320 Step 8: &quot;Technical Q1 (Laravel Architecture): How do Service Providers, the Service Container, and Middleware interact during Laravel's request lifecycle? How do you implement and register a custom deferred service provider?&quot;
321 Step 9: &quot;Technical Q2 (WordPress Core Internals): Explain how the WordPress Action and Filter hook system works internally under the WP_Hook class. When architecting scalable plugins, how do you manage nonces, custom database tables vs Custom Post Types, and transients for cache invalidation?&quot;
322 Step 10: &quot;Technical Q3 (Security &amp; Performance): How do you prevent race conditions, memory exhaustion (e.g., Eloquent chunking vs PHP Generators), and SQL injection when executing bulk database operations across Laravel and WordPress environments?&quot;
323
324 " style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; cursor: pointer; text-align: center; transition: all 0.2s ease;">
325 <div style="color: #0073aa; margin-bottom: 15px;"><span class="dashicons dashicons-businessman" style="font-size: 40px; width: 40px; height: 40px;"></span></div>
326 <h4 style="margin: 0 0 10px 0; font-size: 15px;">Senior PHP Programmer Assessment</h4>
327 <p style="margin: 0; font-size: 12px; color: #666; line-height: 1.4;">Screening candidates for a Senior PHP Developer position.</p>
328 </div>
329 </div>
330 </div>
331
332 <!-- SAVED ACTIONS TABS (Generated) -->
333 <div id="ai-saved-actions-container">
334 <?php
335 $counter = 1;
336 if ( ! empty( $saved_forms ) ) :
337 foreach ( $saved_forms as $form ) :
338 $tab_id = 'ai-action-tab-' . $counter;
339 $chk_interactive_id = 'ai_interactive_' . $counter;
340 $chk_email_id = 'ai_email_' . $counter;
341 ?>
342 <div id="<?php echo esc_attr($tab_id); ?>" class="ai-content-pane ai-form-item saved-ai-action" style="display: none; padding: 20px;">
343
344 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid #eee; padding-bottom: 15px;">
345 <h3 style="margin: 0; font-size: 18px;"><?php esc_html_e('Edit Action', 'chatbot'); ?></h3>
346 <button type="button" class="button remove-ai-form" style="color: #a00; border-color: #a00;"><?php esc_html_e( 'Delete Action', 'chatbot' ); ?></button>
347 </div>
348
349 <h2 class="nav-tab-wrapper wpbot-ai-inner-tabs" style="margin-bottom: 20px;">
350 <a href="#ai-inner-settings-<?php echo esc_attr($counter); ?>" class="nav-tab nav-tab-active" style="cursor: pointer;"><?php esc_html_e('Settings', 'chatbot'); ?></a>
351 <a href="#" class="nav-tab" style="cursor: not-allowed; opacity: 0.6;" onclick="event.preventDefault(); return false;"><?php esc_html_e('History', 'chatbot'); ?> <span style="background: #e64340; color: #fff; font-size: 10px; padding: 2px 6px; border-radius: 4px; margin-left: 5px; vertical-align: middle;">PRO</span></a>
352 </h2>
353
354 <div id="ai-inner-settings-<?php echo esc_attr($counter); ?>" class="ai-inner-tab-content">
355 <div style="margin-bottom: 15px;">
356 <label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php esc_html_e('Action Title', 'chatbot'); ?></label>
357 <input type="text" name="ai_form_title[]" class="form-control ai-form-title-input" style="width: 100%; max-width: 500px;" placeholder="<?php esc_attr_e('e.g., Hotel Booking', 'chatbot'); ?>" value="<?php echo esc_attr( $form['title'] ); ?>" />
358 </div>
359 <div style="margin-bottom: 15px;">
360 <label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php esc_html_e('AI Prompt', 'chatbot'); ?></label>
361 <textarea name="ai_form_prompt[]" class="form-control" style="width: 100%;" rows="15" placeholder="<?php esc_attr_e('Enter your prompt here...', 'chatbot'); ?>"><?php echo esc_textarea( $form['prompt'] ); ?></textarea>
362 </div>
363
364 <div class="cxsc-settings-blocks" style="margin-top: 20px; border-top: 1px solid #eee; padding-top: 20px;">
365 <div>
366 <input type="hidden" name="ai_form_email[]" class="ai-email-val" value="<?php echo esc_attr( isset($form['email']) ? $form['email'] : 1 ); ?>">
367 <input type="checkbox" id="<?php echo esc_attr( $chk_email_id ); ?>" <?php echo ( !isset($form['email']) || $form['email'] == 1 ) ? 'checked' : ''; ?> onchange="jQuery(this).prev('.ai-email-val').val(this.checked ? 1 : 0);">
368 <label for="<?php echo esc_attr( $chk_email_id ); ?>"><strong><?php esc_html_e('Email the data', 'chatbot'); ?></strong></label>
369 </div>
370 <div style="margin-top: 10px;">
371 <label style="font-weight: 600; display: block; margin-bottom: 4px; font-size: 13px;"><?php esc_html_e('Send to Email(s)', 'chatbot'); ?></label>
372 <input type="text" name="ai_form_email_addresses[]" class="form-control" style="width: 100%; max-width: 460px; font-size: 13px;" placeholder="<?php echo esc_attr( get_option('qlcd_wp_chatbot_admin_email', get_option('admin_email')) ); ?>" value="<?php echo esc_attr( isset($form['email_addresses']) ? $form['email_addresses'] : '' ); ?>">
373 <p style="margin: 4px 0 0; font-size: 11px; color: #888;"><?php esc_html_e('Comma-separated. Leave blank to use the default admin email.', 'chatbot'); ?></p>
374 </div>
375 </div>
376 </div>
377
378 <div id="ai-inner-history-<?php echo esc_attr($counter); ?>" class="ai-inner-tab-content" style="display: none;">
379 <div id="ai-inner-history-content-<?php echo esc_attr($counter); ?>">
380 <p style="color: #666; font-style: italic;"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>
381 </div>
382 </div>
383 </div>
384 <?php
385 $counter++;
386 endforeach;
387 endif;
388 ?>
389 </div>
390
391 <div id="ai-save-wrapper" style="padding: 15px 20px; background: #f9f9f9; border-top: 1px solid #eee; display: flex;flex-direction: column;">
392
393 <span style="color: #666; font-size: 13px;">Don't forget to save your changes!</span>
394
395 <span style="color: #f10b0bff; font-size: 16px; font-weight: bold; margin-top: 5px; margin-bottom: 5px;">Create powerful AI Actions with Prompt to collect information and send to your email.</span>
396 <span style="color: #f10b0bff; font-size: 16px; font-weight: bold; margin-top: 5px; margin-bottom: 10px;">After creating an AI Action, you can add it to the Active Start Menu from <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpbot&tab=startmenu' ) ); ?>">Settings->Start Menu</a></span>
397 <input style="max-width: 224px;" type="submit" name="submit" class="button button-primary button-hero" value="<?php esc_attr_e( 'Save Settings', 'chatbot' ); ?>" />
398 </div>
399 </form>
400 </div>
401
402 <!-- RIGHT PLAYGROUND PREVIEW -->
403 <div class="card right-preview" style="width: 480px; flex-shrink: 0; background: #f5f5f5; border: 1px solid #e5e5e5; border-radius: 10px; box-shadow: 0 5px 15px rgba(0,0,0,0.05);">
404 <?php
405 $default_provider = 'openai';
406 if ( get_option( 'qcld_gemini_enabled' ) == 1 ) {
407 $default_provider = 'gemini';
408 } elseif ( get_option( 'qcld_claude_enabled' ) == 1 ) {
409 $default_provider = 'claude';
410 } elseif ( get_option( 'qcld_grok_enabled' ) == 1 ) {
411 $default_provider = 'grok';
412 } elseif ( get_option( 'qcld_openrouter_enabled' ) == 1 ) {
413 $default_provider = 'openrouter';
414 }
415 ?>
416 <div style="background: #4a154b; color: white; padding: 15px; font-weight: bold; text-align: center; border-top-left-radius: 9px; border-top-right-radius: 9px; position: relative;">
417 <?php esc_html_e('Live AI Playground', 'chatbot'); ?>
418 <button type="button" id="ai-playground-refresh" title="<?php esc_attr_e('Refresh Chat', 'chatbot'); ?>" style="position: absolute; right: 15px; top: 12px; background: transparent; border: none; color: white; cursor: pointer; padding: 0;">
419 <span class="dashicons dashicons-image-rotate"></span>
420 </button>
421 </div>
422 <div id="ai-actions-playground-container" style="padding: 15px; display: flex; flex-direction: column; height: 400px; overflow-y: auto;">
423 <div id="ai-actions-playground-messages" style="display: flex; flex-direction: column; justify-content: flex-end; flex: 1;">
424 <div style="display: flex; gap: 10px; align-items: flex-end; margin-bottom: 15px;">
425 <div style="width: 30px; height: 30px; background: #4a154b; border-radius: 50%; flex-shrink: 0; background-image: url('<?php echo esc_url(QCLD_wpCHATBOT_IMG_URL); ?>/icon-1.png'); background-size: cover; background-position: center;"></div>
426 <div style="background: white; padding: 12px; border-radius: 15px; border-bottom-left-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); width: 100%;">
427 <p style="margin-top: 0; margin-bottom: 15px; font-size: 13px; color: #333; line-height: 1.4;"><?php esc_html_e('Hello! I am here to find what you need. What are you looking for?', 'chatbot'); ?></p>
428 <div id="ai-actions-live-preview" style="display: flex; flex-wrap: wrap; gap: 6px;">
429 <!-- Javascript will populate this -->
430 </div>
431 </div>
432 </div>
433 </div>
434 </div>
435 <div style="padding: 12px; background: white; border-top: 1px solid #eee; display: flex; gap: 8px; border-bottom-left-radius: 9px; border-bottom-right-radius: 9px;">
436 <input type="text" id="playground-input" placeholder="<?php esc_attr_e('Send a message...', 'chatbot'); ?>" style="width: 100%; background: #f0f0f0; border: none; border-radius: 20px; padding: 8px 12px; color: #333; font-size: 13px; outline: none;">
437 <button type="button" id="playground-send-btn" class="button button-primary" style="border-radius: 50%; padding: 0; width: 40px; height: 34px; align-items: center; justify-content: center; flex-shrink: 0;">
438 <span class="dashicons dashicons-arrow-right-alt" style="line-height: 1.8;"></span>
439 </button>
440 </div>
441 </div>
442
443 </div>
444 </div>
445 </div>
446
447 <style>
448 /* CSS for the new layout */
449 .ai-sidebar-link:hover, .ai-sidebar-link.active {
450 background: #f0f0f1;
451 color: #0073aa !important;
452 box-shadow: inset 4px 0 0 #0073aa;
453 }
454 .ai-sidebar-saved-link:hover, .ai-sidebar-saved-link.active {
455 background: #eef7fd;
456 color: #0073aa !important;
457 box-shadow: inset 4px 0 0 #0073aa;
458 }
459 .ai-template-card:hover {
460 border-color: #0073aa !important;
461 box-shadow: 0 5px 15px rgba(0,115,170,0.1);
462 transform: translateY(-2px);
463 }
464 .ai-content-pane {
465 animation: fadeIn 0.3s ease-in-out;
466 }
467 @keyframes fadeIn {
468 from { opacity: 0; transform: translateY(5px); }
469 to { opacity: 1; transform: translateY(0); }
470 }
471 </style>
472
473 <script>
474 jQuery(document).ready(function($) {
475 // --- SIDEBAR TAB SWITCHING LOGIC ---
476 function switchTab(targetId, linkObj) {
477 $('.ai-content-pane').hide();
478 $('.ai-sidebar-link').removeClass('active');
479
480 $('#' + targetId).show();
481 if (linkObj) {
482 linkObj.addClass('active');
483 } else {
484 $('.ai-sidebar-link[href="#' + targetId + '"]').addClass('active');
485 }
486
487 // Hide Save button if history tab (if we still had it globally, but we don't)
488 $('#ai-save-wrapper').show();
489
490 // Save to sessionStorage so it stays open after reload
491 sessionStorage.setItem('qcld_ai_active_tab', targetId);
492 }
493
494 // Restore active tab on page load
495 var savedTab = sessionStorage.getItem('qcld_ai_active_tab');
496 if (savedTab) {
497 var linkToOpen = null;
498 var tabToOpen = null;
499
500 if ($('#' + savedTab).length) {
501 tabToOpen = savedTab;
502 linkToOpen = $('.ai-sidebar-link[href="#' + savedTab + '"]');
503 } else if (savedTab.indexOf('ai-action-tab-') === 0) {
504 // Was a newly generated tab. After saving, it becomes the last saved action.
505 var lastSavedLink = $('.ai-sidebar-saved-link').last();
506 if (lastSavedLink.length) {
507 tabToOpen = lastSavedLink.attr('href').substring(1);
508 linkToOpen = lastSavedLink;
509 // Update session storage to the new real ID
510 sessionStorage.setItem('qcld_ai_active_tab', tabToOpen);
511 }
512 }
513
514 if (tabToOpen) {
515 switchTab(tabToOpen, null);
516 if (linkToOpen && linkToOpen.closest('.ai-saved-actions-submenu').length) {
517 $('.ai-saved-actions-submenu').show();
518 $('.ai-sidebar-parent-link .dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
519 }
520 }
521 }
522
523 $(document).on('click', '.ai-sidebar-link', function(e) {
524 e.preventDefault();
525 var target = $(this).attr('href').substring(1);
526 switchTab(target, $(this));
527 });
528
529 // --- SAVED ACTIONS SUBMENU TOGGLE ---
530 $('.ai-sidebar-parent-link').on('click', function(e) {
531 e.preventDefault();
532 var submenu = $(this).next('.ai-saved-actions-submenu');
533 var icon = $(this).find('.dashicons');
534
535 submenu.slideToggle(200);
536 if (icon.hasClass('dashicons-arrow-down-alt2')) {
537 icon.removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
538 } else {
539 icon.removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
540 }
541 });
542
543 // --- INNER TABS (SETTINGS/HISTORY) ---
544 $(document).on('click', '.wpbot-ai-inner-tabs .nav-tab', function(e) {
545 e.preventDefault();
546
547 if ($(this).attr('href') === '#') return false;
548
549 var pane = $(this).closest('.ai-content-pane');
550 var targetId = $(this).attr('href').substring(1);
551
552 // Tab styling
553 pane.find('.wpbot-ai-inner-tabs .nav-tab').removeClass('nav-tab-active');
554 $(this).addClass('nav-tab-active');
555
556 // Tab content
557 pane.find('.ai-inner-tab-content').hide();
558 pane.find('#' + targetId).fadeIn(200);
559
560 // Handle History AJAX loading
561 if ($(this).hasClass('ai-load-history-btn')) {
562 var contentTarget = $(this).data('target');
563 var formTitle = pane.find('.ai-form-title-input').val();
564
565 var targetContainer = $('#' + contentTarget);
566 targetContainer.html('<p style="color: #666; font-style: italic;"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>');
567
568 if (!formTitle || formTitle.trim() === '') {
569 targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Please save the form with a title first to preview entries.', 'chatbot'); ?></p>');
570 return;
571 }
572
573 var data = {
574 action: 'qcld_get_ai_form_entries',
575 form_title: formTitle,
576 nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot_ai_actions' ) ); ?>'
577 };
578
579 $.post(ajaxurl, data, function(response) {
580 if (response.success) {
581 targetContainer.html(response.data.html);
582 } else {
583 targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Error loading entries.', 'chatbot'); ?></p>');
584 }
585 }).fail(function() {
586 targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Error connecting to server.', 'chatbot'); ?></p>');
587 });
588 }
589 });
590
591 // --- DELETE HISTORY ENTRY ---
592 $(document).on('click', '.qcld-delete-ai-entry', function(e) {
593 e.preventDefault();
594 var btn = $(this);
595 var entryId = btn.data('id');
596
597 if (!confirm('<?php esc_html_e('Are you sure you want to delete this history entry?', 'chatbot'); ?>')) {
598 return;
599 }
600
601 btn.prop('disabled', true).text('Deleting...');
602
603 var data = {
604 action: 'qcld_delete_ai_form_entry',
605 entry_id: entryId,
606 nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot_ai_actions' ) ); ?>'
607 };
608
609 $.post(ajaxurl, data, function(response) {
610 if (response.success) {
611 btn.closest('tr').fadeOut(300, function() { $(this).remove(); });
612 } else {
613 alert('Error: ' + response.data);
614 btn.prop('disabled', false).text('Delete');
615 }
616 }).fail(function() {
617 alert('Error connecting to server.');
618 btn.prop('disabled', false).text('Delete');
619 });
620 });
621
622 // --- CREATE NEW ACTION FROM TEMPLATE ---
623 $('.ai-template-card').on('click', function() {
624 var title = $(this).data('title');
625 var prompt = $(this).data('prompt');
626
627 var uniqueId = 'ai_form_' + Math.floor(Math.random() * 1000000);
628 var tabId = 'ai-action-tab-' + uniqueId;
629 var chk_interactive_id = 'ai_interactive_' + uniqueId;
630 var chk_email_id = 'ai_email_' + uniqueId;
631 var displayTitle = title ? title : 'New Blank Action';
632
633 // Remove "No saved actions" if exists
634 $('.ai-no-saved-actions').remove();
635
636 // 1. Add Sidebar Link
637 var linkHtml = '<li><a href="#' + tabId + '" class="ai-sidebar-link ai-sidebar-saved-link" data-id="' + tabId + '" style="display: block; padding: 10px 15px 10px 30px; text-decoration: none; color: #555; font-size: 13px; border-bottom: 1px solid #f5f5f5;">' + displayTitle + '</a></li>';
638 $('.ai-saved-actions-submenu').append(linkHtml);
639
640 // Ensure submenu is open
641 $('.ai-saved-actions-submenu').slideDown(200);
642 $('.ai-sidebar-parent-link .dashicons').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
643
644 // 2. Add Form Pane
645 var template = `
646 <div id="` + tabId + `" class="ai-content-pane ai-form-item" style="display: none; padding: 20px;">
647 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid #eee; padding-bottom: 15px;">
648 <h3 style="margin: 0; font-size: 18px;"><?php esc_html_e('Edit Action', 'chatbot'); ?></h3>
649 <button type="button" class="button remove-ai-form" style="color: #a00; border-color: #a00;"><?php esc_html_e( 'Delete Action', 'chatbot' ); ?></button>
650 </div>
651
652 <h2 class="nav-tab-wrapper wpbot-ai-inner-tabs" style="margin-bottom: 20px;">
653 <a href="#ai-inner-settings-` + uniqueId + `" class="nav-tab nav-tab-active" style="cursor: pointer;"><?php esc_html_e('Settings', 'chatbot'); ?></a>
654 <a href="#" class="nav-tab" style="cursor: not-allowed; opacity: 0.6;" onclick="event.preventDefault(); return false;"><?php esc_html_e('History', 'chatbot'); ?> <span style="background: #e64340; color: #fff; font-size: 10px; padding: 2px 6px; border-radius: 4px; margin-left: 5px; vertical-align: middle;">PRO</span></a>
655 </h2>
656
657 <div id="ai-inner-settings-` + uniqueId + `" class="ai-inner-tab-content">
658 <div style="margin-bottom: 15px;">
659 <label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php esc_html_e('Action Title', 'chatbot'); ?></label>
660 <input type="text" name="ai_form_title[]" class="form-control ai-form-title-input" style="width: 100%; max-width: 500px;" placeholder="<?php esc_attr_e('e.g., Hotel Booking', 'chatbot'); ?>" value="` + title + `" />
661 </div>
662 <div style="margin-bottom: 15px;">
663 <label style="font-weight: 600; display: block; margin-bottom: 5px;"><?php esc_html_e('AI Prompt', 'chatbot'); ?></label>
664 <textarea name="ai_form_prompt[]" class="form-control" style="width: 100%;" rows="8" placeholder="<?php esc_attr_e('Enter your prompt here...', 'chatbot'); ?>">` + prompt + `</textarea>
665 </div>
666
667 <div class="cxsc-settings-blocks" style="margin-top: 20px; border-top: 1px solid #eee; padding-top: 20px;">
668
669 <div>
670 <input type="hidden" name="ai_form_email[]" class="ai-email-val" value="1">
671 <input type="checkbox" id="` + chk_email_id + `" checked onchange="jQuery(this).prev(\'.ai-email-val\').val(this.checked ? 1 : 0);">
672 <label for="` + chk_email_id + `"><strong><?php esc_html_e('Email the data', 'chatbot'); ?></strong></label>
673 </div>
674 <div style="margin-top: 10px;">
675 <label style="font-weight: 600; display: block; margin-bottom: 4px; font-size: 13px;"><?php esc_html_e('Send to Email(s)', 'chatbot'); ?></label>
676 <input type="text" name="ai_form_email_addresses[]" class="form-control" style="width: 100%; max-width: 460px; font-size: 13px;" placeholder="<?php echo esc_attr( get_option('qlcd_wp_chatbot_admin_email', get_option('admin_email')) ); ?>" value="">
677 <p style="margin: 4px 0 0; font-size: 11px; color: #888;"><?php esc_html_e('Comma-separated. Leave blank to use the default admin email.', 'chatbot'); ?></p>
678 </div>
679 </div>
680 </div>
681
682 <div id="ai-inner-history-` + uniqueId + `" class="ai-inner-tab-content" style="display: none;">
683 <div id="ai-inner-history-content-` + uniqueId + `">
684 <p style="color: #666; font-style: italic;"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>
685 </div>
686 </div>
687 </div>
688 `;
689 $('#ai-saved-actions-container').append(template);
690
691 // 3. Switch to it immediately
692 switchTab(tabId, $('.ai-sidebar-link[href="#' + tabId + '"]'));
693
694 // 4. Update preview playground
695 updateAiActionsPreview();
696 });
697
698 // --- REMOVE FORM ITEM ---
699 $(document).on('click', '.remove-ai-form', function(e) {
700 e.preventDefault();
701 var pane = $(this).closest('.ai-content-pane');
702 var tabId = pane.attr('id');
703
704 // Remove pane
705 pane.remove();
706
707 // Remove sidebar link
708 $('.ai-sidebar-link[href="#' + tabId + '"]').parent().remove();
709
710 // Check if submenu is empty
711 if ($('.ai-saved-actions-submenu li').length === 0) {
712 $('.ai-saved-actions-submenu').html('<li class="ai-no-saved-actions" style="padding: 10px 15px 10px 30px; color: #999; font-size: 12px; font-style: italic;"><?php esc_html_e('No saved actions', 'chatbot'); ?></li>');
713 }
714
715 // Switch back to Add New Action tab
716 switchTab('ai-new-action-tab', $('.ai-sidebar-link[href="#ai-new-action-tab"]'));
717
718 updateAiActionsPreview();
719 });
720
721 // --- UPDATE HEADER DYNAMICALLY ---
722 $(document).on('keyup', '.ai-form-title-input', function() {
723 var newTitle = $(this).val();
724 var paneId = $(this).closest('.ai-content-pane').attr('id');
725 var sidebarLink = $('.ai-sidebar-link[href="#' + paneId + '"]');
726
727 if (newTitle.trim() === '') {
728 newTitle = '<?php esc_html_e('Untitled Action', 'chatbot'); ?>';
729 }
730 sidebarLink.text(newTitle);
731 updateAiActionsPreview();
732 });
733
734 // --- PREVIEW UPDATING FUNCTION ---
735 function updateAiActionsPreview() {
736 var previewContainer = $('#ai-actions-live-preview');
737 previewContainer.empty();
738
739 var titles = [];
740 $('.saved-ai-action .ai-form-title-input').each(function() {
741 var val = $(this).val().trim();
742 if(val) {
743 titles.push(val);
744 }
745 });
746
747 if(titles.length === 0) {
748 previewContainer.append('<span style="background: #f0f0f0; border: 1px solid #ddd; padding: 5px 12px; border-radius: 15px; font-size: 12px; color: #555; cursor: default;"><?php esc_html_e('No Actions Created Yet', 'chatbot'); ?></span>');
749 } else {
750 $.each(titles, function(index, title) {
751 previewContainer.append('<span class="playground-ai-action-btn" style="background: #e9f0ff; border: 1px solid #b3ccff; padding: 5px 12px; border-radius: 15px; font-size: 12px; color: #0044cc; cursor: pointer; display: inline-block; transition: all 0.2s;">' + title + '</span>');
752 });
753 }
754 }
755
756 // --- PLAYGROUND INTERACTIVE LOGIC ---
757 var aiContext = [];
758
759 function appendUserMessage(text) {
760 var msgHtml = '<div style="display: flex; justify-content: flex-end; margin-bottom: 12px;">' +
761 '<div style="background: #0044cc; color: white; padding: 8px 12px; border-radius: 15px; border-bottom-right-radius: 5px; max-width: 80%; font-size: 13px;">' +
762 text +
763 '</div>' +
764 '</div>';
765 $('#ai-actions-playground-messages').append(msgHtml);
766 scrollToBottom();
767 }
768
769 function appendBotMessage(text) {
770 var msgHtml = '<div style="display: flex; gap: 8px; align-items: flex-end; margin-bottom: 12px;">' +
771 '<div style="width: 30px; height: 30px; background: #4a154b; border-radius: 50%; flex-shrink: 0; background-image: url(\'<?php echo esc_url(QCLD_wpCHATBOT_IMG_URL); ?>/icon-1.png\'); background-size: cover; background-position: center;"></div>' +
772 '<div style="background: white; padding: 8px 12px; border-radius: 15px; border-bottom-left-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); max-width: 80%; font-size: 13px; color: #333; line-height: 1.4; overflow-wrap: break-word;">' +
773 text +
774 '</div>' +
775 '</div>';
776 $('#ai-actions-playground-messages').append(msgHtml);
777 scrollToBottom();
778 }
779
780 function appendLoader() {
781 var msgHtml = '<div id="playground-loader" style="display: flex; gap: 8px; align-items: flex-end; margin-bottom: 12px;">' +
782 '<div style="width: 30px; height: 30px; background: #4a154b; border-radius: 50%; flex-shrink: 0; background-image: url(\'<?php echo esc_url(QCLD_wpCHATBOT_IMG_URL); ?>/icon-1.png\'); background-size: cover; background-position: center;"></div>' +
783 '<div style="background: white; padding: 8px 12px; border-radius: 15px; border-bottom-left-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); font-size: 13px; color: #999;">' +
784 '<i>Thinking...</i>' +
785 '</div>' +
786 '</div>';
787 $('#ai-actions-playground-messages').append(msgHtml);
788 scrollToBottom();
789 }
790
791 function scrollToBottom() {
792 var container = $('#ai-actions-playground-container');
793 container.scrollTop(container[0].scrollHeight);
794 }
795
796 function formatBotResponse(text) {
797 // Remove internal tracking flag
798 text = text.replace(/__AI_FORM_IN_PROGRESS__/g, '');
799
800 // Extract and format AI_FORM_DATA block
801 // This regex optionally matches surrounding HTML tags to ensure they are replaced too, preventing broken tags.
802 var regex = /(?:<[^>]+>)*\s*AI_FORM_DATA[\s\S]*?__AI_FORM_DATA_END__\s*(?:<\/[^>]+>)*/g;
803 text = text.replace(regex, function(match) {
804 try {
805 // Extract just the JSON part from the match (from the first '{' to the last '}')
806 var jsonMatch = match.match(/\{[\s\S]*\}/);
807 if (!jsonMatch) {
808 return match;
809 }
810 var jsonStr = jsonMatch[0];
811 var data = JSON.parse(jsonStr.trim());
812 var html = '<div style="background: #f4f4f4; padding: 10px; border-left: 3px solid #0044cc; margin: 10px 0; border-radius: 3px;">';
813 if (data.form_title) {
814 html += '<strong style="display:block; margin-bottom: 5px; color: #0044cc; text-transform: capitalize;">' + data.form_title + '</strong>';
815 }
816 if (data.data) {
817 html += '<ul style="margin: 0; padding-left: 15px; font-size: 13px; color: #333;">';
818 for (var key in data.data) {
819 html += '<li style="margin-bottom: 3px;"><strong>' + key + ':</strong> ' + data.data[key] + '</li>';
820 }
821 html += '</ul>';
822 }
823 html += '</div>';
824 return html;
825 } catch (e) {
826 return match; // Return original if parsing fails
827 }
828 });
829
830 var cleanResponse = text.replace(/(\w+)\n/g,'$1 ');
831 cleanResponse = cleanResponse.replace(/```(.*?)```/gs, '<pre style="background: #f4f4f4; padding: 8px; border-radius: 5px; overflow-x: auto; font-size: 12px;">$1</pre>');
832 cleanResponse = cleanResponse.replace(/`(.*?)`/g, '<code style="background: #f4f4f4; padding: 2px 4px; border-radius: 3px;">$1</code>');
833 cleanResponse = cleanResponse.replace(/\n/g, '<br>');
834 return cleanResponse;
835 }
836
837 function sendToAI(text, actionPrompt) {
838 appendUserMessage(text);
839 appendLoader();
840
841 aiContext.push({role: 'user', content: text});
842 if (aiContext.length > 10) {
843 aiContext.shift();
844 }
845
846 var activeProvider = '<?php echo esc_js($default_provider); ?>';
847 var actionMap = {
848 'openai': 'qcld_openai_response',
849 'gemini': 'qcld_gemini_response',
850 'claude': 'claude_response',
851 'grok': 'qcld_grok_response',
852 'openrouter': 'openrouter_response'
853 };
854 var ajaxAction = actionMap[activeProvider] || 'qcld_openai_response';
855
856 var data = {
857 action: ajaxAction,
858 keyword: text,
859 ai_history: JSON.stringify(aiContext),
860 is_ai_actions_playground: 1,
861 action_prompt: actionPrompt || '',
862 nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot' ) ); ?>'
863 };
864
865 $.post(ajaxurl, data, function(res) {
866 $('#playground-loader').remove();
867
868 var json = res;
869 if (typeof res === 'string') {
870 try {
871 json = $.parseJSON(res);
872 } catch(e) {}
873 }
874
875 if (json && json.status === 'success') {
876 var reply = json.message;
877 aiContext.push({role: 'assistant', content: reply});
878 if (aiContext.length > 10) {
879 aiContext.shift();
880 }
881 appendBotMessage(formatBotResponse(reply));
882 } else {
883 appendBotMessage('<?php esc_html_e('Sorry, there was an error processing your request.', 'chatbot'); ?>');
884 }
885 }).fail(function() {
886 $('#playground-loader').remove();
887 appendBotMessage('<?php esc_html_e('Error connecting to AI service.', 'chatbot'); ?>');
888 });
889 }
890
891 $(document).on('click', '.playground-ai-action-btn', function() {
892 var text = $(this).text().trim();
893
894 var matchedPrompt = '';
895 $('.ai-form-title-input').each(function() {
896 if ($(this).val().trim().toLowerCase() === text.toLowerCase()) {
897 matchedPrompt = $(this).closest('.ai-content-pane').find('textarea[name="ai_form_prompt[]"]').val() || '';
898 }
899 });
900
901 aiContext = [];
902 sendToAI(text, matchedPrompt);
903 });
904
905 $('#playground-input').on('keypress', function(e) {
906 if(e.which === 13) {
907 var text = $(this).val().trim();
908 if(text) {
909 $(this).val('');
910 sendToAI(text);
911 }
912 }
913 });
914
915 $('#playground-send-btn').on('click', function() {
916 var text = $('#playground-input').val().trim();
917 if(text) {
918 $('#playground-input').val('');
919 sendToAI(text);
920 }
921 });
922
923 $('#ai-playground-refresh').on('click', function() {
924 var $messages = $('#ai-actions-playground-messages');
925 $messages.children(':not(:first)').remove();
926 updateAiActionsPreview();
927 });
928
929 $(document).on('mouseenter', '.playground-ai-action-btn', function() {
930 $(this).css({background: '#d0e0ff', borderColor: '#8ab4f8'});
931 }).on('mouseleave', '.playground-ai-action-btn', function() {
932 $(this).css({background: '#e9f0ff', borderColor: '#b3ccff'});
933 });
934
935 // --- INITIALIZATION ---
936 updateAiActionsPreview();
937
938 // Make sure initial state shows first tab if history or saved tab isn't already active (fallback)
939 if ($('.ai-sidebar-link.active').length === 0) {
940 $('.ai-sidebar-link[href="#ai-new-action-tab"]').addClass('active');
941 $('#ai-new-action-tab').show();
942 }
943 });
944 </script>
945