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 +851 -1068 4.5.13.5.3 View file →
@@ -1,106 +1,76 @@
1 1 <?php
2 2
3 - namespace WPDeveloper\BetterDocs\Core;
3 +namespace WPDeveloper\BetterDocs\Core;
4 4
5 - use WPDeveloper\BetterDocs\Utils\Base;
6 - use WPDeveloper\BetterDocs\Core\Settings;
7 - use WPDeveloper\BetterDocs\Core\PostType;
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 +use WPDeveloper\BetterDocs\Utils\Helper;
10 10
11 - class WriteWithAI extends Base {
12 -
11 +class WriteWithAI extends Base
12 +{
13 13 public $settings;
14 14
15 - public function __construct( Settings $settings ) {
15 + public function __construct(Settings $settings)
16 + {
16 17 $this->settings = $settings;
17 18 // Get the post ID from the URL
18 - $post_id = isset( $_GET[ 'post' ] ) ? intval( $_GET[ 'post' ] ) : 0; // phpcs:ignore
19 + $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0;
19 20
20 - if ( ! empty( $_GET[ 'post_type' ] ) ) { // phpcs:ignore
21 - $post_type = $_GET[ 'post_type' ]; // phpcs:ignore
22 - } elseif ( $post_id > 0 ) {
23 - $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);
24 25 } else {
25 26 $post_type = '';
26 27 }
27 28
28 - if ( ! empty( $this->isEnabledWriteWithAI() ) && 'docs' == $post_type ) {
29 - add_action( 'admin_footer', array( $this, 'ai_autowrite_button' ) );
30 - 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']);
31 31 }
32 - 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']);
33 33 }
34 34
35 - public function enqueue_ai_edit_assets( $hook ) {
36 - if ( $hook !== 'post.php' && $hook !== 'post-new.php' ) {
37 - return;
38 - }
39 -
40 - global $post_type;
41 - if ( $post_type !== 'docs' ) {
42 - return;
43 - }
44 -
45 - if ( empty( $this->get_api_key() ) ) {
46 - return;
47 - }
48 -
49 - betterdocs()->assets->enqueue( 'betterdocs-ai-edit', 'blocks/ai-edit.js' );
50 - betterdocs()->assets->enqueue( 'betterdocs-ai-edit-style', 'blocks/ai-edit-style.css' );
51 -
52 - wp_localize_script(
53 - 'betterdocs-ai-edit',
54 - 'betterdocsAIEdit',
55 - array(
56 - 'rest_url' => esc_url_raw( rest_url( 'betterdocs/v1/ai-edit' ) ),
57 - 'rest_nonce' => wp_create_nonce( 'wp_rest' ),
58 - 'post_id' => get_the_ID(),
59 - )
60 - );
61 - }
62 -
63 - public function isEnabledWriteWithAI() {
64 - $isEnableAutoWrite = $this->settings->get( 'enable_write_with_ai', true );
35 + public function isEnabledWriteWithAI()
36 + {
37 + $isEnableAutoWrite = $this->settings->get('enable_write_with_ai', true);
65 38 return $isEnableAutoWrite;
66 39 }
67 40
68 - public function isValidAPIKey( $apiKey ) {
69 - if ( empty( $apiKey ) ) {
70 - $api_response[ 'valid' ] = false;
71 - $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.';
72 46
73 47 return $api_response;
74 48 }
75 49
76 - $ch = curl_init( 'https://api.openai.com/v1/engines' ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_init
77 - curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
78 - curl_setopt(
79 - $ch,
80 - CURLOPT_HTTPHEADER,
81 - array( //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
82 - 'Content-Type: application/json',
83 - 'Authorization: Bearer ' . $apiKey
84 - )
85 - );
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 + ]);
86 56
87 - $api_response = array();
57 + $api_response = [];
88 58
89 - $response = curl_exec( $ch ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_exec
90 - $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_getinfo
59 + $response = curl_exec($ch);
60 + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
91 61
92 - curl_close( $ch ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close
62 + curl_close($ch);
93 63
94 - if ( 200 == $httpCode ) {
95 - $api_response[ 'valid' ] = true;
96 - $api_response[ 'message' ] = 'Valid API Key';
64 + if ($httpCode == 200) {
65 + $api_response['valid'] = true;
66 + $api_response['message'] = 'Valid API Key';
97 67 } else {
98 - $responseData = json_decode( $response, true );
68 + $responseData = json_decode($response, true);
99 69 // Access the message data (replace 'data' with the actual key used in the response)
100 - $messageData = $responseData[ 'error' ] ? $responseData[ 'error' ] : '';
101 - $api_response[ 'valid' ] = false;
102 - $api_response[ 'message' ] = $messageData[ 'message' ] ? $messageData[ 'message' ] : 'Invalid API Key';
70 + $messageData = $responseData['error'] ? $responseData['error'] : '';
71 + $api_response['valid'] = false;
72 + $api_response['message'] = $messageData['message'] ? $messageData['message'] : 'Invalid API Key';
103 73 }
104 74
105 75 // print_r($response);
106 76
@@ -106,1212 +76,1025 @@
106 76
107 77 return $api_response;
108 78 }
109 79
110 - public function get_api_key() {
111 - $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', '');
112 83 return $api_key;
113 84 }
114 85
115 - public function get_system_prompt() {
116 - $prompt = <<<'PROMPT'
117 -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.
118 86
119 -## Output format
120 -
121 -Return only HTML body content. Never wrap output in `<!doctype>`, `<html>`, `<head>`, `<body>`, or markdown code fences (no ```html ... ```).
122 -
123 -Use semantic, Gutenberg-friendly tags only:
124 -- Headings: `<h2>`, `<h3>`, `<h4>` (do not emit `<h1>` — it is reserved for the document title)
125 -- Paragraphs: `<p>` for prose
126 -- Lists: `<ul>`/`<ol>` with `<li>` for any list of items, steps, or bullet points — never fake a list with paragraphs or `<br>`
127 -- Links: `<a href="https://...">link text</a>` with absolute URLs
128 -- Inline emphasis: `<strong>`, `<em>`, `<code>`
129 -- Code blocks: `<pre><code>...</code></pre>` for multi-line code or commands
130 -- Quotes: `<blockquote>`
131 -- Tables: `<table>` with `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`
132 -- Images: `<img src="..." alt="...">`
133 -
134 -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.
135 -
136 -Do not emit `<style>`, `<script>`, `<iframe>`, `<form>`, or inline `style=""` / `class=""` attributes (other than the `highlight` class above).
137 -
138 -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.
139 -PROMPT;
140 -
141 - return apply_filters( 'betterdocs_write_with_ai_system_prompt', $prompt );
142 - }
143 -
144 - public function generate_openai_response( $prompt, $keywords ) {
87 + public function generate_openai_response($prompt, $keywords)
88 + {
145 89 try {
146 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
147 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 1500 );
148 - $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);
149 92
150 93 $api_endpoint = 'https://api.openai.com/v1/chat/completions'; // Update the endpoint based on OpenAI API version
151 94
152 - $request_body = array(
153 - 'model' => $model,
154 - 'messages' => array(
155 - array(
156 - 'role' => 'system',
157 - 'content' => $this->get_system_prompt()
158 - ),
159 - array(
160 - 'role' => 'user',
161 - 'content' => $prompt
162 - )
163 - ),
164 - 'max_tokens' => $max_tokens
165 - );
166 -
167 95 $request_options = array(
168 96 'headers' => array(
169 - 'Content-Type' => 'application/json',
170 - 'Authorization' => 'Bearer ' . $api_key
97 + 'Content-Type' => 'application/json',
98 + 'Authorization' => 'Bearer ' . $api_key,
171 99 ),
172 - 'body' => json_encode( $request_body ),
173 - 'timeout' => 50
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,
174 110 );
175 111
176 - $response = wp_remote_post( $api_endpoint, $request_options );
112 + $response = wp_remote_post($api_endpoint, $request_options);
177 113
178 - if ( is_wp_error( $response ) ) {
114 + if (is_wp_error($response)) {
179 115 return 'Error: ' . $response->get_error_message();
180 116 } else {
181 - $body = wp_remote_retrieve_body( $response );
117 + $body = wp_remote_retrieve_body($response);
182 118
183 - $data = json_decode( $body, true );
119 + $data = json_decode($body, true);
184 120
185 - if ( ! empty( $data[ 'error' ] ) ) {
186 - return $data[ 'error' ][ 'message' ];
121 + if (!empty($data['error'])) {
122 + return $data['error']['message'];
187 123 }
188 124
189 - 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
190 126 }
191 - } catch ( Exception $error ) {
127 + } catch (Exception $error) {
192 128 return 'Error: ' . $error->getMessage();
193 129 }
194 130 }
195 131
196 - public function generate_openai_response_full( $prompt ) {
197 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
198 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 1500 );
199 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
200 132
201 - $api_endpoint = 'https://api.openai.com/v1/chat/completions';
202 133
203 - $payload = array(
204 - 'model' => $model,
205 - 'messages' => array(
206 - array(
207 - 'role' => 'system',
208 - 'content' => $this->get_system_prompt()
209 - ),
210 - array(
211 - 'role' => 'user',
212 - 'content' => $prompt
213 - )
214 - ),
215 - 'max_tokens' => $max_tokens
216 - );
217 -
218 - $request_options = array(
219 - 'headers' => array(
220 - 'Content-Type' => 'application/json',
221 - 'Authorization' => 'Bearer ' . $api_key
222 - ),
223 - 'body' => wp_json_encode( $payload ),
224 - 'timeout' => 50
225 - );
226 -
227 - $response = wp_remote_post( $api_endpoint, $request_options );
228 -
229 - if ( is_wp_error( $response ) ) {
230 - return array(
231 - 'success' => false,
232 - 'error' => $response->get_error_message(),
233 - 'model' => $model,
234 - );
235 - }
236 -
237 - $body = wp_remote_retrieve_body( $response );
238 - $data = json_decode( $body, true );
239 -
240 - if ( ! empty( $data['error'] ) ) {
241 - return array(
242 - 'success' => false,
243 - 'error' => isset( $data['error']['message'] ) ? $data['error']['message'] : 'OpenAI error',
244 - 'model' => $model,
245 - 'raw' => $data,
246 - );
247 - }
248 -
249 - $content = isset( $data['choices'][0]['message']['content'] ) ? $data['choices'][0]['message']['content'] : '';
250 - $usage = isset( $data['usage'] ) && is_array( $data['usage'] ) ? $data['usage'] : array();
251 -
252 - return array(
253 - 'success' => true,
254 - 'content' => $content,
255 - 'model' => $model,
256 - 'prompt_tokens' => isset( $usage['prompt_tokens'] ) ? (int) $usage['prompt_tokens'] : null,
257 - 'completion_tokens' => isset( $usage['completion_tokens'] ) ? (int) $usage['completion_tokens'] : null,
258 - 'total_tokens' => isset( $usage['total_tokens'] ) ? (int) $usage['total_tokens'] : null,
259 - 'finish_reason' => isset( $data['choices'][0]['finish_reason'] ) ? $data['choices'][0]['finish_reason'] : null,
260 - );
261 - }
262 -
263 - public function generate_openai_content_callback() {
134 + public function generate_openai_content_callback()
135 + {
264 136 // Verify the nonce
265 - if ( ! isset( $_POST[ 'ai_nonce' ] ) || ! wp_verify_nonce( $_POST[ 'ai_nonce' ], 'generate_openai_content_nonce' ) ) { //phpcs:ignore
266 - 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');
267 139 wp_die();
268 140 }
269 141
270 - if ( ! current_user_can( 'edit_posts' ) ) {
271 - wp_send_json_error( 'Insufficient permissions' );
272 - wp_die();
273 - }
274 -
275 - $prompt = sanitize_text_field( $_POST[ 'prompt' ] ); //phpcs:ignore
142 + $prompt = sanitize_text_field($_POST['prompt']);
276 143 // $num_of_sections = sanitize_text_field($_POST['numOfSections']);
277 144 // $num_of_paragraphs = sanitize_text_field($_POST['numOfParagraphs']);
278 - $keywords = sanitize_text_field( $_POST[ 'keywords' ] ); //phpcs:ignore
145 + $keywords = sanitize_text_field($_POST['keywords']);
279 146
280 - $ai_instance = new WriteWithAI( $this->settings );
147 + $ai_instance = new WriteWithAI($this->settings);
281 148
282 - $generated_content = $ai_instance->generate_openai_response( $prompt, $keywords );
149 + $generated_content = $ai_instance->generate_openai_response($prompt, $keywords);
283 150
284 151 // Send the generated content as the AJAX response
285 - wp_send_json_success( $generated_content );
152 + wp_send_json_success($generated_content);
286 153 wp_die();
287 154 }
288 155
289 - public function ai_autowrite_button() {
156 + public function ai_autowrite_button()
157 + {
290 158
291 159 ?>
292 - <script>
293 - var docsTitle;
160 + <script>
161 + var docsTitle;
294 162
295 - function responseMessage(message) {
296 - return `<div class="warning-message">
297 - <span class="dashicons dashicons-warning"></span>
298 - <div class="footer-message">
299 - ${message}
300 - </div>
301 - </div>`;
302 - }
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 + }
303 171
304 - function generateArticle(e) {
172 + function generateArticle(e) {
305 173
306 174
307 - const title = document.getElementById('betterdocs-ai-title').value;
308 - const keywords = document.getElementById('betterdocs-ai-keyword').value;
309 - // const sectionOptions = document.getElementById('bd-autowrtite-content-section');
310 - // 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;
311 179
312 - // const paragraphOptions = document.getElementById('bd-autowrtite-content-paragraph');
313 - // const numOfParagraphs = paragraphOptions.options[paragraphOptions.selectedIndex].value;
180 + // const paragraphOptions = document.getElementById('bd-autowrtite-content-paragraph');
181 + // const numOfParagraphs = paragraphOptions.options[paragraphOptions.selectedIndex].value;
314 182
315 - const contentTextArea = document.getElementById('betterdocs-ai-content');
316 - const docGenerateBtnTxt = document.querySelector('.generate-btn span');
183 + const contentTextArea = document.getElementById('betterdocs-ai-content');
184 + const docGenerateBtnTxt = document.querySelector('.generate-btn span');
317 185
318 - // Add nonce value to the data being sent
319 - const nonce = document.querySelector('input[name="ai_nonce"]').value;
320 - const isOverwrite = document.getElementById('betterdocs-ai-checkbox').checked;
321 - const generateDocLabel = "<?php echo esc_html__( 'Generate Doc', 'betterdocs' ); ?>";
322 - 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'); ?>";
323 191
324 192
325 - // 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.`;
326 194
327 195
328 - // Check if the title is not empty
329 - if (title.trim() !== '' && keywords.trim() !== '') {
330 - e.preventDefault();
196 + // Check if the title is not empty
197 + if (title.trim() !== '' && keywords.trim() !== '') {
198 + e.preventDefault();
331 199
332 - if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
333 - jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
334 - }
200 + if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
201 + jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
202 + }
335 203
336 - docGenerateBtnTxt.innerHTML = "<?php echo esc_html__( 'Generating...', 'betterdocs' ); ?>";
337 - jQuery('.generate-btn').prop('disabled', true);
204 + docGenerateBtnTxt.innerHTML = "<?php echo esc_html__('Generating...', 'betterdocs'); ?>";
205 + jQuery('.generate-btn').prop('disabled', true);
338 206
339 - jQuery.post({
340 - url: ajaxurl, // Make sure ajaxurl is defined in your script
341 - type: 'POST',
342 - data: {
343 - action: 'generate_openai_content',
344 - prompt: document.querySelector('#betterdocs-ai-content').value,
345 - // numOfSections: numOfSections,
346 - // numOfParagraphs: numOfParagraphs,
347 - keywords: keywords,
348 - ai_nonce: nonce, // Pass the nonce value
349 - },
350 - success: function(response) {
351 - // 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
352 220
353 - if (response.success && (typeof response.data === 'string')) {
354 - docGenerateBtnTxt.innerHTML = "<?php echo esc_html__( 'Generated', 'betterdocs' ); ?>";
355 - setTimeout(() => {
356 - insertContentToEditor(title, response.data, isOverwrite, keywords);
357 - docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
358 - jQuery('.generate-btn').removeAttr('disabled');
359 - }, 2000);
360 - } else {
361 - // alert(response.data.message);
362 - jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
363 - jQuery('#betterdocs-ai-error-message').html(responseMessage(response.data.message));
364 - docGenerateBtnTxt.innerHTML = generateDocLabel;
365 - 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');
366 227
367 - }
368 - },
369 - error: function(error) {
370 - console.error(error);
371 - },
372 - });
228 + // console.log(jQuery('.betterdocs-ai-autowrite-form-container').data('new-doc-page'));
373 229
374 - }
375 - }
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');
376 240
377 - // Function to update the textarea
378 - function updateTextarea() {
379 - const title = document.getElementById('betterdocs-ai-title').value;
380 - const keywords = document.getElementById('betterdocs-ai-keyword').value;
381 - const sectionOptions = document.getElementById('bd-autowrtite-content-section');
382 - let language = 'English';
241 + }
242 + },
243 + error: function(error) {
244 + console.error(error);
245 + },
246 + });
383 247
384 - if (language === '') {
385 - language = 'English';
386 - }
248 + }
249 + }
387 250
388 - let keywordsText = keywords !== '' ? ` and incorporate the keywords: ${keywords}` : '';
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';
389 257
390 - const contentTextArea = document.getElementById('betterdocs-ai-content');
258 + if (language === '') {
259 + language = 'English';
260 + }
391 261
392 - if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
393 - jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
394 - }
262 + let keywordsText = keywords !== '' ? ` and incorporate the keywords: ${keywords}` : '';
395 263
396 - 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.`;
397 - }
264 + const contentTextArea = document.getElementById('betterdocs-ai-content');
398 265
399 - function convertMarkdownToHTML(markdownContent) {
400 - // Simple Markdown to HTML conversion (you may need to enhance this based on your needs)
401 - const htmlContent = markdownContent
402 - .replace(/^# (.+)$/gm, '<h1>$1</h1>')
403 - .replace(/^## (.+)$/gm, '<h2>$1</h2>')
404 - .replace(/^### (.+)$/gm, '<h3>$1</h3>')
405 - .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
406 - .replace(/\*(.+?)\*/g, '<em>$1</em>');
266 + if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
267 + jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
268 + }
407 269
408 - return htmlContent;
409 - }
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 + }
410 272
411 - function replaceHeadingTitle(content, title, overviewTitle) {
412 - let regex = new RegExp(title, 'g');
413 - let updateContent = content.replace(regex, overviewTitle);
414 - return updateContent;
415 - }
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>');
416 281
417 - function removeFirstHeading(htmlString) {
418 - var newDiv = document.createElement('div');
419 - newDiv.innerHTML = htmlString;
420 - var firstHeading = newDiv.querySelector('h1');
421 - if (firstHeading) {
422 - firstHeading.parentNode.removeChild(firstHeading);
423 - }
424 - return newDiv.innerHTML;
425 - }
282 + return htmlContent;
283 + }
426 284
285 + function replaceHeadingTitle(content, title, overviewTitle) {
286 + let regex = new RegExp(title, 'g');
287 + let updateContent = content.replace(regex, overviewTitle);
288 + return updateContent;
289 + }
427 290
428 - function escapeHtml(str) {
429 - return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
430 - }
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 + }
431 300
432 - function escapeRegex(str) {
433 - return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
434 - }
435 301
436 - function stripCodeFences(htmlString) {
437 - if (!htmlString) {
438 - return '';
439 - }
440 - return htmlString
441 - .replace(/^\s*```(?:html|HTML)?\s*\n?/, '')
442 - .replace(/\n?\s*```\s*$/, '');
443 - }
302 + function wrapwithHeighlight(inputString, keywords) {
303 + let modifiedString = inputString.replace(/<(h\d)(.*?)>(.*?)<\/\1>/g, '<$1$2><span class="highlight">$3</span></$1>');
444 304
445 - function wrapwithHeighlight(inputString, keywords) {
446 - if (!inputString) {
447 - return '';
448 - }
305 + const keywordArray = keywords.split(',').map(keyword => keyword.trim());
449 306
450 - const container = document.createElement('div');
451 - container.innerHTML = inputString;
307 + keywordArray.forEach(keyword => {
308 + modifiedString = modifiedString.replace(new RegExp(`\\b(${keyword})\\b`, 'gi'), '<span class="highlight">$1</span>');
309 + });
452 310
453 - // Wrap each heading's visible text with the highlight span (skip if already present)
454 - container.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(function (heading) {
455 - if (heading.querySelector('.highlight')) {
456 - return;
457 - }
458 - const text = heading.textContent;
459 - if (!text || !text.trim()) {
460 - return;
461 - }
462 - heading.innerHTML = '<span class="highlight">' + escapeHtml(text) + '</span>';
463 - });
311 + return modifiedString;
312 + }
464 313
465 - // Wrap keywords only inside text nodes — never inside attributes, code, or existing highlights
466 - const keywordList = (keywords || '')
467 - .split(',')
468 - .map(function (k) { return k.trim(); })
469 - .filter(Boolean);
314 + function getBodyContent(htmlString) {
315 + var match = htmlString.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
470 316
471 - if (keywordList.length) {
472 - const pattern = new RegExp('\\b(' + keywordList.map(escapeRegex).join('|') + ')\\b', 'gi');
473 - const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, {
474 - acceptNode: function (node) {
475 - let parent = node.parentNode;
476 - while (parent && parent !== container) {
477 - if (parent.nodeType === 1) {
478 - const tag = parent.tagName.toLowerCase();
479 - if (tag === 'code' || tag === 'pre') {
480 - return NodeFilter.FILTER_REJECT;
481 - }
482 - if (parent.classList && parent.classList.contains('highlight')) {
483 - return NodeFilter.FILTER_REJECT;
484 - }
485 - }
486 - parent = parent.parentNode;
487 - }
488 - return NodeFilter.FILTER_ACCEPT;
489 - }
490 - });
317 + console.log(match[1].replace(/<p>\s+/g, '<p>'));
491 318
492 - const textNodes = [];
493 - let current;
494 - while ((current = walker.nextNode())) {
495 - textNodes.push(current);
496 - }
319 + return match ? match[1].replace(/<p>\s+/g, '<p>') : '';
320 + }
497 321
498 - textNodes.forEach(function (textNode) {
499 - pattern.lastIndex = 0;
500 - if (!pattern.test(textNode.nodeValue)) {
501 - return;
502 - }
503 - pattern.lastIndex = 0;
504 - const fragmentHost = document.createElement('span');
505 - fragmentHost.innerHTML = escapeHtml(textNode.nodeValue).replace(pattern, '<span class="highlight">$1</span>');
506 - const parent = textNode.parentNode;
507 - while (fragmentHost.firstChild) {
508 - parent.insertBefore(fragmentHost.firstChild, textNode);
509 - }
510 - parent.removeChild(textNode);
511 - });
512 - }
513 322
514 - return container.innerHTML;
515 - }
323 + function insertContentToEditor(title, htmlContent, isOverwrite, keywords) {
516 324
517 - function getBodyContent(htmlString) {
518 - if (!htmlString) {
519 - return '';
520 - }
521 - const cleaned = stripCodeFences(htmlString);
522 - const match = cleaned.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
523 - if (match) {
524 - return match[1].replace(/<p>\s+/g, '<p>');
525 - }
526 - return cleaned;
527 - }
325 + const {
326 + dispatch,
327 + select
328 + } = wp.data;
528 329
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']) : ''; ?>`;
529 334
335 + const blocks = wp.blocks.rawHandler({
336 + HTML: htmlContent
337 + });
530 338
531 - function insertContentToEditor(title, htmlContent, isOverwrite, keywords) {
339 + dispatch('core/editor').editPost({
340 + title: title,
341 + });
532 342
533 - const {
534 - dispatch,
535 - select
536 - } = wp.data;
343 + const selectedBlockClientId = select('core/block-editor').getSelectedBlockClientId();
537 344
538 - htmlContent = getBodyContent(htmlContent);
539 - htmlContent = removeFirstHeading(htmlContent);
540 - htmlContent = wrapwithHeighlight(htmlContent, keywords);
541 - const isPostContent = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_content( $_GET[ 'post' ] ) ) : ''; // phpcs:ignore ?>`;
345 + const allBlocks = select('core/block-editor').getBlocks();
542 346
543 - const blocks = wp.blocks.rawHandler({
544 - HTML: htmlContent
545 - });
347 + if (isOverwrite || isPostContent === '') {
546 348
547 - dispatch('core/editor').editPost({
548 - title: title,
549 - });
349 + allBlocks.forEach((block) => {
350 + dispatch('core/block-editor').removeBlock(block.clientId);
351 + });
352 + dispatch('core/block-editor').insertBlocks(blocks);
550 353
551 - const selectedBlockClientId = select('core/block-editor').getSelectedBlockClientId();
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 + }
552 360
553 - const allBlocks = select('core/block-editor').getBlocks();
361 + closeWriteWithAIForm('afterInsertContent');
362 + }
554 363
555 - if (isOverwrite || isPostContent === '') {
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 + }
556 369
557 - allBlocks.forEach((block) => {
558 - dispatch('core/block-editor').removeBlock(block.clientId);
559 - });
560 - dispatch('core/block-editor').insertBlocks(blocks);
561 370
562 - } else if (selectedBlockClientId) {
563 - const selectedIndex = select('core/block-editor').getBlockIndex(selectedBlockClientId);
564 - dispatch('core/block-editor').insertBlocks(blocks, selectedIndex + 1);
565 - } else {
566 - dispatch('core/block-editor').insertBlocks(blocks);
567 - }
371 + document.addEventListener('DOMContentLoaded', function() {
568 372
569 - closeWriteWithAIForm('afterInsertContent');
570 - }
373 + // Subscribe to changes in the editor state
374 + let previousDocsTitle = '';
571 375
572 - function closeWriteWithAIForm(after) {
573 - jQuery('.betterdocs-ai-autowrite-form-container').addClass('hidden');
574 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').addClass('hidden');
575 - jQuery('.betterdocs-ai-button').addClass('regenerate-btn');
576 - }
376 + wp.data.subscribe(() => {
377 + // Get the updated post title
378 + // const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
577 379
380 + const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
578 381
579 - document.addEventListener('DOMContentLoaded', function() {
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);
580 390
581 - // Subscribe to changes in the editor state
582 - let previousDocsTitle = '';
391 + jQuery('#betterdocs-ai-title').val(docsTitle);
583 392
584 - wp.data.subscribe(() => {
585 - // Get the updated post title
586 - // const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
393 + previousDocsTitle = docsTitle;
394 + }
587 395
588 - const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
589 396
590 - // Check if the title has changed
591 - if (docsTitle !== previousDocsTitle) {
592 - let currentKeywords = jQuery('#betterdocs-ai-keyword').val();
593 - if (!currentKeywords) {
594 - currentKeywords = '{Documentation Keywords}';
595 - }
596 - 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.`;
597 - jQuery('#betterdocs-ai-content').val(currentPrompt);
397 + });
398 + });
598 399
599 - jQuery('#betterdocs-ai-title').val(docsTitle);
600 400
601 - previousDocsTitle = docsTitle;
602 - }
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.
603 403
604 404
605 - });
606 - });
405 + function writeWithAIForm() {
607 406
407 + let title = `<?php echo isset($_GET['post']) ? get_the_title($_GET['post']) : ''; ?>`;
408 + if (docsTitle) {
409 + title = docsTitle;
410 + }
608 411
609 - // This example assumes that this code is executed when your script is loaded.
610 - // You may want to place it within the appropriate context in your application.
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')); ?>";
611 427
612 -
613 - function writeWithAIForm() {
614 -
615 - let title = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_title( $_GET[ 'post' ] ) ) : ''; // phpcs:ignore ?>`;
616 - if (docsTitle) {
617 - title = docsTitle;
618 - }
619 -
620 - const promtTitle = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_title( $_GET[ 'post' ] ) ) : '{Documentation Title}'; // phpcs:ignore ?>`;
621 - const titlePlaceholder = "<?php echo esc_attr__( 'Enter a descriptive title for your documentation.', 'betterdocs' ); ?>";
622 - const keywords = "<?php echo esc_attr( '{Documentation Keywords}' ); ?>";
623 - const keywordsPlaceholder = "<?php echo esc_attr__( 'Add keywords to generate precise & relevant documentation (comma-separated).', 'betterdocs' ); ?>";
624 - const language = "<?php echo esc_attr( 'English' ); ?>";
625 - const titleLabel = "<?php echo esc_html__( 'Documentation Title:', 'betterdocs' ); ?>";
626 - const keywordLabel = "<?php echo esc_html__( 'Keywords:', 'betterdocs' ); ?>";
627 - const secLabel = "<?php echo esc_html__( '# of Sections:', 'betterdocs' ); ?>";
628 - const paraLabel = "<?php echo esc_html__( '# of Paragraph Per Section: ', 'betterdocs' ); ?>";
629 - const langLabel = "<?php echo esc_html__( 'Language:', 'betterdocs' ); ?>";
630 - const promtLabel = "<?php echo esc_html__( 'Prompt:', 'betterdocs' ); ?>";
631 - const promtBtnLabel = "<?php echo esc_html__( 'Generate Prompt', 'betterdocs' ); ?>";
632 - let promtArticleLabel = "<?php echo esc_html__( 'Generate Doc', 'betterdocs' ); ?>";
633 - const checkboxLabel = "<?php echo esc_html__( 'Overwrite your existing Doc:', 'betterdocs' ); ?>";
634 - const nonce = "<?php echo esc_attr( wp_create_nonce( 'generate_openai_content_nonce' ) ); ?>";
635 -
636 - <?php
637 - $is_valid = $this->get_api_key();
638 - $disable_field = 'disabled-input-field';
639 - if ( $this->get_api_key() ) {
640 - $disable_field = '';
641 - }
428 + <?php $is_valid = $this->get_api_key();
429 + $disable_field = 'disabled-input-field';
430 + if ($this->get_api_key()) {
431 + $disable_field = '';
432 + }
642 433 ?>
643 434
644 - let hiddenClass = 'hidden';
645 - let newDocPageAtt = 'data-new-doc-page="true"';
646 - const isPostContent = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_content( $_GET[ 'post' ] ) ) : ''; // phpcs:ignore ?>`;
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']) : ''; ?>`;
647 438
648 - if (isPostContent !== '') {
649 - hiddenClass = '';
650 - newDocPageAtt = '';
651 - }
439 + if (isPostContent !== '') {
440 + hiddenClass = '';
441 + newDocPageAtt = '';
442 + }
652 443
653 444
654 - // 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.`;
655 446
656 - // 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.`;
657 448
658 - 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.`;
659 450
660 - const aiIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="21" height="20" viewBox="0 0 21 20" fill="none">
661 - <g clip-path="url(#clip0_2460_1729)">
662 - <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"/>
663 - </g>
664 - <defs>
665 - <clipPath id="clip0_2460_1729">
666 - <rect width="20" height="20" fill="white" transform="translate(0.5)"/>
667 - </clipPath>
668 - </defs>
669 - </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>`;
670 461
671 462
672 463
673 - return `
674 - <div class="betterdocs-ai-autowrite-form-container hidden" ${newDocPageAtt}>
675 - <div class="betterdocs-ai-autowrite-form-content">
676 - <div class="betterdocs-ai-autowrite-top-part">
677 - <div class="autowrite-heading">
678 - <span class="autowrite-icon">
679 - <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
680 - <g clip-path="url(#clip0_2453_20882)">
681 - <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"/>
682 - </g>
683 - <defs>
684 - <clipPath id="clip0_2453_20882">
685 - <rect width="32" height="32" fill="white"/>
686 - </clipPath>
687 - </defs>
688 - </svg>
689 - </span>
690 - <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>
691 482
692 - </div>
693 - <div class="autowrite-subheadding">
694 - <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>
695 - </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>
696 487
697 - <?php if ( empty( $this->get_api_key() ) ): ?>
698 - <div id="betterdocs-ai-message">
699 - <div class="warning-message">
700 - <span class="dashicons dashicons-warning"></span>
701 - <div>
702 - <?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' ); ?>
703 - </div>
704 - </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>
705 496
706 - </div>
707 - <?php endif; ?>
497 + </div>
498 + <?php endif; ?>
708 499
709 - <div class="form-group hidden">
710 - <div id="betterdocs-ai-error-message"></div>
711 - </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>
712 511
713 - </div>
714 - <form id="betterdocs-ai-form" class="<?php echo esc_attr( $disable_field ); ?>">
715 - <div class="form-inner-content">
716 - <div class="form-group">
717 - <label for="betterdocs-ai-title">${titleLabel}</label>
718 - <input type="text" placeholder="${titlePlaceholder}" id="betterdocs-ai-title" name="betterdocs-ai-title" required value="${title}">
719 - </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>
720 516
721 - <div class="form-group">
722 - <label for="betterdocs-ai-keyword">${keywordLabel}</label>
723 - <input type="text" placeholder="${keywordsPlaceholder}" id="betterdocs-ai-keyword" name="betterdocs-ai-keyword" required>
724 - </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>
725 535
726 - <div class="form-group prompt-field">
727 - <label for="betterdocs-ai-content">${promtLabel}</label>
728 - <textarea id="betterdocs-ai-content" name="betterdocs-ai-content" rows="6" required>${prompt}</textarea>
729 - <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>
730 - </div>
731 - <div class="betterdocs-ai-checkbox-field ${hiddenClass}">
732 - <div class="form-group">
733 - <div class="checkbox-field-label">
734 - <label for="betterdocs-ai-checkbox">${checkboxLabel}</label>
735 - <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>
736 - </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>
737 545
738 - <div class="checkbox-input-field">
739 - <input type="checkbox" id="betterdocs-ai-checkbox" name="betterdocs-ai-checkbox" data-overwrite="false">
740 - <label for="betterdocs-ai-checkbox" class="toggle-label"></label>
741 - </div>
742 - </div>
743 - </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 + }
744 552
745 - <input type="hidden" name="ai_nonce" value="${nonce}" />
746 - </div>
747 - <div class="generate-button-container">
748 - <button type="submit" class="generate-btn" onclick="generateArticle(event)">
749 - ${aiIcon} <span>${promtArticleLabel}</span>
750 - </button>
751 - </div>
752 - </form>
753 - </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 + });
754 557
755 - <div class="bd-close-button" onclick="closeWriteWithAIForm('afterClosedClicked')">✕</div>
756 - </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');
757 568
758 - <div id="betterdocs-ai-autowrite-form-container-overlay" class="hidden"></div>
759 - `;
760 - }
569 + const formHtml = writeWithAIForm();
570 + $(formHtml).addClass('hidden');
761 571
762 - jQuery(document).on('click', '.regenerate-btn', function() {
763 - jQuery('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
764 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
765 - });
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 + });
766 576
767 - jQuery(document).ready(function($) {
768 - // 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);
769 580
770 - 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 + }
771 598
772 - const bdAIButton = $(`<div class="betterdocs-ai-button-container">
773 - <button class="betterdocs-ai-button">
774 - <img src="<?php echo esc_url( BETTERDOCS_ABSURL . 'assets/admin/images/betterdocs-icon-white.png' ); ?>" alt="<?php echo esc_attr__( 'betterdocs icon', 'betterdocs' ); ?>" />
775 - <span><?php echo esc_html__( 'Write with AI', 'betterdocs' ); ?></span>
776 - </button>
777 - </div>`);
599 + $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
600 + closeWriteWithAIForm();
601 + });
602 + });
603 + </script>
778 604
605 + <style>
606 + .hidden {
607 + display: none !important;
608 + }
779 609
780 - 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 + }
781 617
782 - const formHtml = writeWithAIForm();
783 - $(formHtml).addClass('hidden');
618 + .disabled-input-field label {
619 + opacity: 1;
620 + }
784 621
785 - $(document).on('click', '.betterdocs-ai-button', function() {
786 - $('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
787 - $('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
788 - });
622 + .betterdocs-ai-button-container {
623 + margin-left: 10px;
624 + }
789 625
790 - // $(document).on('click', '.betterdocs-ai-button', function() {
791 - if ($('.betterdocs-ai-autowrite-form-container').length < 1) {
792 - $('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 + }
793 635
794 - // Add event listeners to input elements
795 - document.getElementById('betterdocs-ai-title').addEventListener('input', updateTextarea);
796 - document.getElementById('betterdocs-ai-keyword').addEventListener('input', updateTextarea);
797 - // document.getElementById('bd-autowrtite-content-section').addEventListener('change', updateTextarea);
798 - // document.getElementById('bd-autowrtite-content-paragraph').addEventListener('change', updateTextarea);
799 - // document.getElementById('betterdocs-ai-language').addEventListener('input', updateTextarea);
800 - }
801 - // });
802 - const btn = document.createElement('button');
803 - wp.data.subscribe(function() {
804 - setTimeout(() => {
805 - if ($('.edit-post-header__settings').length > 0) {
806 - $('.edit-post-header__settings').prepend(bdAIButton);
807 - } else if ($('.editor-header__settings').length > 0) {
808 - $('.editor-header__settings').prepend(bdAIButton);
809 - }
636 + .autowrite-icon svg {
637 + width: 28px;
638 + height: 28px;
639 + }
810 640
811 - }, 1);
812 - });
813 - }
641 + .autowrite-heading {
642 + display: flex;
643 + gap: 10px;
644 + align-items: center;
645 + }
814 646
815 - $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
816 - closeWriteWithAIForm();
817 - });
818 - });
819 - </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 + }
820 656
821 - <style>
822 - .hidden {
823 - display: none !important;
824 - }
657 + .autowrite-heading p,
658 + form#betterdocs-ai-form p {
659 + margin: 0;
660 + margin-bottom: 24px;
661 + }
825 662
826 - .disabled-input-field input,
827 - .disabled-input-field textarea,
828 - .disabled-input-field button,
829 - .disabled-input-field label {
830 - pointer-events: none;
831 - opacity: 0.6;
832 - }
663 + .autowrite-subheadding p {
664 + font-family: 'IBM Plex Sans', sans-serif;
665 + font-size: 14px;
666 + }
833 667
834 - .disabled-input-field label {
835 - opacity: 1;
836 - }
668 + .prompt-field .input-description {
669 + margin: 0 !important;
670 + }
837 671
838 - .betterdocs-ai-button-container {
839 - margin-left: 10px;
840 - white-space: nowrap;
841 - max-width: 145px;
842 - }
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 + }
843 679
844 - .autowrite-icon {
845 - display: flex;
846 - align-items: center;
847 - width: 55px;
848 - height: 55px;
849 - background: #FFE4E8;
850 - justify-content: center;
851 - border-radius: 50px;
852 - }
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 + }
853 696
854 - .autowrite-icon svg {
855 - width: 28px;
856 - height: 28px;
857 - }
697 + .betterdocs-ai-button img {
698 + width: 20px;
699 + height: 20px;
700 + }
858 701
859 - .autowrite-heading {
860 - display: flex;
861 - gap: 10px;
862 - align-items: center;
863 - }
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 + }
864 717
865 - .autowrite-heading h1 {
866 - color: #1D2939;
867 - font-family: 'IBM Plex Sans', sans-serif;
868 - font-size: 24px;
869 - font-style: normal;
870 - font-weight: 500;
871 - line-height: normal;
872 - margin: 0;
873 - }
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%;
874 726
875 - .autowrite-heading p,
876 - form#betterdocs-ai-form p {
877 - margin: 0;
878 - margin-bottom: 24px;
879 - }
727 + }
880 728
881 - .autowrite-subheadding p {
882 - font-family: 'IBM Plex Sans', sans-serif;
883 - font-size: 14px;
884 - }
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 + }
885 735
886 - .prompt-field .input-description {
887 - margin: 0 !important;
888 - }
736 + #betterdocs-ai-form {
737 + display: flex;
738 + flex-direction: column;
739 + /* height: 100%; */
740 + overflow: hidden;
741 + }
889 742
890 - .autowrite-heading p {
891 - color: #475467;
892 - font-family: 'IBM Plex Sans', sans-serif;
893 - font-size: 16px;
894 - font-style: normal;
895 - font-weight: 400;
896 - }
743 + .form-inner-content {
744 + overflow: auto;
745 + height: 100%;
746 + max-height: 435px;
747 + /* max-height: 330px; */
748 + padding: 0 40px;
749 + }
897 750
898 - .betterdocs-ai-button {
899 - background: #00B884;
900 - border: 1px solid transparent;
901 - color: #fff;
902 - box-shadow: none;
903 - font-size: 12px;
904 - margin-right: 8px;
905 - padding: 0px 15px;
906 - cursor: pointer;
907 - border-radius: 3px;
908 - height: 38px;
909 - display: flex;
910 - align-items: center;
911 - justify-content: space-between;
912 - gap: 10px;
913 - width: 135px;
914 - }
751 + .form-inner-content>.form-group {
752 + margin-top: 20px;
753 + }
915 754
916 - .betterdocs-ai-button img {
917 - width: 20px;
918 - height: 20px;
919 - }
920 755
921 - .betterdocs-ai-autowrite-form-container {
922 - position: fixed;
923 - top: 50%;
924 - left: 50%;
925 - transform: translate(-50%, -50%);
926 - z-index: 100001;
927 - width: 650px;
928 - margin: 0 auto;
929 - background-color: #fff;
930 - border-radius: 5px;
931 - font-family: 'IBM Plex Sans', sans-serif;
932 - /* max-height: 600px; */
933 - max-height: 750px;
934 - max-width: 100%;
935 - }
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 + }
936 765
937 - .betterdocs-ai-autowrite-form-content {
938 - background-color: #fff;
939 - padding: 20px 0px;
940 - border-radius: 5px;
941 - padding-bottom: 0;
942 - overflow: auto;
943 - /* max-height: 700px; */
944 - height: 100%;
945 766
946 - }
947 767
948 - .betterdocs-ai-autowrite-top-part {
949 - /* padding-bottom: 20px; */
950 - border-bottom: 1px solid #ddd;
951 - /* margin-bottom: 20px; */
952 - padding: 0 40px;
953 - }
768 + #betterdocs-ai-form {
769 + display: flex;
770 + flex-direction: column;
771 + }
954 772
955 - #betterdocs-ai-form {
956 - display: flex;
957 - flex-direction: column;
958 - /* height: 100%; */
959 - overflow: hidden;
960 - }
773 + #betterdocs-ai-form .form-group {
774 + margin-bottom: 24px;
775 + }
961 776
962 - .form-inner-content {
963 - overflow: auto;
964 - height: 100%;
965 - max-height: 435px;
966 - /* max-height: 330px; */
967 - padding: 0 40px;
968 - }
777 + #betterdocs-ai-form .bd-aiform-flex {
778 + display: flex;
779 + justify-content: space-between;
780 + }
969 781
970 - .form-inner-content>.form-group {
971 - margin-top: 20px;
972 - }
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 + }
973 789
790 + select#bd-autowrtite-content-section,
791 + #bd-autowrtite-content-paragraph,
792 + #betterdocs-ai-language {
793 + width: 150px !important;
794 + height: 40px;
795 + }
974 796
975 - #betterdocs-ai-autowrite-form-container-overlay {
976 - position: fixed;
977 - top: 0;
978 - right: 0;
979 - bottom: 0;
980 - left: 0;
981 - background-color: rgba(0, 0, 0, .7);
982 - z-index: 100000;
983 - }
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 + }
984 807
808 + /* Override autofill text color */
809 + #betterdocs-ai-form input:-webkit-autofill {
810 + -webkit-text-fill-color: #667085 !important;
811 + }
985 812
813 + #betterdocs-ai-form input::placeholder {
814 + color: #acb2bf;
815 + }
986 816
987 - #betterdocs-ai-form {
988 - display: flex;
989 - flex-direction: column;
990 - }
817 + #betterdocs-ai-form textarea {
818 + color: #667085;
819 + }
991 820
992 - #betterdocs-ai-form .form-group {
993 - margin-bottom: 24px;
994 - }
821 + #betterdocs-ai-form input:focus,
822 + #betterdocs-ai-form textarea:focus {
823 + box-shadow: none;
824 + }
995 825
996 - #betterdocs-ai-form .bd-aiform-flex {
997 - display: flex;
998 - justify-content: space-between;
999 - }
826 + #betterdocs-ai-form textarea:focus {
827 + color: inherit;
828 + box-shadow: none;
1000 829
1001 - #betterdocs-ai-form label {
1002 - font-weight: 600;
1003 - margin-bottom: 5px;
1004 - display: block;
1005 - font-size: 14px;
1006 - line-height: 20px;
1007 - }
830 + }
1008 831
1009 - select#bd-autowrtite-content-section,
1010 - #bd-autowrtite-content-paragraph,
1011 - #betterdocs-ai-language {
1012 - width: 150px !important;
1013 - height: 40px;
1014 - }
1015 832
1016 - #betterdocs-ai-form input[type="text"],
1017 - #betterdocs-ai-form textarea {
1018 - width: 100%;
1019 - padding: 8px;
1020 - box-sizing: border-box;
1021 - border: 1px solid #D0D5DD;
1022 - border-radius: 4px;
1023 - color: #667085;
1024 - font-weight: 400;
1025 - }
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 + }
1026 847
1027 - /* Override autofill text color */
1028 - #betterdocs-ai-form input:-webkit-autofill {
1029 - -webkit-text-fill-color: #667085 !important;
1030 - }
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 + }
1031 856
1032 - #betterdocs-ai-form input::placeholder {
1033 - color: #acb2bf;
1034 - }
857 + .input-description {
858 + font-size: 14px;
859 + color: #667085;
860 + }
1035 861
1036 - #betterdocs-ai-form textarea {
1037 - color: #667085;
1038 - }
862 + .betterdocs-ai-checkbox-field .form-group {
863 + display: flex;
864 + align-items: start;
865 + /* gap: 200px; */
866 + justify-content: space-between;
867 + }
1039 868
1040 - #betterdocs-ai-form input:focus,
1041 - #betterdocs-ai-form textarea:focus {
1042 - box-shadow: none;
1043 - }
869 + .betterdocs-ai-checkbox-field input {
870 + width: 20px;
871 + height: 20px;
872 + }
1044 873
1045 - #betterdocs-ai-form textarea:focus {
1046 - color: inherit;
1047 - box-shadow: none;
874 + /* Add this CSS to your existing stylesheet or create a new one */
1048 875
1049 - }
876 + .betterdocs-ai-checkbox-field {
877 + position: relative;
878 + font-size: 16px;
879 + /* Adjust font size as needed */
880 + }
1050 881
882 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
883 + padding: 2px;
884 + }
1051 885
1052 - .generate-button-container {
1053 - position: sticky;
1054 - bottom: 0px;
1055 - width: 100%;
1056 - margin-left: 0;
1057 - z-index: 999999 !important;
1058 - padding: 20px 0;
1059 - display: flex;
1060 - justify-content: end;
1061 - border-top: 1px solid #ddd;
1062 - background: white;
1063 - border-bottom-right-radius: 5px;
1064 - border-bottom-left-radius: 5px;
1065 - }
886 + .betterdocs-ai-checkbox-field input[type=checkbox] {
887 + border: 1px solid #00b884;
888 + }
1066 889
1067 - .generate-button-container button {
1068 - display: flex;
1069 - gap: 8px;
1070 - align-items: center;
1071 - justify-content: center;
1072 - opacity: 1 !important;
1073 - margin-right: 40px;
1074 - }
890 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
891 + content: '\2713';
892 + color: #00b884;
893 + }
1075 894
1076 - .input-description {
1077 - font-size: 14px;
1078 - color: #667085;
1079 - }
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 + }
1080 908
1081 - .betterdocs-ai-checkbox-field .form-group {
1082 - display: flex;
1083 - align-items: start;
1084 - /* gap: 200px; */
1085 - justify-content: space-between;
1086 - }
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 + }
1087 915
1088 - .betterdocs-ai-checkbox-field input {
1089 - width: 20px;
1090 - height: 20px;
1091 - }
916 + .checkbox-field-label {
917 + width: calc(100% - 150px);
918 + }
1092 919
1093 - /* Add this CSS to your existing stylesheet or create a new one */
920 + .checkbox-field-label p {
921 + margin: 0 !important;
922 + }
1094 923
1095 - .betterdocs-ai-checkbox-field {
1096 - position: relative;
1097 - font-size: 16px;
1098 - /* Adjust font size as needed */
1099 - }
924 + .checkbox-input-field {
925 + width: 300px;
926 + text-align: right;
927 + }
1100 928
1101 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1102 - padding: 2px;
1103 - }
929 + .checkbox-input-field {
930 + position: relative;
931 + display: inline-block;
932 + width: 60px;
933 + height: 34px;
934 + }
1104 935
1105 - .betterdocs-ai-checkbox-field input[type=checkbox] {
1106 - border: 1px solid #00b884;
1107 - }
936 + .checkbox-input-field input {
937 + display: none;
938 + }
1108 939
1109 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1110 - content: '\2713';
1111 - color: #00b884;
1112 - }
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 + }
1113 954
1114 - /* Change the default checkbox color */
1115 - .betterdocs-ai-checkbox-field input[type="checkbox"]:hover {
1116 - -webkit-appearance: none;
1117 - /* WebKit/Blink Browsers */
1118 - -moz-appearance: none;
1119 - /* Firefox */
1120 - appearance: none;
1121 - border: 1px solid #00b884;
1122 - /* Set the height of the checkbox */
1123 - /* Optional: Round the corners */
1124 - outline: none;
1125 - /* Remove the default outline */
1126 - }
1127 955
1128 - /* Style the checked state */
1129 - .betterdocs-ai-checkbox-field input[type="checkbox"]:checked {
1130 - /* Set the background color when checked */
1131 - border: 1px solid #00b884;
1132 - /* Set the border color when checked */
1133 - }
956 + .checkbox-input-field input:checked+.toggle-label {
957 + background-color: #00b884;
958 + }
1134 959
1135 - .checkbox-field-label {
1136 - width: calc(100% - 150px);
1137 - }
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 + }
1138 971
1139 - .checkbox-field-label p {
1140 - margin: 0 !important;
1141 - }
972 + .checkbox-input-field input:checked+.toggle-label:after {
973 + transform: translateX(26px);
974 + }
1142 975
1143 - .checkbox-input-field {
1144 - width: 300px;
1145 - text-align: right;
1146 - }
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 + }
1147 990
1148 - .checkbox-input-field {
1149 - position: relative;
1150 - display: inline-block;
1151 - width: 60px;
1152 - height: 34px;
1153 - }
991 + .generate-btn[disabled] {
992 + cursor: unset;
993 + }
1154 994
1155 - .checkbox-input-field input {
1156 - display: none;
1157 - }
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 + }
1158 1014
1159 - .toggle-label {
1160 - position: absolute;
1161 - cursor: pointer;
1162 - top: 0;
1163 - left: 0;
1164 - right: 0;
1165 - bottom: 0;
1166 - background-color: #ccc;
1167 - border-radius: 34px;
1168 - transition: background-color 0.3s;
1169 - scale: .9;
1170 - width: 52px;
1171 - height: 26px;
1172 - }
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 + }
1173 1022
1023 + div#betterdocs-ai-error-message a,
1024 + #betterdocs-ai-message a {
1025 + text-decoration: none;
1026 + font-weight: 600;
1027 + }
1174 1028
1175 - .checkbox-input-field input:checked+.toggle-label {
1176 - background-color: #00b884;
1177 - }
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 + }
1178 1035
1179 - .toggle-label:after {
1180 - content: "";
1181 - position: absolute;
1182 - height: 22px;
1183 - width: 22px;
1184 - left: 2px;
1185 - bottom: 2px;
1186 - background-color: white;
1187 - border-radius: 50%;
1188 - transition: transform 0.3s;
1189 - }
1036 + #betterdocs-ai-message span {
1037 + color: #d63638;
1038 + }
1190 1039
1191 - .checkbox-input-field input:checked+.toggle-label:after {
1192 - transform: translateX(26px);
1193 - }
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 + }
1194 1051
1195 - .generate-btn,
1196 - .prompt-btn,
1197 - .keep-btn {
1198 - background-color: #00b884;
1199 - color: #fff;
1200 - border: none;
1201 - padding: 10px 15px;
1202 - text-align: center;
1203 - text-decoration: none;
1204 - display: inline-block;
1205 - font-size: 16px;
1206 - cursor: pointer;
1207 - border-radius: 4px;
1208 - }
1052 + .warning-message svg {
1053 + width: 20px;
1054 + height: 20px;
1055 + }
1209 1056
1210 - .generate-btn[disabled] {
1211 - cursor: unset;
1212 - }
1057 + .warning-message span {
1058 + color: #d63638;
1059 + }
1213 1060
1214 - .bd-close-button {
1215 - cursor: pointer;
1216 - font-size: 18px;
1217 - font-weight: bold;
1218 - float: right;
1219 - position: absolute;
1220 - top: -16px;
1221 - border-radius: 50%;
1222 - background: #ffffff;
1223 - width: 40px;
1224 - height: 40px;
1225 - display: flex;
1226 - align-items: center;
1227 - justify-content: center;
1228 - color: #281617;
1229 - right: -42px;
1230 - }
1061 + .warning-message .footer-message {
1062 + width: calc(100% - 20px);
1063 + }
1231 1064
1232 - div#betterdocs-ai-error-message,
1233 - #betterdocs-ai-message {
1234 - font-size: 14px;
1235 - font-family: 'IBM Plex Sans', sans-serif;
1236 - color: #667085;
1237 - margin-bottom: 20px;
1238 - }
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 + }
1239 1071
1240 - div#betterdocs-ai-error-message a,
1241 - #betterdocs-ai-message a {
1242 - text-decoration: none;
1243 - font-weight: 600;
1244 - }
1072 + .betterdocs-ai-autowrite-form-content {
1073 + overflow-x: auto;
1074 + }
1075 + }
1245 1076
1246 - div#betterdocs-ai-error-message a:focus,
1247 - #betterdocs-ai-message a:focus {
1248 - outline: none;
1249 - box-shadow: none;
1250 - color: #2271b1;
1251 - }
1077 + @media only screen and (max-width: 740px) {
1252 1078
1253 - #betterdocs-ai-message span {
1254 - color: #d63638;
1255 - }
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 + }
1256 1095
1257 - .warning-message {
1258 - display: flex;
1259 - align-items: center;
1260 - gap: 10px;
1261 - background: #fbebed;
1262 - padding: 12px;
1263 - border-radius: 5px;
1264 - font-size: 14px;
1265 - line-height: 1.4em;
1266 - border-left: 4px solid #d63638;
1267 - }
1268 -
1269 - .warning-message svg {
1270 - width: 20px;
1271 - height: 20px;
1272 - }
1273 -
1274 - .warning-message span {
1275 - color: #d63638;
1276 - }
1277 -
1278 - .warning-message .footer-message {
1279 - width: calc(100% - 20px);
1280 - }
1281 -
1282 - @media only screen and (max-width: 991px) {
1283 - .betterdocs-ai-autowrite-form-container {
1284 - left: 0;
1285 - right: 0;
1286 - transform: translate(0%, -50%);
1287 - }
1288 -
1289 - .betterdocs-ai-autowrite-form-content {
1290 - overflow-x: auto;
1291 - }
1292 - }
1293 -
1294 - @media only screen and (max-width: 740px) {
1295 -
1296 - /* .bd-close-button {
1297 - right: px;
1298 - top: 1px;
1299 - border-radius: 5px;
1300 - width: 12px;
1301 - height: 12px;
1302 - color: #ffffff;
1303 - background: #00b884;
1304 - } */
1305 - .bd-close-button {
1306 - right: 0px;
1307 - top: 0px;
1308 - width: 12px;
1309 - height: 12px;
1310 - font-size: 14px;
1311 - }
1312 -
1313 - }
1314 - </style>
1315 - <?php
1316 1096 }
1317 - }
1097 + </style>
1098 +<?php
1099 + }
1100 +}