PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.8.0
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.8.0
8.8.0 8.7.9 8.7.8 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 All 536 releases
← All changes | includes/admin/templates/ai-actions.php +953 -944 8.7.3 → 8.8.0 View file →
@@ -1,944 +1,953 @@
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 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 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 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 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>
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 qcld-ai-actions-page">
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 src="<?php echo esc_url( QCLD_wpCHATBOT_IMG_URL . '/chatbot.png' ); ?>" alt="WPBot"> 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="wp-chatbot-wrap">
79 + <section class="wp-chatbot-tab-container-inner">
80 + <div class="wp-chatbot-tabs wp-chatbot-tabs-style-flip qcld-ai-actions-layout">
81 +
82 + <nav>
83 + <ul class="qcld-ai-sidebar-menu">
84 + <li class="tab-current">
85 + <a href="#ai-new-action-tab" class="ai-sidebar-link active">
86 + <span class="wpwbot-admin-tab-icon"><span class="dashicons dashicons-plus-alt"></span></span>
87 + <span class="wpwbot-admin-tab-name"><?php esc_html_e('Add New Action', 'chatbot'); ?></span>
88 + </a>
89 + </li>
90 + <li class="qcld-ai-saved-parent">
91 + <a href="#" class="ai-sidebar-parent-link">
92 + <span class="wpwbot-admin-tab-icon"><span class="dashicons dashicons-portfolio"></span></span>
93 + <span class="wpwbot-admin-tab-name"><?php esc_html_e('Saved Actions', 'chatbot'); ?></span>
94 + <span class="dashicons dashicons-arrow-down-alt2 qcld-ai-saved-toggle"></span>
95 + </a>
96 + <ul class="ai-saved-actions-submenu">
97 + <?php
98 + $counter = 1;
99 + if ( ! empty( $saved_forms ) ) {
100 + foreach ( $saved_forms as $form ) {
101 + $tab_id = 'ai-action-tab-' . $counter;
102 + echo '<li><a href="#' . esc_attr( $tab_id ) . '" class="ai-sidebar-link ai-sidebar-saved-link" data-id="' . esc_attr( $tab_id ) . '">' . esc_html( $form['title'] ) . '</a></li>';
103 + $counter++;
104 + }
105 + } else {
106 + echo '<li class="ai-no-saved-actions">' . esc_html__( 'No saved actions', 'chatbot' ) . '</li>';
107 + }
108 + ?>
109 + </ul>
110 + </li>
111 + </ul>
112 + </nav>
113 +
114 + <div class="content-wrap qcld-ai-actions-content">
115 + <form action="" method="POST" id="ai-actions-main-form">
116 + <?php wp_nonce_field( 'wp_chatbot_ai_actions', '_wpnonce' ); ?>
117 +
118 + <div id="ai-new-action-tab" class="ai-content-pane active">
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 class="qcld-ai-actions-alert">
128 + <?php esc_html_e('No AI connection is active. Please enable AI integration.', 'chatbot'); ?>
129 + </div>
130 + <?php endif; ?>
131 + <h3 class="qcld-wpbot-main-tabs-title"><?php esc_html_e('Choose a Template', 'chatbot'); ?></h3>
132 + <p><?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 class="qcld-ai-template-grid">
135 + <!-- Blank -->
136 + <div class="ai-template-card" data-title="" data-prompt="" >
137 + <div class="ai-template-card-icon"><span class="dashicons dashicons-plus-alt2" ></span></div>
138 + <h4>Blank Prompt</h4>
139 + <p>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 +" >
152 + <div class="ai-template-card-icon"><span class="dashicons dashicons-desktop" ></span></div>
153 + <h4>Web Agency Quote</h4>
154 + <p>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 +" >
168 + <div class="ai-template-card-icon"><span class="dashicons dashicons-building" ></span></div>
169 + <h4>Real Estate Inquiry</h4>
170 + <p>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 +" >
185 + <div class="ai-template-card-icon"><span class="dashicons dashicons-sos" ></span></div>
186 + <h4>Priority Support</h4>
187 + <p>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 +" >
200 + <div class="ai-template-card-icon"><span class="dashicons dashicons-chart-pie" ></span></div>
201 + <h4>SaaS Demo Booking</h4>
202 + <p>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 +" >
216 + <div class="ai-template-card-icon"><span class="dashicons dashicons-cart" ></span></div>
217 + <h4>E-Commerce Wholesale</h4>
218 + <p>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 +" >
231 + <div class="ai-template-card-icon"><span class="dashicons dashicons-portfolio" ></span></div>
232 + <h4>Legal Case Intake</h4>
233 + <p>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 +" >
246 + <div class="ai-template-card-icon"><span class="dashicons dashicons-heart" ></span></div>
247 + <h4>Healthcare Booking</h4>
248 + <p>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 +" >
262 + <div class="ai-template-card-icon"><span class="dashicons dashicons-calendar-alt" ></span></div>
263 + <h4>Event Planning</h4>
264 + <p>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 +" >
278 + <div class="ai-template-card-icon"><span class="dashicons dashicons-car" ></span></div>
279 + <h4>Auto Dealership</h4>
280 + <p>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 +" >
294 + <div class="ai-template-card-icon"><span class="dashicons dashicons-welcome-learn-more" ></span></div>
295 + <h4>Education Admissions</h4>
296 + <p>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 +" >
325 + <div class="ai-template-card-icon"><span class="dashicons dashicons-businessman" ></span></div>
326 + <h4>Senior PHP Programmer Assessment</h4>
327 + <p>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;">
343 +
344 + <div class="qcld-ai-action-edit-head">
345 + <h3 class="qcld-wpbot-main-tabs-title"><?php esc_html_e('Edit Action', 'chatbot'); ?></h3>
346 + <div class="qcld-ai-action-edit-actions">
347 + <button type="button" class="qcld-btn-primary qcld-ai-goto-new-action"><?php esc_html_e('Add New Action', 'chatbot'); ?></button>
348 + <button type="button" class="button remove-ai-form"><?php esc_html_e( 'Delete Action', 'chatbot' ); ?></button>
349 + </div>
350 + </div>
351 +
352 + <h2 class="nav-tab-wrapper wpbot-ai-inner-tabs">
353 + <a href="#ai-inner-settings-<?php echo esc_attr($counter); ?>" class="nav-tab nav-tab-active"><?php esc_html_e('Settings', 'chatbot'); ?></a>
354 + <a href="#" class="nav-tab qcld-ai-history-pro-tab"><?php esc_html_e('History', 'chatbot'); ?> <span class="qc_wpbot_pro">PRO</span></a>
355 + </h2>
356 +
357 + <div id="ai-inner-settings-<?php echo esc_attr($counter); ?>" class="ai-inner-tab-content">
358 + <div class="form-group">
359 + <label><?php esc_html_e('Action Title', 'chatbot'); ?></label>
360 + <input type="text" name="ai_form_title[]" class="form-control ai-form-title-input" placeholder="<?php esc_attr_e('e.g., Hotel Booking', 'chatbot'); ?>" value="<?php echo esc_attr( $form['title'] ); ?>" />
361 + </div>
362 + <div class="form-group">
363 + <label><?php esc_html_e('AI Prompt', 'chatbot'); ?></label>
364 + <textarea name="ai_form_prompt[]" class="form-control" rows="15" placeholder="<?php esc_attr_e('Enter your prompt here...', 'chatbot'); ?>"><?php echo esc_textarea( $form['prompt'] ); ?></textarea>
365 + </div>
366 +
367 + <div class="cxsc-settings-blocks">
368 + <div class="form-group qcld-ai-email-toggle">
369 + <input type="hidden" name="ai_form_email[]" class="ai-email-val" value="<?php echo esc_attr( isset($form['email']) ? $form['email'] : 1 ); ?>">
370 + <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);">
371 + <label for="<?php echo esc_attr( $chk_email_id ); ?>"><?php esc_html_e('Email the data', 'chatbot'); ?></label>
372 + </div>
373 + <div class="qcld-ai-email-field">
374 + <label><?php esc_html_e('Send to Email(s)', 'chatbot'); ?></label>
375 + <input type="text" name="ai_form_email_addresses[]" class="form-control" 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'] : '' ); ?>">
376 + <p class="qcld-ai-field-hint"><?php esc_html_e('Comma-separated. Leave blank to use the default admin email.', 'chatbot'); ?></p>
377 + </div>
378 + </div>
379 + </div>
380 +
381 + <div id="ai-inner-history-<?php echo esc_attr($counter); ?>" class="ai-inner-tab-content" style="display: none;">
382 + <div id="ai-inner-history-content-<?php echo esc_attr($counter); ?>">
383 + <p class="qcld-ai-muted"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>
384 + </div>
385 + </div>
386 + </div>
387 + <?php
388 + $counter++;
389 + endforeach;
390 + endif;
391 + ?>
392 + </div>
393 +
394 + <div id="ai-save-wrapper" class="wp-chatbot-admin-footer qcld-ai-save-footer">
395 + <div class="cxsc-settings-blocks-notic">
396 + <p><?php esc_html_e("Don't forget to save your changes!", 'chatbot'); ?></p>
397 + <p><strong><?php esc_html_e('Create powerful AI Actions with Prompt to collect information and send to your email.', 'chatbot'); ?></strong></p>
398 + <p><strong><?php esc_html_e('After creating an AI Action, you can add it to the Active Start Menu from', 'chatbot'); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpbot&tab=startmenu' ) ); ?>"><?php esc_html_e('Settings -> Start Menu', 'chatbot'); ?></a></strong></p>
399 + </div>
400 + <input type="submit" name="submit" class="qcld-btn-primary" value="<?php esc_attr_e( 'Save Settings', 'chatbot' ); ?>" />
401 + </div>
402 + </form>
403 + </div>
404 +
405 + <?php
406 + $default_provider = 'openai';
407 + if ( get_option( 'qcld_gemini_enabled' ) == 1 ) {
408 + $default_provider = 'gemini';
409 + } elseif ( get_option( 'qcld_claude_enabled' ) == 1 ) {
410 + $default_provider = 'claude';
411 + } elseif ( get_option( 'qcld_grok_enabled' ) == 1 ) {
412 + $default_provider = 'grok';
413 + } elseif ( get_option( 'qcld_openrouter_enabled' ) == 1 ) {
414 + $default_provider = 'openrouter';
415 + }
416 +
417 + if ( get_option( 'wp_chatbot_icon' ) == 'custom.png' ) {
418 + $wp_chatbot_custom_icon_path = ( ! empty( get_option( 'wp_chatbot_custom_icon_path' ) ) ) ? get_option( 'wp_chatbot_custom_icon_path' ) : QCLD_wpCHATBOT_IMG_URL . 'icon-1.png';
419 + } elseif ( get_option( 'wp_chatbot_icon' ) ) {
420 + $wp_chatbot_custom_icon_path = QCLD_wpCHATBOT_IMG_URL . get_option( 'wp_chatbot_icon' );
421 + } else {
422 + $wp_chatbot_custom_icon_path = QCLD_wpCHATBOT_IMG_URL . 'icon-1.png';
423 + }
424 + ?>
425 + <aside class="wp-chatbot-admin-upgrade-pro-sidebar qcld-ai-actions-playground">
426 + <div class="qcld-ai-playground">
427 + <div class="qcld-ai-playground-header">
428 + <span><?php esc_html_e('Live AI Playground', 'chatbot'); ?></span>
429 + <button type="button" id="ai-playground-refresh" title="<?php esc_attr_e('Refresh Chat', 'chatbot'); ?>">
430 + <span class="dashicons dashicons-update-alt"></span>
431 + </button>
432 + </div>
433 + <div id="ai-actions-playground-container">
434 + <div id="ai-actions-playground-messages">
435 + <div class="qcld-ai-pg-bot-row">
436 + <div class="qcld-ai-pg-avatar" style="background-image: url('<?php echo esc_url( $wp_chatbot_custom_icon_path ); ?>');"></div>
437 + <div class="qcld-ai-pg-bubble">
438 + <p><?php esc_html_e('Hello! I am here to find what you need. What are you looking for?', 'chatbot'); ?></p>
439 + <div id="ai-actions-live-preview"></div>
440 + </div>
441 + </div>
442 + </div>
443 + </div>
444 + <div class="qcld-ai-playground-footer">
445 + <input type="text" id="playground-input" placeholder="<?php esc_attr_e('Send a message...', 'chatbot'); ?>">
446 + <button type="button" id="playground-send-btn">
447 + <span class="dashicons dashicons-arrow-up-alt"></span>
448 + </button>
449 + </div>
450 + </div>
451 + </aside>
452 +
453 + </div>
454 + </section>
455 + </div>
456 +</div>
457 +
458 +<script>
459 +jQuery(document).ready(function($) {
460 + // --- SIDEBAR TAB SWITCHING LOGIC ---
461 + function switchTab(targetId, linkObj) {
462 + $('.ai-content-pane').hide();
463 + $('.ai-sidebar-link').removeClass('active');
464 + $('.qcld-ai-actions-layout nav > ul > li').removeClass('tab-current');
465 + $('.ai-saved-actions-submenu li').removeClass('tab-current');
466 +
467 + $('#' + targetId).show();
468 + if (linkObj) {
469 + linkObj.addClass('active');
470 + } else {
471 + linkObj = $('.ai-sidebar-link[href="#' + targetId + '"]');
472 + linkObj.addClass('active');
473 + }
474 + if (linkObj && linkObj.length) {
475 + linkObj.closest('li').addClass('tab-current');
476 + if (linkObj.hasClass('ai-sidebar-saved-link')) {
477 + $('.qcld-ai-saved-parent').addClass('is-open');
478 + }
479 + }
480 +
481 + // Hide Save button if history tab (if we still had it globally, but we don't)
482 + $('#ai-save-wrapper').show();
483 +
484 + // Save to sessionStorage so it stays open after reload
485 + sessionStorage.setItem('qcld_ai_active_tab', targetId);
486 + }
487 +
488 + // Restore active tab on page load
489 + var savedTab = sessionStorage.getItem('qcld_ai_active_tab');
490 + if (savedTab) {
491 + var linkToOpen = null;
492 + var tabToOpen = null;
493 +
494 + if ($('#' + savedTab).length) {
495 + tabToOpen = savedTab;
496 + linkToOpen = $('.ai-sidebar-link[href="#' + savedTab + '"]');
497 + } else if (savedTab.indexOf('ai-action-tab-') === 0) {
498 + // Was a newly generated tab. After saving, it becomes the last saved action.
499 + var lastSavedLink = $('.ai-sidebar-saved-link').last();
500 + if (lastSavedLink.length) {
501 + tabToOpen = lastSavedLink.attr('href').substring(1);
502 + linkToOpen = lastSavedLink;
503 + // Update session storage to the new real ID
504 + sessionStorage.setItem('qcld_ai_active_tab', tabToOpen);
505 + }
506 + }
507 +
508 + if (tabToOpen) {
509 + switchTab(tabToOpen, null);
510 + if (linkToOpen && linkToOpen.closest('.ai-saved-actions-submenu').length) {
511 + $('.ai-saved-actions-submenu').show();
512 + $('.qcld-ai-saved-parent').addClass('is-open');
513 + $('.qcld-ai-saved-toggle').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
514 + }
515 + }
516 + }
517 +
518 + $(document).on('click', '.qcld-ai-goto-new-action', function(e) {
519 + e.preventDefault();
520 + switchTab('ai-new-action-tab', $('.ai-sidebar-link[href="#ai-new-action-tab"]'));
521 + });
522 +
523 + $(document).on('click', '.ai-sidebar-link', function(e) {
524 + e.preventDefault();
525 + var href = $(this).attr('href') || '';
526 + if (href.indexOf('#') === -1) {
527 + return;
528 + }
529 + var target = href.substring(href.indexOf('#') + 1);
530 + if (!target) {
531 + return;
532 + }
533 + switchTab(target, $(this));
534 + });
535 +
536 + // --- SAVED ACTIONS SUBMENU TOGGLE ---
537 + $('.ai-sidebar-parent-link').on('click', function(e) {
538 + e.preventDefault();
539 + var submenu = $(this).next('.ai-saved-actions-submenu');
540 + var icon = $(this).find('.qcld-ai-saved-toggle');
541 + $(this).closest('li').toggleClass('is-open');
542 +
543 + submenu.slideToggle(200);
544 + if (icon.hasClass('dashicons-arrow-down-alt2')) {
545 + icon.removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
546 + } else {
547 + icon.removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
548 + }
549 + });
550 +
551 + // --- INNER TABS (SETTINGS/HISTORY) ---
552 + $(document).on('click', '.wpbot-ai-inner-tabs .nav-tab', function(e) {
553 + e.preventDefault();
554 +
555 + if ($(this).attr('href') === '#') return false;
556 +
557 + var pane = $(this).closest('.ai-content-pane');
558 + var targetId = $(this).attr('href').substring(1);
559 +
560 + // Tab styling
561 + pane.find('.wpbot-ai-inner-tabs .nav-tab').removeClass('nav-tab-active');
562 + $(this).addClass('nav-tab-active');
563 +
564 + // Tab content
565 + pane.find('.ai-inner-tab-content').hide();
566 + pane.find('#' + targetId).fadeIn(200);
567 +
568 + // Handle History AJAX loading
569 + if ($(this).hasClass('ai-load-history-btn')) {
570 + var contentTarget = $(this).data('target');
571 + var formTitle = pane.find('.ai-form-title-input').val();
572 +
573 + var targetContainer = $('#' + contentTarget);
574 + targetContainer.html('<p style="color: #666; font-style: italic;"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>');
575 +
576 + if (!formTitle || formTitle.trim() === '') {
577 + targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Please save the form with a title first to preview entries.', 'chatbot'); ?></p>');
578 + return;
579 + }
580 +
581 + var data = {
582 + action: 'qcld_get_ai_form_entries',
583 + form_title: formTitle,
584 + nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot_ai_actions' ) ); ?>'
585 + };
586 +
587 + $.post(ajaxurl, data, function(response) {
588 + if (response.success) {
589 + targetContainer.html(response.data.html);
590 + } else {
591 + targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Error loading entries.', 'chatbot'); ?></p>');
592 + }
593 + }).fail(function() {
594 + targetContainer.html('<p style="color: #a00;"><?php esc_html_e('Error connecting to server.', 'chatbot'); ?></p>');
595 + });
596 + }
597 + });
598 +
599 + // --- DELETE HISTORY ENTRY ---
600 + $(document).on('click', '.qcld-delete-ai-entry', function(e) {
601 + e.preventDefault();
602 + var btn = $(this);
603 + var entryId = btn.data('id');
604 +
605 + if (!confirm('<?php esc_html_e('Are you sure you want to delete this history entry?', 'chatbot'); ?>')) {
606 + return;
607 + }
608 +
609 + btn.prop('disabled', true).text('Deleting...');
610 +
611 + var data = {
612 + action: 'qcld_delete_ai_form_entry',
613 + entry_id: entryId,
614 + nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot_ai_actions' ) ); ?>'
615 + };
616 +
617 + $.post(ajaxurl, data, function(response) {
618 + if (response.success) {
619 + btn.closest('tr').fadeOut(300, function() { $(this).remove(); });
620 + } else {
621 + alert('Error: ' + response.data);
622 + btn.prop('disabled', false).text('Delete');
623 + }
624 + }).fail(function() {
625 + alert('Error connecting to server.');
626 + btn.prop('disabled', false).text('Delete');
627 + });
628 + });
629 +
630 + // --- CREATE NEW ACTION FROM TEMPLATE ---
631 + $('.ai-template-card').on('click', function() {
632 + var title = $(this).data('title');
633 + var prompt = $(this).data('prompt');
634 +
635 + var uniqueId = 'ai_form_' + Math.floor(Math.random() * 1000000);
636 + var tabId = 'ai-action-tab-' + uniqueId;
637 + var chk_interactive_id = 'ai_interactive_' + uniqueId;
638 + var chk_email_id = 'ai_email_' + uniqueId;
639 + var displayTitle = title ? title : 'New Blank Action';
640 +
641 + // Remove "No saved actions" if exists
642 + $('.ai-no-saved-actions').remove();
643 +
644 + // 1. Add Sidebar Link
645 + var linkHtml = '<li><a href="#' + tabId + '" class="ai-sidebar-link ai-sidebar-saved-link" data-id="' + tabId + '">' + displayTitle + '</a></li>';
646 + $('.ai-saved-actions-submenu').append(linkHtml);
647 +
648 + // Ensure submenu is open
649 + $('.ai-saved-actions-submenu').slideDown(200);
650 + $('.qcld-ai-saved-parent').addClass('is-open');
651 + $('.qcld-ai-saved-toggle').removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
652 +
653 + // 2. Add Form Pane
654 + var template = `
655 + <div id="` + tabId + `" class="ai-content-pane ai-form-item" style="display: none;">
656 + <div class="qcld-ai-action-edit-head">
657 + <h3 class="qcld-wpbot-main-tabs-title"><?php esc_html_e('Edit Action', 'chatbot'); ?></h3>
658 + <div class="qcld-ai-action-edit-actions">
659 + <button type="button" class="qcld-btn-primary qcld-ai-goto-new-action"><?php esc_html_e('Add New Action', 'chatbot'); ?></button>
660 + <button type="button" class="button remove-ai-form"><?php esc_html_e( 'Delete Action', 'chatbot' ); ?></button>
661 + </div>
662 + </div>
663 +
664 + <h2 class="nav-tab-wrapper wpbot-ai-inner-tabs">
665 + <a href="#ai-inner-settings-` + uniqueId + `" class="nav-tab nav-tab-active"><?php esc_html_e('Settings', 'chatbot'); ?></a>
666 + <a href="#" class="nav-tab qcld-ai-history-pro-tab"><?php esc_html_e('History', 'chatbot'); ?> <span class="qc_wpbot_pro">PRO</span></a>
667 + </h2>
668 +
669 + <div id="ai-inner-settings-` + uniqueId + `" class="ai-inner-tab-content">
670 + <div class="form-group">
671 + <label><?php esc_html_e('Action Title', 'chatbot'); ?></label>
672 + <input type="text" name="ai_form_title[]" class="form-control ai-form-title-input" placeholder="<?php esc_attr_e('e.g., Hotel Booking', 'chatbot'); ?>" value="` + title + `" />
673 + </div>
674 + <div class="form-group">
675 + <label><?php esc_html_e('AI Prompt', 'chatbot'); ?></label>
676 + <textarea name="ai_form_prompt[]" class="form-control" rows="8" placeholder="<?php esc_attr_e('Enter your prompt here...', 'chatbot'); ?>">` + prompt + `</textarea>
677 + </div>
678 +
679 + <div class="cxsc-settings-blocks">
680 + <div class="form-group qcld-ai-email-toggle">
681 + <input type="hidden" name="ai_form_email[]" class="ai-email-val" value="1">
682 + <input type="checkbox" id="` + chk_email_id + `" checked onchange="jQuery(this).prev(\'.ai-email-val\').val(this.checked ? 1 : 0);">
683 + <label for="` + chk_email_id + `"><?php esc_html_e('Email the data', 'chatbot'); ?></label>
684 + </div>
685 + <div class="qcld-ai-email-field">
686 + <label><?php esc_html_e('Send to Email(s)', 'chatbot'); ?></label>
687 + <input type="text" name="ai_form_email_addresses[]" class="form-control" placeholder="<?php echo esc_attr( get_option('qlcd_wp_chatbot_admin_email', get_option('admin_email')) ); ?>" value="">
688 + <p class="qcld-ai-field-hint"><?php esc_html_e('Comma-separated. Leave blank to use the default admin email.', 'chatbot'); ?></p>
689 + </div>
690 + </div>
691 + </div>
692 +
693 + <div id="ai-inner-history-` + uniqueId + `" class="ai-inner-tab-content" style="display: none;">
694 + <div id="ai-inner-history-content-` + uniqueId + `">
695 + <p class="qcld-ai-muted"><?php esc_html_e('Loading history...', 'chatbot'); ?></p>
696 + </div>
697 + </div>
698 + </div>
699 + `;
700 + $('#ai-saved-actions-container').append(template);
701 +
702 + // 3. Switch to it immediately
703 + switchTab(tabId, $('.ai-sidebar-link[href="#' + tabId + '"]'));
704 +
705 + // 4. Update preview playground
706 + updateAiActionsPreview();
707 + });
708 +
709 + // --- REMOVE FORM ITEM ---
710 + $(document).on('click', '.remove-ai-form', function(e) {
711 + e.preventDefault();
712 + var pane = $(this).closest('.ai-content-pane');
713 + var tabId = pane.attr('id');
714 +
715 + // Remove pane
716 + pane.remove();
717 +
718 + // Remove sidebar link
719 + $('.ai-sidebar-link[href="#' + tabId + '"]').parent().remove();
720 +
721 + // Check if submenu is empty
722 + if ($('.ai-saved-actions-submenu li').length === 0) {
723 + $('.ai-saved-actions-submenu').html('<li class="ai-no-saved-actions"><?php esc_html_e('No saved actions', 'chatbot'); ?></li>');
724 + }
725 +
726 + // Switch back to Add New Action tab
727 + switchTab('ai-new-action-tab', $('.ai-sidebar-link[href="#ai-new-action-tab"]'));
728 +
729 + updateAiActionsPreview();
730 + });
731 +
732 + // --- UPDATE HEADER DYNAMICALLY ---
733 + $(document).on('keyup', '.ai-form-title-input', function() {
734 + var newTitle = $(this).val();
735 + var paneId = $(this).closest('.ai-content-pane').attr('id');
736 + var sidebarLink = $('.ai-sidebar-link[href="#' + paneId + '"]');
737 +
738 + if (newTitle.trim() === '') {
739 + newTitle = '<?php esc_html_e('Untitled Action', 'chatbot'); ?>';
740 + }
741 + sidebarLink.text(newTitle);
742 + updateAiActionsPreview();
743 + });
744 +
745 + // --- PREVIEW UPDATING FUNCTION ---
746 + function updateAiActionsPreview() {
747 + var previewContainer = $('#ai-actions-live-preview');
748 + previewContainer.empty();
749 +
750 + var titles = [];
751 + $('.saved-ai-action .ai-form-title-input').each(function() {
752 + var val = $(this).val().trim();
753 + if(val) {
754 + titles.push(val);
755 + }
756 + });
757 +
758 + if(titles.length === 0) {
759 + previewContainer.append('<span class="playground-ai-action-btn is-empty"><?php esc_html_e('No Actions Created Yet', 'chatbot'); ?></span>');
760 + } else {
761 + $.each(titles, function(index, title) {
762 + previewContainer.append('<span class="playground-ai-action-btn">' + title + '</span>');
763 + });
764 + }
765 + }
766 +
767 + // --- PLAYGROUND INTERACTIVE LOGIC ---
768 + var aiContext = [];
769 +
770 + var playgroundIcon = '<?php echo esc_url( $wp_chatbot_custom_icon_path ); ?>';
771 +
772 + function appendUserMessage(text) {
773 + var msgHtml = '<div class="qcld-ai-pg-user-row">' +
774 + '<div class="qcld-ai-pg-user-bubble">' + text + '</div>' +
775 + '</div>';
776 + $('#ai-actions-playground-messages').append(msgHtml);
777 + scrollToBottom();
778 + }
779 +
780 + function appendBotMessage(text) {
781 + var msgHtml = '<div class="qcld-ai-pg-bot-row">' +
782 + '<div class="qcld-ai-pg-avatar" style="background-image: url(\'' + playgroundIcon + '\');"></div>' +
783 + '<div class="qcld-ai-pg-bubble">' + text + '</div>' +
784 + '</div>';
785 + $('#ai-actions-playground-messages').append(msgHtml);
786 + scrollToBottom();
787 + }
788 +
789 + function appendLoader() {
790 + var msgHtml = '<div id="playground-loader" class="qcld-ai-pg-bot-row">' +
791 + '<div class="qcld-ai-pg-avatar" style="background-image: url(\'' + playgroundIcon + '\');"></div>' +
792 + '<div class="qcld-ai-pg-bubble is-loading"><i>Thinking...</i></div>' +
793 + '</div>';
794 + $('#ai-actions-playground-messages').append(msgHtml);
795 + scrollToBottom();
796 + }
797 +
798 + function scrollToBottom() {
799 + var container = $('#ai-actions-playground-container');
800 + container.scrollTop(container[0].scrollHeight);
801 + }
802 +
803 + function formatBotResponse(text) {
804 + // Remove internal tracking flag
805 + text = text.replace(/__AI_FORM_IN_PROGRESS__/g, '');
806 +
807 + // Extract and format AI_FORM_DATA block
808 + // This regex optionally matches surrounding HTML tags to ensure they are replaced too, preventing broken tags.
809 + var regex = /(?:<[^>]+>)*\s*AI_FORM_DATA[\s\S]*?__AI_FORM_DATA_END__\s*(?:<\/[^>]+>)*/g;
810 + text = text.replace(regex, function(match) {
811 + try {
812 + // Extract just the JSON part from the match (from the first '{' to the last '}')
813 + var jsonMatch = match.match(/\{[\s\S]*\}/);
814 + if (!jsonMatch) {
815 + return match;
816 + }
817 + var jsonStr = jsonMatch[0];
818 + var data = JSON.parse(jsonStr.trim());
819 + var html = '<div class="qcld-ai-pg-form-data">';
820 + if (data.form_title) {
821 + html += '<strong>' + data.form_title + '</strong>';
822 + }
823 + if (data.data) {
824 + html += '<ul>';
825 + for (var key in data.data) {
826 + html += '<li style="margin-bottom: 3px;"><strong>' + key + ':</strong> ' + data.data[key] + '</li>';
827 + }
828 + html += '</ul>';
829 + }
830 + html += '</div>';
831 + return html;
832 + } catch (e) {
833 + return match; // Return original if parsing fails
834 + }
835 + });
836 +
837 + var cleanResponse = text.replace(/(\w+)\n/g,'$1 ');
838 + cleanResponse = cleanResponse.replace(/```(.*?)```/gs, '<pre style="background: #f4f4f4; padding: 8px; border-radius: 5px; overflow-x: auto; font-size: 12px;">$1</pre>');
839 + cleanResponse = cleanResponse.replace(/`(.*?)`/g, '<code style="background: #f4f4f4; padding: 2px 4px; border-radius: 3px;">$1</code>');
840 + cleanResponse = cleanResponse.replace(/\n/g, '<br>');
841 + return cleanResponse;
842 + }
843 +
844 + function sendToAI(text, actionPrompt) {
845 + appendUserMessage(text);
846 + appendLoader();
847 +
848 + aiContext.push({role: 'user', content: text});
849 + if (aiContext.length > 10) {
850 + aiContext.shift();
851 + }
852 +
853 + var activeProvider = '<?php echo esc_js($default_provider); ?>';
854 + var actionMap = {
855 + 'openai': 'qcld_openai_response',
856 + 'gemini': 'qcld_gemini_response',
857 + 'claude': 'claude_response',
858 + 'grok': 'qcld_grok_response',
859 + 'openrouter': 'openrouter_response'
860 + };
861 + var ajaxAction = actionMap[activeProvider] || 'qcld_openai_response';
862 +
863 + var data = {
864 + action: ajaxAction,
865 + keyword: text,
866 + ai_history: JSON.stringify(aiContext),
867 + is_ai_actions_playground: 1,
868 + action_prompt: actionPrompt || '',
869 + nonce: '<?php echo esc_js( wp_create_nonce( 'wp_chatbot' ) ); ?>'
870 + };
871 +
872 + $.post(ajaxurl, data, function(res) {
873 + $('#playground-loader').remove();
874 +
875 + var json = res;
876 + if (typeof res === 'string') {
877 + try {
878 + json = $.parseJSON(res);
879 + } catch(e) {}
880 + }
881 +
882 + if (json && json.status === 'success') {
883 + var reply = json.message;
884 + aiContext.push({role: 'assistant', content: reply});
885 + if (aiContext.length > 10) {
886 + aiContext.shift();
887 + }
888 + appendBotMessage(formatBotResponse(reply));
889 + } else {
890 + appendBotMessage('<?php esc_html_e('Sorry, there was an error processing your request.', 'chatbot'); ?>');
891 + }
892 + }).fail(function() {
893 + $('#playground-loader').remove();
894 + appendBotMessage('<?php esc_html_e('Error connecting to AI service.', 'chatbot'); ?>');
895 + });
896 + }
897 +
898 + $(document).on('click', '.playground-ai-action-btn', function() {
899 + if ($(this).hasClass('is-empty')) {
900 + return;
901 + }
902 + var text = $(this).text().trim();
903 +
904 + var matchedPrompt = '';
905 + $('.ai-form-title-input').each(function() {
906 + if ($(this).val().trim().toLowerCase() === text.toLowerCase()) {
907 + matchedPrompt = $(this).closest('.ai-content-pane').find('textarea[name="ai_form_prompt[]"]').val() || '';
908 + }
909 + });
910 +
911 + aiContext = [];
912 + sendToAI(text, matchedPrompt);
913 + });
914 +
915 + $('#playground-input').on('keypress', function(e) {
916 + if(e.which === 13) {
917 + var text = $(this).val().trim();
918 + if(text) {
919 + $(this).val('');
920 + sendToAI(text);
921 + }
922 + }
923 + });
924 +
925 + $('#playground-send-btn').on('click', function() {
926 + var text = $('#playground-input').val().trim();
927 + if(text) {
928 + $('#playground-input').val('');
929 + sendToAI(text);
930 + }
931 + });
932 +
933 + $('#ai-playground-refresh').on('click', function() {
934 + var $messages = $('#ai-actions-playground-messages');
935 + $messages.children(':not(:first)').remove();
936 + updateAiActionsPreview();
937 + });
938 +
939 + $(document).on('click', '.qcld-ai-history-pro-tab', function(e) {
940 + e.preventDefault();
941 + return false;
942 + });
943 +
944 + // --- INITIALIZATION ---
945 + updateAiActionsPreview();
946 +
947 + // Make sure initial state shows first tab if history or saved tab isn't already active (fallback)
948 + if ($('.ai-sidebar-link.active').length === 0) {
949 + $('.ai-sidebar-link[href="#ai-new-action-tab"]').addClass('active');
950 + $('#ai-new-action-tab').show();
951 + }
952 +});
953 +</script>