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.2 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 All 200 releases
← All changes | includes/Core/WriteWithAI.php +853 -1197 4.5.63.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,1329 +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="21" height="20" viewBox="0 0 21 20" fill="none">
788 - <g clip-path="url(#clip0_2460_1729)">
789 - <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"/>
790 - </g>
791 - <defs>
792 - <clipPath id="clip0_2460_1729">
793 - <rect width="20" height="20" fill="white" transform="translate(0.5)"/>
794 - </clipPath>
795 - </defs>
796 - </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>`;
797 461
798 462
799 463
800 - return `
801 - <div class="betterdocs-ai-autowrite-form-container hidden" ${newDocPageAtt}>
802 - <div class="betterdocs-ai-autowrite-form-content">
803 - <div class="betterdocs-ai-autowrite-top-part">
804 - <div class="autowrite-heading">
805 - <span class="autowrite-icon">
806 - <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
807 - <g clip-path="url(#clip0_2453_20882)">
808 - <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"/>
809 - </g>
810 - <defs>
811 - <clipPath id="clip0_2453_20882">
812 - <rect width="32" height="32" fill="white"/>
813 - </clipPath>
814 - </defs>
815 - </svg>
816 - </span>
817 - <h1><?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>
818 482
819 - </div>
820 - <div class="autowrite-subheadding">
821 - <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>
822 - </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>
823 487
824 - <?php if ( empty( $this->get_api_key() ) ): ?>
825 - <div id="betterdocs-ai-message">
826 - <div class="warning-message">
827 - <span class="dashicons dashicons-warning"></span>
828 - <div>
829 - <?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' ); ?>
830 - </div>
831 - </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>
832 496
833 - </div>
834 - <?php endif; ?>
497 + </div>
498 + <?php endif; ?>
835 499
836 - <div class="form-group hidden">
837 - <div id="betterdocs-ai-error-message"></div>
838 - </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>
839 511
840 - </div>
841 - <form id="betterdocs-ai-form" class="<?php echo esc_attr( $disable_field ); ?>">
842 - <div class="form-inner-content">
843 - <div class="form-group">
844 - <label for="betterdocs-ai-title">${titleLabel}</label>
845 - <input type="text" placeholder="${titlePlaceholder}" id="betterdocs-ai-title" name="betterdocs-ai-title" required value="${title}">
846 - </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>
847 516
848 - <div class="form-group">
849 - <label for="betterdocs-ai-keyword">${keywordLabel}</label>
850 - <input type="text" placeholder="${keywordsPlaceholder}" id="betterdocs-ai-keyword" name="betterdocs-ai-keyword" required>
851 - </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>
852 535
853 - <div class="form-group prompt-field">
854 - <label for="betterdocs-ai-content">${promtLabel}</label>
855 - <textarea id="betterdocs-ai-content" name="betterdocs-ai-content" rows="6" required>${prompt}</textarea>
856 - <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>
857 - </div>
858 - <div class="betterdocs-ai-checkbox-field ${hiddenClass}">
859 - <div class="form-group">
860 - <div class="checkbox-field-label">
861 - <label for="betterdocs-ai-checkbox">${checkboxLabel}</label>
862 - <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>
863 - </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>
864 545
865 - <div class="checkbox-input-field">
866 - <input type="checkbox" id="betterdocs-ai-checkbox" name="betterdocs-ai-checkbox" data-overwrite="false">
867 - <label for="betterdocs-ai-checkbox" class="toggle-label"></label>
868 - </div>
869 - </div>
870 - </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 + }
871 552
872 - <input type="hidden" name="ai_nonce" value="${nonce}" />
873 - </div>
874 - <div class="generate-button-container">
875 - <button type="submit" class="generate-btn" onclick="generateArticle(event)">
876 - ${aiIcon} <span>${promtArticleLabel}</span>
877 - </button>
878 - </div>
879 - </form>
880 - </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 + });
881 557
882 - <div class="bd-close-button" onclick="closeWriteWithAIForm('afterClosedClicked')">✕</div>
883 - </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');
884 568
885 - <div id="betterdocs-ai-autowrite-form-container-overlay" class="hidden"></div>
886 - `;
887 - }
569 + const formHtml = writeWithAIForm();
570 + $(formHtml).addClass('hidden');
888 571
889 - jQuery(document).on('click', '.regenerate-btn', function() {
890 - jQuery('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
891 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
892 - });
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 + });
893 576
894 - jQuery(document).ready(function($) {
895 - // 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);
896 580
897 - 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 + }
898 598
899 - const bdAIButton = $(`<div class="betterdocs-ai-button-container">
900 - <button class="betterdocs-ai-button">
901 - <img src="<?php echo esc_url( BETTERDOCS_ABSURL . 'assets/admin/images/betterdocs-icon-white.png' ); ?>" alt="<?php echo esc_attr__( 'betterdocs icon', 'betterdocs' ); ?>" />
902 - <span><?php echo esc_html__( 'Write with AI', 'betterdocs' ); ?></span>
903 - </button>
904 - </div>`);
599 + $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
600 + closeWriteWithAIForm();
601 + });
602 + });
603 + </script>
905 604
605 + <style>
606 + .hidden {
607 + display: none !important;
608 + }
906 609
907 - 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 + }
908 617
909 - const formHtml = writeWithAIForm();
910 - $(formHtml).addClass('hidden');
618 + .disabled-input-field label {
619 + opacity: 1;
620 + }
911 621
912 - $(document).on('click', '.betterdocs-ai-button', function() {
913 - $('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
914 - $('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
915 - });
622 + .betterdocs-ai-button-container {
623 + margin-left: 10px;
624 + }
916 625
917 - // $(document).on('click', '.betterdocs-ai-button', function() {
918 - if ($('.betterdocs-ai-autowrite-form-container').length < 1) {
919 - $('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 + }
920 635
921 - // Add event listeners to input elements
922 - document.getElementById('betterdocs-ai-title').addEventListener('input', updateTextarea);
923 - document.getElementById('betterdocs-ai-keyword').addEventListener('input', updateTextarea);
924 - // document.getElementById('bd-autowrtite-content-section').addEventListener('change', updateTextarea);
925 - // document.getElementById('bd-autowrtite-content-paragraph').addEventListener('change', updateTextarea);
926 - // document.getElementById('betterdocs-ai-language').addEventListener('input', updateTextarea);
927 - }
928 - // });
929 - const btn = document.createElement('button');
930 - wp.data.subscribe(function() {
931 - setTimeout(() => {
932 - if ($('.edit-post-header__settings').length > 0) {
933 - $('.edit-post-header__settings').prepend(bdAIButton);
934 - } else if ($('.editor-header__settings').length > 0) {
935 - $('.editor-header__settings').prepend(bdAIButton);
936 - }
636 + .autowrite-icon svg {
637 + width: 28px;
638 + height: 28px;
639 + }
937 640
938 - }, 1);
939 - });
940 - }
641 + .autowrite-heading {
642 + display: flex;
643 + gap: 10px;
644 + align-items: center;
645 + }
941 646
942 - $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
943 - closeWriteWithAIForm();
944 - });
945 - });
946 - </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 + }
947 656
948 - <style>
949 - .hidden {
950 - display: none !important;
951 - }
657 + .autowrite-heading p,
658 + form#betterdocs-ai-form p {
659 + margin: 0;
660 + margin-bottom: 24px;
661 + }
952 662
953 - .disabled-input-field input,
954 - .disabled-input-field textarea,
955 - .disabled-input-field button,
956 - .disabled-input-field label {
957 - pointer-events: none;
958 - opacity: 0.6;
959 - }
663 + .autowrite-subheadding p {
664 + font-family: 'IBM Plex Sans', sans-serif;
665 + font-size: 14px;
666 + }
960 667
961 - .disabled-input-field label {
962 - opacity: 1;
963 - }
668 + .prompt-field .input-description {
669 + margin: 0 !important;
670 + }
964 671
965 - .betterdocs-ai-button-container {
966 - margin-left: 10px;
967 - white-space: nowrap;
968 - max-width: 145px;
969 - }
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 + }
970 679
971 - .autowrite-icon {
972 - display: flex;
973 - align-items: center;
974 - width: 55px;
975 - height: 55px;
976 - background: #FFE4E8;
977 - justify-content: center;
978 - border-radius: 50px;
979 - }
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 + }
980 696
981 - .autowrite-icon svg {
982 - width: 28px;
983 - height: 28px;
984 - }
697 + .betterdocs-ai-button img {
698 + width: 20px;
699 + height: 20px;
700 + }
985 701
986 - .autowrite-heading {
987 - display: flex;
988 - gap: 10px;
989 - align-items: center;
990 - }
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 + }
991 717
992 - .autowrite-heading h1 {
993 - color: #1D2939;
994 - font-family: 'IBM Plex Sans', sans-serif;
995 - font-size: 24px;
996 - font-style: normal;
997 - font-weight: 500;
998 - line-height: normal;
999 - margin: 0;
1000 - }
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%;
1001 726
1002 - .autowrite-heading p,
1003 - form#betterdocs-ai-form p {
1004 - margin: 0;
1005 - margin-bottom: 24px;
1006 - }
727 + }
1007 728
1008 - .autowrite-subheadding p {
1009 - font-family: 'IBM Plex Sans', sans-serif;
1010 - font-size: 14px;
1011 - }
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 + }
1012 735
1013 - .prompt-field .input-description {
1014 - margin: 0 !important;
1015 - }
736 + #betterdocs-ai-form {
737 + display: flex;
738 + flex-direction: column;
739 + /* height: 100%; */
740 + overflow: hidden;
741 + }
1016 742
1017 - .autowrite-heading p {
1018 - color: #475467;
1019 - font-family: 'IBM Plex Sans', sans-serif;
1020 - font-size: 16px;
1021 - font-style: normal;
1022 - font-weight: 400;
1023 - }
743 + .form-inner-content {
744 + overflow: auto;
745 + height: 100%;
746 + max-height: 435px;
747 + /* max-height: 330px; */
748 + padding: 0 40px;
749 + }
1024 750
1025 - .betterdocs-ai-button {
1026 - background: #00B884;
1027 - border: 1px solid transparent;
1028 - color: #fff;
1029 - box-shadow: none;
1030 - font-size: 12px;
1031 - margin-right: 8px;
1032 - padding: 0px 15px;
1033 - cursor: pointer;
1034 - border-radius: 3px;
1035 - height: 38px;
1036 - display: flex;
1037 - align-items: center;
1038 - justify-content: space-between;
1039 - gap: 10px;
1040 - width: 135px;
1041 - }
751 + .form-inner-content>.form-group {
752 + margin-top: 20px;
753 + }
1042 754
1043 - .betterdocs-ai-button img {
1044 - width: 20px;
1045 - height: 20px;
1046 - }
1047 755
1048 - .betterdocs-ai-autowrite-form-container {
1049 - position: fixed;
1050 - top: 50%;
1051 - left: 50%;
1052 - transform: translate(-50%, -50%);
1053 - z-index: 100001;
1054 - width: 650px;
1055 - margin: 0 auto;
1056 - background-color: #fff;
1057 - border-radius: 5px;
1058 - font-family: 'IBM Plex Sans', sans-serif;
1059 - /* max-height: 600px; */
1060 - max-height: 750px;
1061 - max-width: 100%;
1062 - }
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 + }
1063 765
1064 - .betterdocs-ai-autowrite-form-content {
1065 - background-color: #fff;
1066 - padding: 20px 0px;
1067 - border-radius: 5px;
1068 - padding-bottom: 0;
1069 - overflow: auto;
1070 - /* max-height: 700px; */
1071 - height: 100%;
1072 766
1073 - }
1074 767
1075 - .betterdocs-ai-autowrite-top-part {
1076 - /* padding-bottom: 20px; */
1077 - border-bottom: 1px solid #ddd;
1078 - /* margin-bottom: 20px; */
1079 - padding: 0 40px;
1080 - }
768 + #betterdocs-ai-form {
769 + display: flex;
770 + flex-direction: column;
771 + }
1081 772
1082 - #betterdocs-ai-form {
1083 - display: flex;
1084 - flex-direction: column;
1085 - /* height: 100%; */
1086 - overflow: hidden;
1087 - }
773 + #betterdocs-ai-form .form-group {
774 + margin-bottom: 24px;
775 + }
1088 776
1089 - .form-inner-content {
1090 - overflow: auto;
1091 - height: 100%;
1092 - max-height: 435px;
1093 - /* max-height: 330px; */
1094 - padding: 0 40px;
1095 - }
777 + #betterdocs-ai-form .bd-aiform-flex {
778 + display: flex;
779 + justify-content: space-between;
780 + }
1096 781
1097 - .form-inner-content>.form-group {
1098 - margin-top: 20px;
1099 - }
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 + }
1100 789
790 + select#bd-autowrtite-content-section,
791 + #bd-autowrtite-content-paragraph,
792 + #betterdocs-ai-language {
793 + width: 150px !important;
794 + height: 40px;
795 + }
1101 796
1102 - #betterdocs-ai-autowrite-form-container-overlay {
1103 - position: fixed;
1104 - top: 0;
1105 - right: 0;
1106 - bottom: 0;
1107 - left: 0;
1108 - background-color: rgba(0, 0, 0, .7);
1109 - z-index: 100000;
1110 - }
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 + }
1111 807
808 + /* Override autofill text color */
809 + #betterdocs-ai-form input:-webkit-autofill {
810 + -webkit-text-fill-color: #667085 !important;
811 + }
1112 812
813 + #betterdocs-ai-form input::placeholder {
814 + color: #acb2bf;
815 + }
1113 816
1114 - #betterdocs-ai-form {
1115 - display: flex;
1116 - flex-direction: column;
1117 - }
817 + #betterdocs-ai-form textarea {
818 + color: #667085;
819 + }
1118 820
1119 - #betterdocs-ai-form .form-group {
1120 - margin-bottom: 24px;
1121 - }
821 + #betterdocs-ai-form input:focus,
822 + #betterdocs-ai-form textarea:focus {
823 + box-shadow: none;
824 + }
1122 825
1123 - #betterdocs-ai-form .bd-aiform-flex {
1124 - display: flex;
1125 - justify-content: space-between;
1126 - }
826 + #betterdocs-ai-form textarea:focus {
827 + color: inherit;
828 + box-shadow: none;
1127 829
1128 - #betterdocs-ai-form label {
1129 - font-weight: 600;
1130 - margin-bottom: 5px;
1131 - display: block;
1132 - font-size: 14px;
1133 - line-height: 20px;
1134 - }
830 + }
1135 831
1136 - select#bd-autowrtite-content-section,
1137 - #bd-autowrtite-content-paragraph,
1138 - #betterdocs-ai-language {
1139 - width: 150px !important;
1140 - height: 40px;
1141 - }
1142 832
1143 - #betterdocs-ai-form input[type="text"],
1144 - #betterdocs-ai-form textarea {
1145 - width: 100%;
1146 - padding: 8px;
1147 - box-sizing: border-box;
1148 - border: 1px solid #D0D5DD;
1149 - border-radius: 4px;
1150 - color: #667085;
1151 - font-weight: 400;
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 - /* Override autofill text color */
1155 - #betterdocs-ai-form input:-webkit-autofill {
1156 - -webkit-text-fill-color: #667085 !important;
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 input::placeholder {
1160 - color: #acb2bf;
1161 - }
857 + .input-description {
858 + font-size: 14px;
859 + color: #667085;
860 + }
1162 861
1163 - #betterdocs-ai-form textarea {
1164 - color: #667085;
1165 - }
862 + .betterdocs-ai-checkbox-field .form-group {
863 + display: flex;
864 + align-items: start;
865 + /* gap: 200px; */
866 + justify-content: space-between;
867 + }
1166 868
1167 - #betterdocs-ai-form input:focus,
1168 - #betterdocs-ai-form textarea:focus {
1169 - box-shadow: none;
1170 - }
869 + .betterdocs-ai-checkbox-field input {
870 + width: 20px;
871 + height: 20px;
872 + }
1171 873
1172 - #betterdocs-ai-form textarea:focus {
1173 - color: inherit;
1174 - box-shadow: none;
874 + /* Add this CSS to your existing stylesheet or create a new one */
1175 875
1176 - }
876 + .betterdocs-ai-checkbox-field {
877 + position: relative;
878 + font-size: 16px;
879 + /* Adjust font size as needed */
880 + }
1177 881
882 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
883 + padding: 2px;
884 + }
1178 885
1179 - .generate-button-container {
1180 - position: sticky;
1181 - bottom: 0px;
1182 - width: 100%;
1183 - margin-left: 0;
1184 - z-index: 999999 !important;
1185 - padding: 20px 0;
1186 - display: flex;
1187 - justify-content: end;
1188 - border-top: 1px solid #ddd;
1189 - background: white;
1190 - border-bottom-right-radius: 5px;
1191 - border-bottom-left-radius: 5px;
1192 - }
886 + .betterdocs-ai-checkbox-field input[type=checkbox] {
887 + border: 1px solid #00b884;
888 + }
1193 889
1194 - .generate-button-container button {
1195 - display: flex;
1196 - gap: 8px;
1197 - align-items: center;
1198 - justify-content: center;
1199 - opacity: 1 !important;
1200 - margin-right: 40px;
1201 - }
890 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
891 + content: '\2713';
892 + color: #00b884;
893 + }
1202 894
1203 - .input-description {
1204 - font-size: 14px;
1205 - color: #667085;
1206 - }
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 + }
1207 908
1208 - .betterdocs-ai-checkbox-field .form-group {
1209 - display: flex;
1210 - align-items: start;
1211 - /* gap: 200px; */
1212 - justify-content: space-between;
1213 - }
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 + }
1214 915
1215 - .betterdocs-ai-checkbox-field input {
1216 - width: 20px;
1217 - height: 20px;
1218 - }
916 + .checkbox-field-label {
917 + width: calc(100% - 150px);
918 + }
1219 919
1220 - /* Add this CSS to your existing stylesheet or create a new one */
920 + .checkbox-field-label p {
921 + margin: 0 !important;
922 + }
1221 923
1222 - .betterdocs-ai-checkbox-field {
1223 - position: relative;
1224 - font-size: 16px;
1225 - /* Adjust font size as needed */
1226 - }
924 + .checkbox-input-field {
925 + width: 300px;
926 + text-align: right;
927 + }
1227 928
1228 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1229 - padding: 2px;
1230 - }
929 + .checkbox-input-field {
930 + position: relative;
931 + display: inline-block;
932 + width: 60px;
933 + height: 34px;
934 + }
1231 935
1232 - .betterdocs-ai-checkbox-field input[type=checkbox] {
1233 - border: 1px solid #00b884;
1234 - }
936 + .checkbox-input-field input {
937 + display: none;
938 + }
1235 939
1236 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1237 - content: '\2713';
1238 - color: #00b884;
1239 - }
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 + }
1240 954
1241 - /* Change the default checkbox color */
1242 - .betterdocs-ai-checkbox-field input[type="checkbox"]:hover {
1243 - -webkit-appearance: none;
1244 - /* WebKit/Blink Browsers */
1245 - -moz-appearance: none;
1246 - /* Firefox */
1247 - appearance: none;
1248 - border: 1px solid #00b884;
1249 - /* Set the height of the checkbox */
1250 - /* Optional: Round the corners */
1251 - outline: none;
1252 - /* Remove the default outline */
1253 - }
1254 955
1255 - /* Style the checked state */
1256 - .betterdocs-ai-checkbox-field input[type="checkbox"]:checked {
1257 - /* Set the background color when checked */
1258 - border: 1px solid #00b884;
1259 - /* Set the border color when checked */
1260 - }
956 + .checkbox-input-field input:checked+.toggle-label {
957 + background-color: #00b884;
958 + }
1261 959
1262 - .checkbox-field-label {
1263 - width: calc(100% - 150px);
1264 - }
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 + }
1265 971
1266 - .checkbox-field-label p {
1267 - margin: 0 !important;
1268 - }
972 + .checkbox-input-field input:checked+.toggle-label:after {
973 + transform: translateX(26px);
974 + }
1269 975
1270 - .checkbox-input-field {
1271 - width: 300px;
1272 - text-align: right;
1273 - }
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 + }
1274 990
1275 - .checkbox-input-field {
1276 - position: relative;
1277 - display: inline-block;
1278 - width: 60px;
1279 - height: 34px;
1280 - }
991 + .generate-btn[disabled] {
992 + cursor: unset;
993 + }
1281 994
1282 - .checkbox-input-field input {
1283 - display: none;
1284 - }
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 + }
1285 1014
1286 - .toggle-label {
1287 - position: absolute;
1288 - cursor: pointer;
1289 - top: 0;
1290 - left: 0;
1291 - right: 0;
1292 - bottom: 0;
1293 - background-color: #ccc;
1294 - border-radius: 34px;
1295 - transition: background-color 0.3s;
1296 - scale: .9;
1297 - width: 52px;
1298 - height: 26px;
1299 - }
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 + }
1300 1022
1023 + div#betterdocs-ai-error-message a,
1024 + #betterdocs-ai-message a {
1025 + text-decoration: none;
1026 + font-weight: 600;
1027 + }
1301 1028
1302 - .checkbox-input-field input:checked+.toggle-label {
1303 - background-color: #00b884;
1304 - }
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 + }
1305 1035
1306 - .toggle-label:after {
1307 - content: "";
1308 - position: absolute;
1309 - height: 22px;
1310 - width: 22px;
1311 - left: 2px;
1312 - bottom: 2px;
1313 - background-color: white;
1314 - border-radius: 50%;
1315 - transition: transform 0.3s;
1316 - }
1036 + #betterdocs-ai-message span {
1037 + color: #d63638;
1038 + }
1317 1039
1318 - .checkbox-input-field input:checked+.toggle-label:after {
1319 - transform: translateX(26px);
1320 - }
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 + }
1321 1051
1322 - .generate-btn,
1323 - .prompt-btn,
1324 - .keep-btn {
1325 - background-color: #00b884;
1326 - color: #fff;
1327 - border: none;
1328 - padding: 10px 15px;
1329 - text-align: center;
1330 - text-decoration: none;
1331 - display: inline-block;
1332 - font-size: 16px;
1333 - cursor: pointer;
1334 - border-radius: 4px;
1335 - }
1052 + .warning-message svg {
1053 + width: 20px;
1054 + height: 20px;
1055 + }
1336 1056
1337 - .generate-btn[disabled] {
1338 - cursor: unset;
1339 - }
1057 + .warning-message span {
1058 + color: #d63638;
1059 + }
1340 1060
1341 - .bd-close-button {
1342 - cursor: pointer;
1343 - font-size: 18px;
1344 - font-weight: bold;
1345 - float: right;
1346 - position: absolute;
1347 - top: -16px;
1348 - border-radius: 50%;
1349 - background: #ffffff;
1350 - width: 40px;
1351 - height: 40px;
1352 - display: flex;
1353 - align-items: center;
1354 - justify-content: center;
1355 - color: #281617;
1356 - right: -42px;
1357 - }
1061 + .warning-message .footer-message {
1062 + width: calc(100% - 20px);
1063 + }
1358 1064
1359 - div#betterdocs-ai-error-message,
1360 - #betterdocs-ai-message {
1361 - font-size: 14px;
1362 - font-family: 'IBM Plex Sans', sans-serif;
1363 - color: #667085;
1364 - margin-bottom: 20px;
1365 - }
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 + }
1366 1071
1367 - div#betterdocs-ai-error-message a,
1368 - #betterdocs-ai-message a {
1369 - text-decoration: none;
1370 - font-weight: 600;
1371 - }
1072 + .betterdocs-ai-autowrite-form-content {
1073 + overflow-x: auto;
1074 + }
1075 + }
1372 1076
1373 - div#betterdocs-ai-error-message a:focus,
1374 - #betterdocs-ai-message a:focus {
1375 - outline: none;
1376 - box-shadow: none;
1377 - color: #2271b1;
1378 - }
1077 + @media only screen and (max-width: 740px) {
1379 1078
1380 - #betterdocs-ai-message span {
1381 - color: #d63638;
1382 - }
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 + }
1383 1095
1384 - .warning-message {
1385 - display: flex;
1386 - align-items: center;
1387 - gap: 10px;
1388 - background: #fbebed;
1389 - padding: 12px;
1390 - border-radius: 5px;
1391 - font-size: 14px;
1392 - line-height: 1.4em;
1393 - border-left: 4px solid #d63638;
1394 - }
1395 -
1396 - .warning-message svg {
1397 - width: 20px;
1398 - height: 20px;
1399 - }
1400 -
1401 - .warning-message span {
1402 - color: #d63638;
1403 - }
1404 -
1405 - .warning-message .footer-message {
1406 - width: calc(100% - 20px);
1407 - }
1408 -
1409 - @media only screen and (max-width: 991px) {
1410 - .betterdocs-ai-autowrite-form-container {
1411 - left: 0;
1412 - right: 0;
1413 - transform: translate(0%, -50%);
1414 - }
1415 -
1416 - .betterdocs-ai-autowrite-form-content {
1417 - overflow-x: auto;
1418 - }
1419 - }
1420 -
1421 - @media only screen and (max-width: 740px) {
1422 -
1423 - /* .bd-close-button {
1424 - right: px;
1425 - top: 1px;
1426 - border-radius: 5px;
1427 - width: 12px;
1428 - height: 12px;
1429 - color: #ffffff;
1430 - background: #00b884;
1431 - } */
1432 - .bd-close-button {
1433 - right: 0px;
1434 - top: 0px;
1435 - width: 12px;
1436 - height: 12px;
1437 - font-size: 14px;
1438 - }
1439 -
1440 - }
1441 - </style>
1442 - <?php
1443 1096 }
1444 - }
1097 + </style>
1098 +<?php
1099 + }
1100 +}