PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.3
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
← All changes | includes/Core/WriteWithAI.php +853 -1252 4.6.03.5.3 View file →
@@ -1,116 +1,76 @@
1 1 <?php
2 2
3 - namespace WPDeveloper\BetterDocs\Core;
3 +namespace WPDeveloper\BetterDocs\Core;
4 4
5 -if ( ! defined( 'ABSPATH' ) ) {
6 - exit;
7 -}
5 +use WPDeveloper\BetterDocs\Utils\Base;
6 +use WPDeveloper\BetterDocs\Core\Settings;
7 +use WPDeveloper\BetterDocs\Core\PostType;
8 8
9 +use WPDeveloper\BetterDocs\Utils\Helper;
9 10
10 - use WPDeveloper\BetterDocs\Utils\Base;
11 - use WPDeveloper\BetterDocs\Core\Settings;
12 - use WPDeveloper\BetterDocs\Core\PostType;
13 -
14 - use WPDeveloper\BetterDocs\Utils\Helper;
15 - use WPDeveloper\BetterDocs\Utils\AIHelper;
16 - use WPDeveloper\BetterDocs\Utils\AIUsage;
17 -
18 - class WriteWithAI extends Base {
19 -
11 +class WriteWithAI extends Base
12 +{
20 13 public $settings;
21 14
22 - public function __construct( Settings $settings ) {
15 + public function __construct(Settings $settings)
16 + {
23 17 $this->settings = $settings;
24 18 // Get the post ID from the URL
25 - $post_id = isset( $_GET[ 'post' ] ) ? intval( $_GET[ 'post' ] ) : 0; // phpcs:ignore
19 + $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0;
26 20
27 - if ( ! empty( $_GET[ 'post_type' ] ) ) { // phpcs:ignore
28 - $post_type = $_GET[ 'post_type' ]; // phpcs:ignore
29 - } elseif ( $post_id > 0 ) {
30 - $post_type = get_post_type( $post_id );
21 + if (!empty($_GET['post_type'])) {
22 + $post_type = $_GET['post_type'];
23 + } else if ($post_id > 0) {
24 + $post_type = get_post_type($post_id);
31 25 } else {
32 26 $post_type = '';
33 27 }
34 28
35 - if ( ! empty( $this->isEnabledWriteWithAI() ) && 'docs' == $post_type ) {
36 - add_action( 'admin_footer', array( $this, 'ai_autowrite_button' ) );
37 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_ai_edit_assets' ) );
29 + if (!empty($this->isEnabledWriteWithAI()) && $post_type == 'docs') {
30 + add_action('admin_footer', [$this, 'ai_autowrite_button']);
38 31 }
39 - add_action( 'wp_ajax_generate_openai_content', array( $this, 'generate_openai_content_callback' ) );
32 + add_action('wp_ajax_generate_openai_content', [$this, 'generate_openai_content_callback']);
40 33 }
41 34
42 - public function enqueue_ai_edit_assets( $hook ) {
43 - if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
44 - return;
45 - }
46 -
47 - global $post_type;
48 - if ( 'docs' !== $post_type ) {
49 - return;
50 - }
51 -
52 - if ( empty( $this->get_api_key() ) ) {
53 - return;
54 - }
55 -
56 - betterdocs()->assets->enqueue( 'betterdocs-ai-edit', 'blocks/ai-edit.js' );
57 - betterdocs()->assets->enqueue( 'betterdocs-ai-edit-style', 'blocks/ai-edit-style.css' );
58 -
59 - wp_localize_script(
60 - 'betterdocs-ai-edit',
61 - 'betterdocsAIEdit',
62 - array(
63 - 'rest_url' => esc_url_raw( rest_url( 'betterdocs/v1/ai-edit' ) ),
64 - 'rest_nonce' => wp_create_nonce( 'wp_rest' ),
65 - 'post_id' => get_the_ID()
66 - )
67 - );
68 - }
69 -
70 - public function isEnabledWriteWithAI() {
71 - $isEnableAutoWrite = $this->settings->get( 'enable_write_with_ai', true );
35 + public function isEnabledWriteWithAI()
36 + {
37 + $isEnableAutoWrite = $this->settings->get('enable_write_with_ai', true);
72 38 return $isEnableAutoWrite;
73 39 }
74 40
75 - public function isValidAPIKey( $apiKey ) {
76 - if ( empty( $apiKey ) ) {
77 - $api_response[ 'valid' ] = false;
78 - $api_response[ 'message' ] = 'Please Insert your <a href="/admin.php?page=betterdocs-settings#betterdocs-ai">OpenAI API Key</a> to use this Write with AI feature.';
41 + public function isValidAPIKey($apiKey)
42 + {
43 + if (empty($apiKey)) {
44 + $api_response['valid'] = false;
45 + $api_response['message'] = 'Please Insert your <a href="/admin.php?page=betterdocs-settings">OpenAI API Key</a> to use this Write with AI feature.';
79 46
80 47 return $api_response;
81 48 }
82 49
83 - $api_response = array();
50 + $ch = curl_init('https://api.openai.com/v1/engines');
51 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
52 + curl_setopt($ch, CURLOPT_HTTPHEADER, [
53 + 'Content-Type: application/json',
54 + 'Authorization: Bearer ' . $apiKey,
55 + ]);
84 56
85 - $response = wp_safe_remote_get(
86 - 'https://api.openai.com/v1/engines',
87 - array(
88 - 'headers' => array(
89 - 'Content-Type' => 'application/json',
90 - 'Authorization' => 'Bearer ' . $apiKey,
91 - ),
92 - 'timeout' => 15,
93 - )
94 - );
57 + $api_response = [];
95 58
96 - if ( is_wp_error( $response ) ) {
97 - $api_response[ 'valid' ] = false;
98 - $api_response[ 'message' ] = $response->get_error_message();
99 - return $api_response;
100 - }
59 + $response = curl_exec($ch);
60 + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
101 61
102 - $httpCode = (int) wp_remote_retrieve_response_code( $response );
103 - $body = wp_remote_retrieve_body( $response );
62 + curl_close($ch);
104 63
105 - if ( 200 === $httpCode ) {
106 - $api_response[ 'valid' ] = true;
107 - $api_response[ 'message' ] = 'Valid API Key';
64 + if ($httpCode == 200) {
65 + $api_response['valid'] = true;
66 + $api_response['message'] = 'Valid API Key';
108 67 } else {
109 - $responseData = json_decode( $body, true );
110 - $messageData = ! empty( $responseData[ 'error' ] ) ? $responseData[ 'error' ] : array();
111 - $api_response[ 'valid' ] = false;
112 - $api_response[ 'message' ] = ! empty( $messageData[ 'message' ] ) ? $messageData[ 'message' ] : 'Invalid API Key';
68 + $responseData = json_decode($response, true);
69 + // Access the message data (replace 'data' with the actual key used in the response)
70 + $messageData = $responseData['error'] ? $responseData['error'] : '';
71 + $api_response['valid'] = false;
72 + $api_response['message'] = $messageData['message'] ? $messageData['message'] : 'Invalid API Key';
113 73 }
114 74
115 75 // print_r($response);
116 76
@@ -116,1384 +76,1025 @@
116 76
117 77 return $api_response;
118 78 }
119 79
120 - public function get_api_key() {
121 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
80 + public function get_api_key()
81 + {
82 + $api_key = $this->settings->get('ai_autowrite_api_key', '');
122 83 return $api_key;
123 84 }
124 85
125 - public function get_system_prompt() {
126 - $prompt = <<<'PROMPT'
127 -You are a Senior Technical Writer specializing in comprehensive, high-quality documentation. Your goal is to produce documentation that scores 100/100 on clarity, completeness, and structure.
128 86
129 -## Output format
130 -
131 -Return only HTML body content. Never wrap output in `<!doctype>`, `<html>`, `<head>`, `<body>`, or markdown code fences (no ```html ... ```).
132 -
133 -Use semantic, Gutenberg-friendly tags only:
134 -- Headings: `<h2>`, `<h3>`, `<h4>` (do not emit `<h1>` — it is reserved for the document title)
135 -- Paragraphs: `<p>` for prose
136 -- Lists: `<ul>`/`<ol>` with `<li>` for any list of items, steps, or bullet points — never fake a list with paragraphs or `<br>`
137 -- Links: `<a href="https://...">link text</a>` with absolute URLs
138 -- Inline emphasis: `<strong>`, `<em>`, `<code>`
139 -- Code blocks: `<pre><code>...</code></pre>` for multi-line code or commands
140 -- Quotes: `<blockquote>`
141 -- Tables: `<table>` with `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`
142 -- Images: `<img src="..." alt="...">`
143 -
144 -Apply `<span class="highlight">key term</span>` to important topic terms inside headings and to the first occurrence of each keyword in body text. Use it sparingly — never wrap whole sentences or wrap text inside `href`, `src`, `alt`, or other attributes.
145 -
146 -Do not emit `<style>`, `<script>`, `<iframe>`, `<form>`, or inline `style=""` / `class=""` attributes (other than the `highlight` class above).
147 -
148 -If — and only if — the user's prompt explicitly asks for raw/custom HTML, embed code, or a non-standard structure, follow that request instead of these defaults.
149 -PROMPT;
150 -
151 - return apply_filters( 'betterdocs_write_with_ai_system_prompt', $prompt );
152 - }
153 -
154 - public function generate_openai_response( $prompt, $keywords ) {
87 + public function generate_openai_response($prompt, $keywords)
88 + {
155 89 try {
156 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
157 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 2500 );
158 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
90 + $api_key = $this->settings->get('ai_autowrite_api_key', '');
91 + $max_tokens = $this->settings->get('ai_autowrite_max_token', 1500);
159 92
160 93 $api_endpoint = 'https://api.openai.com/v1/chat/completions'; // Update the endpoint based on OpenAI API version
161 94
162 - $request_body = AIHelper::build_openai_payload(
163 - $model,
164 - array(
165 - array(
166 - 'role' => 'system',
167 - 'content' => $this->get_system_prompt()
168 - ),
169 - array(
170 - 'role' => 'user',
171 - 'content' => $prompt
172 - )
173 - ),
174 - $max_tokens,
175 - null,
176 - 'write_with_ai'
177 - );
178 -
179 95 $request_options = array(
180 96 'headers' => array(
181 97 'Content-Type' => 'application/json',
182 - 'Authorization' => 'Bearer ' . $api_key
98 + 'Authorization' => 'Bearer ' . $api_key,
183 99 ),
184 - 'body' => json_encode( $request_body ),
185 - 'timeout' => 300
100 + 'body' => json_encode(array(
101 + 'model' => 'gpt-3.5-turbo', // Add the model parameter here
102 + 'messages' => array(
103 + array('role' => 'system', 'content' => 'You are a helpful assistant who writes documentation for users.'),
104 + array('role' => 'user', 'content' => $prompt),
105 + ),
106 + 'max_tokens' => $max_tokens,
107 +
108 + )),
109 + 'timeout' => 50,
186 110 );
187 111
188 - // GPT-5.5 reasoning can run well past the default limits; give PHP and
189 - // the HTTP call room to finish (still subject to server php-fpm/nginx limits).
190 - if ( function_exists( 'set_time_limit' ) ) {
191 - set_time_limit( 300 ); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- long-running AI generation needs an extended limit; still bounded by server fpm/nginx timeouts.
192 - }
112 + $response = wp_remote_post($api_endpoint, $request_options);
193 113
194 - $response = wp_remote_post( $api_endpoint, $request_options );
195 -
196 - if ( is_wp_error( $response ) ) {
114 + if (is_wp_error($response)) {
197 115 return 'Error: ' . $response->get_error_message();
198 116 } else {
199 - $body = wp_remote_retrieve_body( $response );
117 + $body = wp_remote_retrieve_body($response);
200 118
201 - $data = json_decode( $body, true );
119 + $data = json_decode($body, true);
202 120
203 - if ( ! empty( $data[ 'error' ] ) ) {
204 - return $data[ 'error' ][ 'message' ];
121 + if (!empty($data['error'])) {
122 + return $data['error']['message'];
205 123 }
206 124
207 - return $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ]; // Update this line to get the assistant's message
125 + return $data['choices'][0]['message']['content']; // Update this line to get the assistant's message
208 126 }
209 - } catch ( Exception $error ) {
127 + } catch (Exception $error) {
210 128 return 'Error: ' . $error->getMessage();
211 129 }
212 130 }
213 131
214 - public function generate_openai_response_ai_edit( $prompt ) {
215 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
216 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 2500 );
217 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
218 132
219 - $api_endpoint = 'https://api.openai.com/v1/chat/completions';
220 133
221 - $payload = AIHelper::build_openai_payload(
222 - $model,
223 - array(
224 - array(
225 - 'role' => 'system',
226 - 'content' => $this->get_system_prompt()
227 - ),
228 - array(
229 - 'role' => 'user',
230 - 'content' => $prompt
231 - )
232 - ),
233 - $max_tokens,
234 - null,
235 - 'write_with_ai'
236 - );
237 -
238 - $request_options = array(
239 - 'headers' => array(
240 - 'Content-Type' => 'application/json',
241 - 'Authorization' => 'Bearer ' . $api_key
242 - ),
243 - 'body' => wp_json_encode( $payload ),
244 - 'timeout' => 300
245 - );
246 -
247 - // GPT-5.5 reasoning can run well past the default limits; give PHP and
248 - // the HTTP call room to finish (still subject to server php-fpm/nginx limits).
249 - if ( function_exists( 'set_time_limit' ) ) {
250 - set_time_limit( 300 ); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- long-running AI generation needs an extended limit; still bounded by server fpm/nginx timeouts.
251 - }
252 -
253 - $response = wp_remote_post( $api_endpoint, $request_options );
254 -
255 - if ( is_wp_error( $response ) ) {
256 - return array(
257 - 'success' => false,
258 - 'error' => $response->get_error_message(),
259 - 'model' => $model
260 - );
261 - }
262 -
263 - $body = wp_remote_retrieve_body( $response );
264 - $data = json_decode( $body, true );
265 -
266 - if ( ! empty( $data[ 'error' ] ) ) {
267 - return array(
268 - 'success' => false,
269 - 'error' => isset( $data[ 'error' ][ 'message' ] ) ? $data[ 'error' ][ 'message' ] : 'OpenAI error',
270 - 'model' => $model,
271 - 'raw' => $data
272 - );
273 - }
274 -
275 - $content = isset( $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ] ) ? $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ] : '';
276 - $usage = isset( $data[ 'usage' ] ) && is_array( $data[ 'usage' ] ) ? $data[ 'usage' ] : array();
277 -
278 - return array(
279 - 'success' => true,
280 - 'content' => $content,
281 - 'model' => $model,
282 - 'prompt_tokens' => isset( $usage[ 'prompt_tokens' ] ) ? (int) $usage[ 'prompt_tokens' ] : null,
283 - 'completion_tokens' => isset( $usage[ 'completion_tokens' ] ) ? (int) $usage[ 'completion_tokens' ] : null,
284 - 'total_tokens' => isset( $usage[ 'total_tokens' ] ) ? (int) $usage[ 'total_tokens' ] : null,
285 - 'finish_reason' => isset( $data[ 'choices' ][ 0 ][ 'finish_reason' ] ) ? $data[ 'choices' ][ 0 ][ 'finish_reason' ] : null
286 - );
287 - }
288 -
289 - /**
290 - * Generic chat completion using the Write-with-AI model/token/key settings.
291 - *
292 - * Shared by lightweight, plain-text generators (glossary definitions, FAQ answers)
293 - * that need the same dynamic model as Write with AI / AI Edit but a caller-supplied
294 - * system prompt instead of the doc-authoring HTML prompt. Returns the same structured
295 - * array shape as {@see self::generate_openai_response_ai_edit()}.
296 - *
297 - * @param string $user_prompt The user message.
298 - * @param string $system_prompt Optional system message (omitted when empty).
299 - * @return array { success:bool, content?:string, error?:string, model:string, *_tokens?:int }
300 - */
301 - public function generate_text( $user_prompt, $system_prompt = '' ) {
302 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
303 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 2500 );
304 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
305 -
306 - $messages = array();
307 - if ( $system_prompt !== '' ) {
308 - $messages[] = array(
309 - 'role' => 'system',
310 - 'content' => $system_prompt
311 - );
312 - }
313 - $messages[] = array(
314 - 'role' => 'user',
315 - 'content' => $user_prompt
316 - );
317 -
318 - $api_endpoint = 'https://api.openai.com/v1/chat/completions';
319 -
320 - $payload = AIHelper::build_openai_payload( $model, $messages, $max_tokens, null, 'write_with_ai' );
321 -
322 - $request_options = array(
323 - 'headers' => array(
324 - 'Content-Type' => 'application/json',
325 - 'Authorization' => 'Bearer ' . $api_key
326 - ),
327 - 'body' => wp_json_encode( $payload ),
328 - 'timeout' => 300
329 - );
330 -
331 - // GPT-5.5 reasoning can run well past the default limits; give PHP and
332 - // the HTTP call room to finish (still subject to server php-fpm/nginx limits).
333 - if ( function_exists( 'set_time_limit' ) ) {
334 - set_time_limit( 300 );
335 - }
336 -
337 - $response = wp_remote_post( $api_endpoint, $request_options );
338 -
339 - if ( is_wp_error( $response ) ) {
340 - return array(
341 - 'success' => false,
342 - 'error' => $response->get_error_message(),
343 - 'model' => $model
344 - );
345 - }
346 -
347 - $body = wp_remote_retrieve_body( $response );
348 - $data = json_decode( $body, true );
349 -
350 - if ( ! empty( $data[ 'error' ] ) ) {
351 - return array(
352 - 'success' => false,
353 - 'error' => isset( $data[ 'error' ][ 'message' ] ) ? $data[ 'error' ][ 'message' ] : 'OpenAI error',
354 - 'model' => $model,
355 - 'raw' => $data
356 - );
357 - }
358 -
359 - $content = isset( $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ] ) ? $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ] : '';
360 - $usage = isset( $data[ 'usage' ] ) && is_array( $data[ 'usage' ] ) ? $data[ 'usage' ] : array();
361 -
362 - return array(
363 - 'success' => true,
364 - 'content' => $content,
365 - 'model' => $model,
366 - 'prompt_tokens' => isset( $usage[ 'prompt_tokens' ] ) ? (int) $usage[ 'prompt_tokens' ] : null,
367 - 'completion_tokens' => isset( $usage[ 'completion_tokens' ] ) ? (int) $usage[ 'completion_tokens' ] : null,
368 - 'total_tokens' => isset( $usage[ 'total_tokens' ] ) ? (int) $usage[ 'total_tokens' ] : null,
369 - 'finish_reason' => isset( $data[ 'choices' ][ 0 ][ 'finish_reason' ] ) ? $data[ 'choices' ][ 0 ][ 'finish_reason' ] : null
370 - );
371 - }
372 -
373 - public function generate_openai_content_callback() {
134 + public function generate_openai_content_callback()
135 + {
374 136 // Verify the nonce
375 - $ai_nonce = isset( $_POST['ai_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['ai_nonce'] ) ) : '';
376 - if ( ! wp_verify_nonce( $ai_nonce, 'generate_openai_content_nonce' ) ) {
377 - wp_send_json_error( 'Invalid nonce' );
137 + if (!isset($_POST['ai_nonce']) || !wp_verify_nonce($_POST['ai_nonce'], 'generate_openai_content_nonce')) {
138 + wp_send_json_error('Invalid nonce');
378 139 wp_die();
379 140 }
380 141
381 - if ( ! current_user_can( 'edit_posts' ) ) {
382 - wp_send_json_error( 'Insufficient permissions' );
383 - wp_die();
384 - }
142 + $prompt = sanitize_text_field($_POST['prompt']);
143 + // $num_of_sections = sanitize_text_field($_POST['numOfSections']);
144 + // $num_of_paragraphs = sanitize_text_field($_POST['numOfParagraphs']);
145 + $keywords = sanitize_text_field($_POST['keywords']);
385 146
386 - $prompt = isset( $_POST['prompt'] ) ? sanitize_text_field( wp_unslash( $_POST['prompt'] ) ) : '';
387 - $keywords = isset( $_POST['keywords'] ) ? sanitize_text_field( wp_unslash( $_POST['keywords'] ) ) : '';
147 + $ai_instance = new WriteWithAI($this->settings);
388 148
389 - $ai_instance = new WriteWithAI( $this->settings );
149 + $generated_content = $ai_instance->generate_openai_response($prompt, $keywords);
390 150
391 - $generated_content = $ai_instance->generate_openai_response( $prompt, $keywords );
392 -
393 - // Count a successful generation (skip obvious upstream errors).
394 - if ( is_string( $generated_content ) && $generated_content !== '' && strpos( $generated_content, 'Error:' ) !== 0 ) {
395 - $post_id = isset( $_POST[ 'post_id' ] ) ? intval( $_POST[ 'post_id' ] ) : 0; //phpcs:ignore
396 - AIUsage::record( 'write_with_ai', $post_id );
397 - }
398 -
399 151 // Send the generated content as the AJAX response
400 - wp_send_json_success( $generated_content );
152 + wp_send_json_success($generated_content);
401 153 wp_die();
402 154 }
403 155
404 - public function ai_autowrite_button() {
156 + public function ai_autowrite_button()
157 + {
405 158
406 159 ?>
407 - <script>
408 - var docsTitle;
160 + <script>
161 + var docsTitle;
409 162
410 - function responseMessage(message) {
411 - return `<div class="warning-message">
412 - <span class="dashicons dashicons-warning"></span>
413 - <div class="footer-message">
414 - ${message}
415 - </div>
416 - </div>`;
417 - }
163 + function responseMessage(message) {
164 + return `<div class="warning-message">
165 + <span class="dashicons dashicons-warning"></span>
166 + <div class="footer-message">
167 + ${message}
168 + </div>
169 + </div>`;
170 + }
418 171
419 - function generateArticle(e) {
172 + function generateArticle(e) {
420 173
421 174
422 - const title = document.getElementById('betterdocs-ai-title').value;
423 - const keywords = document.getElementById('betterdocs-ai-keyword').value;
424 - // const sectionOptions = document.getElementById('bd-autowrtite-content-section');
425 - // const numOfSections = sectionOptions.options[sectionOptions.selectedIndex].value;
175 + const title = document.getElementById('betterdocs-ai-title').value;
176 + const keywords = document.getElementById('betterdocs-ai-keyword').value;
177 + // const sectionOptions = document.getElementById('bd-autowrtite-content-section');
178 + // const numOfSections = sectionOptions.options[sectionOptions.selectedIndex].value;
426 179
427 - // const paragraphOptions = document.getElementById('bd-autowrtite-content-paragraph');
428 - // const numOfParagraphs = paragraphOptions.options[paragraphOptions.selectedIndex].value;
180 + // const paragraphOptions = document.getElementById('bd-autowrtite-content-paragraph');
181 + // const numOfParagraphs = paragraphOptions.options[paragraphOptions.selectedIndex].value;
429 182
430 - const contentTextArea = document.getElementById('betterdocs-ai-content');
431 - const docGenerateBtnTxt = document.querySelector('.generate-btn span');
183 + const contentTextArea = document.getElementById('betterdocs-ai-content');
184 + const docGenerateBtnTxt = document.querySelector('.generate-btn span');
432 185
433 - // Add nonce value to the data being sent
434 - const nonce = document.querySelector('input[name="ai_nonce"]').value;
435 - const isOverwrite = document.getElementById('betterdocs-ai-checkbox').checked;
436 - const generateDocLabel = "<?php echo esc_html__( 'Generate Doc', 'betterdocs' ); ?>";
437 - const reGenerateDocLabel = "<?php echo esc_html__( 'Regenerate Doc', 'betterdocs' ); ?>";
186 + // Add nonce value to the data being sent
187 + const nonce = document.querySelector('input[name="ai_nonce"]').value;
188 + const isOverwrite = document.getElementById('betterdocs-ai-checkbox').checked;
189 + const generateDocLabel = "<?php echo esc_html__('Generate Doc', 'betterdocs'); ?>";
190 + const reGenerateDocLabel = "<?php echo esc_html__('Regenerate Doc', 'betterdocs'); ?>";
438 191
439 192
440 - // contentTextArea.value = `Write an article about ${title} in English. The article is organized by the following exact ${numOfSections} headings. Write exact ${numOfParagraphs} number of paragraphs per heading.${keywords} Use Markdown for formatting. Add an introduction and a conclusion. Style: creative. Tone: cheerful.`;
193 + // contentTextArea.value = `Write an article about ${title} in English. The article is organized by the following exact ${numOfSections} headings. Write exact ${numOfParagraphs} number of paragraphs per heading.${keywords} Use Markdown for formatting. Add an introduction and a conclusion. Style: creative. Tone: cheerful.`;
441 194
442 195
443 - // Check if the title is not empty
444 - if (title.trim() !== '' && keywords.trim() !== '') {
445 - e.preventDefault();
196 + // Check if the title is not empty
197 + if (title.trim() !== '' && keywords.trim() !== '') {
198 + e.preventDefault();
446 199
447 - if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
448 - jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
449 - }
200 + if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
201 + jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
202 + }
450 203
451 - docGenerateBtnTxt.innerHTML = "<?php echo esc_html__( 'Generating...', 'betterdocs' ); ?>";
452 - jQuery('.generate-btn').prop('disabled', true);
204 + docGenerateBtnTxt.innerHTML = "<?php echo esc_html__('Generating...', 'betterdocs'); ?>";
205 + jQuery('.generate-btn').prop('disabled', true);
453 206
454 - jQuery.post({
455 - url: ajaxurl, // Make sure ajaxurl is defined in your script
456 - type: 'POST',
457 - data: {
458 - action: 'generate_openai_content',
459 - prompt: document.querySelector('#betterdocs-ai-content').value,
460 - // numOfSections: numOfSections,
461 - // numOfParagraphs: numOfParagraphs,
462 - keywords: keywords,
463 - post_id: (document.getElementById('post_ID') ? document.getElementById('post_ID').value : 0),
464 - ai_nonce: nonce, // Pass the nonce value
465 - },
466 - success: function(response) {
467 - // Update the content in the textarea
207 + jQuery.post({
208 + url: ajaxurl, // Make sure ajaxurl is defined in your script
209 + type: 'POST',
210 + data: {
211 + action: 'generate_openai_content',
212 + prompt: document.querySelector('#betterdocs-ai-content').value,
213 + // numOfSections: numOfSections,
214 + // numOfParagraphs: numOfParagraphs,
215 + keywords: keywords,
216 + ai_nonce: nonce, // Pass the nonce value
217 + },
218 + success: function(response) {
219 + // Update the content in the textarea
468 220
469 - if (response.success && (typeof response.data === 'string')) {
470 - docGenerateBtnTxt.innerHTML = "<?php echo esc_html__( 'Generated', 'betterdocs' ); ?>";
471 - setTimeout(() => {
472 - insertContentToEditor(title, response.data, isOverwrite, keywords);
473 - docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
474 - jQuery('.generate-btn').removeAttr('disabled');
475 - }, 2000);
476 - } else {
477 - // alert(response.data.message);
478 - jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
479 - jQuery('#betterdocs-ai-error-message').html(responseMessage(response.data.message));
480 - docGenerateBtnTxt.innerHTML = generateDocLabel;
481 - jQuery('.generate-btn').removeAttr('disabled');
221 + if (response.success && (typeof response.data === 'string')) {
222 + docGenerateBtnTxt.innerHTML = "<?php echo esc_html__('Generated', 'betterdocs'); ?>";
223 + setTimeout(() => {
224 + insertContentToEditor(title, response.data, isOverwrite, keywords);
225 + docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
226 + jQuery('.generate-btn').removeAttr('disabled');
482 227
483 - }
484 - },
485 - error: function(jqXHR, textStatus, errorThrown) {
486 - console.error(jqXHR, textStatus, errorThrown);
228 + // console.log(jQuery('.betterdocs-ai-autowrite-form-container').data('new-doc-page'));
487 229
488 - // Reset the UI so a slow/failed request never leaves a permanent "Generating...".
489 - var timedOut = ( textStatus === 'timeout' ) || ( jqXHR && jqXHR.status === 504 ) || ( jqXHR && jqXHR.status === 0 );
490 - var errMessage = timedOut
491 - ? "<?php echo esc_html__( 'The request timed out before a response came back. The AI may still have generated content on the server — try again, or pick a faster model / lower the token limit.', 'betterdocs' ); ?>"
492 - : "<?php echo esc_html__( 'Something went wrong while generating. Please try again.', 'betterdocs' ); ?>";
230 + // if(jQuery('.betterdocs-ai-autowrite-form-container')?.data('new-doc-page')) {
231 + // docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
232 + // }
233 + }, 2000);
234 + } else {
235 + // alert(response.data.message);
236 + jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
237 + jQuery('#betterdocs-ai-error-message').html(responseMessage(response.data.message));
238 + docGenerateBtnTxt.innerHTML = generateDocLabel;
239 + jQuery('.generate-btn').removeAttr('disabled');
493 240
494 - jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
495 - jQuery('#betterdocs-ai-error-message').html(responseMessage(errMessage));
496 - docGenerateBtnTxt.innerHTML = generateDocLabel;
497 - jQuery('.generate-btn').removeAttr('disabled');
498 - },
499 - });
241 + }
242 + },
243 + error: function(error) {
244 + console.error(error);
245 + },
246 + });
500 247
501 - }
502 - }
248 + }
249 + }
503 250
504 - // Function to update the textarea
505 - function updateTextarea() {
506 - const title = document.getElementById('betterdocs-ai-title').value;
507 - const keywords = document.getElementById('betterdocs-ai-keyword').value;
508 - const sectionOptions = document.getElementById('bd-autowrtite-content-section');
509 - let language = 'English';
251 + // Function to update the textarea
252 + function updateTextarea() {
253 + const title = document.getElementById('betterdocs-ai-title').value;
254 + const keywords = document.getElementById('betterdocs-ai-keyword').value;
255 + const sectionOptions = document.getElementById('bd-autowrtite-content-section');
256 + let language = 'English';
510 257
511 - if (language === '') {
512 - language = 'English';
513 - }
258 + if (language === '') {
259 + language = 'English';
260 + }
514 261
515 - let keywordsText = keywords !== '' ? ` and incorporate the keywords: ${keywords}` : '';
262 + let keywordsText = keywords !== '' ? ` and incorporate the keywords: ${keywords}` : '';
516 263
517 - const contentTextArea = document.getElementById('betterdocs-ai-content');
264 + const contentTextArea = document.getElementById('betterdocs-ai-content');
518 265
519 - if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
520 - jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
521 - }
266 + if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
267 + jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
268 + }
522 269
523 - contentTextArea.value = `Write documentation for '${title}'. Cover these topics in depth: ${keywords}. Use headings, paragraphs, lists, links, code blocks, and tables wherever they help the reader. Follow the output-format rules in the system instructions.`;
524 - }
270 + contentTextArea.value = `Generate a documentation using HTML heading tags for '${title}'. Include relevant details on ${keywords} in the documentation. Ensure all content is enclosed with <p> tags and apply a <span> tag with the class 'highlight' to headings and topic tags for emphasis.`;
271 + }
525 272
526 - function convertMarkdownToHTML(markdownContent) {
527 - // Simple Markdown to HTML conversion (you may need to enhance this based on your needs)
528 - const htmlContent = markdownContent
529 - .replace(/^# (.+)$/gm, '<h1>$1</h1>')
530 - .replace(/^## (.+)$/gm, '<h2>$1</h2>')
531 - .replace(/^### (.+)$/gm, '<h3>$1</h3>')
532 - .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
533 - .replace(/\*(.+?)\*/g, '<em>$1</em>');
273 + function convertMarkdownToHTML(markdownContent) {
274 + // Simple Markdown to HTML conversion (you may need to enhance this based on your needs)
275 + const htmlContent = markdownContent
276 + .replace(/^# (.+)$/gm, '<h1>$1</h1>')
277 + .replace(/^## (.+)$/gm, '<h2>$1</h2>')
278 + .replace(/^### (.+)$/gm, '<h3>$1</h3>')
279 + .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
280 + .replace(/\*(.+?)\*/g, '<em>$1</em>');
534 281
535 - return htmlContent;
536 - }
282 + return htmlContent;
283 + }
537 284
538 - function replaceHeadingTitle(content, title, overviewTitle) {
539 - let regex = new RegExp(title, 'g');
540 - let updateContent = content.replace(regex, overviewTitle);
541 - return updateContent;
542 - }
285 + function replaceHeadingTitle(content, title, overviewTitle) {
286 + let regex = new RegExp(title, 'g');
287 + let updateContent = content.replace(regex, overviewTitle);
288 + return updateContent;
289 + }
543 290
544 - function removeFirstHeading(htmlString) {
545 - var newDiv = document.createElement('div');
546 - newDiv.innerHTML = htmlString;
547 - var firstHeading = newDiv.querySelector('h1');
548 - if (firstHeading) {
549 - firstHeading.parentNode.removeChild(firstHeading);
550 - }
551 - return newDiv.innerHTML;
552 - }
291 + function removeFirstHeading(htmlString) {
292 + var newDiv = document.createElement('div');
293 + newDiv.innerHTML = htmlString;
294 + var firstHeading = newDiv.querySelector('h1');
295 + if (firstHeading) {
296 + firstHeading.parentNode.removeChild(firstHeading);
297 + }
298 + return newDiv.innerHTML;
299 + }
553 300
554 301
555 - function escapeHtml(str) {
556 - return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
557 - }
302 + function wrapwithHeighlight(inputString, keywords) {
303 + let modifiedString = inputString.replace(/<(h\d)(.*?)>(.*?)<\/\1>/g, '<$1$2><span class="highlight">$3</span></$1>');
558 304
559 - function escapeRegex(str) {
560 - return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
561 - }
305 + const keywordArray = keywords.split(',').map(keyword => keyword.trim());
562 306
563 - function stripCodeFences(htmlString) {
564 - if (!htmlString) {
565 - return '';
566 - }
567 - return htmlString
568 - .replace(/^\s*```(?:html|HTML)?\s*\n?/, '')
569 - .replace(/\n?\s*```\s*$/, '');
570 - }
307 + keywordArray.forEach(keyword => {
308 + modifiedString = modifiedString.replace(new RegExp(`\\b(${keyword})\\b`, 'gi'), '<span class="highlight">$1</span>');
309 + });
571 310
572 - function wrapwithHeighlight(inputString, keywords) {
573 - if (!inputString) {
574 - return '';
575 - }
311 + return modifiedString;
312 + }
576 313
577 - const container = document.createElement('div');
578 - container.innerHTML = inputString;
314 + function getBodyContent(htmlString) {
315 + var match = htmlString.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
579 316
580 - // Wrap each heading's visible text with the highlight span (skip if already present)
581 - container.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(function (heading) {
582 - if (heading.querySelector('.highlight')) {
583 - return;
584 - }
585 - const text = heading.textContent;
586 - if (!text || !text.trim()) {
587 - return;
588 - }
589 - heading.innerHTML = '<span class="highlight">' + escapeHtml(text) + '</span>';
590 - });
317 + console.log(match[1].replace(/<p>\s+/g, '<p>'));
591 318
592 - // Wrap keywords only inside text nodes — never inside attributes, code, or existing highlights
593 - const keywordList = (keywords || '')
594 - .split(',')
595 - .map(function (k) { return k.trim(); })
596 - .filter(Boolean);
319 + return match ? match[1].replace(/<p>\s+/g, '<p>') : '';
320 + }
597 321
598 - if (keywordList.length) {
599 - const pattern = new RegExp('\\b(' + keywordList.map(escapeRegex).join('|') + ')\\b', 'gi');
600 - const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, {
601 - acceptNode: function (node) {
602 - let parent = node.parentNode;
603 - while (parent && parent !== container) {
604 - if (parent.nodeType === 1) {
605 - const tag = parent.tagName.toLowerCase();
606 - if (tag === 'code' || tag === 'pre') {
607 - return NodeFilter.FILTER_REJECT;
608 - }
609 - if (parent.classList && parent.classList.contains('highlight')) {
610 - return NodeFilter.FILTER_REJECT;
611 - }
612 - }
613 - parent = parent.parentNode;
614 - }
615 - return NodeFilter.FILTER_ACCEPT;
616 - }
617 - });
618 322
619 - const textNodes = [];
620 - let current;
621 - while ((current = walker.nextNode())) {
622 - textNodes.push(current);
623 - }
323 + function insertContentToEditor(title, htmlContent, isOverwrite, keywords) {
624 324
625 - textNodes.forEach(function (textNode) {
626 - pattern.lastIndex = 0;
627 - if (!pattern.test(textNode.nodeValue)) {
628 - return;
629 - }
630 - pattern.lastIndex = 0;
631 - const fragmentHost = document.createElement('span');
632 - fragmentHost.innerHTML = escapeHtml(textNode.nodeValue).replace(pattern, '<span class="highlight">$1</span>');
633 - const parent = textNode.parentNode;
634 - while (fragmentHost.firstChild) {
635 - parent.insertBefore(fragmentHost.firstChild, textNode);
636 - }
637 - parent.removeChild(textNode);
638 - });
639 - }
325 + const {
326 + dispatch,
327 + select
328 + } = wp.data;
640 329
641 - return container.innerHTML;
642 - }
330 + htmlContent = getBodyContent(htmlContent);
331 + htmlContent = removeFirstHeading(htmlContent);
332 + htmlContent = wrapwithHeighlight(htmlContent, keywords);
333 + const isPostContent = `<?php echo isset($_GET['post']) ? get_the_content($_GET['post']) : ''; ?>`;
643 334
644 - function getBodyContent(htmlString) {
645 - if (!htmlString) {
646 - return '';
647 - }
648 - const cleaned = stripCodeFences(htmlString);
649 - const match = cleaned.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
650 - if (match) {
651 - return match[1].replace(/<p>\s+/g, '<p>');
652 - }
653 - return cleaned;
654 - }
335 + const blocks = wp.blocks.rawHandler({
336 + HTML: htmlContent
337 + });
655 338
339 + dispatch('core/editor').editPost({
340 + title: title,
341 + });
656 342
343 + const selectedBlockClientId = select('core/block-editor').getSelectedBlockClientId();
657 344
658 - function insertContentToEditor(title, htmlContent, isOverwrite, keywords) {
345 + const allBlocks = select('core/block-editor').getBlocks();
659 346
660 - const {
661 - dispatch,
662 - select
663 - } = wp.data;
347 + if (isOverwrite || isPostContent === '') {
664 348
665 - htmlContent = getBodyContent(htmlContent);
666 - htmlContent = removeFirstHeading(htmlContent);
667 - htmlContent = wrapwithHeighlight(htmlContent, keywords);
668 - const isPostContent = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_content( absint( wp_unslash( $_GET['post'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
349 + allBlocks.forEach((block) => {
350 + dispatch('core/block-editor').removeBlock(block.clientId);
351 + });
352 + dispatch('core/block-editor').insertBlocks(blocks);
669 353
670 - const blocks = wp.blocks.rawHandler({
671 - HTML: htmlContent
672 - });
354 + } else if (selectedBlockClientId) {
355 + const selectedIndex = select('core/block-editor').getBlockIndex(selectedBlockClientId);
356 + dispatch('core/block-editor').insertBlocks(blocks, selectedIndex + 1);
357 + } else {
358 + dispatch('core/block-editor').insertBlocks(blocks);
359 + }
673 360
674 - dispatch('core/editor').editPost({
675 - title: title,
676 - });
361 + closeWriteWithAIForm('afterInsertContent');
362 + }
677 363
678 - const selectedBlockClientId = select('core/block-editor').getSelectedBlockClientId();
364 + function closeWriteWithAIForm(after) {
365 + jQuery('.betterdocs-ai-autowrite-form-container').addClass('hidden');
366 + jQuery('#betterdocs-ai-autowrite-form-container-overlay').addClass('hidden');
367 + jQuery('.betterdocs-ai-button').addClass('regenerate-btn');
368 + }
679 369
680 - const allBlocks = select('core/block-editor').getBlocks();
681 370
682 - if (isOverwrite || isPostContent === '') {
371 + document.addEventListener('DOMContentLoaded', function() {
683 372
684 - allBlocks.forEach((block) => {
685 - dispatch('core/block-editor').removeBlock(block.clientId);
686 - });
687 - dispatch('core/block-editor').insertBlocks(blocks);
373 + // Subscribe to changes in the editor state
374 + let previousDocsTitle = '';
688 375
689 - } else if (selectedBlockClientId) {
690 - const selectedIndex = select('core/block-editor').getBlockIndex(selectedBlockClientId);
691 - dispatch('core/block-editor').insertBlocks(blocks, selectedIndex + 1);
692 - } else {
693 - dispatch('core/block-editor').insertBlocks(blocks);
694 - }
376 + wp.data.subscribe(() => {
377 + // Get the updated post title
378 + // const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
695 379
696 - closeWriteWithAIForm('afterInsertContent');
697 - }
380 + const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
698 381
699 - function closeWriteWithAIForm(after) {
700 - jQuery('.betterdocs-ai-autowrite-form-container').addClass('hidden');
701 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').addClass('hidden');
702 - jQuery('.betterdocs-ai-button').addClass('regenerate-btn');
703 - }
382 + // Check if the title has changed
383 + if (docsTitle !== previousDocsTitle) {
384 + let currentKeywords = jQuery('#betterdocs-ai-keyword').val();
385 + if (!currentKeywords) {
386 + currentKeywords = '{Documentation Keywords}';
387 + }
388 + const currentPrompt = `Generate documentation using HTML heading tags for '${docsTitle?docsTitle:'{Documentation title}'}'. Include relevant details on ${currentKeywords} in the documentation. Ensure all content is enclosed with <p> tags and apply a <span> tag with the class 'highlight' to headings and topic tags for emphasis.`;
389 + jQuery('#betterdocs-ai-content').val(currentPrompt);
704 390
391 + jQuery('#betterdocs-ai-title').val(docsTitle);
705 392
706 - document.addEventListener('DOMContentLoaded', function() {
393 + previousDocsTitle = docsTitle;
394 + }
707 395
708 - // Subscribe to changes in the editor state
709 - let previousDocsTitle = '';
710 396
711 - wp.data.subscribe(() => {
712 - // Get the updated post title
713 - // const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
397 + });
398 + });
714 399
715 - const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
716 400
717 - // Check if the title has changed
718 - if (docsTitle !== previousDocsTitle) {
719 - let currentKeywords = jQuery('#betterdocs-ai-keyword').val();
720 - if (!currentKeywords) {
721 - currentKeywords = '{Documentation Keywords}';
722 - }
723 - const currentPrompt = `Write documentation for '${docsTitle?docsTitle:'{Documentation title}'}'. Cover these topics in depth: ${currentKeywords}. Use headings, paragraphs, lists, links, code blocks, and tables wherever they help the reader. Follow the output-format rules in the system instructions.`;
724 - jQuery('#betterdocs-ai-content').val(currentPrompt);
401 + // This example assumes that this code is executed when your script is loaded.
402 + // You may want to place it within the appropriate context in your application.
725 403
726 - jQuery('#betterdocs-ai-title').val(docsTitle);
727 404
728 - previousDocsTitle = docsTitle;
729 - }
405 + function writeWithAIForm() {
730 406
407 + let title = `<?php echo isset($_GET['post']) ? get_the_title($_GET['post']) : ''; ?>`;
408 + if (docsTitle) {
409 + title = docsTitle;
410 + }
731 411
732 - });
733 - });
412 + const promtTitle = `<?php echo isset($_GET['post']) ? get_the_title($_GET['post']) : '{Documentation Title}'; ?>`;
413 + const titlePlaceholder = "<?php echo esc_attr__('Enter a descriptive title for your documentation.', 'betterdocs'); ?>";
414 + const keywords = "<?php echo esc_attr('{Documentation Keywords}'); ?>";
415 + const keywordsPlaceholder = "<?php echo esc_attr__('Add keywords to generate precise & relevant documentation (comma-separated).', 'betterdocs'); ?>";
416 + const language = "<?php echo esc_attr('English'); ?>";
417 + const titleLabel = "<?php echo esc_html__('Documentation Title:', 'betterdocs'); ?>";
418 + const keywordLabel = "<?php echo esc_html__('Keywords:', 'betterdocs'); ?>";
419 + const secLabel = "<?php echo esc_html__('# of Sections:', 'betterdocs'); ?>";
420 + const paraLabel = "<?php echo esc_html__('# of Paragraph Per Section: ', 'betterdocs'); ?>";
421 + const langLabel = "<?php echo esc_html__('Language:', 'betterdocs'); ?>";
422 + const promtLabel = "<?php echo esc_html__('Prompt:', 'betterdocs'); ?>";
423 + const promtBtnLabel = "<?php echo esc_html__('Generate Prompt', 'betterdocs'); ?>";
424 + let promtArticleLabel = "<?php echo esc_html__('Generate Doc', 'betterdocs'); ?>";
425 + const checkboxLabel = "<?php echo esc_html__('Overwrite your existing Doc:', 'betterdocs'); ?>";
426 + const nonce = "<?php echo esc_attr(wp_create_nonce('generate_openai_content_nonce')); ?>";
734 427
735 -
736 - // This example assumes that this code is executed when your script is loaded.
737 - // You may want to place it within the appropriate context in your application.
738 -
739 -
740 - function writeWithAIForm() {
741 -
742 - let title = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_title( absint( wp_unslash( $_GET['post'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
743 - if (docsTitle) {
744 - title = docsTitle;
745 - }
746 -
747 - const promtTitle = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_title( absint( wp_unslash( $_GET['post'] ) ) ) ) : '{Documentation Title}'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
748 - const titlePlaceholder = "<?php echo esc_attr__( 'Enter a descriptive title for your documentation.', 'betterdocs' ); ?>";
749 - const keywords = "<?php echo esc_attr( '{Documentation Keywords}' ); ?>";
750 - const keywordsPlaceholder = "<?php echo esc_attr__( 'Add keywords to generate precise & relevant documentation (comma-separated).', 'betterdocs' ); ?>";
751 - const language = "<?php echo esc_attr( 'English' ); ?>";
752 - const titleLabel = "<?php echo esc_html__( 'Documentation Title:', 'betterdocs' ); ?>";
753 - const keywordLabel = "<?php echo esc_html__( 'Keywords:', 'betterdocs' ); ?>";
754 - const secLabel = "<?php echo esc_html__( '# of Sections:', 'betterdocs' ); ?>";
755 - const paraLabel = "<?php echo esc_html__( '# of Paragraph Per Section: ', 'betterdocs' ); ?>";
756 - const langLabel = "<?php echo esc_html__( 'Language:', 'betterdocs' ); ?>";
757 - const promtLabel = "<?php echo esc_html__( 'Prompt:', 'betterdocs' ); ?>";
758 - const promtBtnLabel = "<?php echo esc_html__( 'Generate Prompt', 'betterdocs' ); ?>";
759 - let promtArticleLabel = "<?php echo esc_html__( 'Generate Doc', 'betterdocs' ); ?>";
760 - const checkboxLabel = "<?php echo esc_html__( 'Overwrite your existing Doc:', 'betterdocs' ); ?>";
761 - const nonce = "<?php echo esc_attr( wp_create_nonce( 'generate_openai_content_nonce' ) ); ?>";
762 -
763 - <?php
764 - $is_valid = $this->get_api_key();
765 - $disable_field = 'disabled-input-field';
766 - if ( $this->get_api_key() ) {
767 - $disable_field = '';
768 - }
428 + <?php $is_valid = $this->get_api_key();
429 + $disable_field = 'disabled-input-field';
430 + if ($this->get_api_key()) {
431 + $disable_field = '';
432 + }
769 433 ?>
770 434
771 - let hiddenClass = 'hidden';
772 - let newDocPageAtt = 'data-new-doc-page="true"';
773 - const isPostContent = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_content( absint( wp_unslash( $_GET['post'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
435 + let hiddenClass = 'hidden';
436 + let newDocPageAtt = 'data-new-doc-page="true"';
437 + const isPostContent = `<?php echo isset($_GET['post']) ? get_the_content($_GET['post']) : ''; ?>`;
774 438
775 - if (isPostContent !== '') {
776 - hiddenClass = '';
777 - newDocPageAtt = '';
778 - }
439 + if (isPostContent !== '') {
440 + hiddenClass = '';
441 + newDocPageAtt = '';
442 + }
779 443
780 444
781 - // const prompt = `Make a knowledge base article with html heading tags about [${title}] in [${language}]. Here is some topic to describe the article: [${keywords}]. and wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
445 + // const prompt = `Make a knowledge base article with html heading tags about [${title}] in [${language}]. Here is some topic to describe the article: [${keywords}]. and wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
782 446
783 - // const prompt = `Create a details knowledge base article in [${language}] about [${title}] with html heading tags. Here is some topic to describe the article: [${keywords}]. And wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
447 + // const prompt = `Create a details knowledge base article in [${language}] about [${title}] with html heading tags. Here is some topic to describe the article: [${keywords}]. And wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
784 448
785 - const prompt = `Write documentation for '${promtTitle}'. Cover these topics in depth: ${keywords}. Use headings, paragraphs, lists, links, code blocks, and tables wherever they help the reader. Follow the output-format rules in the system instructions.`;
449 + const prompt = `Generate a documentation using HTML heading tags for '${promtTitle}'. Include relevant details on ${keywords} in the documentation. Ensure all content is enclosed with <p> tags and apply a <span> tag with the class 'highlight' to headings and topic tags for emphasis.`;
786 450
787 - const aiIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="-1.5 -1.5 23 23" fill="none"><path d="m9.895 18.861-4.286.371.371-4.286 8.915-8.857a1.429 1.429 0 0 1 2.043 0l1.814 1.829a1.431 1.431 0 0 1 0 2.029l-8.857 8.914ZM1.204 5.674c-.501-.088-.501-.807 0-.894a4.537 4.537 0 0 0 3.654-3.5l.03-.139c.109-.494.814-.499.929-.003l.036.16a4.561 4.561 0 0 0 3.663 3.48c.504.086.504.81 0 .899a4.561 4.561 0 0 0-3.664 3.479l-.037.161c-.112.494-.818.491-.926-.004l-.029-.139a4.537 4.537 0 0 0-3.658-3.5h.003Z" stroke="#fff" stroke-width="1.429" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
451 + const aiIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="21" height="20" viewBox="0 0 21 20" fill="none">
452 + <g clip-path="url(#clip0_2460_1729)">
453 + <path d="M10.3956 18.8608L6.10991 19.2322L6.48134 14.9465L15.3956 6.08936C15.5287 5.95329 15.6876 5.84518 15.863 5.77137C16.0384 5.69756 16.2268 5.65954 16.4171 5.65954C16.6074 5.65954 16.7957 5.69756 16.9711 5.77137C17.1466 5.84518 17.3054 5.95329 17.4385 6.08936L19.2528 7.91793C19.3865 8.05083 19.4926 8.20886 19.565 8.38293C19.6375 8.55701 19.6747 8.74368 19.6747 8.93221C19.6747 9.12075 19.6375 9.30742 19.565 9.48149C19.4926 9.65557 19.3865 9.8136 19.2528 9.9465L10.3956 18.8608ZM1.7042 5.67507C1.20277 5.58793 1.20277 4.86793 1.7042 4.78079C2.59203 4.62626 3.41374 4.21085 4.06456 3.58751C4.71538 2.96417 5.16583 2.16113 5.35848 1.28079L5.38848 1.14221C5.49705 0.647929 6.20277 0.643643 6.31705 1.13936L6.35277 1.29936C6.55248 2.17579 7.0067 2.97367 7.65837 3.59281C8.31005 4.21195 9.13013 4.62475 10.0156 4.77936C10.5199 4.86507 10.5199 5.58936 10.0156 5.67793C9.13005 5.83218 8.3098 6.24465 7.65787 6.86354C7.00594 7.48243 6.5514 8.28014 6.35134 9.1565L6.3142 9.31793C6.20134 9.81221 5.49563 9.80936 5.38705 9.31364L5.35848 9.17507C5.16564 8.29433 4.71476 7.49102 4.06339 6.86764C3.41202 6.24426 2.58969 5.82908 1.70134 5.67507H1.7042Z" stroke="white" stroke-width="1.42857" stroke-linecap="round" stroke-linejoin="round"/>
454 + </g>
455 + <defs>
456 + <clipPath id="clip0_2460_1729">
457 + <rect width="20" height="20" fill="white" transform="translate(0.5)"/>
458 + </clipPath>
459 + </defs>
460 + </svg>`;
788 461
789 462
790 463
791 - return `
792 - <div class="betterdocs-ai-autowrite-form-container hidden" ${newDocPageAtt}>
793 - <div class="betterdocs-ai-autowrite-form-content">
794 - <div class="betterdocs-ai-autowrite-top-part">
795 - <div class="autowrite-heading">
796 - <span class="autowrite-icon" style="--bd-icon-tint: rgb(127, 86, 217); --bd-icon-tint-rgb: 127, 86, 217; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; flex-shrink:0; border-radius:9px; color:rgb(127, 86, 217); background:rgba(127, 86, 217, 0.2);">
797 - <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="-1.5 -1.5 23 23"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.429" d="m9.895 18.861-4.286.371.371-4.286 8.915-8.857a1.43 1.43 0 0 1 2.043 0l1.814 1.829a1.43 1.43 0 0 1 0 2.029zM1.204 5.674c-.501-.088-.501-.807 0-.894a4.54 4.54 0 0 0 3.654-3.5l.03-.139c.109-.494.814-.499.929-.003l.036.16a4.56 4.56 0 0 0 3.663 3.48c.504.086.504.81 0 .899a4.56 4.56 0 0 0-3.664 3.479l-.037.161c-.112.494-.818.491-.926-.004l-.029-.139a4.54 4.54 0 0 0-3.658-3.5h.003Z"></path></svg>
798 - </span>
799 - <h1 style="margin:0; font-family:'IBM Plex Sans',sans-serif; font-size:18px; font-weight:600; line-height:1.3; color:#101828;"><?php echo esc_html__( 'Write Documentation with BetterDocs AI', 'betterdocs' ); ?></h1>
464 + return `
465 + <div class="betterdocs-ai-autowrite-form-container hidden" ${newDocPageAtt}>
466 + <div class="betterdocs-ai-autowrite-form-content">
467 + <div class="betterdocs-ai-autowrite-top-part">
468 + <div class="autowrite-heading">
469 + <span class="autowrite-icon">
470 + <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
471 + <g clip-path="url(#clip0_2453_20882)">
472 + <path d="M15.8322 30.1765L8.97508 30.7708L9.56936 23.9136L23.8322 9.74219C24.0451 9.52448 24.2993 9.3515 24.58 9.23341C24.8606 9.11531 25.162 9.05447 25.4665 9.05447C25.771 9.05447 26.0724 9.11531 26.3531 9.23341C26.6337 9.3515 26.8879 9.52448 27.1008 9.74219L30.0037 12.6679C30.2176 12.8805 30.3874 13.1334 30.5033 13.4119C30.6192 13.6904 30.6788 13.9891 30.6788 14.2908C30.6788 14.5924 30.6192 14.8911 30.5033 15.1696C30.3874 15.4481 30.2176 15.701 30.0037 15.9136L15.8322 30.1765ZM1.92593 9.07933C1.12365 8.9399 1.12365 7.7879 1.92593 7.64848C3.34647 7.40124 4.6612 6.73658 5.70251 5.73923C6.74382 4.74188 7.46455 3.45703 7.77279 2.04848L7.82079 1.82676C7.99451 1.03591 9.12365 1.02905 9.30651 1.82219L9.36365 2.07819C9.68319 3.48048 10.4099 4.75709 11.4526 5.74772C12.4953 6.73834 13.8074 7.39881 15.2242 7.64619C16.0311 7.78333 16.0311 8.94219 15.2242 9.0839C13.8073 9.33071 12.4949 9.99066 11.4518 10.9809C10.4087 11.9711 9.68146 13.2474 9.36136 14.6496L9.30193 14.9079C9.12136 15.6988 7.99222 15.6942 7.81851 14.901L7.77279 14.6793C7.46424 13.2702 6.74284 11.9849 5.70064 10.9874C4.65845 9.99003 3.34273 9.32574 1.92136 9.07933H1.92593Z" stroke="#E31B54" stroke-width="2.28571" stroke-linecap="round" stroke-linejoin="round"/>
473 + </g>
474 + <defs>
475 + <clipPath id="clip0_2453_20882">
476 + <rect width="32" height="32" fill="white"/>
477 + </clipPath>
478 + </defs>
479 + </svg>
480 + </span>
481 + <h1><?php echo esc_html__('Write Documentation with BetterDocs AI', 'betterdocs'); ?></h1>
800 482
801 - </div>
802 - <div class="autowrite-subheadding">
803 - <p style="margin:8px 0 0; font-family:'IBM Plex Sans',sans-serif; font-size:14px; font-weight:400; line-height:1.4; color:#667085;"><?php echo esc_html__( 'Generate documentation effortlessly with BetterDocs AI. Simply input your doc title, keywords, prompt and let the system automatically generate comprehensive documentation tailored to your needs.', 'betterdocs' ); ?></p>
804 - </div>
483 + </div>
484 + <div class="autowrite-subheadding">
485 + <p><?php echo esc_html__('Generate documentation effortlessly with BetterDocs AI. Simply input your doc title, keywords, prompt and let the system automatically generate comprehensive documentation tailored to your needs.', 'betterdocs'); ?></p>
486 + </div>
805 487
806 - <?php if ( empty( $this->get_api_key() ) ): ?>
807 - <div id="betterdocs-ai-message">
808 - <div class="warning-message">
809 - <span class="dashicons dashicons-warning"></span>
810 - <div>
811 - <?php echo wp_kses_post( 'Please Insert your <a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=betterdocs-settings#betterdocs-ai' ) ) . '">OpenAI API Key</a> to use this Write with AI feature.', 'betterdocs' ); ?>
812 - </div>
813 - </div>
488 + <?php if (empty($this->get_api_key())) : ?>
489 + <div id="betterdocs-ai-message">
490 + <div class="warning-message">
491 + <span class="dashicons dashicons-warning"></span>
492 + <div>
493 + <?php echo wp_kses_post('Please Insert your <a target="_blank" href="' . esc_url(admin_url('admin.php?page=betterdocs-settings&tab=tab-ai-autowrite')) . '">OpenAI API Key</a> to use this Write with AI feature.', 'betterdocs'); ?>
494 + </div>
495 + </div>
814 496
815 - </div>
816 - <?php endif; ?>
497 + </div>
498 + <?php endif; ?>
817 499
818 - <div class="form-group hidden">
819 - <div id="betterdocs-ai-error-message"></div>
820 - </div>
500 + <div class="form-group hidden">
501 + <div id="betterdocs-ai-error-message"></div>
502 + </div>
503 +
504 + </div>
505 + <form id="betterdocs-ai-form" class="<?php echo esc_attr($disable_field); ?>">
506 + <div class="form-inner-content">
507 + <div class="form-group">
508 + <label for="betterdocs-ai-title">${titleLabel}</label>
509 + <input type="text" placeholder="${titlePlaceholder}" id="betterdocs-ai-title" name="betterdocs-ai-title" required value="${title}">
510 + </div>
821 511
822 - </div>
823 - <form id="betterdocs-ai-form" class="<?php echo esc_attr( $disable_field ); ?>">
824 - <div class="form-inner-content">
825 - <div class="form-group">
826 - <label for="betterdocs-ai-title">${titleLabel}</label>
827 - <input type="text" placeholder="${titlePlaceholder}" id="betterdocs-ai-title" name="betterdocs-ai-title" required value="${title}">
828 - </div>
512 + <div class="form-group">
513 + <label for="betterdocs-ai-keyword">${keywordLabel}</label>
514 + <input type="text" placeholder="${keywordsPlaceholder}" id="betterdocs-ai-keyword" name="betterdocs-ai-keyword" required>
515 + </div>
829 516
830 - <div class="form-group">
831 - <label for="betterdocs-ai-keyword">${keywordLabel}</label>
832 - <input type="text" placeholder="${keywordsPlaceholder}" id="betterdocs-ai-keyword" name="betterdocs-ai-keyword" required>
833 - </div>
517 + <div class="form-group prompt-field">
518 + <label for="betterdocs-ai-content">${promtLabel}</label>
519 + <textarea id="betterdocs-ai-content" name="betterdocs-ai-content" rows="6" required>${prompt}</textarea>
520 + <p class="input-description"><?php echo esc_html__('Ensure you include a clear and detailed prompt to receive the desired output. Follow the guidelines provided for the best results.', 'betterdocs'); ?></p>
521 + </div>
522 + <div class="betterdocs-ai-checkbox-field ${hiddenClass}">
523 + <div class="form-group">
524 + <div class="checkbox-field-label">
525 + <label for="betterdocs-ai-checkbox">${checkboxLabel}</label>
526 + <p class="input-description"><?php echo esc_html__('Overwrite the existing doc with the AI Generated Content. If Disabled, new AI Generated content will be added in the section you are currently editing.', 'betterdocs'); ?></p>
527 + </div>
528 +
529 + <div class="checkbox-input-field">
530 + <input type="checkbox" id="betterdocs-ai-checkbox" name="betterdocs-ai-checkbox" data-overwrite="false">
531 + <label for="betterdocs-ai-checkbox" class="toggle-label"></label>
532 + </div>
533 + </div>
534 + </div>
834 535
835 - <div class="form-group prompt-field">
836 - <label for="betterdocs-ai-content">${promtLabel}</label>
837 - <textarea id="betterdocs-ai-content" name="betterdocs-ai-content" rows="6" required>${prompt}</textarea>
838 - <p class="input-description"><?php echo esc_html__( 'Ensure you include a clear and detailed prompt to receive the desired output. Follow the guidelines provided for the best results.', 'betterdocs' ); ?></p>
839 - </div>
840 - <div class="betterdocs-ai-checkbox-field ${hiddenClass}">
841 - <div class="form-group">
842 - <div class="checkbox-field-label">
843 - <label for="betterdocs-ai-checkbox">${checkboxLabel}</label>
844 - <p class="input-description"><?php echo esc_html__( 'Overwrite the existing doc with the AI Generated Content. If Disabled, new AI Generated content will be added in the section you are currently editing.', 'betterdocs' ); ?></p>
845 - </div>
536 + <input type="hidden" name="ai_nonce" value="${nonce}" />
537 + </div>
538 + <div class="generate-button-container">
539 + <button type="submit" class="generate-btn" onclick="generateArticle(event)">
540 + ${aiIcon} <span>${promtArticleLabel}</span>
541 + </button>
542 + </div>
543 + </form>
544 + </div>
846 545
847 - <div class="checkbox-input-field">
848 - <input type="checkbox" id="betterdocs-ai-checkbox" name="betterdocs-ai-checkbox" data-overwrite="false">
849 - <label for="betterdocs-ai-checkbox" class="toggle-label"></label>
850 - </div>
851 - </div>
852 - </div>
546 + <div class="bd-close-button" onclick="closeWriteWithAIForm('afterClosedClicked')">✕</div>
547 + </div>
548 +
549 + <div id="betterdocs-ai-autowrite-form-container-overlay" class="hidden"></div>
550 + `;
551 + }
853 552
854 - <input type="hidden" name="ai_nonce" value="${nonce}" />
855 - </div>
856 - <div class="generate-button-container">
857 - <button type="submit" class="generate-btn" onclick="generateArticle(event)">
858 - ${aiIcon} <span>${promtArticleLabel}</span>
859 - </button>
860 - </div>
861 - </form>
862 - </div>
553 + jQuery(document).on('click', '.regenerate-btn', function() {
554 + jQuery('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
555 + jQuery('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
556 + });
863 557
864 - <div class="bd-close-button" onclick="closeWriteWithAIForm('afterClosedClicked')"><svg width="15" height="14" viewBox="0 0 15 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.69687 14L0.296875 12.6L5.89687 7L0.296875 1.4L1.69687 0L7.29688 5.6L12.8969 0L14.2969 1.4L8.69688 7L14.2969 12.6L12.8969 14L7.29688 8.4L1.69687 14Z" fill="currentColor"/></svg></div>
865 - </div>
558 + jQuery(document).ready(function($) {
559 + // Check if we are in the Edit Post screen
560 + if ($('.block-editor-page').length > 0) {
561 + const bdAIButton = $(`<div class="betterdocs-ai-button-container">
562 + <button class="betterdocs-ai-button">
563 + <img src="<?php echo esc_url(BETTERDOCS_ABSURL . 'assets/admin/images/betterdocs-icon-white.png'); ?>" alt="<?php echo esc_attr__('betterdocs icon', 'embedpress'); ?>" />
564 + <span><?php echo esc_html__('Write with AI', 'embedpress'); ?></span>
565 + </button>
566 + </div>`);
567 + const closeBtn = $('bd-close-button');
866 568
867 - <div id="betterdocs-ai-autowrite-form-container-overlay" class="hidden"></div>
868 - `;
869 - }
569 + const formHtml = writeWithAIForm();
570 + $(formHtml).addClass('hidden');
870 571
871 - jQuery(document).on('click', '.regenerate-btn', function() {
872 - jQuery('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
873 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
874 - });
572 + $(document).on('click', '.betterdocs-ai-button', function() {
573 + $('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
574 + $('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
575 + });
875 576
876 - jQuery(document).ready(function($) {
877 - // Check if we are in the Edit Post screen
577 + // $(document).on('click', '.betterdocs-ai-button', function() {
578 + if ($('.betterdocs-ai-autowrite-form-container').length < 1) {
579 + $('body').append(formHtml);
878 580
879 - if ($('.block-editor-page').length > 0) {
581 + // Add event listeners to input elements
582 + document.getElementById('betterdocs-ai-title').addEventListener('input', updateTextarea);
583 + document.getElementById('betterdocs-ai-keyword').addEventListener('input', updateTextarea);
584 + // document.getElementById('bd-autowrtite-content-section').addEventListener('change', updateTextarea);
585 + // document.getElementById('bd-autowrtite-content-paragraph').addEventListener('change', updateTextarea);
586 + // document.getElementById('betterdocs-ai-language').addEventListener('input', updateTextarea);
587 + }
588 + // });
589 + const btn = document.createElement('button');
590 + wp.data.subscribe(function() {
591 + setTimeout(() => {
592 + if ($('.edit-post-header__settings').length > 0) {
593 + $('.edit-post-header__settings').prepend(bdAIButton);
594 + }
595 + }, 1);
596 + });
597 + }
880 598
881 - const bdAIButton = $(`<div class="betterdocs-ai-button-container">
882 - <button class="betterdocs-ai-button">
883 - <img src="<?php echo esc_url( BETTERDOCS_ABSURL . 'assets/admin/images/betterdocs-icon-white.png' ); ?>" alt="<?php echo esc_attr__( 'betterdocs icon', 'betterdocs' ); ?>" />
884 - <span><?php echo esc_html__( 'Write with AI', 'betterdocs' ); ?></span>
885 - </button>
886 - </div>`);
599 + $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
600 + closeWriteWithAIForm();
601 + });
602 + });
603 + </script>
887 604
605 + <style>
606 + .hidden {
607 + display: none !important;
608 + }
888 609
889 - const closeBtn = $('bd-close-button');
610 + .disabled-input-field input,
611 + .disabled-input-field textarea,
612 + .disabled-input-field button,
613 + .disabled-input-field label {
614 + pointer-events: none;
615 + opacity: 0.6;
616 + }
890 617
891 - const formHtml = writeWithAIForm();
892 - $(formHtml).addClass('hidden');
618 + .disabled-input-field label {
619 + opacity: 1;
620 + }
893 621
894 - $(document).on('click', '.betterdocs-ai-button', function() {
895 - $('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
896 - $('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
897 - });
622 + .betterdocs-ai-button-container {
623 + margin-left: 10px;
624 + }
898 625
899 - // $(document).on('click', '.betterdocs-ai-button', function() {
900 - if ($('.betterdocs-ai-autowrite-form-container').length < 1) {
901 - $('body').append(formHtml);
626 + .autowrite-icon {
627 + display: flex;
628 + align-items: center;
629 + width: 55px;
630 + height: 55px;
631 + background: #FFE4E8;
632 + justify-content: center;
633 + border-radius: 50px;
634 + }
902 635
903 - // Add event listeners to input elements
904 - document.getElementById('betterdocs-ai-title').addEventListener('input', updateTextarea);
905 - document.getElementById('betterdocs-ai-keyword').addEventListener('input', updateTextarea);
906 - // document.getElementById('bd-autowrtite-content-section').addEventListener('change', updateTextarea);
907 - // document.getElementById('bd-autowrtite-content-paragraph').addEventListener('change', updateTextarea);
908 - // document.getElementById('betterdocs-ai-language').addEventListener('input', updateTextarea);
909 - }
910 - // });
911 - const btn = document.createElement('button');
912 - wp.data.subscribe(function() {
913 - setTimeout(() => {
914 - if ($('.edit-post-header__settings').length > 0) {
915 - $('.edit-post-header__settings').prepend(bdAIButton);
916 - } else if ($('.editor-header__settings').length > 0) {
917 - $('.editor-header__settings').prepend(bdAIButton);
918 - }
636 + .autowrite-icon svg {
637 + width: 28px;
638 + height: 28px;
639 + }
919 640
920 - }, 1);
921 - });
922 - }
641 + .autowrite-heading {
642 + display: flex;
643 + gap: 10px;
644 + align-items: center;
645 + }
923 646
924 - $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
925 - closeWriteWithAIForm();
926 - });
927 - });
928 - </script>
647 + .autowrite-heading h1 {
648 + color: #1D2939;
649 + font-family: 'IBM Plex Sans', sans-serif;
650 + font-size: 24px;
651 + font-style: normal;
652 + font-weight: 500;
653 + line-height: normal;
654 + margin: 0;
655 + }
929 656
930 - <style>
931 - .hidden {
932 - display: none !important;
933 - }
657 + .autowrite-heading p,
658 + form#betterdocs-ai-form p {
659 + margin: 0;
660 + margin-bottom: 24px;
661 + }
934 662
935 - .disabled-input-field input,
936 - .disabled-input-field textarea,
937 - .disabled-input-field button,
938 - .disabled-input-field label {
939 - pointer-events: none;
940 - opacity: 0.6;
941 - }
663 + .autowrite-subheadding p {
664 + font-family: 'IBM Plex Sans', sans-serif;
665 + font-size: 14px;
666 + }
942 667
943 - .disabled-input-field label {
944 - opacity: 1;
945 - }
668 + .prompt-field .input-description {
669 + margin: 0 !important;
670 + }
946 671
947 - .betterdocs-ai-button-container {
948 - margin-left: 10px;
949 - white-space: nowrap;
950 - max-width: 145px;
951 - }
672 + .autowrite-heading p {
673 + color: #475467;
674 + font-family: 'IBM Plex Sans', sans-serif;
675 + font-size: 16px;
676 + font-style: normal;
677 + font-weight: 400;
678 + }
952 679
953 - .autowrite-icon {
954 - display: flex;
955 - align-items: center;
956 - width: 32px;
957 - height: 32px;
958 - flex-shrink: 0;
959 - /* Mint chip + green sparkle — matches the FAQ/Glossary modal
960 - header icons (rgba(#00B884, 0.12)). */
961 - background: rgba(0, 184, 132, 0.12);
962 - justify-content: center;
963 - border-radius: 9px;
964 - }
680 + .betterdocs-ai-button {
681 + background: #00B884;
682 + border: 1px solid transparent;
683 + color: #fff;
684 + box-shadow: none;
685 + font-size: 12px;
686 + margin-right: 8px;
687 + padding: 0px 15px;
688 + cursor: pointer;
689 + border-radius: 3px;
690 + height: 38px;
691 + display: flex;
692 + align-items: center;
693 + justify-content: space-between;
694 + gap: 10px;
695 + }
965 696
966 - .autowrite-icon svg {
967 - width: 17px;
968 - height: 17px;
969 - }
697 + .betterdocs-ai-button img {
698 + width: 20px;
699 + height: 20px;
700 + }
970 701
971 - .autowrite-heading {
972 - display: flex;
973 - gap: 10px;
974 - align-items: center;
975 - /* Keep the title clear of the in-header close button. */
976 - padding-right: 64px;
977 - }
702 + .betterdocs-ai-autowrite-form-container {
703 + position: fixed;
704 + top: 50%;
705 + left: 50%;
706 + transform: translate(-50%, -50%);
707 + z-index: 100001;
708 + width: 650px;
709 + margin: 0 auto;
710 + background-color: #fff;
711 + border-radius: 5px;
712 + font-family: 'IBM Plex Sans', sans-serif;
713 + /* max-height: 600px; */
714 + max-height: 750px;
715 + max-width: 100%;
716 + }
978 717
979 - .autowrite-heading h1 {
980 - color: #101828;
981 - font-family: 'IBM Plex Sans', sans-serif;
982 - font-size: 18px;
983 - font-style: normal;
984 - font-weight: 600;
985 - line-height: 1.3;
986 - margin: 0;
987 - }
718 + .betterdocs-ai-autowrite-form-content {
719 + background-color: #fff;
720 + padding: 20px 0px;
721 + border-radius: 5px;
722 + padding-bottom: 0;
723 + overflow: auto;
724 + /* max-height: 700px; */
725 + height: 100%;
988 726
989 - .autowrite-heading p,
990 - form#betterdocs-ai-form p {
991 - margin: 0;
992 - margin-bottom: 24px;
993 - }
727 + }
994 728
995 - .autowrite-subheadding p {
996 - font-family: 'IBM Plex Sans', sans-serif;
997 - font-size: 13px;
998 - color: #667085;
999 - }
729 + .betterdocs-ai-autowrite-top-part {
730 + /* padding-bottom: 20px; */
731 + border-bottom: 1px solid #ddd;
732 + /* margin-bottom: 20px; */
733 + padding: 0 40px;
734 + }
1000 735
1001 - .prompt-field .input-description {
1002 - margin: 0 !important;
1003 - }
736 + #betterdocs-ai-form {
737 + display: flex;
738 + flex-direction: column;
739 + /* height: 100%; */
740 + overflow: hidden;
741 + }
1004 742
1005 - .autowrite-heading p {
1006 - color: #475467;
1007 - font-family: 'IBM Plex Sans', sans-serif;
1008 - font-size: 16px;
1009 - font-style: normal;
1010 - font-weight: 400;
1011 - }
743 + .form-inner-content {
744 + overflow: auto;
745 + height: 100%;
746 + max-height: 435px;
747 + /* max-height: 330px; */
748 + padding: 0 40px;
749 + }
1012 750
1013 - .betterdocs-ai-button {
1014 - background: #00B884;
1015 - border: 1px solid transparent;
1016 - color: #fff;
1017 - box-shadow: none;
1018 - font-size: 12px;
1019 - margin-right: 8px;
1020 - padding: 0px 15px;
1021 - cursor: pointer;
1022 - border-radius: 3px;
1023 - height: 38px;
1024 - display: flex;
1025 - align-items: center;
1026 - justify-content: space-between;
1027 - gap: 10px;
1028 - width: 135px;
1029 - }
751 + .form-inner-content>.form-group {
752 + margin-top: 20px;
753 + }
1030 754
1031 - .betterdocs-ai-button img {
1032 - width: 20px;
1033 - height: 20px;
1034 - }
1035 755
1036 - .betterdocs-ai-autowrite-form-container {
1037 - position: fixed;
1038 - top: 50%;
1039 - left: 50%;
1040 - transform: translate(-50%, -50%);
1041 - z-index: 100001;
1042 - width: 650px;
1043 - margin: 0 auto;
1044 - background-color: #fff;
1045 - border-radius: 20px;
1046 - font-family: 'IBM Plex Sans', sans-serif;
1047 - /* max-height: 600px; */
1048 - max-height: 750px;
1049 - max-width: 100%;
1050 - }
756 + #betterdocs-ai-autowrite-form-container-overlay {
757 + position: fixed;
758 + top: 0;
759 + right: 0;
760 + bottom: 0;
761 + left: 0;
762 + background-color: rgba(0, 0, 0, .7);
763 + z-index: 100000;
764 + }
1051 765
1052 - .betterdocs-ai-autowrite-form-content {
1053 - background-color: #fff;
1054 - padding: 0;
1055 - border-radius: 20px;
1056 - overflow: auto;
1057 - /* max-height: 700px; */
1058 - height: 100%;
1059 766
1060 - }
1061 767
1062 - .betterdocs-ai-autowrite-top-part {
1063 - /* Soft-gray header bar — matches the FAQ/Glossary/Edit-with-AI modals. */
1064 - background: #f9fafb;
1065 - border-bottom: 1px solid #f2f4f7;
1066 - border-radius: 20px 20px 0 0;
1067 - padding: 24px 40px 20px;
1068 - }
768 + #betterdocs-ai-form {
769 + display: flex;
770 + flex-direction: column;
771 + }
1069 772
1070 - #betterdocs-ai-form {
1071 - display: flex;
1072 - flex-direction: column;
1073 - /* height: 100%; */
1074 - overflow: hidden;
1075 - }
773 + #betterdocs-ai-form .form-group {
774 + margin-bottom: 24px;
775 + }
1076 776
1077 - .form-inner-content {
1078 - overflow: auto;
1079 - height: 100%;
1080 - max-height: 435px;
1081 - /* max-height: 330px; */
1082 - padding: 0 40px;
1083 - }
777 + #betterdocs-ai-form .bd-aiform-flex {
778 + display: flex;
779 + justify-content: space-between;
780 + }
1084 781
1085 - .form-inner-content>.form-group {
1086 - margin-top: 20px;
1087 - }
782 + #betterdocs-ai-form label {
783 + font-weight: 600;
784 + margin-bottom: 5px;
785 + display: block;
786 + font-size: 14px;
787 + line-height: 20px;
788 + }
1088 789
790 + select#bd-autowrtite-content-section,
791 + #bd-autowrtite-content-paragraph,
792 + #betterdocs-ai-language {
793 + width: 150px !important;
794 + height: 40px;
795 + }
1089 796
1090 - #betterdocs-ai-autowrite-form-container-overlay {
1091 - position: fixed;
1092 - top: 0;
1093 - right: 0;
1094 - bottom: 0;
1095 - left: 0;
1096 - background-color: rgba(0, 0, 0, .7);
1097 - z-index: 100000;
1098 - }
797 + #betterdocs-ai-form input[type="text"],
798 + #betterdocs-ai-form textarea {
799 + width: 100%;
800 + padding: 8px;
801 + box-sizing: border-box;
802 + border: 1px solid #D0D5DD;
803 + border-radius: 4px;
804 + color: #667085;
805 + font-weight: 400;
806 + }
1099 807
808 + /* Override autofill text color */
809 + #betterdocs-ai-form input:-webkit-autofill {
810 + -webkit-text-fill-color: #667085 !important;
811 + }
1100 812
813 + #betterdocs-ai-form input::placeholder {
814 + color: #acb2bf;
815 + }
1101 816
1102 - #betterdocs-ai-form {
1103 - display: flex;
1104 - flex-direction: column;
1105 - }
817 + #betterdocs-ai-form textarea {
818 + color: #667085;
819 + }
1106 820
1107 - #betterdocs-ai-form .form-group {
1108 - margin-bottom: 24px;
1109 - }
821 + #betterdocs-ai-form input:focus,
822 + #betterdocs-ai-form textarea:focus {
823 + box-shadow: none;
824 + }
1110 825
1111 - #betterdocs-ai-form .bd-aiform-flex {
1112 - display: flex;
1113 - justify-content: space-between;
1114 - }
826 + #betterdocs-ai-form textarea:focus {
827 + color: inherit;
828 + box-shadow: none;
1115 829
1116 - #betterdocs-ai-form label {
1117 - font-size: 14px;
1118 - font-weight: 500;
1119 - color: #667085;
1120 - margin-bottom: 5px;
1121 - display: block;
1122 - line-height: 20px;
1123 - }
830 + }
1124 831
1125 - select#bd-autowrtite-content-section,
1126 - #bd-autowrtite-content-paragraph,
1127 - #betterdocs-ai-language {
1128 - width: 150px !important;
1129 - height: 40px;
1130 - border: 1px solid #f2f4f7;
1131 - background: #f2f4f7;
1132 - color: #101828;
1133 - font-size: 14px;
1134 - border-radius: 5px;
1135 - padding: 5px 12px;
1136 - outline: none;
1137 - box-shadow: none;
1138 - }
1139 832
1140 - #betterdocs-ai-form input[type="text"],
1141 - #betterdocs-ai-form textarea {
1142 - width: 100%;
1143 - box-sizing: border-box;
1144 - border: 1px solid #f2f4f7;
1145 - background: #fff;
1146 - border-radius: 5px;
1147 - color: #101828;
1148 - font-size: 14px;
1149 - font-weight: 400;
1150 - outline: none;
1151 - box-shadow: none;
1152 - }
833 + .generate-button-container {
834 + position: sticky;
835 + bottom: 0px;
836 + width: 100%;
837 + margin-left: 0;
838 + z-index: 999999 !important;
839 + padding: 20px 0;
840 + display: flex;
841 + justify-content: end;
842 + border-top: 1px solid #ddd;
843 + background: white;
844 + border-bottom-right-radius: 5px;
845 + border-bottom-left-radius: 5px;
846 + }
1153 847
1154 - #betterdocs-ai-form input[type="text"] {
1155 - height: 40px;
1156 - padding: 5px 15px;
1157 - }
848 + .generate-button-container button {
849 + display: flex;
850 + gap: 8px;
851 + align-items: center;
852 + justify-content: center;
853 + opacity: 1 !important;
854 + margin-right: 40px;
855 + }
1158 856
1159 - #betterdocs-ai-form textarea {
1160 - padding: 10px 15px;
1161 - min-height: 100px;
1162 - }
857 + .input-description {
858 + font-size: 14px;
859 + color: #667085;
860 + }
1163 861
1164 - /* Override autofill text color */
1165 - #betterdocs-ai-form input:-webkit-autofill {
1166 - -webkit-text-fill-color: #101828 !important;
1167 - }
862 + .betterdocs-ai-checkbox-field .form-group {
863 + display: flex;
864 + align-items: start;
865 + /* gap: 200px; */
866 + justify-content: space-between;
867 + }
1168 868
1169 - #betterdocs-ai-form input::placeholder,
1170 - #betterdocs-ai-form textarea::placeholder {
1171 - color: #667085;
1172 - }
869 + .betterdocs-ai-checkbox-field input {
870 + width: 20px;
871 + height: 20px;
872 + }
1173 873
1174 - #betterdocs-ai-form input:focus,
1175 - #betterdocs-ai-form textarea:focus {
1176 - border-color: #00b884;
1177 - box-shadow: 0 0 0 3px rgba(0, 184, 132, 0.15);
1178 - outline: none;
1179 - }
874 + /* Add this CSS to your existing stylesheet or create a new one */
1180 875
876 + .betterdocs-ai-checkbox-field {
877 + position: relative;
878 + font-size: 16px;
879 + /* Adjust font size as needed */
880 + }
1181 881
1182 - /* Footer bar — soft gray surface; Cancel pinned left, Generate right. */
1183 - .generate-button-container {
1184 - position: sticky;
1185 - bottom: 0px;
1186 - width: 100%;
1187 - box-sizing: border-box;
1188 - margin-left: 0;
1189 - z-index: 999999 !important;
1190 - padding: 16px 22px;
1191 - display: flex;
1192 - align-items: center;
1193 - justify-content: flex-end;
1194 - border-top: 1px solid #f2f4f7;
1195 - background: #f9fafb;
1196 - border-bottom-right-radius: 20px;
1197 - border-bottom-left-radius: 20px;
1198 - }
882 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
883 + padding: 2px;
884 + }
1199 885
1200 - .generate-button-container button {
1201 - display: flex;
1202 - gap: 8px;
1203 - align-items: center;
1204 - justify-content: center;
1205 - opacity: 1 !important;
1206 - }
886 + .betterdocs-ai-checkbox-field input[type=checkbox] {
887 + border: 1px solid #00b884;
888 + }
1207 889
1208 - /* Cancel — white pill with neutral border. Stays clickable even when
1209 - the form is disabled (missing API key). */
1210 - .generate-button-container .bd-ai-cancel-btn {
1211 - pointer-events: auto;
1212 - display: inline-flex;
1213 - min-height: 36px;
1214 - padding: 7px 16px;
1215 - justify-content: center;
1216 - align-items: center;
1217 - background-color: #ffffff;
1218 - color: #344054;
1219 - border: 1px solid #d0d5dd;
1220 - border-radius: 9px;
1221 - font-size: 16px;
1222 - cursor: pointer;
1223 - text-decoration: none;
1224 - transition: all 0.3s ease 0s;
1225 - box-sizing: border-box;
1226 - }
890 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
891 + content: '\2713';
892 + color: #00b884;
893 + }
1227 894
1228 - .generate-button-container .bd-ai-cancel-btn:hover {
1229 - background-color: #f2f4f7;
1230 - color: #101828;
1231 - }
895 + /* Change the default checkbox color */
896 + .betterdocs-ai-checkbox-field input[type="checkbox"]:hover {
897 + -webkit-appearance: none;
898 + /* WebKit/Blink Browsers */
899 + -moz-appearance: none;
900 + /* Firefox */
901 + appearance: none;
902 + border: 1px solid #00b884;
903 + /* Set the height of the checkbox */
904 + /* Optional: Round the corners */
905 + outline: none;
906 + /* Remove the default outline */
907 + }
1232 908
1233 - .input-description {
1234 - font-size: 14px;
1235 - color: #667085;
1236 - }
909 + /* Style the checked state */
910 + .betterdocs-ai-checkbox-field input[type="checkbox"]:checked {
911 + /* Set the background color when checked */
912 + border: 1px solid #00b884;
913 + /* Set the border color when checked */
914 + }
1237 915
1238 - .betterdocs-ai-checkbox-field .form-group {
1239 - display: flex;
1240 - align-items: start;
1241 - /* gap: 200px; */
1242 - justify-content: space-between;
1243 - }
916 + .checkbox-field-label {
917 + width: calc(100% - 150px);
918 + }
1244 919
1245 - .betterdocs-ai-checkbox-field input {
1246 - width: 20px;
1247 - height: 20px;
1248 - }
920 + .checkbox-field-label p {
921 + margin: 0 !important;
922 + }
1249 923
1250 - /* Add this CSS to your existing stylesheet or create a new one */
924 + .checkbox-input-field {
925 + width: 300px;
926 + text-align: right;
927 + }
1251 928
1252 - .betterdocs-ai-checkbox-field {
1253 - position: relative;
1254 - font-size: 16px;
1255 - /* Adjust font size as needed */
1256 - }
929 + .checkbox-input-field {
930 + position: relative;
931 + display: inline-block;
932 + width: 60px;
933 + height: 34px;
934 + }
1257 935
1258 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1259 - padding: 2px;
1260 - }
936 + .checkbox-input-field input {
937 + display: none;
938 + }
1261 939
1262 - .betterdocs-ai-checkbox-field input[type=checkbox] {
1263 - border: 1px solid #00b884;
1264 - }
940 + .toggle-label {
941 + position: absolute;
942 + cursor: pointer;
943 + top: 0;
944 + left: 0;
945 + right: 0;
946 + bottom: 0;
947 + background-color: #ccc;
948 + border-radius: 34px;
949 + transition: background-color 0.3s;
950 + scale: .9;
951 + width: 52px;
952 + height: 26px;
953 + }
1265 954
1266 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1267 - content: '\2713';
1268 - color: #00b884;
1269 - }
1270 955
1271 - /* Change the default checkbox color */
1272 - .betterdocs-ai-checkbox-field input[type="checkbox"]:hover {
1273 - -webkit-appearance: none;
1274 - /* WebKit/Blink Browsers */
1275 - -moz-appearance: none;
1276 - /* Firefox */
1277 - appearance: none;
1278 - border: 1px solid #00b884;
1279 - /* Set the height of the checkbox */
1280 - /* Optional: Round the corners */
1281 - outline: none;
1282 - /* Remove the default outline */
1283 - }
956 + .checkbox-input-field input:checked+.toggle-label {
957 + background-color: #00b884;
958 + }
1284 959
1285 - /* Style the checked state */
1286 - .betterdocs-ai-checkbox-field input[type="checkbox"]:checked {
1287 - /* Set the background color when checked */
1288 - border: 1px solid #00b884;
1289 - /* Set the border color when checked */
1290 - }
960 + .toggle-label:after {
961 + content: "";
962 + position: absolute;
963 + height: 22px;
964 + width: 22px;
965 + left: 2px;
966 + bottom: 2px;
967 + background-color: white;
968 + border-radius: 50%;
969 + transition: transform 0.3s;
970 + }
1291 971
1292 - .checkbox-field-label {
1293 - width: calc(100% - 150px);
1294 - }
972 + .checkbox-input-field input:checked+.toggle-label:after {
973 + transform: translateX(26px);
974 + }
1295 975
1296 - .checkbox-field-label p {
1297 - margin: 0 !important;
1298 - }
976 + .generate-btn,
977 + .prompt-btn,
978 + .keep-btn {
979 + background-color: #00b884;
980 + color: #fff;
981 + border: none;
982 + padding: 10px 15px;
983 + text-align: center;
984 + text-decoration: none;
985 + display: inline-block;
986 + font-size: 16px;
987 + cursor: pointer;
988 + border-radius: 4px;
989 + }
1299 990
1300 - .checkbox-input-field {
1301 - width: 300px;
1302 - text-align: right;
1303 - }
991 + .generate-btn[disabled] {
992 + cursor: unset;
993 + }
1304 994
1305 - .checkbox-input-field {
1306 - position: relative;
1307 - display: inline-block;
1308 - width: 60px;
1309 - height: 34px;
1310 - }
995 + .bd-close-button {
996 + cursor: pointer;
997 + font-size: 18px;
998 + font-weight: bold;
999 + float: right;
1000 + position: absolute;
1001 + right: 1px;
1002 + top: 1px;
1003 + padding: 10px;
1004 + background: #ffffff;
1005 + border-radius: 25px;
1006 + width: 20px;
1007 + height: 20px;
1008 + display: flex;
1009 + align-items: center;
1010 + justify-content: center;
1011 + color: #281617;
1012 + right: -60px;
1013 + }
1311 1014
1312 - .checkbox-input-field input {
1313 - display: none;
1314 - }
1015 + div#betterdocs-ai-error-message,
1016 + #betterdocs-ai-message {
1017 + font-size: 14px;
1018 + font-family: 'IBM Plex Sans', sans-serif;
1019 + color: #667085;
1020 + margin-bottom: 20px;
1021 + }
1315 1022
1316 - .toggle-label {
1317 - position: absolute;
1318 - cursor: pointer;
1319 - top: 0;
1320 - left: 0;
1321 - right: 0;
1322 - bottom: 0;
1323 - background-color: #ccc;
1324 - border-radius: 34px;
1325 - transition: background-color 0.3s;
1326 - scale: .9;
1327 - width: 52px;
1328 - height: 26px;
1329 - }
1023 + div#betterdocs-ai-error-message a,
1024 + #betterdocs-ai-message a {
1025 + text-decoration: none;
1026 + font-weight: 600;
1027 + }
1330 1028
1029 + div#betterdocs-ai-error-message a:focus,
1030 + #betterdocs-ai-message a:focus {
1031 + outline: none;
1032 + box-shadow: none;
1033 + color: #2271b1;
1034 + }
1331 1035
1332 - .checkbox-input-field input:checked+.toggle-label {
1333 - background-color: #00b884;
1334 - }
1036 + #betterdocs-ai-message span {
1037 + color: #d63638;
1038 + }
1335 1039
1336 - .toggle-label:after {
1337 - content: "";
1338 - position: absolute;
1339 - height: 22px;
1340 - width: 22px;
1341 - left: 2px;
1342 - bottom: 2px;
1343 - background-color: white;
1344 - border-radius: 50%;
1345 - transition: transform 0.3s;
1346 - }
1040 + .warning-message {
1041 + display: flex;
1042 + align-items: center;
1043 + gap: 10px;
1044 + background: #fbebed;
1045 + padding: 12px;
1046 + border-radius: 5px;
1047 + font-size: 14px;
1048 + line-height: 1.4em;
1049 + border-left: 4px solid #d63638;
1050 + }
1347 1051
1348 - .checkbox-input-field input:checked+.toggle-label:after {
1349 - transform: translateX(26px);
1350 - }
1052 + .warning-message svg {
1053 + width: 20px;
1054 + height: 20px;
1055 + }
1351 1056
1352 - .generate-btn,
1353 - .prompt-btn,
1354 - .keep-btn {
1355 - display: inline-flex;
1356 - min-height: 0;
1357 - padding: 9px 20px;
1358 - gap: 8px;
1359 - justify-content: center;
1360 - align-items: center;
1361 - background-color: #00b884;
1362 - color: #fff;
1363 - border: 1px solid transparent;
1364 - border-radius: 10px;
1365 - font-size: 13px;
1366 - font-weight: 600;
1367 - cursor: pointer;
1368 - text-decoration: none;
1369 - box-shadow: none;
1370 - transition: background 0.15s, transform 0.05s;
1371 - box-sizing: border-box;
1372 - }
1057 + .warning-message span {
1058 + color: #d63638;
1059 + }
1373 1060
1374 - .generate-btn:hover,
1375 - .prompt-btn:hover,
1376 - .keep-btn:hover {
1377 - background-color: #00956b;
1378 - }
1061 + .warning-message .footer-message {
1062 + width: calc(100% - 20px);
1063 + }
1379 1064
1380 - .generate-btn[disabled] {
1381 - cursor: unset;
1382 - }
1065 + @media only screen and (max-width: 991px) {
1066 + .betterdocs-ai-autowrite-form-container {
1067 + left: 0;
1068 + right: 0;
1069 + transform: translate(0%, -50%);
1070 + }
1383 1071
1384 - /* Close — 44px gray rounded square INSIDE the modal, top-right of
1385 - the header, aligned with the header icon. */
1386 - .bd-close-button {
1387 - cursor: pointer;
1388 - position: absolute;
1389 - top: 24px;
1390 - right: 24px;
1391 - z-index: 2;
1392 - width: 32px;
1393 - height: 32px;
1394 - display: flex;
1395 - align-items: center;
1396 - justify-content: center;
1397 - border-radius: 9px;
1398 - background: #f2f4f7;
1399 - box-shadow: none;
1400 - color: #667085;
1401 - transition: all 0.2s ease-in-out;
1402 - }
1072 + .betterdocs-ai-autowrite-form-content {
1073 + overflow-x: auto;
1074 + }
1075 + }
1403 1076
1404 - .bd-close-button svg {
1405 - width: 16px;
1406 - height: 16px;
1407 - }
1077 + @media only screen and (max-width: 740px) {
1408 1078
1409 - .bd-close-button:hover {
1410 - background: #eaecf0;
1411 - color: #101828;
1412 - }
1079 + /* .bd-close-button {
1080 + right: px;
1081 + top: 1px;
1082 + border-radius: 5px;
1083 + width: 12px;
1084 + height: 12px;
1085 + color: #ffffff;
1086 + background: #00b884;
1087 + } */
1088 + .bd-close-button {
1089 + right: 0px;
1090 + top: 0px;
1091 + width: 12px;
1092 + height: 12px;
1093 + font-size: 14px;
1094 + }
1413 1095
1414 - div#betterdocs-ai-error-message,
1415 - #betterdocs-ai-message {
1416 - font-size: 14px;
1417 - font-family: 'IBM Plex Sans', sans-serif;
1418 - color: #667085;
1419 - margin-bottom: 20px;
1420 - }
1421 -
1422 - div#betterdocs-ai-error-message a,
1423 - #betterdocs-ai-message a {
1424 - text-decoration: none;
1425 - font-weight: 600;
1426 - }
1427 -
1428 - div#betterdocs-ai-error-message a:focus,
1429 - #betterdocs-ai-message a:focus {
1430 - outline: none;
1431 - box-shadow: none;
1432 - color: #2271b1;
1433 - }
1434 -
1435 - #betterdocs-ai-message span {
1436 - color: #d63638;
1437 - }
1438 -
1439 - .warning-message {
1440 - display: flex;
1441 - align-items: center;
1442 - gap: 10px;
1443 - background: #fbebed;
1444 - padding: 12px;
1445 - border-radius: 5px;
1446 - font-size: 14px;
1447 - line-height: 1.4em;
1448 - border-left: 4px solid #d63638;
1449 - }
1450 -
1451 - .warning-message svg {
1452 - width: 20px;
1453 - height: 20px;
1454 - }
1455 -
1456 - .warning-message span {
1457 - color: #d63638;
1458 - }
1459 -
1460 - .warning-message .footer-message {
1461 - width: calc(100% - 20px);
1462 - }
1463 -
1464 - @media only screen and (max-width: 991px) {
1465 - .betterdocs-ai-autowrite-form-container {
1466 - left: 0;
1467 - right: 0;
1468 - transform: translate(0%, -50%);
1469 - }
1470 -
1471 - .betterdocs-ai-autowrite-form-content {
1472 - overflow-x: auto;
1473 - }
1474 - }
1475 -
1476 - @media only screen and (max-width: 740px) {
1477 -
1478 - /* .bd-close-button {
1479 - right: px;
1480 - top: 1px;
1481 - border-radius: 5px;
1482 - width: 12px;
1483 - height: 12px;
1484 - color: #ffffff;
1485 - background: #00b884;
1486 - } */
1487 - .bd-close-button {
1488 - right: 0px;
1489 - top: 0px;
1490 - width: 12px;
1491 - height: 12px;
1492 - font-size: 14px;
1493 - }
1494 -
1495 - }
1496 - </style>
1497 - <?php
1498 1096 }
1499 - }
1097 + </style>
1098 +<?php
1099 + }
1100 +}