Changeset 3272415
- Timestamp:
- 04/14/2025 12:40:44 PM (10 months ago)
- Location:
- ai-app-onsite
- Files:
-
- 42 edited
- 1 copied
-
tags/1.1.0 (copied) (copied from ai-app-onsite/trunk)
-
tags/1.1.0/ai-app-onsite.php (modified) (8 diffs)
-
tags/1.1.0/assets/css/ai-app-onsite-form-style.css (modified) (10 diffs)
-
tags/1.1.0/assets/css/ai-app-onsite-style.css (modified) (7 diffs)
-
tags/1.1.0/assets/js/ai-app-onsite-admin.js (modified) (8 diffs)
-
tags/1.1.0/assets/js/ai-app-onsite-app-preview.js (modified) (3 diffs)
-
tags/1.1.0/assets/js/ai-app-onsite-app-properties.js (modified) (22 diffs)
-
tags/1.1.0/assets/js/ai-app-onsite-model-settings.js (modified) (13 diffs)
-
tags/1.1.0/assets/js/ai-app-onsite-plugin-settings.js (modified) (4 diffs)
-
tags/1.1.0/assets/js/ai-app-onsite-prompt-editor.js (modified) (2 diffs)
-
tags/1.1.0/handler/ai-app-onsite-app-preview.php (modified) (8 diffs)
-
tags/1.1.0/handler/ai-app-onsite-app-properties.php (modified) (12 diffs)
-
tags/1.1.0/handler/ai-app-onsite-model-settings.php (modified) (5 diffs)
-
tags/1.1.0/handler/ai-app-onsite-prompt-editor.php (modified) (4 diffs)
-
tags/1.1.0/handler/ai-app-onsite-user-stats.php (modified) (2 diffs)
-
tags/1.1.0/includes/class-ai-app-onsite-admin.php (modified) (6 diffs)
-
tags/1.1.0/includes/class-ai-app-onsite-app-preview.php (modified) (2 diffs)
-
tags/1.1.0/includes/class-ai-app-onsite-app-properties.php (modified) (1 diff)
-
tags/1.1.0/includes/class-ai-app-onsite-db-handler.php (modified) (1 diff)
-
tags/1.1.0/includes/class-ai-app-onsite-model-settings.php (modified) (8 diffs)
-
tags/1.1.0/includes/class-ai-app-onsite-plugin-settings.php (modified) (6 diffs)
-
tags/1.1.0/includes/class-ai-app-onsite-prompt-editor.php (modified) (2 diffs)
-
trunk/ai-app-onsite.php (modified) (8 diffs)
-
trunk/assets/css/ai-app-onsite-form-style.css (modified) (10 diffs)
-
trunk/assets/css/ai-app-onsite-style.css (modified) (7 diffs)
-
trunk/assets/js/ai-app-onsite-admin.js (modified) (8 diffs)
-
trunk/assets/js/ai-app-onsite-app-preview.js (modified) (3 diffs)
-
trunk/assets/js/ai-app-onsite-app-properties.js (modified) (22 diffs)
-
trunk/assets/js/ai-app-onsite-model-settings.js (modified) (13 diffs)
-
trunk/assets/js/ai-app-onsite-plugin-settings.js (modified) (4 diffs)
-
trunk/assets/js/ai-app-onsite-prompt-editor.js (modified) (2 diffs)
-
trunk/handler/ai-app-onsite-app-preview.php (modified) (8 diffs)
-
trunk/handler/ai-app-onsite-app-properties.php (modified) (12 diffs)
-
trunk/handler/ai-app-onsite-model-settings.php (modified) (5 diffs)
-
trunk/handler/ai-app-onsite-prompt-editor.php (modified) (4 diffs)
-
trunk/handler/ai-app-onsite-user-stats.php (modified) (2 diffs)
-
trunk/includes/class-ai-app-onsite-admin.php (modified) (6 diffs)
-
trunk/includes/class-ai-app-onsite-app-preview.php (modified) (2 diffs)
-
trunk/includes/class-ai-app-onsite-app-properties.php (modified) (1 diff)
-
trunk/includes/class-ai-app-onsite-db-handler.php (modified) (1 diff)
-
trunk/includes/class-ai-app-onsite-model-settings.php (modified) (8 diffs)
-
trunk/includes/class-ai-app-onsite-plugin-settings.php (modified) (6 diffs)
-
trunk/includes/class-ai-app-onsite-prompt-editor.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ai-app-onsite/tags/1.1.0/ai-app-onsite.php
r3250856 r3272415 4 4 * Plugin Name: AI App Onsite 5 5 * Description: AIappOnsite - AI Web App Creator WP Plugin allows users to create their own AI-powered web app and launch it on their own site with no additional development needed. AI App Onsite web app creator is an AI web app builder for WordPress. 6 * Version: 1. 0.06 * Version: 1.1.0 7 7 * Author: By AIappOnsite 8 8 * Author URI: https://aiapponsite.com/ … … 62 62 63 63 if (!function_exists('ai_app_onsite_enqueue_admin_script')) { 64 65 function ai_app_onsite_enqueue_admin_script() 66 { 67 68 // Register jQuery script (it is already included by default in WordPress) 69 wp_enqueue_script('jquery'); 70 71 // Register JavaScript files and then enqueue them 72 wp_register_script('admin-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-admin.js', array('jquery'), time(), true); 73 wp_enqueue_script('admin-script'); 74 75 wp_register_script('ai-app-onsite-field-selector-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-field-selector.js', array('jquery'), time(), true); 76 wp_enqueue_script('ai-app-onsite-field-selector-script'); 77 78 wp_register_script('bootstrape-poper-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/popper.min.js', array('jquery'), time(), true); 79 wp_enqueue_script('bootstrape-poper-script'); 80 81 wp_register_script('bootstrape-script-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/bootstrap.min.js', array('jquery'), time(), true); 82 wp_enqueue_script('bootstrape-script-script'); 83 84 wp_register_script('email-interation-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-email-settings.js', array('jquery'), time(), true); 85 wp_enqueue_script('email-interation-script'); 86 87 wp_register_script('blockword-script-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-blockword.js', array('jquery'), time(), true); 88 wp_enqueue_script('blockword-script-script'); 89 90 wp_register_script('model_settings', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-model-settings.js', array('jquery'), time(), true); 91 wp_enqueue_script('model_settings'); 92 93 wp_register_script('plugin_settings-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-plugin-settings.js', array('jquery'), time(), true); 94 wp_enqueue_script('plugin_settings-script'); 95 96 wp_register_script('app_properties', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-app-properties.js', array('jquery'), time(), true); 97 wp_enqueue_script('app_properties'); 98 99 wp_register_script('prompt-editor-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-prompt-editor.js', array('jquery'), time(), true); 100 wp_enqueue_script('prompt-editor-script'); 101 102 wp_register_script('app-preview-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-app-preview.js', array('jquery'), time(), true); 103 wp_enqueue_script('app-preview-script'); 104 105 wp_register_script('ai-app-onsite-jquery-sweetalert', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/sweetalert2.all.min.js', array('jquery'), time(), true); 106 wp_enqueue_script('ai-app-onsite-jquery-sweetalert'); 107 108 wp_register_script('ai-app-onsite-jquery-choice', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/choice.min.js', array('jquery'), time(), true); 109 wp_enqueue_script('ai-app-onsite-jquery-choice'); 110 111 // Localize the script with the AJAX URL 64 function ai_app_onsite_enqueue_admin_script($hook) 65 { 66 // Only load on plugin settings page - adjust this to match your plugin's actual settings page slug 67 if ($hook !== 'toplevel_page_ai-app-onsite-menu') { 68 return; 69 } 70 71 // Enqueue CSS for admin 72 wp_enqueue_style('ai-app-onsite-style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-style.css', array(), time()); 73 74 // Check if Bootstrap is already loaded 75 global $wp_scripts, $wp_styles; 76 $is_bootstrap_loaded = false; 77 78 foreach ($wp_scripts->registered as $registered_script) { 79 if (str_contains($registered_script->src, 'bootstrap')) { 80 $is_bootstrap_loaded = true; 81 break; 82 } 83 } 84 85 if (!$is_bootstrap_loaded) { 86 foreach ($wp_styles->registered as $registered_style) { 87 if (str_contains($registered_style->src, 'bootstrap')) { 88 $is_bootstrap_loaded = true; 89 break; 90 } 91 } 92 } 93 94 // Enqueue Bootstrap if not already loaded 95 if (!$is_bootstrap_loaded) { 96 wp_register_script('bootstrape-poper-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/popper.min.js', array('jquery'), time(), true); 97 wp_enqueue_script('bootstrape-poper-script'); 98 99 wp_register_script('bootstrape-script-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/bootstrap.min.js', array('jquery'), time(), true); 100 wp_enqueue_script('bootstrape-script-script'); 101 102 wp_register_style('ai_app_onsite_style_bootstrap', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/bootstrap.min.css', array(), time()); 103 wp_enqueue_style('ai_app_onsite_style_bootstrap'); 104 } 105 106 // All other scripts 107 $scripts = [ 108 'admin-script' => 'ai-app-onsite-admin.js', 109 'ai-app-onsite-field-selector-script' => 'ai-app-onsite-field-selector.js', 110 'email-interation-script' => 'ai-app-onsite-email-settings.js', 111 'blockword-script-script' => 'ai-app-onsite-blockword.js', 112 'model_settings' => 'ai-app-onsite-model-settings.js', 113 'plugin_settings-script' => 'ai-app-onsite-plugin-settings.js', 114 'app_properties' => 'ai-app-onsite-app-properties.js', 115 'prompt-editor-script' => 'ai-app-onsite-prompt-editor.js', 116 'app-preview-script' => 'ai-app-onsite-app-preview.js', 117 'ai-app-onsite-jquery-sweetalert' => 'sweetalert2.all.min.js', 118 'ai-app-onsite-jquery-choice' => 'choice.min.js', 119 'terms-of-service-script' => 'jspdf.umd.min.js', 120 ]; 121 122 foreach ($scripts as $handle => $filename) { 123 wp_register_script($handle, AI_APP_ONSITE_PLUGIN_URL . 'assets/js/' . $filename, array('jquery'), time(), true); 124 wp_enqueue_script($handle); 125 } 126 127 // Pass the fresh installation flag to JavaScript 128 $is_fresh_install = get_option('ai_app_onsite_fresh_install', false); 129 // Localize the main admin script 112 130 wp_localize_script( 113 'admin-script', // Handle of the registered script114 'myPluginAjax', // Name of the JavaScript object131 'admin-script', 132 'myPluginAjax', 115 133 array( 116 'ajaxurl' => admin_url('admin-ajax.php'), // URL for AJAX requests 117 'deleteNonce' => wp_create_nonce('ai_app_onsite_delete_field_nonce'), // Nonce for delete action 118 'downloadUserStatsNonce' => wp_create_nonce('ai_app_onsite_download_user_stats_nonce'), // Nonce for download user stats 119 'fieldSelectorOrder' => wp_create_nonce('ai_app_onsite_fields_selector_order_nonce'), // Nonce for download user stats 134 'ajaxurl' => admin_url('admin-ajax.php'), 135 'deleteNonce' => wp_create_nonce('ai_app_onsite_delete_field_nonce'), 136 'downloadUserStatsNonce' => wp_create_nonce('ai_app_onsite_download_user_stats_nonce'), 137 'fieldSelectorOrder' => wp_create_nonce('ai_app_onsite_fields_selector_order_nonce'), 138 'isFreshInstall' => $is_fresh_install, 120 139 ) 121 140 ); 122 141 123 142 124 // Pass the plugin URL to JavaScript using wp_add_inline_script() 143 // Remove the flag after it's been used 144 if ($is_fresh_install) { 145 delete_option('ai_app_onsite_fresh_install'); 146 } 147 125 148 wp_add_inline_script('admin-script', 'var AI_APP_ONSITE_PLUGIN_URL = "' . esc_url(AI_APP_ONSITE_PLUGIN_URL) . '";', 'before'); 126 127 // Download Terms of Service128 wp_register_script('terms-of-service-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/jspdf.umd.min.js', array('jquery'), time(), true);129 wp_enqueue_script('terms-of-service-script');130 149 } 131 150 132 151 add_action('admin_enqueue_scripts', 'ai_app_onsite_enqueue_admin_script'); 133 152 } 153 134 154 135 155 … … 154 174 function AI_APP_ONSITE_My_Form_Block_Assets() 155 175 { 156 // Enqueue block editor script with file mtime for versioning (cache-busting)176 // Enqueue block editor script with file time for versioning (cache-busting) 157 177 wp_enqueue_script( 158 178 'ai-app-onsite-form-block-editor', … … 166 186 167 187 if (!function_exists('ai_app_onsite_enqueue_style')) { 168 function ai_app_onsite_enqueue_style() 169 { 170 // Enqueue styles with time() for cache-busting 171 // Register and enqueue stylesheets for the admin area 172 wp_register_style('ai_app_onsite_form_style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-form-style.css', array(), time()); 173 wp_enqueue_style('ai_app_onsite_form_style'); 174 175 wp_register_style('ai_app_onsite_style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-style.css', array(), time()); 176 wp_enqueue_style('ai_app_onsite_style'); 177 178 wp_register_style('ai_app_onsite_style_bootstrap', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/bootstrap.min.css', array(), time()); 179 wp_enqueue_style('ai_app_onsite_style_bootstrap'); 180 } 181 182 // Enqueue styles for both admin and frontend 183 add_action('admin_print_styles', 'ai_app_onsite_enqueue_style'); 184 add_action('wp_enqueue_scripts', 'ai_app_onsite_enqueue_style'); 185 } 188 function ai_app_onsite_enqueue_style() 189 { 190 // Enqueue styles with time() for cache-busting 191 // Register and enqueue stylesheets for the admin area 192 wp_register_style('ai_app_onsite_form_style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-form-style.css', array(), time()); 193 wp_enqueue_style('ai_app_onsite_form_style'); 194 195 196 // Check if Bootstrap is already loaded 197 global $wp_scripts, $wp_styles; 198 $is_bootstrap_loaded = false; 199 200 foreach ($wp_scripts->registered as $registered_script) { 201 if (str_contains($registered_script->src, 'bootstrap')) { 202 $is_bootstrap_loaded = true; 203 break; 204 } 205 } 206 207 if (!$is_bootstrap_loaded) { 208 foreach ($wp_styles->registered as $registered_style) { 209 if (str_contains($registered_style->src, 'bootstrap')) { 210 $is_bootstrap_loaded = true; 211 break; 212 } 213 } 214 } 215 216 // Enqueue Bootstrap if not already loaded 217 if (!$is_bootstrap_loaded) { 218 wp_register_style('ai_app_onsite_style_bootstrap', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/bootstrap.min.css', array(), time()); 219 wp_enqueue_style('ai_app_onsite_style_bootstrap'); 220 } 221 222 223 } 224 225 // Enqueue styles for both admin and frontend 226 add_action('admin_print_styles', 'ai_app_onsite_enqueue_style'); 227 add_action('wp_enqueue_scripts', 'ai_app_onsite_enqueue_style'); 228 } 229 186 230 187 231 … … 192 236 { 193 237 global $wpdb; // Access the global $wpdb variable 238 239 add_option('ai_app_onsite_fresh_install', true); 240 194 241 require_once AI_APP_ONSITE_PLUGIN_DIR . 'includes/class-ai-app-onsite-db-handler.php'; 195 242 // Create an instance of the database handler class and pass $wpdb … … 202 249 203 250 251 204 252 if (! function_exists('ai_app_onsite_deactivate')) { 205 253 // Deactivation hook callback function 206 function ai_app_onsite_deactivate() {} 254 function ai_app_onsite_deactivate() 255 { 256 // Enqueue a script to delete cookies on plugin deactivation 257 add_action('admin_footer', function () { 258 echo '<script> 259 document.cookie = "ai_app_onsite_active_tab=; path=/; max-age=0"; 260 </script>'; 261 }); 262 } 207 263 } 208 264 … … 271 327 function ai_app_onsite_editor_callback() 272 328 { 273 // Check karein ki function exist karta hai ya nahi274 329 if (function_exists('wp_editor')) { 275 330 $content = ''; // Default content … … 290 345 } 291 346 } 347 348 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'ai_app_onsite_settings_link'); 349 350 function ai_app_onsite_settings_link($links) 351 { 352 $settings_link = '<a href="' . admin_url('admin.php?page=ai-app-onsite-menu') . '">Settings</a>'; 353 array_unshift($links, $settings_link); // Add it at the beginning 354 return $links; 355 } -
ai-app-onsite/tags/1.1.0/assets/css/ai-app-onsite-form-style.css
r3250856 r3272415 1 1 /* start loader css */ 2 2 3 . loader {3 .ai-app-form-wrap .loader { 4 4 height: 80px; 5 5 aspect-ratio: 1; … … 7 7 } 8 8 9 . loader:before,10 . loader:after {9 .ai-app-form-wrap .loader:before, 10 .ai-app-form-wrap .loader:after { 11 11 content: ""; 12 --c: no-repeat linear-gradient( var(--purple)0 0);12 --c: no-repeat linear-gradient(#635aff 0 0); 13 13 background: var(--c), var(--c); 14 14 background-size: 25% 50%; … … 16 16 } 17 17 18 . loader:after {18 .ai-app-form-wrap .loader:after { 19 19 transform: scale(-1); 20 } 21 .ai-app-form-wrap .fields-error { 22 color: red; 23 font-size: 12px; 20 24 } 21 25 … … 40 44 } 41 45 42 #loader {46 .ai-app-form-wrap #loader { 43 47 position: fixed; 44 48 height: 100%; … … 53 57 } 54 58 55 . message-container span,59 .ai-app-form-wrap .message-container span, 56 60 .modal-message-container span { 57 61 text-align: center; … … 63 67 } 64 68 65 . select-box-icon.right-icon input[type="text"]::placeholder {69 .ai-app-form-wrap .select-box-icon.right-icon input[type="text"]::placeholder { 66 70 color: #818898 !important; 67 71 } … … 69 73 /* end loader css */ 70 74 71 . select-box-icon .ai-app-onsite-openAi-app-shortcode {75 .ai-app-form-wrap .select-box-icon .ai-app-onsite-openAi-app-shortcode { 72 76 padding-left: 38px !important; 73 77 padding-right: 38px !important; … … 86 90 } 87 91 88 . field-copy-icon {92 .ai-app-form-wrap .field-copy-icon { 89 93 position: absolute; 90 94 top: 6px; … … 100 104 border-radius: 8px; 101 105 box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); 102 margin-bottom: 32px; 103 /*max-width: 800px !important;*/ 104 width: 100%; 105 margin: auto auto 32px auto; 106 width: 100%; 107 margin: auto auto 2rem auto; 106 108 } 107 109 … … 258 260 font-weight: 600; 259 261 } 260 261 /* @media (max-width: 576px) {262 div#ai-app-openAi-app-logo {263 max-width: 180px;264 }265 } */ -
ai-app-onsite/tags/1.1.0/assets/css/ai-app-onsite-style.css
r3250856 r3272415 19 19 --neutral-black-10: #f8fafc; 20 20 } 21 21 * { 22 box-sizing: border-box; 23 } 22 24 .bg-purple { 23 25 background-color: var(--purple) !important; … … 97 99 98 100 .divider-light { 99 height: 1px;101 height: 2.5px; 100 102 width: 100%; 101 103 background-color: var(--neutral-black-20); … … 332 334 333 335 /* BEGIN::Modal styles */ 334 335 * {336 box-sizing: border-box;337 }338 339 336 .container { 340 337 max-width: 50vw; … … 926 923 } 927 924 928 .api-key-icon.select-box-icon p {925 /* .api-key-icon.select-box-icon p { 929 926 padding-left: 36px; 930 927 padding-top: 8px; 931 } 928 } */ 932 929 933 930 .api-key-icon.select-box-icon { … … 1510 1507 font-weight: 400; 1511 1508 } 1509 .app-preview-content .app-preview-content__heading { 1510 width: 40%; 1511 } 1512 .app-preview-content .app-preview-content__description{ 1513 width: 60%; 1514 } 1512 1515 1513 1516 .fields-error { … … 1668 1671 1669 1672 .assets-copy-icon { 1670 width: 20px;1671 HEIGHT: 25PX;1673 width: 1.25rem; 1674 height: 1.56rem; 1672 1675 background-image: url('../media/copy-icon.png'); 1673 1676 background-repeat: no-repeat; 1674 1677 background-size: inherit; 1675 1678 background-position: center; 1676 } 1677 1679 cursor: pointer; 1680 } 1681 .icon-success { 1682 width: 1.25rem; 1683 height: 1.56rem; 1684 background-image: url('../media/copy-icon-success.png'); 1685 background-repeat: no-repeat; 1686 background-size: inherit; 1687 background-position: center; 1688 cursor: pointer; transition: color 0.3s ease; 1689 } 1690 .key-toggle .mask__toggle , .key-toggle .copy__btn { 1691 cursor: pointer; 1692 font-size: 14px; 1693 } 1694 #model-help-text{ 1695 font-size: .875em; 1696 } 1697 .small-text { 1698 font-size: .775em; 1699 } 1700 1701 .border-danger { 1702 border: 2px solid red !important; 1703 animation: shake 0.3s ease-in-out 2; 1704 } 1705 1706 @keyframes shake { 1707 0% { transform: translateX(0px); } 1708 25% { transform: translateX(-3px); } 1709 50% { transform: translateX(3px); } 1710 75% { transform: translateX(-3px); } 1711 100% { transform: translateX(0px); } 1712 } 1713 .blurred { 1714 filter: blur(2px); 1715 pointer-events: none; 1716 opacity: 0.6; 1717 position: relative; 1718 } 1719 1720 .field-copy-icon { 1721 position: absolute; 1722 top: 6px; 1723 right: 10px; 1724 cursor: pointer; 1725 } 1678 1726 #key-remove-btn { 1679 1727 display: flex; … … 1950 1998 } 1951 1999 } 2000 #ai-app-onsite-test { 2001 background-image: linear-gradient(to right, #006175 0%, #3c7bbd 100%); 2002 border-radius: 4px; 2003 box-sizing: border-box; 2004 color: #3c7bbd; 2005 display: block; 2006 font-size:1rem; 2007 height: 2.6rem; 2008 letter-spacing: 1px; 2009 padding: 1.7px; 2010 position: relative; 2011 text-decoration: none; 2012 text-transform: uppercase; 2013 width: 12.5rem; 2014 z-index: 2; 2015 } 2016 2017 #ai-app-onsite-test:hover { 2018 color: #fff; 2019 } 2020 2021 #ai-app-onsite-test span { 2022 align-items: center; 2023 background: #fff; 2024 border-radius: 4px; 2025 display: flex; 2026 justify-content: center; 2027 height: 100%; 2028 transition: background .5s ease; 2029 width: 100%; 2030 } 2031 2032 #ai-app-onsite-test:hover span { 2033 background: transparent; 2034 } -
ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-admin.js
r3250856 r3272415 1 var removeLogoBtn = document.getElementById('remove-logo-btn'); 2 var previewImage = document.getElementById('previewImage'); 3 var fileUploadDiv = document.getElementById('file-upload-div'); 4 5 // === Save & Restore Tab using Cookie === 6 7 document.addEventListener('DOMContentLoaded', function () { 8 function getCookie(name) { 9 return document.cookie 10 .split('; ') 11 .find(row => row.startsWith(name + '=')) 12 ?.split('=')[1] || ''; 13 } 14 15 function deleteCookie(name) { 16 document.cookie = name + '=; path=/; max-age=0'; 17 } 18 19 const savedTabId = getCookie('ai_app_onsite_active_tab'); 20 const fallbackTabId = 'plugin-settings-tab'; 21 22 const isFreshInstall = myPluginAjax.isFreshInstall == '1' ? true : false; 23 console.log('isFreshInstall:', isFreshInstall); 24 25 if (isFreshInstall) { 26 deleteCookie('ai_app_onsite_active_tab'); 27 handleTabClick(fallbackTabId); // Activate the default tab 28 } else if (savedTabId) { 29 handleTabClick(savedTabId); // Activate the saved tab 30 } else { 31 handleTabClick(fallbackTabId); // Activate the default tab 32 } 33 }); 34 35 // === Main Tab Click Handler === 36 1 37 function handleTabClick(tabId) { 2 // alert(tabId);3 38 event.preventDefault(); 4 39 … … 7 42 // Check if the clicked tab is already active 8 43 if (tab.classList.contains('nav-tab-active')) { 9 return; // Do nothing if the tab is already active44 return; 10 45 } 11 46 … … 25 60 tab.classList.add('nav-tab-active'); 26 61 27 // Show corresponding tab content (if applicable)62 // Show corresponding tab content 28 63 var contentId = tabId.replace("tab", "content"); 29 64 var content = document.getElementById(contentId); … … 32 67 } 33 68 34 // Your function logic goes here based on the tab ID 35 // For example: 69 // ✅ Save active tab in cookie for 7 days 70 document.cookie = "ai_app_onsite_active_tab=" + tabId + "; path=/; max-age=" + (60 * 60 * 24 * 7); 71 72 // ✅ Custom logic per tab 36 73 if (tabId === 'plugin-settings-tab') { 37 74 ai_app_onsite_get_plugin_settings(); … … 43 80 ai_app_onsite_read_field_selector(); 44 81 } else if (tabId === 'prompt-editor-tab') { 82 ai_app_onsite_get_Model_Token_field(); 45 83 ai_app_onsite_get_field_tags(); 46 84 ai_app_onsite_get_prompt_editor(); … … 69 107 //End get plugin setting from db js 70 108 109 110 function removeLogoFile(input) { 111 console.log("removeLogoFile"); 112 removeLogoBtn.style.display = 'none'; 113 previewImage.style.display = 'none'; 114 fileUploadDiv.classList.add('col-md-12'); 115 fileUploadDiv.classList.remove('col-md-8'); 116 117 var xhr = new XMLHttpRequest(); 118 119 xhr.onreadystatechange = function () { 120 if (xhr.readyState === 4) { 121 if (xhr.status === 200) { 122 123 response = JSON.parse(xhr.responseText); 124 if (response.status === '404') { 125 return; 126 } 127 console.log("image deleted"); 128 } else { 129 // Handle error response 130 console.error('Error occurred: ' + xhr.responseText); 131 } 132 } 133 }; 134 135 xhr.open('POST', myPluginAjax.ajaxurl, true); 136 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 137 xhr.send('action=ai_app_onsite_remove_app_logo'); 138 } 139 71 140 //upload file js 72 141 function validateFile(input) { … … 95 164 96 165 function uploadSiteLogo(file) { 166 removeLogoBtn.style.display = 'block'; 167 fileUploadDiv.classList.add('col-md-8'); 168 fileUploadDiv.classList.remove('col-md-12'); 97 169 var formData = new FormData(); 98 170 formData.append('app-file', file); … … 123 195 previewImage.style.width = '350px'; 124 196 previewImage.style.height = '160px'; 197 previewImage.style.position = 'relative'; 125 198 } 126 199 -
ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-app-preview.js
r3250856 r3272415 17 17 response = JSON.parse(xhr.responseText); 18 18 19 20 if (response.status === '404' ) {19 console.log('response', response); 20 if (response.status === '404' || response.status === '400') { 21 21 console.log('message', response.message); 22 22 formContainer.innerHTML = '<p>No form Field Found Please Create Form Field</p>'; … … 98 98 // Handle error response 99 99 console.error('Error occurred: ' + xhr.responseText); 100 101 formContainer.innerHTML = '<p>It looks like some required settings are missing. Please ensure that "App Properties," "Model Settings," and "Form Fields" are configured before previewing the form.</p>'; 102 openAiAppShortcode.value = ''; 103 testAppContainer.style.display = 'none'; 104 shortcodeBox.style.display = 'none'; 105 return; 100 106 } 101 107 } … … 128 134 if (xhr.status === 200) { 129 135 130 // console.log(xhr);131 136 // Handle the response from the server 132 137 var response = JSON.parse(xhr.responseText); 133 134 138 if (response.success) { 135 139 // Show success AI result -
ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-app-properties.js
r3250856 r3272415 3 3 var xhr = new XMLHttpRequest(); 4 4 5 xhr.onreadystatechange = function () {5 xhr.onreadystatechange = function () { 6 6 if (xhr.readyState === 4) { 7 7 if (xhr.status === 200) { 8 var response = JSON.parse(xhr.responseText);8 var response = JSON.parse(xhr.responseText); 9 9 // Check if status is 404 (Table does not exist or no rows found) 10 10 if (response.status === '404') { … … 12 12 return; 13 13 } 14 // Accessing the first object in the array14 // Accessing the first object in the array 15 15 var firstObject = response[0]; 16 16 console.log(firstObject, 'firstObject'); 17 var app_logo = firstObject.appLogoImagePreview;18 console.log(app_logo, 'app_logo');19 17 var app_logo = firstObject.appLogoImagePreview; 20 21 if (app_logo!= 'No preview available') { 18 console.log(app_logo, 'app_logo'); 19 var app_logo = firstObject.appLogoImagePreview; 20 var fileUploadDiv = document.getElementById('file-upload-div'); 21 var removeLogoBtn = document.getElementById('remove-logo-btn'); 22 23 if (app_logo != 'No preview available') { 22 24 var previewImage = document.getElementById('previewImage'); 23 25 previewImage.style.backgroundImage = `url('${app_logo}')`; … … 28 30 previewImage.style.width = '350px'; 29 31 previewImage.style.height = '160px'; 32 fileUploadDiv.classList.add('col-md-8'); 33 fileUploadDiv.classList.remove('col-md-12'); 34 } else { 35 var removeLogoBtn = document.getElementById('remove-logo-btn'); 36 removeLogoBtn.style.display = 'none'; 37 fileUploadDiv.classList.add('col-md-12'); 38 fileUploadDiv.classList.remove('col-md-8'); 30 39 } 31 40 … … 34 43 // Accessing properties of the first object 35 44 var app_name = firstObject.app_name; 36 45 var app_name_show = firstObject.app_name_show; 46 37 47 var app_disclaimer = firstObject.app_disclaimer; 38 48 var app_description = firstObject.app_description; 39 49 var submit_button_txt = firstObject.submit_button_txt; 40 50 //var title_color = firstObject.title_color; 41 42 var title_colors = JSON.parse(firstObject.title_color);43 44 45 // var font_color = firstObject.font_color;46 // var bg_color = firstObject.bg_color;47 48 var font_colors = JSON.parse(firstObject.font_color);49 var bg_colors = JSON.parse(firstObject.bg_color);50 51 52 51 52 var title_colors = JSON.parse(firstObject.title_color); 53 54 55 // var font_color = firstObject.font_color; 56 // var bg_color = firstObject.bg_color; 57 58 var font_colors = JSON.parse(firstObject.font_color); 59 var bg_colors = JSON.parse(firstObject.bg_color); 60 61 62 53 63 54 64 // var obj = JSON.parse(title_color); 55 56 document.getElementById('app-name').value = app_name; 65 if (app_name_show === "") { 66 document.getElementById('app-name').value = app_name; 67 } else { 68 document.getElementById('app-name').value = app_name_show; 69 var checkbox = document.getElementById('app-name-toggle'); 70 checkbox.checked = true; 71 } 72 57 73 document.getElementById('app-disclaimer').value = app_disclaimer; 58 74 document.getElementById('app-description').value = app_description; 59 75 document.getElementById('submit-btn-txt').value = submit_button_txt; 60 76 document.getElementById('preview-submit-btn-txt').textContent = submit_button_txt; 61 62 setTimeout(function() {63 var selected_title_color = getSelectedTitleColor(title_colors);64 var selected_font_colors= getSelectedFontColor(font_colors);65 var selected_bg_colors = getSelectedBgColor(bg_colors);66 var radioInputs = document.querySelectorAll('.input-group-color input[type="radio"]');67 radioInputs.forEach(function(radio) {68 var label = radio.closest('label'); // Find the parent label of the radio input69 if (radio.value === selected_title_color) {70 var colorWithoutHash = selected_title_color.replace(/^#/, '');71 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe72 label.click();73 } else {74 var colorWithoutHash = selected_title_color.replace(/^#/, '');75 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels76 }77 if (radio.value === selected_font_colors) {78 var colorWithoutHash = selected_font_colors.replace(/^#/, '');79 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe80 label.click();81 } else {82 var colorWithoutHash = selected_font_colors.replace(/^#/, '');83 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels84 }85 86 if (radio.value === selected_bg_colors) {87 var colorWithoutHash = selected_bg_colors.replace(/^#/, '');88 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe89 label.click();90 } else {91 var colorWithoutHash = selected_bg_colors.replace(/^#/, '');92 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels93 }94 95 });96 97 }, 100);77 78 setTimeout(function () { 79 var selected_title_color = getSelectedTitleColor(title_colors); 80 var selected_font_colors = getSelectedFontColor(font_colors); 81 var selected_bg_colors = getSelectedBgColor(bg_colors); 82 var radioInputs = document.querySelectorAll('.input-group-color input[type="radio"]'); 83 radioInputs.forEach(function (radio) { 84 var label = radio.closest('label'); // Find the parent label of the radio input 85 if (radio.value === selected_title_color) { 86 var colorWithoutHash = selected_title_color.replace(/^#/, ''); 87 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe 88 label.click(); 89 } else { 90 var colorWithoutHash = selected_title_color.replace(/^#/, ''); 91 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels 92 } 93 if (radio.value === selected_font_colors) { 94 var colorWithoutHash = selected_font_colors.replace(/^#/, ''); 95 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe 96 label.click(); 97 } else { 98 var colorWithoutHash = selected_font_colors.replace(/^#/, ''); 99 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels 100 } 101 102 if (radio.value === selected_bg_colors) { 103 var colorWithoutHash = selected_bg_colors.replace(/^#/, ''); 104 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe 105 label.click(); 106 } else { 107 var colorWithoutHash = selected_bg_colors.replace(/^#/, ''); 108 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels 109 } 110 111 }); 112 113 }, 100); 98 114 99 115 // Define an array of objects containing the variables and their corresponding radio button sets 100 title_colors.forEach(function (title_color) {116 title_colors.forEach(function (title_color) { 101 117 102 118 // Initialize the variableSets array … … 105 121 // Check if title_color.title_color_selected exists 106 122 if (title_color.title_color_selected) { 107 console.log(title_color.title_color_selected , 'title_color.title_color_selected');123 console.log(title_color.title_color_selected, 'title_color.title_color_selected'); 108 124 // If title_color_selected exists, add it to variableSets 109 125 variableSets.push({ … … 122 138 123 139 // Iterate over each object in the array 124 variableSets.forEach(function (variableSet) {140 variableSets.forEach(function (variableSet) { 125 141 // If the variable is an array, iterate over each object in the array 126 142 if (Array.isArray(variableSet.variable)) { 127 variableSet.variable.forEach(function (colorObject) {143 variableSet.variable.forEach(function (colorObject) { 128 144 // Iterate over each key-value pair in the object 129 Object.keys(colorObject).forEach(function (key) {145 Object.keys(colorObject).forEach(function (key) { 130 146 // Find the radio button with the value matching the key's value 131 var radioButton = Array.from(variableSet.radios).find(function (radio) {147 var radioButton = Array.from(variableSet.radios).find(function (radio) { 132 148 return radio.value === colorObject[key]; 133 149 }); … … 140 156 }); 141 157 } else { // If the variable is a string, find and set the corresponding radio button 142 var radioButton = Array.from(variableSet.radios).find(function (radio) {158 var radioButton = Array.from(variableSet.radios).find(function (radio) { 143 159 return radio.value === variableSet.variable; 144 160 }); … … 159 175 160 176 // Define an array of objects containing the variables and their corresponding radio button sets 161 font_colors.forEach(function (font_color) {162 163 177 font_colors.forEach(function (font_color) { 178 179 164 180 165 181 // Initialize the variableSets array … … 185 201 186 202 // Iterate over each object in the array 187 variableSets.forEach(function (variableSet) {203 variableSets.forEach(function (variableSet) { 188 204 // If the variable is an array, iterate over each object in the array 189 205 if (Array.isArray(variableSet.variable)) { 190 variableSet.variable.forEach(function (colorObject) {206 variableSet.variable.forEach(function (colorObject) { 191 207 // Iterate over each key-value pair in the object 192 Object.keys(colorObject).forEach(function (key) {208 Object.keys(colorObject).forEach(function (key) { 193 209 // Find the radio button with the value matching the key's value 194 var radioButton = Array.from(variableSet.radios).find(function (radio) {210 var radioButton = Array.from(variableSet.radios).find(function (radio) { 195 211 return radio.value === colorObject[key]; 196 212 }); … … 203 219 }); 204 220 } else { // If the variable is a string, find and set the corresponding radio button 205 var radioButton = Array.from(variableSet.radios).find(function (radio) {221 var radioButton = Array.from(variableSet.radios).find(function (radio) { 206 222 return radio.value === variableSet.variable; 207 223 }); … … 222 238 223 239 // Define an array of objects containing the variables and their corresponding radio button sets 224 bg_colors.forEach(function(bg_color) {240 bg_colors.forEach(function (bg_color) { 225 241 226 242 // Initialize the variableSets array … … 244 260 } 245 261 246 262 247 263 // Iterate over each object in the array 248 variableSets.forEach(function (variableSet) {264 variableSets.forEach(function (variableSet) { 249 265 // If the variable is an array, iterate over each object in the array 250 266 if (Array.isArray(variableSet.variable)) { 251 variableSet.variable.forEach(function (colorObject) {267 variableSet.variable.forEach(function (colorObject) { 252 268 // Iterate over each key-value pair in the object 253 Object.keys(colorObject).forEach(function (key) {269 Object.keys(colorObject).forEach(function (key) { 254 270 // Find the radio button with the value matching the key's value 255 var radioButton = Array.from(variableSet.radios).find(function (radio) {271 var radioButton = Array.from(variableSet.radios).find(function (radio) { 256 272 return radio.value === colorObject[key]; 257 273 }); … … 264 280 }); 265 281 } else { // If the variable is a string, find and set the corresponding radio button 266 var radioButton = Array.from(variableSet.radios).find(function (radio) {282 var radioButton = Array.from(variableSet.radios).find(function (radio) { 267 283 return radio.value === variableSet.variable; 268 284 }); … … 322 338 function ai_app_onsite_save_app_properties() { 323 339 console.log('Nonce value:', document.getElementById('ai_app_onsite_app_properties_nonce_field').value); 324 console.log('Form data:', formData);340 console.log('Form data:', formData); 325 341 // Clear all previous error messages 326 document.querySelectorAll('.fields-error').forEach(function (error) {342 document.querySelectorAll('.fields-error').forEach(function (error) { 327 343 error.textContent = ''; 328 344 }); 329 345 330 346 // Get form fields 331 var appName = document.getElementById('app-name').value.trim(); 347 var appName = document.getElementById('app-name').value.trim(); 332 348 var appDescription = document.getElementById('app-description').value.trim(); 333 349 var appDisclaimer = document.getElementById('app-disclaimer').value.trim(); 334 //var fileUpload = document.getElementById('file-upload').value.trim();335 350 var appNameToggle = document.getElementById('app-name-toggle').checked 351 336 352 // Collect error messages 337 353 var errors = []; … … 351 367 // If there are errors, display them and return 352 368 if (errors.length > 0) { 353 errors.forEach(function (error) {369 errors.forEach(function (error) { 354 370 // Find the corresponding error container and display the message 355 371 if (error === 'App Name is required.') { … … 375 391 // Create and send AJAX request 376 392 var xhr = new XMLHttpRequest(); 377 xhr.onreadystatechange = function () {393 xhr.onreadystatechange = function () { 378 394 if (xhr.readyState === 4) { 379 395 var messageContainer = document.getElementById('app-properties-msg-container'); 380 setTimeout(function () {396 setTimeout(function () { 381 397 loader.style.display = 'none'; 382 398 … … 397 413 } 398 414 // Hide message after 3 seconds 399 setTimeout(function () {415 setTimeout(function () { 400 416 messageContainer.innerHTML = ''; 401 417 }, 3000); … … 412 428 formData.append('action', 'ai_app_onsite_save_app_properties'); 413 429 formData.append('app-name', document.getElementById("app-name") ? document.getElementById("app-name").value : ''); 430 formData.append('app-name-show', document.getElementById("app-name-toggle").checked); 414 431 415 432 // Check if file is selected … … 423 440 formData.append('app-disclaimer', document.getElementById("app-disclaimer") ? document.getElementById("app-disclaimer").value : ''); 424 441 formData.append('submit-btn-txt', document.getElementById("submit-btn-txt") ? document.getElementById("submit-btn-txt").value : ''); 425 442 426 443 // Check if radio buttons are selected before accessing their value 427 444 //var titleColorRadio = document.querySelector('input[name="title-color"]:checked'); … … 429 446 var titleColorRadios = document.querySelectorAll('input[type="radio"][name="title-color"]'); 430 447 var titleColors = []; 431 432 if (titleColorRadios){433 titleColorRadios.forEach(function (titleColorRadio) {448 449 if (titleColorRadios) { 450 titleColorRadios.forEach(function (titleColorRadio) { 434 451 if (titleColorRadio.checked) { 435 452 titleColors.push({ "title_color_selected": titleColorRadio.value }); … … 447 464 var fontColorRadios = document.querySelectorAll('input[type="radio"][name="font-color"]'); 448 465 var fontColor = []; 449 450 if (fontColorRadios){451 fontColorRadios.forEach(function (fontColorRadio) {466 467 if (fontColorRadios) { 468 fontColorRadios.forEach(function (fontColorRadio) { 452 469 if (fontColorRadio.checked) { 453 470 fontColor.push({ "font_color_selected": fontColorRadio.value }); … … 464 481 var bgColorRadios = document.querySelectorAll('input[type="radio"][name="bg-color"]'); 465 482 var bgColor = []; 466 bgColor467 if (bgColorRadios){468 bgColorRadios.forEach(function (bgColorRadio) {483 bgColor 484 if (bgColorRadios) { 485 bgColorRadios.forEach(function (bgColorRadio) { 469 486 if (bgColorRadio.checked) { 470 487 bgColor.push({ "bg_color_selected": bgColorRadio.value }); -
ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-model-settings.js
r3250856 r3272415 49 49 // Handle the response from the server 50 50 var response = JSON.parse(xhr.responseText); 51 console.log(response.data.data.temperature, 'ai_app_onsite_save_model_settings');52 console.log(response.data.data.top_p, 'ai_app_onsite_save_model_settings');53 console.log(response.data.data.f_penalty, 'ai_app_onsite_save_model_settings');54 console.log(response.data.data.p_penalty, 'ai_app_onsite_save_model_settings');55 console.log(response.data.data.max_tokens, 'ai_app_onsite_save_model_settings');56 console.log(response.data.data.model, 'ai_app_onsite_save_model_settings');57 58 51 59 52 let temperatureSettings = { … … 116 109 // Handle success response 117 110 var response = JSON.parse(xhr.responseText); 111 console.log(response, 'ai_app_onsite_get_model_settings'); 118 112 if (response.status === '404') { 119 113 var saveKpenapiKeyBtn = document.getElementById('save-openapi-key'); 120 114 var apiDisableBtn = document.getElementById("api-disable-btn"); 121 122 //jQuery('#apiinfoModal').modal('show'); 123 const modalElement = document.getElementById('apiinfoModal'); 124 const modalInstance = new bootstrap.Modal(modalElement); 125 modalInstance.show(); 126 127 //saveKpenapiKeyBtn.disabled = true; 128 apiDisableBtn.disabled = true; 129 apiDisableBtn.checked = false; 115 var apiKeyMgtBtn = document.getElementById("api-key-management"); 116 117 118 const engineDropdown = document.getElementById('model'); 119 var dependentFieldsWrapper = document.getElementById('model-dependent-fields'); 120 121 // Keep default placeholder selected 122 engineDropdown.value = ''; 123 124 // Add Highlight Class 125 engineDropdown.classList.add('border-danger'); 126 127 // Show Helper Text 128 document.getElementById('model-help-text').innerHTML = 'Please select a model to continue'; 129 130 dependentFieldsWrapper.classList.add('blurred'); 131 132 //hide the api key mgt button 133 apiKeyMgtBtn.style.display = 'none'; 134 135 136 // Optional: Disable other fields until model selected 137 document.querySelectorAll('.model-dependent').forEach(function (el) { 138 el.disabled = true; 139 }); 140 141 // Listen for change 142 engineDropdown.addEventListener('change', function () { 143 if (engineDropdown.value !== '') { 144 engineDropdown.classList.remove('border-danger'); 145 document.getElementById('model-help-text').innerHTML = ''; 146 147 // Enable fields 148 dependentFieldsWrapper.classList.remove('blurred'); 149 document.querySelectorAll('#model-dependent-fields').forEach(function (el) { 150 el.disabled = false; 151 }); 152 153 const modalElement = document.getElementById('apiinfoModal'); 154 const modalInstance = new bootstrap.Modal(modalElement); 155 modalInstance.show() 156 157 apiKeyMgtBtn.style.display = 'block'; 158 159 160 //saveKpenapiKeyBtn.disabled = true; 161 apiDisableBtn.disabled = true; 162 apiDisableBtn.checked = false; 163 } 164 }); 165 130 166 131 167 return; 132 168 } 133 169 170 171 134 172 // Accessing the first object in the array 135 173 var firstObject = response[0]; 136 137 174 // Accessing properties of the first object 138 var model = firstObject.model;139 var max_tokens = firstObject.max_tokens;140 var p_penalty = firstObject.p_penalty;141 var f_penalty = firstObject.f_penalty;175 var model = firstObject.model; 176 var max_tokens = firstObject.max_tokens; 177 var p_penalty = firstObject.p_penalty; 178 var f_penalty = firstObject.f_penalty; 142 179 var temperature = firstObject.temperature; 143 var top_p = firstObject.top_p; 144 var openai_key = firstObject.openai_key; 145 var key_status = firstObject.key_status; 180 var top_p = firstObject.top_p; 181 var openai_key = firstObject.openai_key; 182 var key_status = firstObject.key_status; 183 146 184 if (key_status == 'false') { 147 document.getElementById('key-status').textContent = 'D ISABLED';185 document.getElementById('key-status').textContent = 'Disabled'; 148 186 var element = document.getElementById('key-status'); 149 element.textContent = 'D ISABLED';187 element.textContent = 'Disabled'; 150 188 element.style.color = 'red'; 189 document.getElementById("api-disable-btn").checked = false; 190 151 191 } else { 152 192 var element = document.getElementById('key-status'); 153 element.textContent = 'E NABLED';193 element.textContent = 'Enabled'; 154 194 element.style.color = 'Green'; 195 document.getElementById("api-disable-btn").checked = true; 196 155 197 } 156 var openaiKey = document.getElementById('openai-key');157 var openaiKeyHidden = document.getElementById('openai-key-hidden');198 var openaiKey = document.getElementById('openai-key'); 199 var openaiKeyHidden = document.getElementById('openai-key-hidden'); 158 200 var saveKpenapiKeyBtn = document.getElementById('save-openapi-key'); 159 var apiDisableBtn = document.getElementById("api-disable-btn");201 var apiDisableBtn = document.getElementById("api-disable-btn"); 160 202 161 203 // Check if the value is null or empty … … 172 214 openaiKey.value = maskAPIKey(openai_key); 173 215 openaiKeyHidden.value = openai_key; 174 apiDisableBtn.checked = key_status; 175 216 var element = document.getElementById('text-switch'); 217 218 if (key_status == 'false') { 219 element.textContent = 'Disabled'; 220 element.style.color = 'Red'; 221 apiDisableBtn.checked = false; 222 223 } else { 224 element.textContent = 'Enabled'; 225 element.style.color = 'Green'; 226 apiDisableBtn.checked = true; 227 228 } 176 229 177 230 } … … 237 290 var errors = []; 238 291 if (openaiKeyError === '' || openaiKeyHidden === '') { 239 errors.push('API key is req ired.');292 errors.push('API key is required.'); 240 293 } 241 294 … … 244 297 errors.forEach(function (error) { 245 298 // Find the corresponding error container and display the message 246 if (error === 'API key is req ired.') {299 if (error === 'API key is required.') { 247 300 document.getElementById('openai-key-error').textContent = error; 248 301 } … … 261 314 const api_status = document.getElementById("api-disable-btn") ? document.getElementById("api-disable-btn").checked : ""; 262 315 const api_nonce = document.getElementById("ai_app_onsite_model_settings_nonce_field") ? document.getElementById("ai_app_onsite_model_settings_nonce_field").value : ""; 263 316 const engineDropdown = document.getElementById('model'); 317 console.log(api_status); 264 318 // Send the API key to the server using an AJAX request 265 319 fetch(myPluginAjax.ajaxurl, { … … 269 323 }, 270 324 body: new URLSearchParams({ 271 action: 'ai_app_onsite_save_openai_key', // Action for the server-side function 272 api_key: api_Key, 273 api_status: api_status, 274 api_Key_nonce: api_nonce 325 action : 'ai_app_onsite_save_openai_key', // Action for the server-side function 326 api_key : api_Key, 327 api_status : api_status, 328 api_Key_nonce: api_nonce, 329 engine_model : engineDropdown.value, 275 330 }) 276 331 }) … … 302 357 } 303 358 359 document.addEventListener('DOMContentLoaded', function () { 360 const copyButton = document.querySelector('.copy-api-key'); 361 if (copyButton) { 362 copyButton.addEventListener('click', ai_app_onsite_copy_openapi_key); 363 } 364 }); 365 366 document.addEventListener('DOMContentLoaded', function () { 367 const maskToggle = document.getElementById('maskToggle'); 368 const openaiKeyInput = document.getElementById('openai-key'); 369 const openaiKeyHidden = document.getElementById('openai-key-hidden'); 370 371 if (maskToggle && openaiKeyInput && openaiKeyHidden) { 372 // Initial check to hide maskToggle text if no value is present in openaiKeyHidden 373 updateMaskToggleVisibility(); 374 375 // Add event listener for maskToggle click 376 maskToggle.addEventListener('click', function () { 377 if (maskToggle.textContent.trim() === 'Show Key') { 378 // Show the full API key 379 openaiKeyInput.value = openaiKeyHidden.value; 380 maskToggle.textContent = 'Hide Key'; 381 } else { 382 // Mask the API key 383 openaiKeyInput.value = maskAPIKey(openaiKeyHidden.value); 384 maskToggle.textContent = 'Show Key'; 385 } 386 }); 387 388 // Function to update the visibility of maskToggle text 389 function updateMaskToggleVisibility() { 390 if (!openaiKeyHidden.value.trim()) { 391 maskToggle.textContent = ''; // Hide text if no value is present 392 } else { 393 maskToggle.textContent = 'Show Key'; // Default text when value exists 394 } 395 } 396 397 // Observe changes to the value of openaiKeyHidden 398 const observer = new MutationObserver(updateMaskToggleVisibility); 399 observer.observe(openaiKeyHidden, { attributes: true, attributeFilter: ['value'] }); 400 } 401 402 // Helper function to mask the API key 403 function maskAPIKey(input) { 404 var maxLength = 40; 405 var len = input.length; 406 if (len <= 6) return input; 407 var maskedPart = input.slice(0, 2) + '*'.repeat(Math.min(len - 6, maxLength - 6)) + input.slice(len - 4); 408 return maskedPart.slice(0, maxLength); 409 } 410 }); 304 411 305 412 function ai_app_onsite_copy_openapi_key() { 306 413 var openai_key = document.getElementById('openai-key'); 307 414 var openaiKeyHidden = document.getElementById('openai-key-hidden'); 415 var copyIcon = document.querySelector('.copy-api-key .assets-copy-icon'); 416 const maskToggle = document.getElementById('maskToggle'); 417 if (!openai_key || !openaiKeyHidden || !copyIcon) { 418 console.error('Required elements not found: openai-key, openai-key-hidden, or copy-icon'); 419 return; 420 } 421 422 // Temporarily set the visible input field to the full API key 308 423 openai_key.value = openaiKeyHidden.value; 309 424 310 // Select the text field 311 openai_key.select(); 312 openai_key.setSelectionRange(0, 99999); // For mobile devices 313 314 // Copy the text inside the text field 315 document.execCommand("copy"); 316 425 try { 426 // Select the text field 427 openai_key.select(); 428 openai_key.setSelectionRange(0, openai_key.value.length); // For mobile devices 429 430 // Copy the text inside the text field 431 if (document.execCommand('copy')) { 432 console.log('API key copied to clipboard successfully.'); 433 434 // Change the icon color by adding a class 435 copyIcon.classList.add('icon-success'); 436 437 // Remove the class after 2 seconds 438 setTimeout(() => { 439 copyIcon.classList.remove('icon-success'); 440 }, 2000); 441 } else { 442 console.error('Failed to copy API key to clipboard.'); 443 } 444 } catch (err) { 445 console.error('Error copying API key:', err); 446 } 447 maskToggle.textContent = 'Hide Key'; 448 // Restore the masked API key in the visible input field 317 449 openai_key.value = maskAPIKey(openaiKeyHidden.value); 318 319 openai_key.select(); 450 maskToggle.textContent = 'Show Key'; 451 452 // Deselect the input field 453 openai_key.blur(); 320 454 } 321 455 … … 323 457 document.getElementById('openai-key').value = ""; 324 458 document.getElementById("openai-key-hidden").value = ""; 459 460 const apiDisableBtn = document.getElementById('api-disable-btn'); 461 const apiDisableTxt = document.getElementById('text-switch'); 462 463 const keyStatus = document.getElementById('key-status'); 464 465 keyStatus.textContent = 'Disabled'; 466 keyStatus.style.color = 'red'; 467 468 apiDisableTxt.textContent = 'Disabled'; 469 apiDisableTxt.style.color = 'red'; 470 471 apiDisableBtn.checked = false; 325 472 } 326 473 … … 329 476 const api_Key = document.getElementById("openai-key"); 330 477 331 if (api_status) { 332 // If api_status is checked, disable the api_Key input field 333 api_Key.disabled = true; 334 } else { 335 // If api_status is not checked, enable the api_Key input field 336 api_Key.disabled = false; 337 } 478 api_Key.disabled = !!api_status; 338 479 } 339 480 … … 358 499 console.log(key_status, 'key_status'); 359 500 if (key_status == 'false') { 360 console.log('sderfdfgfgfgfgfgf'); 361 document.getElementById('key-status').textContent = 'DISABLED'; 501 document.getElementById('key-status').textContent = 'Disabled'; 362 502 document.getElementById("api-disable-btn").checked = false; 363 document.getElementsByClassName('text-switch')[0].textContent = 'D ISABLED';503 document.getElementsByClassName('text-switch')[0].textContent = 'Disabled'; 364 504 document.getElementsByClassName('text-switch')[0].style.color = 'red'; 365 505 506 console.log('Disabled'); 507 366 508 } else { 367 document.getElementById('key-status').textContent = 'E NABLED';368 document.getElementsByClassName('text-switch')[0].textContent = 'E NABLED';509 document.getElementById('key-status').textContent = 'Enabled'; 510 document.getElementsByClassName('text-switch')[0].textContent = 'Enabled'; 369 511 document.getElementsByClassName('text-switch')[0].style.color = 'green'; 370 512 document.getElementById("api-disable-btn").checked = true; 513 514 console.log('Enabled'); 371 515 // Get the value of the element with ID 'openai-key-hidden' 372 516 } … … 407 551 // Function to initialize the modal with original API key value 408 552 function handleInputChange() { 409 var inputElement = document.getElementById('openai-key'); 410 var openaiKeyHidden = document.getElementById('openai-key-hidden'); 411 var saveKpenapiKeyBtn = document.getElementById('save-openapi-key'); 412 var apiDisableBtn = document.getElementById('api-disable-btn'); 413 var openaiKeyError = document.getElementById('openai-key-error'); 414 var maskedValue = maskAPIKey(inputElement.value); 415 553 const inputElement = document.getElementById('openai-key'); 554 const openaiKeyHidden = document.getElementById('openai-key-hidden'); 555 const openaiKeyError = document.getElementById('openai-key-error'); 556 const apiDisableText = document.getElementById('text-switch'); 557 const keyStatus = document.getElementById('key-status'); 558 const apiDisableBtn = document.getElementById('api-disable-btn'); 416 559 417 560 if (inputElement.value) { 561 // Clear error message 418 562 openaiKeyError.textContent = ''; 563 564 // Update hidden input and mask the visible input 419 565 openaiKeyHidden.value = inputElement.value; 420 inputElement.value = maskedValue; 421 //saveKpenapiKeyBtn.disabled = false; 422 apiDisableBtn.disabled = false; 423 424 } 425 426 427 } 428 566 inputElement.value = maskAPIKey(inputElement.value); 567 568 // Update status text and color 569 const statusText = 'Enabled'; 570 const statusColor = 'green'; 571 apiDisableText.textContent = statusText; 572 apiDisableText.style.color = statusColor; 573 keyStatus.textContent = statusText; 574 keyStatus.style.color = statusColor; 575 apiDisableBtn.checked = true; 576 } 577 } 578 // Function to handle the change event for the API key toggle 429 579 document.getElementById('api-disable-btn').addEventListener('change', function () { 430 console.log(this.checked); 431 if (this.checked == true) { 432 433 var switchText = document.getElementsByClassName('text-switch')[0]; 434 switchText.textContent = 'ENABLED'; 435 switchText.style.color = 'Green'; 436 var element = document.getElementById('key-status'); 437 element.textContent = 'ENABLED'; 438 element.style.color = 'Green'; 439 } else { 440 441 var switchText = document.getElementsByClassName('text-switch')[0]; 442 switchText.textContent = 'DISABLED'; 443 switchText.style.color = 'Red'; 444 var element = document.getElementById('key-status'); 445 element.textContent = 'DISABLED'; 446 element.style.color = 'Red'; 447 } 448 }) 449 580 const isChecked = this.checked; 581 const switchText = document.getElementsByClassName('text-switch')[0]; 582 const keyStatusElement = document.getElementById('key-status'); 583 584 const statusText = isChecked ? 'Enabled' : 'Disabled'; 585 const statusColor = isChecked ? 'Green' : 'Red'; 586 587 // Update switch text and key status 588 switchText.textContent = statusText; 589 switchText.style.color = statusColor; 590 keyStatusElement.textContent = statusText; 591 keyStatusElement.style.color = statusColor; 592 593 }); 594 595 // Function to handle the change event for the model selection 450 596 document.addEventListener('DOMContentLoaded', function () { 451 597 document.getElementById('model').addEventListener('change', function () { … … 474 620 }); 475 621 }); 476 477 document.getElementById('openai-key').addEventListener('blur', function (event) { 478 const checkbox = document.getElementById('api-disable-btn'); 479 checkbox.checked = true; 480 var element = document.getElementsByClassName('text-switch')[0]; 481 element.textContent = 'ENABLED'; 482 element.style.color = 'green'; 483 var elementStatus = document.getElementById('key-status'); 484 elementStatus.textContent = 'ENABLED'; 485 elementStatus.style.color = 'Green'; 486 622 document.addEventListener('DOMContentLoaded', function () { 623 const hiddenKeyInput = document.getElementById('openai-key-hidden'); 624 const removeKeyButton = document.getElementById('key-remove-btn'); 625 626 if (hiddenKeyInput && removeKeyButton) { 627 // Initial check when the page loads 628 updateRemoveButtonVisibility(); 629 630 // Periodically check if the value of the hidden input changes dynamically 631 const observer = new MutationObserver(updateRemoveButtonVisibility); 632 observer.observe(hiddenKeyInput, { attributes: true, attributeFilter: ['value'] }); 633 634 // Function to update the visibility of the remove button 635 function updateRemoveButtonVisibility() { 636 if (!hiddenKeyInput.value.trim()) { 637 removeKeyButton.style.display = 'none'; 638 } else { 639 removeKeyButton.style.display = 'flex'; 640 } 641 } 642 } 487 643 }); 644 645 // document.getElementById('openai-key').addEventListener('blur', function (event) { 646 // const checkbox = document.getElementById('api-disable-btn'); 647 // checkbox.checked = true; 648 // var element = document.getElementsByClassName('text-switch')[0]; 649 // element.textContent = 'Enabled'; 650 // element.style.color = 'green'; 651 // var elementStatus = document.getElementById('key-status'); 652 // elementStatus.textContent = 'Enabled'; 653 // elementStatus.style.color = 'Green'; 654 655 // }); -
ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-plugin-settings.js
r3250856 r3272415 1 1 // Function to setup terms of service modal 2 2 function setupTermsOfServiceModal() { 3 var termsCheckbox = document.getElementById("terms_conditions");4 var acceptButton = document.getElementById("accept_ai_app_terms_of_service");5 var oldTermsCheckbox = document.getElementById("terms_of_service-old");6 var modal = document.getElementById("terms_conditions_modal");7 var closeButton = modal.querySelector(".btn-close");8 var savePluginSetting = document.getElementById("save_ai_app_plugin_settings_data");3 var termsCheckbox = document.getElementById("terms_conditions"); 4 var acceptButton = document.getElementById("accept_ai_app_terms_of_service"); 5 var oldTermsCheckbox = document.getElementById("terms_of_service-old"); 6 var modal = document.getElementById("terms_conditions_modal"); 7 var closeButton = modal.querySelector(".btn-close"); 8 var savePluginSetting = document.getElementById("save_ai_app_plugin_settings_data"); 9 9 var termsOfServiceError = document.getElementById('terms_of_service-error'); 10 10 … … 186 186 } 187 187 188 console.log(response[0]);189 190 188 // Accessing the first object in the array 191 189 var firstObject = response[0]; 192 190 193 191 // Accessing properties of the first object 194 var id = firstObject.id;195 var agreeTerms = firstObject.agree_terms;196 var appSelector = firstObject.app_selector;197 var userStats = firstObject.user_stats;198 var bannedWords = firstObject.banned_words;192 var id = firstObject.id; 193 var agreeTerms = firstObject.agree_terms; 194 var appSelector = firstObject.app_selector; 195 var userStats = firstObject.user_stats; 196 var bannedWords = firstObject.banned_words; 199 197 var bannedWordsCSV = firstObject.banned_words_csv; 200 var appName = firstObject.appName;198 var appName = firstObject.appName; 201 199 const selectElement = document.getElementById('bannedWords'); 202 200 … … 232 230 if (agreeTerms === "1") { 233 231 document.getElementById('terms_of_service-old').checked = true; 234 // document.getElementById('save_ai_app_plugin_settings_data').disabled = false;235 } else{236 // jQuery('#terms_conditions_modal').modal('show');232 // Ensure the modal is not triggered 233 } else { 234 // Show the modal if terms are not agreed to 237 235 const modalElement = document.getElementById('terms_conditions_modal'); 238 236 const modalInstance = new bootstrap.Modal(modalElement); 239 237 modalInstance.show(); 240 241 238 } 242 239 … … 455 452 456 453 // Function to clear error message when month selection is changed 457 document.getElementById('ai_app_onsite-user-stats').addEventListener('change', function() {458 document.getElementById('ai_app_onsite-user-stats-error').textContent = '';459 });454 // document.getElementById('ai_app_onsite-user-stats').addEventListener('change', function() { 455 // document.getElementById('ai_app_onsite-user-stats-error').textContent = ''; 456 // }); 460 457 461 458 //upload file js -
ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-prompt-editor.js
r3250856 r3272415 1 1 var availableFields = document.getElementById("available-fields"); 2 2 var promptInput = document.getElementById('prompt'); 3 var promptMaxTokenValue = document.getElementById('prompt-max-token-value'); 3 4 var promptError = document.getElementById('prompt-error'); 4 5 var aiResponseStyle = document.getElementById('ai-response-style'); … … 47 48 } 48 49 49 50 // read Model_Token_field 51 function ai_app_onsite_get_Model_Token_field() { 52 var xhr = new XMLHttpRequest(); 53 54 xhr.onreadystatechange = function () { 55 if (xhr.readyState === 4) { 56 if (xhr.status === 200) { 57 58 response = JSON.parse(xhr.responseText); 59 if (response.status === '404') { 60 return; 61 } 62 promptMaxTokenValue.innerHTML = response[0].max_tokens; 63 promptMaxTokenValue.style.display = 'none'; 64 65 } else { 66 // Handle error response 67 console.error('Error occurred: ' + xhr.responseText); 68 } 69 } 70 }; 71 72 xhr.open('POST', myPluginAjax.ajaxurl, true); 73 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 74 xhr.send('action=ai_app_onsite_get_Model_Token_field'); 75 } 50 76 51 77 // read field_tags -
ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-app-preview.php
r3250856 r3272415 1 1 <?php 2 3 use JetBrains\PhpStorm\NoReturn; 4 2 5 if (! class_exists('AI_APP_ONSITE_App_Preview_Handler')) { 3 6 class AI_APP_ONSITE_App_Preview_Handler 4 7 { 5 private $appProperty;8 private array $appProperty; 6 9 7 10 public function __construct() … … 11 14 $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties'; 12 15 $appropriates = $wpdb->get_results("SELECT * FROM $table_appropriate", ARRAY_A); 16 if (empty($appropriates)) { 17 error_log('No data found in $appropriates'); 18 return; 19 } 13 20 $titleColors = json_decode($appropriates[0]['title_color'], true); 14 21 $fontColors = json_decode($appropriates[0]['font_color'], true); 15 22 $bgColors = json_decode($appropriates[0]['bg_color'], true); 16 23 24 17 25 $title_color_selected = null; 18 26 $font_color_selected = null; 19 27 $bg_color_selected = null; 20 28 21 foreach ($titleColors as $color) { 22 if (isset($color['title_color_selected'])) { 23 $title_color_selected = $color['title_color_selected']; 24 break; 25 } 26 } 27 28 foreach ($fontColors as $color) { 29 if (isset($color['font_color_selected'])) { 30 $font_color_selected = $color['font_color_selected']; 31 break; 32 } 33 } 34 35 foreach ($bgColors as $color) { 36 if (isset($color['bg_color_selected'])) { 37 $bg_color_selected = $color['bg_color_selected']; 38 break; 39 } 40 } 41 42 43 if ($appropriates) { 29 if(!is_null($titleColors)) { 30 foreach ($titleColors as $color) { 31 if (isset($color['title_color_selected'])) { 32 $title_color_selected = $color['title_color_selected']; 33 break; 34 } 35 } 36 } 37 38 if(!is_null($fontColors)) { 39 foreach ($fontColors as $color) { 40 if (isset($color['font_color_selected'])) { 41 $font_color_selected = $color['font_color_selected']; 42 break; 43 } 44 } 45 } 46 47 foreach ($bgColors as $color) { 48 if (isset($color['bg_color_selected'])) { 49 $bg_color_selected = $color['bg_color_selected']; 50 break; 51 } 52 } 53 54 55 44 56 45 57 $this->appProperty = [ … … 58 70 59 71 ]; 60 }61 72 62 73 // Hook the AJAX action to the appropriate method in this class … … 78 89 //TODO: Old Logic 79 90 //New Logic 80 $appName = isset($appropriates[0]['app_name']) ? $appropriates[0]['app_name'] : 'aiapp'; 91 $appName = isset($appropriates[0]['app_name']) && !empty($appropriates[0]['app_name']) ? $appropriates[0]['app_name'] : 'aiapp'; 92 if ($appName == "aiapp") { 93 $appName = $appropriates[0]['app_name_show']; 94 } 81 95 if ($appName !== "aiapp") { 82 96 … … 109 123 110 124 // AJAX callback function 111 public function ai_app_onsite_create_app_preview_form()125 public function ai_app_onsite_create_app_preview_form() 112 126 { 113 127 global $wpdb; … … 136 150 $app_logo_image_url = wp_get_attachment_url($app_logo); 137 151 138 $form_width_size = isset($results[0]['app_width']) ? $results[0]['app_width'] :'70';152 $form_width_size = $results[0]['app_width'] ?? '70'; 139 153 140 154 … … 153 167 <img src="' . $app_logo_image_url . '" alt="App Logo" style="width: 100%; height: auto;" /> 154 168 </div>'; 155 } else {156 // Show fallback text if URL is empty157 // $formHTML .= '<div class="ai-app-image-wrap form-width" id="ai-app-openAi-app-logo"></div>';158 169 } 159 170 //App Logo End … … 235 246 236 247 // Define shortcode function 237 public function ai_app_onsite_create_openAi_app_form_shortcode() 238 { 248 public function ai_app_onsite_create_openAi_app_form_shortcode(): string { 239 249 global $wpdb; 240 250 $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties'; -
ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-app-properties.php
r3250856 r3272415 1 1 <?php 2 if ( ! class_exists( 'AI_APP_ONSITE_App_Properties_Handler' ) ) { 3 class AI_APP_ONSITE_App_Properties_Handler { 4 public function __construct() { 2 if (! class_exists('AI_APP_ONSITE_App_Properties_Handler')) { 3 class AI_APP_ONSITE_App_Properties_Handler 4 { 5 public function __construct() 6 { 5 7 // Hook the AJAX action to the appropriate method in this class 6 8 7 9 // Ajax handler 8 add_action( 'wp_ajax_ai_app_onsite_save_app_properties', array( $this, 'ai_app_onsite_save_app_properties_callback' ) ); 9 add_action( 'wp_ajax_nopriv_ai_app_onsite_save_app_properties', array( $this, 'ai_app_onsite_save_app_properties_callback' ) ); 10 11 add_action( 'wp_ajax_ai_app_onsite_get_app_properties', array( $this, 'ai_app_onsite_get_app_properties' ) ); 12 add_action( 'wp_ajax_nopriv_ai_app_onsite_get_app_properties', array( $this, 'ai_app_onsite_get_app_properties' ) ); 13 14 add_action( 'wp_ajax_ai_app_onsite_handle_sitelogo_upload', array( $this, 'ai_app_onsite_handle_sitelogo_upload_callback' ) ); 15 add_action( 'wp_ajax_nopriv_ai_app_onsite_handle_sitelogo_upload', array( $this, 'ai_app_onsite_handle_sitelogo_upload_callback' ) ); 16 17 } 18 19 function ai_app_onsite_save_app_properties_callback() { 10 add_action('wp_ajax_ai_app_onsite_save_app_properties', array($this, 'ai_app_onsite_save_app_properties_callback')); 11 add_action('wp_ajax_nopriv_ai_app_onsite_save_app_properties', array($this, 'ai_app_onsite_save_app_properties_callback')); 12 13 add_action('wp_ajax_ai_app_onsite_get_app_properties', array($this, 'ai_app_onsite_get_app_properties')); 14 add_action('wp_ajax_nopriv_ai_app_onsite_get_app_properties', array($this, 'ai_app_onsite_get_app_properties')); 15 16 add_action('wp_ajax_ai_app_onsite_handle_sitelogo_upload', array($this, 'ai_app_onsite_handle_sitelogo_upload_callback')); 17 add_action('wp_ajax_nopriv_ai_app_onsite_handle_sitelogo_upload', array($this, 'ai_app_onsite_handle_sitelogo_upload_callback')); 18 19 add_action('wp_ajax_ai_app_onsite_remove_app_logo', array($this, 'ai_app_onsite_remove_app_logo_callback')); 20 add_action('wp_ajax_nopriv_ai_app_onsite_remove_app_logo', array($this, 'ai_app_onsite_remove_app_logo_callback')); 21 } 22 23 function ai_app_onsite_save_app_properties_callback() 24 { 20 25 21 26 … … 23 28 // Verify if the request came via AJAX 24 29 if ( 25 ! isset( $_POST['action'] ) ||26 sanitize_text_field( wp_unslash( $_POST['action'] ) ) !== 'ai_app_onsite_save_app_properties' ||27 ! isset( $_POST['ai_app_onsite_app_properties_nonce_field'] ) ||28 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ai_app_onsite_app_properties_nonce_field'] ) ), 'ai_app_onsite_app_properties_nonce')30 ! isset($_POST['action']) || 31 sanitize_text_field(wp_unslash($_POST['action'])) !== 'ai_app_onsite_save_app_properties' || 32 ! isset($_POST['ai_app_onsite_app_properties_nonce_field']) || 33 ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_app_properties_nonce_field'])), 'ai_app_onsite_app_properties_nonce') 29 34 ) { 30 wp_send_json_error( 'Unauthorized request');35 wp_send_json_error('Unauthorized request'); 31 36 } 32 37 33 38 // Extract individual settings values 34 $app_name = isset( $_POST['app-name'] ) ? sanitize_text_field( wp_unslash($_POST['app-name']) ) : ''; 35 $app_description = isset( $_POST['app-description'] ) ? sanitize_text_field( wp_unslash($_POST['app-description']) ) : ''; 36 $app_disclaimer = isset( $_POST['app-disclaimer'] ) ? sanitize_text_field( wp_unslash($_POST['app-disclaimer']) ) : ''; 37 $submit_btn_txt = isset( $_POST['submit-btn-txt'] ) ? sanitize_text_field( wp_unslash($_POST['submit-btn-txt']) ) : ''; 39 $app_name = isset($_POST['app-name']) ? sanitize_text_field(wp_unslash($_POST['app-name'])) : ''; 40 $app_name_show = isset($_POST['app-name-show']) ? sanitize_text_field(wp_unslash($_POST['app-name-show'])) : ''; 41 $app_description = isset($_POST['app-description']) ? sanitize_text_field(wp_unslash($_POST['app-description'])) : ''; 42 $app_disclaimer = isset($_POST['app-disclaimer']) ? sanitize_text_field(wp_unslash($_POST['app-disclaimer'])) : ''; 43 $submit_btn_txt = isset($_POST['submit-btn-txt']) ? sanitize_text_field(wp_unslash($_POST['submit-btn-txt'])) : ''; 38 44 39 45 // Get the JSON string from $_POST 40 $titleColorsJson = isset( $_POST['titleColors'] ) ? sanitize_text_field( wp_unslash( $_POST['titleColors'] )) : '';46 $titleColorsJson = isset($_POST['titleColors']) ? sanitize_text_field(wp_unslash($_POST['titleColors'])) : ''; 41 47 $titleColorsJson = stripslashes($titleColorsJson); 42 48 43 $fontColorsJson = isset( $_POST['fontColor'] ) ? sanitize_text_field( wp_unslash( $_POST['fontColor'] )) : '';49 $fontColorsJson = isset($_POST['fontColor']) ? sanitize_text_field(wp_unslash($_POST['fontColor'])) : ''; 44 50 $fontColorsJson = stripslashes($fontColorsJson); 45 51 46 $bgColorsJson = isset( $_POST['bgColor'] ) ? sanitize_text_field( wp_unslash( $_POST['bgColor'] )) : '';52 $bgColorsJson = isset($_POST['bgColor']) ? sanitize_text_field(wp_unslash($_POST['bgColor'])) : ''; 47 53 $bgColorsJson = stripslashes($bgColorsJson); 48 54 … … 50 56 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; 51 57 52 $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings");58 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 53 59 54 60 // Check if a file was uploaded 55 if ( isset( $_FILES['app-file'] ) && ! empty( $_FILES['app-file']['name'] )) {61 if (isset($_FILES['app-file']) && ! empty($_FILES['app-file']['name'])) { 56 62 // Handle file upload 57 $upload_overrides = array( 'test_form' => false );58 $movefile = wp_handle_upload( $_FILES['app-file'], $upload_overrides );59 60 if ( $movefile && ! isset( $movefile['error'] )) {63 $upload_overrides = array('test_form' => false); 64 $movefile = wp_handle_upload($_FILES['app-file'], $upload_overrides); 65 66 if ($movefile && ! isset($movefile['error'])) { 61 67 $file_url = $movefile['url']; // Get the file URL 62 63 } else { 64 wp_send_json_error( 'Error uploading file: ' . $movefile['error'] ); 65 } 66 } else { 67 $file_url = $existing_settings->app_logo; 68 } 69 70 if ( $existing_settings ) { 68 69 } else { 70 wp_send_json_error('Error uploading file: ' . $movefile['error']); 71 } 72 } else { 73 $file_url = $existing_settings->app_logo; 74 } 75 76 if ($app_name_show == "true") { 77 $app_name_temp = $app_name; 78 $app_name = ""; 79 } else { 80 $app_name_temp = ""; 81 } 82 83 if ($existing_settings) { 71 84 $wpdb->update( 72 85 $table_name_settings, 73 86 array( 74 87 'app_name' => $app_name, 75 'app_logo' => $file_url, 88 'app_name_show' => $app_name_temp, 89 'app_logo' => $file_url, 76 90 'app_description' => $app_description, 77 91 'app_disclaimer' => $app_disclaimer, … … 80 94 'font_color' => $fontColorsJson, 81 95 'bg_color' => $bgColorsJson 82 83 ), 84 array( 'id' => $existing_settings->id),85 array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'),86 array( '%d')96 97 ), 98 array('id' => $existing_settings->id), 99 array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'), 100 array('%d') 87 101 ); 88 102 … … 101 115 'app_id' => 1, 102 116 'app_name' => $app_name, 103 'app_logo' => $file_url, 117 'app_name_show' => $app_name_temp, 118 'app_logo' => $file_url, 104 119 'app_description' => $app_description, 105 120 'app_disclaimer' => $app_disclaimer, … … 109 124 'bg_color' => $bgColorsJson 110 125 ), 111 array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')126 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 112 127 ); 113 128 … … 122 137 } 123 138 124 public static function ai_app_onsite_get_app_properties() { 125 139 public static function ai_app_onsite_get_app_properties() 140 { 141 126 142 global $wpdb; 127 143 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; … … 149 165 150 166 $generateURLForID = $results[0]['app_logo']; 151 $appLogoImagePreview = wp_get_attachment_url( $generateURLForID);152 153 if ( $appLogoImagePreview) {154 // Add the image preview URL to the $results array155 $results[0]['appLogoImagePreview'] = $appLogoImagePreview;167 $appLogoImagePreview = wp_get_attachment_url($generateURLForID); 168 169 if ($appLogoImagePreview) { 170 // Add the image preview URL to the $results array 171 $results[0]['appLogoImagePreview'] = $appLogoImagePreview; 156 172 } else { 157 173 $results[0]['appLogoImagePreview'] = 'No preview available'; // Handle cases where no URL is found … … 163 179 } 164 180 165 function ai_app_onsite_handle_sitelogo_upload_callback(){ 181 function ai_app_onsite_handle_sitelogo_upload_callback() 182 { 166 183 global $wpdb; 167 168 169 // Verify nonce to ensure the request is valid170 if (184 185 186 // Verify nonce to ensure the request is valid 187 if ( 171 188 !isset($_POST['ai_app_onsite_app_properties_logo_field_nonce_field']) || 172 189 !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_app_properties_logo_field_nonce_field'])), 'ai_app_onsite_app_properties_nonce') … … 175 192 return; 176 193 } 177 178 194 195 179 196 // Check for file upload 180 if ( isset( $_FILES['app-file'] ) && ! empty( $_FILES['app-file']['name'] )) {181 $upload_overrides = array( 'test_form' => false );182 $movefile = wp_handle_upload( $_FILES['app-file'], $upload_overrides);183 if ( $movefile && ! isset( $movefile['error'] )) {197 if (isset($_FILES['app-file']) && ! empty($_FILES['app-file']['name'])) { 198 $upload_overrides = array('test_form' => false); 199 $movefile = wp_handle_upload($_FILES['app-file'], $upload_overrides); 200 if ($movefile && ! isset($movefile['error'])) { 184 201 // File uploaded successfully 185 202 $file_path = $movefile['file']; // Local file path 186 203 $file_url = $movefile['url']; // File URL 187 204 188 205 // Create attachment 189 $filetype = wp_check_filetype( $file_path, null);206 $filetype = wp_check_filetype($file_path, null); 190 207 $attachment = array( 191 208 'post_mime_type' => $filetype['type'], 192 'post_title' => sanitize_file_name( basename( $file_path )),209 'post_title' => sanitize_file_name(basename($file_path)), 193 210 'post_content' => '', 194 211 'post_status' => 'inherit' 195 212 ); 196 213 197 $attachment_id = wp_insert_attachment( $attachment, $file_path);214 $attachment_id = wp_insert_attachment($attachment, $file_path); 198 215 199 216 // Include the image handling functions … … 201 218 202 219 // Generate metadata and update attachment 203 $attach_data = wp_generate_attachment_metadata( $attachment_id, $file_path ); 204 wp_update_attachment_metadata( $attachment_id, $attach_data ); 205 206 207 } else { 208 wp_send_json_error( 'Error uploading file: ' . $movefile['error'] ); 209 } 210 } else { 211 wp_send_json_error( 'No file uploaded.' ); 220 $attach_data = wp_generate_attachment_metadata($attachment_id, $file_path); 221 wp_update_attachment_metadata($attachment_id, $attach_data); 222 } else { 223 wp_send_json_error('Error uploading file: ' . $movefile['error']); 224 } 225 } else { 226 wp_send_json_error('No file uploaded.'); 212 227 } 213 228 214 229 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; 215 230 216 $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings");217 if ( $existing_settings) {231 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 232 if ($existing_settings) { 218 233 219 234 $wpdb->update( 220 $table_name_settings,221 array(235 $table_name_settings, 236 array( 222 237 'app_logo' => $attachment_id 223 ),224 array( 'id' => $existing_settings->id),225 array('%s'),226 array( '%d')227 );228 229 // Check if the database operation was successful230 if ($wpdb->last_error) {231 wp_send_json_error('Error updating data: ' . $wpdb->last_error);232 } else {233 // Return success message for update234 wp_send_json_success(array(238 ), 239 array('id' => $existing_settings->id), 240 array('%s'), 241 array('%d') 242 ); 243 244 // Check if the database operation was successful 245 if ($wpdb->last_error) { 246 wp_send_json_error('Error updating data: ' . $wpdb->last_error); 247 } else { 248 // Return success message for update 249 wp_send_json_success(array( 235 250 'attachment_id' => $attachment_id, 236 251 'file_url' => $file_url, 237 ) ); 238 } 239 } else { 240 // Insert new row 241 $wpdb->insert( 242 $table_name_settings, 243 array( 244 'app_id' => 1, 245 'app_name' => '', 246 'app_logo' => $attachment_id, 247 'app_description' => '', 248 'app_disclaimer' => '', 249 'submit_button_txt' => '', 250 'title_color' => '', 251 'font_color' => '', 252 'bg_color' => '' 253 ), 254 array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 255 ); 256 } 257 258 $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings" ); 252 )); 253 } 254 } else { 255 // Insert new row 256 $wpdb->insert( 257 $table_name_settings, 258 array( 259 'app_id' => 1, 260 'app_name' => '', 261 'app_name_show' => '', 262 'app_logo' => $attachment_id, 263 'app_description' => '', 264 'app_disclaimer' => '', 265 'submit_button_txt' => '', 266 'title_color' => '', 267 'font_color' => '', 268 'bg_color' => '' 269 ), 270 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 271 ); 272 } 273 274 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 259 275 $file_url = $existing_settings->app_logo; 260 276 // Check if the database operation was successful 261 if ($wpdb->last_error) { 262 wp_send_json_error('Error saving data: ' . $wpdb->last_error); 263 } else { 264 265 // Send response with the attachment ID 266 wp_send_json_success( array( 267 'attachment_id' => $attachment_id, 268 'file_url' => $file_url, 269 ) ); 270 271 } 272 273 } 274 275 276 277 277 if ($wpdb->last_error) { 278 wp_send_json_error('Error saving data: ' . $wpdb->last_error); 279 } else { 280 281 // Send response with the attachment ID 282 wp_send_json_success(array( 283 'attachment_id' => $attachment_id, 284 'file_url' => $file_url, 285 )); 286 } 287 } 288 289 public static function ai_app_onsite_remove_app_logo_callback() 290 { 291 global $wpdb; 292 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; 293 294 // Check if the table exists 295 if ($wpdb->get_var("SHOW TABLES LIKE '$table_name_settings'") != $table_name_settings) { 296 die('Table does not exist.'); 297 } 298 299 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 300 if ($existing_settings) { 301 302 $wpdb->update( 303 $table_name_settings, 304 array( 305 'app_logo' => '' 306 ), 307 array('id' => $existing_settings->id), 308 array('%s'), 309 array('%d') 310 ); 311 312 // Check if the database operation was successful 313 if ($wpdb->last_error) { 314 wp_send_json_error('Error updating data: ' . $wpdb->last_error); 315 } else { 316 // Return success message for update 317 wp_send_json_success(array( 318 'status' => '200', 319 'message' => 'Logo removed', 320 )); 321 } 322 } 323 // Don't forget to exit 324 exit; 325 } 278 326 } 279 327 … … 285 333 new AI_APP_ONSITE_App_Properties_Handler(); // Instantiate the class 286 334 } 287 -
ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-model-settings.php
r3250856 r3272415 40 40 41 41 // Extract individual settings values openai-iv 42 $model = isset($_POST['model']) ? sanitize_text_field(wp_unslash($_POST['model'])) : '';43 $max_tokens = isset($_POST['max-tokens']) ? sanitize_text_field(wp_unslash($_POST['max-tokens'])) : '';42 $model = isset($_POST['model']) ? sanitize_text_field(wp_unslash($_POST['model'])) : ''; 43 $max_tokens = isset($_POST['max-tokens']) ? sanitize_text_field(wp_unslash($_POST['max-tokens'])) : ''; 44 44 $temperature = isset($_POST['temperature']) ? sanitize_text_field(wp_unslash($_POST['temperature'])) : ''; 45 $top_p = isset($_POST['top-p']) ? floatval(sanitize_text_field(wp_unslash($_POST['top-p']))) : 0;46 $f_penalty = isset($_POST['f-penalty']) ? sanitize_text_field(wp_unslash($_POST['f-penalty'])) : '';47 $p_penalty = isset($_POST['p-penalty']) ? sanitize_text_field(wp_unslash($_POST['p-penalty'])) : '';45 $top_p = isset($_POST['top-p']) ? floatval(sanitize_text_field(wp_unslash($_POST['top-p']))) : 0; 46 $f_penalty = isset($_POST['f-penalty']) ? sanitize_text_field(wp_unslash($_POST['f-penalty'])) : ''; 47 $p_penalty = isset($_POST['p-penalty']) ? sanitize_text_field(wp_unslash($_POST['p-penalty'])) : ''; 48 48 49 49 … … 58 58 $table_name_settings, 59 59 array( 60 'model' => $model,60 'model' => $model, 61 61 'temperature' => $temperature, 62 'f_penalty' => $f_penalty,63 'p_penalty' => $p_penalty,64 'max_tokens' => $max_tokens,65 'top_p' => $top_p62 'f_penalty' => $f_penalty, 63 'p_penalty' => $p_penalty, 64 'max_tokens' => $max_tokens, 65 'top_p' => $top_p 66 66 67 67 ), … … 84 84 $table_name_settings, 85 85 array( 86 'app_id' => 1,87 'model' => $model,86 'app_id' => 1, 87 'model' => $model, 88 88 'temperature' => $temperature, 89 'f_penalty' => $f_penalty,90 'p_penalty' => $p_penalty,91 'max_tokens' => $max_tokens,92 'top_p' => $top_p89 'f_penalty' => $f_penalty, 90 'p_penalty' => $p_penalty, 91 'max_tokens' => $max_tokens, 92 'top_p' => $top_p 93 93 ), 94 94 array('%d', '%s', '%d', '%d', '%d', '%d', '%d') … … 188 188 $openai_key = isset($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : ''; 189 189 $api_status = isset($_POST['api_status']) ? sanitize_text_field(wp_unslash($_POST['api_status'])) : ''; 190 191 $engine_model = isset($_POST['engine_model']) ? sanitize_text_field(wp_unslash($_POST['engine_model'])) : ''; 190 192 191 193 … … 221 223 $table_name_settings, 222 224 array( 223 'app_id' => 1, 224 'openai_key' => $openai_key, 225 'key_status' => $api_status, 225 'app_id' => 1, 226 'openai_key' => $openai_key, 227 'key_status' => $api_status, 228 'model' => $engine_model, 226 229 'temperature' => '0.7', 227 'f_penalty' => '0',228 'p_penalty' => '0',229 'max_tokens' => '3000',230 'top_p' => '1',230 'f_penalty' => '0', 231 'p_penalty' => '0', 232 'max_tokens' => '3000', 233 'top_p' => '1', 231 234 ), 232 235 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s') -
ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-prompt-editor.php
r3250856 r3272415 8 8 add_action('wp_ajax_ai_app_onsite_get_field_tags', array($this, 'ai_app_onsite_get_field_tags')); 9 9 add_action('wp_ajax_nopriv_ai_app_onsite_get_field_tags', array($this, 'ai_app_onsite_get_field_tags')); 10 11 add_action('wp_ajax_ai_app_onsite_get_Model_Token_field', array($this, 'ai_app_onsite_get_Model_Token_field')); 12 add_action('wp_ajax_nopriv_ai_app_onsite_get_Model_Token_field', array($this, 'ai_app_onsite_get_Model_Token_field')); 10 13 11 14 add_action('wp_ajax_ai_app_onsite_save_prompt_editor', array($this, 'ai_app_onstie_save_prompt_editor_callback')); … … 134 137 } 135 138 136 public static function ai_app_onsite_get_prompt_editor() 137 { 139 public static function ai_app_onsite_get_Model_Token_field() 140 { 141 138 142 global $wpdb; 139 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_ prompt_editor';143 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_model_settings'; 140 144 141 145 // Check if the table exists … … 147 151 $rows_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name_settings"); 148 152 if ($rows_count == 0) { 149 150 153 $results = array('status' => '404', 'message' => 'No rows found in the table.'); 151 154 … … 165 168 exit; 166 169 } 170 171 public static function ai_app_onsite_get_prompt_editor() 172 { 173 global $wpdb; 174 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_prompt_editor'; 175 176 // Check if the table exists 177 if ($wpdb->get_var("SHOW TABLES LIKE '$table_name_settings'") != $table_name_settings) { 178 die('Table does not exist.'); 179 } 180 181 // Check if the table has rows 182 $rows_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name_settings"); 183 if ($rows_count == 0) { 184 185 $results = array('status' => '404', 'message' => 'No rows found in the table.'); 186 187 // Return the data 188 wp_send_json($results); 189 190 die(); 191 } 192 193 // Fetch the data 194 $results = $wpdb->get_results("SELECT * FROM $table_name_settings", ARRAY_A); 195 196 // Return the data 197 wp_send_json($results); 198 199 // Don't forget to exit 200 exit; 201 } 167 202 } 168 203 -
ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-user-stats.php
r3250856 r3272415 11 11 } 12 12 13 public function ai_app_onsite_save_user_stats($result, $prompt, $formData) { 13 public function ai_app_onsite_save_user_stats($result, $prompt, $formData): void 14 { 14 15 global $wpdb; 15 16 16 // Get user IP address and geolocation using ipinfo.io 17 $user_ip = ''; 18 $user_geolocation = ''; 17 $ipinfo_token = '83cebbc0b4b378'; // Replace with your IPinfo API token 18 $ipinfo_url = "https://ipinfo.io?token={$ipinfo_token}"; 19 19 20 $ipinfo_token = '83cebbc0b4b378'; // Replace with your IPinfo API token 21 $ipinfo_url = "https://ipinfo.io?token={$ipinfo_token}"; 20 $response = wp_remote_get($ipinfo_url); 22 21 23 // Use WordPress HTTP API instead of CURL 24 $response = wp_remote_get($ipinfo_url); 22 if (!is_wp_error($response)) { 23 $body = wp_remote_retrieve_body($response); 24 $data = json_decode($body, true); 25 25 26 if (!is_wp_error($response)) { 27 $body = wp_remote_retrieve_body($response); 28 $data = json_decode($body, true); 26 $user_ip = !empty($data['ip']) ? sanitize_text_field($data['ip']) : 'Unknown'; 27 $user_geolocation = wp_json_encode($data); 28 } else { 29 // Fallback: Get IP using PHP if ipinfo fails 30 if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 31 $user_ip = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']); 32 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 33 // Sometimes contains multiple IPs (first is original) 34 $forwarded_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); 35 $user_ip = sanitize_text_field(trim($forwarded_ips[0])); 36 } elseif (!empty($_SERVER['REMOTE_ADDR'])) { 37 $user_ip = sanitize_text_field($_SERVER['REMOTE_ADDR']); 38 } else { 39 $user_ip = 'Unknown'; 40 } 29 41 30 if (!empty($data['ip'])) { 31 $user_ip = sanitize_text_field($data['ip']); 32 } 33 $user_geolocation = wp_json_encode($data); 34 } else { 35 wp_send_json_error('Error fetching IP info: ' . $response->get_error_message());36 }42 // Optional fallback message 43 $user_geolocation = wp_json_encode(array( 44 'ip' => $user_ip, 45 'source' => 'fallback-php', 46 'error' => $response->get_error_message() 47 )); 48 } 37 49 38 50 // Extract individual settings values 39 $formData = isset($formData) ? wp_json_encode($formData) : '';40 $used_token = isset($result['usage']['total_tokens']) ? sanitize_text_field($result['usage']['total_tokens']) : '';51 $formData = isset($formData) ? wp_json_encode($formData) : ''; 52 $used_token = isset($result['usage']['total_tokens']) ? sanitize_text_field($result['usage']['total_tokens']) : ''; 41 53 $response_Id = isset($result['id']) ? sanitize_text_field($result['id']) : ''; 42 $prompt = isset($prompt) ? sanitize_text_field($prompt) : '';54 $prompt = isset($prompt) ? sanitize_text_field($prompt) : ''; 43 55 44 56 // Insert new row … … 47 59 $table_name_stats, 48 60 array( 49 'app_id' => 1,50 'response_id' => $response_Id,51 'user_ip' => $user_ip,61 'app_id' => 1, 62 'response_id' => $response_Id, 63 'user_ip' => $user_ip, 52 64 'user_geolocation' => $user_geolocation, 53 'prompt' => $prompt,54 'data' => $formData,55 'used_token' => $used_token,56 'created_at' => current_time('mysql'),57 'updated_at' => current_time('mysql')65 'prompt' => $prompt, 66 'data' => $formData, 67 'used_token' => $used_token, 68 'created_at' => current_time('mysql'), 69 'updated_at' => current_time('mysql') 58 70 ), 59 71 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-admin.php
r3250856 r3272415 35 35 </h5> 36 36 </div> 37 <div class="ai-app-onsite-tab-content-box ">37 <div class="ai-app-onsite-tab-content-box shadow-sm rounded"> 38 38 <!-- Tab navigation --> 39 39 <h2 class="nav-tab-wrapper"> … … 78 78 <div class="assets-preview-icon-blue-icon"></div> 79 79 </div> 80 AppPreview80 Style & Preview 81 81 </a> 82 82 </h2> … … 204 204 ); 205 205 ?> 206 <div id="plugin-settings-content" class="tab-content ">206 <div id="plugin-settings-content" class="tab-content plugin-settings-tab-section"> 207 207 <?php echo wp_kses(AI_App_Onsite_Plugin_Settings::render_plugin_settings(), $allowed_html); ?> 208 208 </div> 209 209 210 <div id="app-properties-content" class="tab-content " style="display: none;">210 <div id="app-properties-content" class="tab-content app-properties-tab-section" style="display: none;"> 211 211 <?php 212 212 echo wp_kses(AI_App_Onsite_App_Properties::render_app_properties(), $allowed_html); … … 214 214 </div> 215 215 216 <div id="model-settings-content" class="tab-content " style="display: none;">216 <div id="model-settings-content" class="tab-content model-settings-tab-section" style="display: none;"> 217 217 <?php echo wp_kses(AI_App_Onsite_Model_Settings::render_model_settings(), $allowed_html); ?> 218 218 </div> 219 219 220 <div id="field-selector-content" class="tab-content " style="display: none;">220 <div id="field-selector-content" class="tab-content field-selector-tab-section" style="display: none;"> 221 221 <?php echo wp_kses(AI_App_Onsite_Field_Selector::render_field_selector(), $allowed_html); ?> 222 222 </div> 223 223 224 <div id="prompt-editor-content" class="tab-content " style="display: none;">224 <div id="prompt-editor-content" class="tab-content prompt-editor-tab-section" style="display: none;"> 225 225 <?php 226 226 //echo AI_App_Onsite_Prompt_Editor::render_prompt_editor(); … … 233 233 'textarea_rows' => 10, // Number of rows for the editor. 234 234 'teeny' => false, // Full TinyMCE editor. 235 'quicktags' => false, // Disable the Visual and Text tabs. 236 'menubar' => false, 235 237 ); 236 238 … … 240 242 241 243 ?> 242 </div> 243 244 <div id="app-preview-content" class="tab-content" style="display: none;"> 244 <script type="text/javascript"> 245 // Wait until TinyMCE is initialized 246 jQuery(document).ready(function($) { 247 // Access TinyMCE editor instance 248 var editor = tinymce.get('prompt'); // 'prompt' is the editor ID 249 250 // Function to update the word count 251 function updateWordCount() { 252 var content = editor.getContent({ 253 format: 'text' 254 }); // Get plain text content 255 var wordCount = content.split(/\s+/).filter(function(word) { 256 return Boolean(word); 257 258 }).length; // Count words 259 var maxToken = document.getElementById("prompt-max-token-value").innerHTML 260 let estimatedTokens = Math.ceil(wordCount * 1.33); 261 let percentage = Math.ceil((estimatedTokens / maxToken) * 100); 262 $('#word-count') 263 .text(estimatedTokens + ' / ' + maxToken + ' Est. Tokens Used') 264 .css({ 265 'color': percentage < 50 ? 'green' : percentage < 80 ? 'orange' : 'red', 266 'font-weight': '600', 267 'margin-bottom': '10px', 268 'font-size': '13px' 269 }); 270 // Update the word count display 271 } 272 273 // Bind keyup event to editor content change (every time user types) 274 editor.on('keyup', function() { 275 updateWordCount(); // Update word count on keyup 276 }); 277 }); 278 </script> 279 </div> 280 281 <div id="app-preview-content" class="tab-content app-preview-tab-section" style="display: none;"> 245 282 <?php echo wp_kses(AI_App_Onsite_App_Preview::render_app_preview_content(), $allowed_html); ?> 246 283 </div> 247 284 </div> 248 285 </div> 286 287 <!-- Modal --> 288 <div class="modal fade bd-example-modal-sm plugin-setting" id="terms_conditions_modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"> 289 <div class="modal-dialog modal-dialog-centered" role="document"> 290 <div class="modal-content"> 291 <div class="modal-header"> 292 <h5 class="fs-bold-16" id="terms_conditions_modal_label">Terms of Services</h5> 293 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 294 </div> 295 <div class="modal-body mb-1"> 296 <div id="terms-conditions-modal-pdf"> 297 <p class="fs-regular-14 neutral-black-fs-100 mb-3 text-center">Terms of Services</p> 298 <p class="fs-regular-14 neutral-black-fs-90">Please read these terms carefully before using our service.</p> 299 <p class="fs-regular-14 neutral-black-fs-100 mb-1">1. User Responsibility</p> 300 <p class="fs-regular-12 neutral-black-fs-70">If you reside in the European Economic Area, Switzerland, the UK, California or some other locations, you may be subject to special conditions and laws that govern the use of AI. These and other locales also have privacy and data protection rules and laws that may also dictate how you can leverage tools like AIappOnsite.</p> 301 <p class="fs-regular-12 neutral-black-fs-70">It is important that you abide by all such applicable laws. Furthermore, you may not use the Service in a way that infringes, misappropriates or violates anyone’s rights. You may also not use the Service in a way that endangers or harms, or intends to do the same, to end users of applications built with the Service.</p> 302 303 <p class="fs-regular-14 neutral-black-fs-100 mb-1">2. Using AI Services</p> 304 <p class="fs-regular-12 neutral-black-fs-70">The Service requires that the site owner or their designee provide an API key which the Service will use tointegrate with an AI model provider. All AI functionality of the Service depends on one or more API keys, whichis provided by the various AI model vendors. An account must be opened with one of these vendors in order to get an API key.</p> 305 <p class="fs-regular-12 neutral-black-fs-70">These AI model providers are separate companies and unaffiliated with the Service, and have their own terms and conditions. Read them carefully. The API keys and their use are bound by the terms and conditions of the AI model provider and strictly controlled by the site owner or their designee (not AIappOnsite).</p> 306 307 <p class="fs-regular-14 neutral-black-fs-100 mb-1">3. Limitation of Liability</p> 308 <p class="fs-regular-12 neutral-black-fs-70">Given that the site owner fully controls the use, purpose and output of any application built with it, AIappOnsite bears no responsibility or liability for how it is used, or to any consequences of its use by site owners or their site visitors.</p> 309 <p class="fs-regular-12 neutral-black-fs-70">You agree that you are leveraging third party AI models and services separate from AIappOnsite, and that you have full control over and final responsibility for the prompts that will access the API as well as the end-user experience, and any representations made to them.</p> 310 311 <p class="fs-regular-14 neutral-black-fs-100 mb-1">4. Paid Accounts</p> 312 <p class="fs-regular-12 neutral-black-fs-70">Billing. If you purchase any services, you will provide complete and accurate billing information, including a valid payment method. For paid subscriptions, we will automatically charge your payment method on each agreed-upon periodic renewal until you cancel. You’re responsible for all applicable taxes, and we’ll charge tax when required. If your payment cannot be completed, we may downgrade your account or suspend your access to our services until payment is received.</p> 313 <p class="fs-regular-12 neutral-black-fs-70">Cancellation. You can cancel your paid subscription at any time. Previous payments are non-refundable,except where required by law. These Terms do not override any mandatory local laws regarding your cancellation rights.</p> 314 <p class="fs-regular-12 neutral-black-fs-70">Changes. We may change our prices from time to time. If we increase our subscription prices, we will give you at least 30 days’ notice and any price increase will take effect on your next renewal so that you can cancel if you do not agree to the price increase</p> 315 316 <p class="fs-regular-14 neutral-black-fs-100 mb-1">5. Termination and Suspension</p> 317 <p class="fs-regular-12 neutral-black-fs-70">Termination. You are free to stop using our Services at any time. We reserve the right to suspend or terminate your access to our Services or delete your account if we determine: 318 <ul class="pl-2"> 319 <li class="fs-regular-12 neutral-black-fs-70">- You breached these Terms of Service.</li> 320 <li class="fs-regular-12 neutral-black-fs-70">- We must do so to comply with the law.</li> 321 <li class="fs-regular-12 neutral-black-fs-70">- Your use of our Services could cause risk or harm to AIappOnsite or anyone else.</li> 322 </ul> 323 </p> 324 <p class="fs-regular-12 neutral-black-fs-70">Appeals. If you believe we have suspended or terminated your account in error, you can file an appeal with us by contacting our Support team.</p> 325 326 <p class="fs-regular-14 neutral-black-fs-100 mb-1">6. Discontinuation of Services</p> 327 <p class="fs-regular-12 neutral-black-fs-70">We may decide to discontinue our Services, but if we do, we will give you advance notice and a refund for any prepaid, unused services.</p> 328 329 <p class="fs-regular-14 neutral-black-fs-100 mb-1">7. Disclaimer of Warranties</p> 330 <p class="fs-regular-12 neutral-black-fs-70">Our services are provided “as is.” except to the extent prohibited by law, we and our affiliates and licensors make no warranties (express, implied, statutory or otherwise) with respect to the services, and disclaim all warranties including, but not limited to, warranties of merchantability, fitness for a particular purpose,satisfactory quality, non-infringement, and quiet enjoyment, and any warranties arising out of any course of dealing or trade usage. We do not warrant that the services will be uninterrupted, accurate or error free, or that any content will be secure or not lost or altered.</p> 331 <p class="fs-regular-12 neutral-black-fs-70">You accept and agree that any use of the service is at your sole risk.</p> 332 333 <p class="fs-regular-14 neutral-black-fs-100 mb-1">8. Limitation of liability</p> 334 <p class="fs-regular-12 neutral-black-fs-70">Neither we nor any of our affiliates or licensors will be liable for any indirect,incidental, special, consequential, or exemplary damages, including damages for loss of profits, goodwill, use, or data or other losses, even if we have been advised of the possibility of such damages. Our aggregate liability under these terms will not exceed the greater of the amount you paid for the service that gave rise to the claim during the 12 months before the liability arose or one hundred dollars ($100).The limitations in this section apply only to the maximum extent permitted by applicable law.</p> 335 <p class="fs-regular-12 neutral-black-fs-70">Some countries and states do not allow the disclaimer of certain warranties or the limitation of certain damages, so some or all of the terms above may not apply to you, and you may have additional rights. In that case, these Terms only limit our responsibilities to the maximum extent permissible in your country of residence.</p> 336 <p class="fs-regular-12 neutral-black-fs-70">Aiapponsite’s affiliates, suppliers, licensors, and distributors are intended third party beneficiaries of this section.</p> 337 338 <p class="fs-regular-14 neutral-black-fs-100 mb-1">9. Indemnity</p> 339 <p class="fs-regular-12 neutral-black-fs-70">If you are a business or organization, to the extent permitted by law, you will indemnify and hold harmless us,our affiliates, and our personnel, from and against any costs, losses, liabilities, and expenses (including attorneys’ fees) from third party claims arising out of or relating to your use of the Services and Content or any violation of these Terms.</p> 340 341 <div class="terms-form-group form-group mb-0"> 342 <input type="checkbox" id="terms_conditions"> 343 <label for="terms_conditions" class="fs-regular-14 pl-1 neutral-black-fs-90">Agree to Terms of Service</label> 344 </div> 345 </div> 346 <div class="divider-light mt-2 mb-3"></div> 347 <div class="button-wrap"> 348 <button type="button" id="download_ai_app_terms_of_service" role="button" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-white" name="save-plugin-settings" onclick="ai_app_onsite_download_terms_Of_service()">Download</button> 349 <button type="button" id="accept_ai_app_terms_of_service" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-purple border-purple text-white" name="save-plugin-settings" data-bs-dismiss="modal">Accept</button> 350 </div> 351 </div> 352 </div> 353 </div> 354 </div> 249 355 250 356 <?php -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-app-preview.php
r3250856 r3272415 11 11 <div class="app-preview-content"> 12 12 <div class="form-wrapper"> 13 <p class="fs-bold-14">Add App To Website</p> 13 <div class="#"> 14 <div class="d-flex align-items-baseline justify-content-between mb-2"> 15 <p class="font-bold fs-5 mb-0 app-preview-content__heading">Add App To Website</p> 16 <p class="font-regular mb-0 app-preview-content__description">Use the Shortcode or Name Block to add your app to a page or do more customization and test your app prompt below.</p> 17 </div> 18 </div> 14 19 <div> 15 20 <div class="row" id="shortcode-box"> 16 21 <div class="col-lg-6"> 17 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 ">Shortcode</label>22 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 text-muted">Shortcode</label> 18 23 <div class="select-box-icon"> 19 24 <span class="field-icon"> 20 25 <div class="assets-shortcode-icon"></div> 21 26 </span> 22 <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_shortcode()"> 23 <div class="assets-copy-icon"></div> 24 </span> 25 <input type="text" id="ai-app-onsite-openAi-app-shortcode" class="ai-app-onsite-openAi-app-shortcode" data-target="#ai-app-onsite-openAi-app-shortcode" readonly> 27 <div class="select-box-icon"> 28 <span class="field-icon"> 29 <div class="assets-shortcode-icon"></div> 30 </span> 31 <input type="text" id="ai-app-onsite-openAi-app-shortcode" class="ai-app-onsite-openAi-app-shortcode" data-target="#ai-app-onsite-openAi-app-shortcode" readonly> 32 <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_shortcode()"> 33 <div class="assets-copy-icon"></div> 34 </span> 35 </div> 26 36 </div> 27 37 <p class="neutral-black-fs-60 fs-regular-12 mb-0">Copy to add in Wordpress Classic Editor</p> 28 38 </div> 29 39 <div class="col-lg-6"> 30 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 ">Name Block</label>40 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 text-muted">Name Block</label> 31 41 <div class="select-box-icon"> 32 42 <span class="field-icon"> 33 43 <div class="assets-shortcode-icon"></div> 34 44 </span> 45 <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly> 35 46 <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_gutenberg_block()"> 36 47 <div class="assets-copy-icon"></div> 37 48 </span> 38 <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly>39 49 </div> 40 50 <p class="neutral-black-fs-60 fs-regular-12 mb-0">Name block to add in Gutenberg</p> … … 48 58 49 59 <div class="form-group mt-2" id="test-app-container"> 50 <div class="d-flex justify-content-between align-items-center"> 51 <label class="d-block fs-medium-16 mb-only-4 mt-2">Test Response</label> 52 <button type="button" class="btn fs-medium-14 neutral-black-fs-100 radius-6 py-8 px-16 border border-2 bg-white" name="ai-app-onsite-test" id="ai-app-onsite-test" onclick="ai_app_onsite_test_from()">Test App</button> 60 <div class="d-flex justify-content-between align-items-center mb-2"> 61 <label class="d-block fs-medium-16 mb-only-4 mt-2 text-muted">Test Response</label> 62 <button type="button" class="#" name="ai-app-onsite-test" id="ai-app-onsite-test" onclick="ai_app_onsite_test_from()"> 63 <span>Click To Test App</span> 64 </button> 53 65 </div> 54 66 <div class="select-box-icon select-box-icon-textarea mb-30"> -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-app-properties.php
r3250856 r3272415 14 14 <div class="form-group mb-20"> 15 15 <label class="fs-medium-14">App Name<span class="text-danger">*</span></label> 16 <div class="select-box-icon"> 17 <span class="field-icon"> 18 <div class="assets-folder-icon"></div> 19 </span> 20 <input type="text" name="app-name" id="app-name" class="border border-1 w-100 mb-1 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8"> 21 <p id="app-name-error" class="fields-error"></p> 22 </div> 16 <div class="col-12 d-flex flex-column flex-md-row"> 17 <!-- First div with the text input --> 18 <div class="col-12 col-md-7 select-box-icon mb-3 mb-md-0 me-md-2"> 19 <span class="field-icon"> 20 <div class="assets-folder-icon"></div> 21 </span> 22 <input type="text" name="app-name" id="app-name" class="border border-1 w-100 mb-1 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8"> 23 <p id="app-name-error" class="fields-error"></p> 24 </div> 25 26 <!-- Second div with the checkbox --> 27 <div class="col-12 col-md-5 m-2"> 28 <label for="app-name-toggle" class="d-flex align-items-center"> 29 <input type="checkbox" name="app-name-toggle" id="app-name-toggle" class="me-2"> 30 <span>Disable app name display</span> 31 </label> 32 </div> 33 </div> 34 23 35 </div> 24 36 <div class="form-group"> 25 <label class="fs-medium-14">App Logo/Image</label> 26 <div class="preview-img-box"> 27 <div id="previewImage"></div> 28 <div class="file-drop-area border "> 29 <span class="fake-btn"> 30 <div class="assets-upload-file-icon"></div> 31 </span> 32 <div> 33 <p class="file-msg-top mb-0 neutral-black-fs-110"><span class="text-purple">Click to upload</span> or drag and drop</p> 34 <p class="neutral-black-fs-50 mb-0 fs-regular-12">SVG, PNG, JPG or GIF (max. 800x400px)</p> 35 </div> 36 <input class="file-input" type="file" id="file-upload" name="fileUpload" accept=".svg, .png, .jpg, .gif" onchange="validateFile(this)"> 37 </div> 38 </div> 39 <p id="fileError" class="mt-1 fields-error"></p> 37 <label class="fs-medium-14 mb-1">App Logo/Image</label> 38 <div class="col-12 d-flex flex-column flex-md-row"> 39 <!-- First div with the file input and preview --> 40 <div class="col-12 col-md-12 select-box-icon mb-3 mb-md-0 me-md-2"> 41 <div id="previewImage"></div> 42 <div class="row d-flex align-items-center mt-2"> 43 <div class="col-md-8" id="file-upload-div"> 44 <div class="file-drop-area border "> 45 <span class="fake-btn"> 46 <div class="assets-upload-file-icon"></div> 47 </span> 48 <div> 49 <p class="file-msg-top mb-0 neutral-black-fs-110"><span class="text-purple">Click to upload</span> or drag and drop</p> 50 <p class="neutral-black-fs-50 mb-0 fs-regular-12">SVG, PNG, JPG or GIF (max. 800x400px)</p> 51 </div> 52 <input class="file-input" type="file" id="file-upload" name="fileUpload" accept=".svg, .png, .jpg, .gif" onchange="validateFile(this)"> 53 </div> 54 </div> 55 <!-- Second div with the button and cross icon --> 56 <div class="col-md-4" id="remove-logo-btn"> 57 <button type="button" class="btn btn-outline-danger d-flex align-items-center" onclick="removeLogoFile(this)"> 58 <span class="me-2"> 59 <div class="assets-cross-icon"></div> <!-- You can replace this with an actual cross icon --> 60 </span> 61 <span>Remove Logo</span> 62 </button> 63 64 </div> 65 66 </div> 67 <p id="fileError" class="mt-1 fields-error"></p> 68 69 70 </div> 71 </div> 40 72 </div> 41 73 <div class="form-group"> -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-db-handler.php
r3250856 r3272415 64 64 app_name TEXT, 65 65 app_logo TEXT, 66 app_name_show TEXT, 66 67 app_disclaimer VARCHAR(300), 67 68 app_description VARCHAR(1000), -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-model-settings.php
r3250856 r3272415 14 14 <?php wp_nonce_field('ai_app_onsite_model_settings_nonce', 'ai_app_onsite_model_settings_nonce_field'); ?> 15 15 <div class="row"> 16 <div class="col-lg- 6">17 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 ">Engine/Model </label>16 <div class="col-lg-12"> 17 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 font-semibold">Choose Engine/Model </label> 18 18 <div class="select-box-icon mb-20"> 19 19 <span class="field-icon"> … … 21 21 </span> 22 22 <select id="model" class="border border-1 w-100 mb-1 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8"> 23 <option >Select</option>23 <option value="">Please Select Model</option> 24 24 <option value="gpt-4o">Open AI - gpt-4o</option> 25 25 <option value="gpt-4-turbo">Open AI - gpt-4-turbo</option> … … 29 29 <option value="gpt-3.5-turbo">Open AI - gpt-3.5-turbo</option> 30 30 </select> 31 31 <span id="model-help-text" class="text-danger"></span> 32 32 <p id="model-error" class="fields-error"></p> 33 33 </div> 34 34 </div> 35 <div class="col-lg-6"> 35 </div> 36 <div id="model-dependent-fields" class="row"> 37 38 <div class="col-lg-6 mb-20"> 36 39 <div class="form-group"> 37 <label class="fs-medium-14 ">Max Tokens</label>40 <label class="fs-medium-14 font-semibold">Max Tokens</label> 38 41 <div class="select-box-icon"> 39 42 <span class="field-icon"> 40 43 <div class="assets-token-icon"></div> 41 44 </span> 42 <input type="text" name="" placeholder="3000" id="max-tokens" class="border border-1 w-100 mb-20 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="3000"> 45 <input type="text" name="" placeholder="3000" id="max-tokens" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="3000"> 46 <span class="small-text text-muted">Maximum number of tokens (words & characters) allowed in response.</span> 43 47 </div> 44 48 </div> 45 49 </div> 46 <div class="col-lg-6 ">50 <div class="col-lg-6 mb-20"> 47 51 <div class="form-group"> 48 <label class="fs-medium-14 ">Temperature</label>52 <label class="fs-medium-14 font-semibold">Temperature</label> 49 53 <div class="select-box-icon"> 50 54 <span class="field-icon"> 51 55 <div class="assets-temprature-icon"></div> 52 56 </span> 53 <input type="text" name="temperature" placeholder="1" id="temperature" class="border border-1 w-100 mb-20 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0.7"> 57 <input type="text" name="temperature" placeholder="1" id="temperature" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0.7"> 58 <span class="small-text text-muted">Controls creativity — higher value = more random responses.</span> 54 59 </div> 55 60 </div> 56 61 </div> 57 <div class="col-lg-6 ">62 <div class="col-lg-6 mb-20"> 58 63 <div class="form-group"> 59 <label class="fs-medium-14 ">Top P</label>64 <label class="fs-medium-14 font-semibold">Top P</label> 60 65 <div class="select-box-icon"> 61 66 <span class="field-icon"> 62 67 <div class="assets-temprature-icon"></div> 63 68 </span> 64 <input type="text" name="top-p" placeholder="1" id="top-p" class="border border-1 w-100 mb-20 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="1"> 69 <input type="text" name="top-p" placeholder="1" id="top-p" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="1"> 70 <span class="small-text text-muted">Controls diversity — lower value = more focused responses.</span> 65 71 </div> 66 72 </div> 67 73 </div> 68 <div class="col-lg-6 ">74 <div class="col-lg-6 mb-20"> 69 75 <div class="form-group mb-0"> 70 <label class="fs-medium-14 ">F. Penalty</label>76 <label class="fs-medium-14 font-semibold">F. Penalty</label> 71 77 <div class="select-box-icon"> 72 78 <span class="field-icon"> … … 74 80 </span> 75 81 <input type="text" name="f-penalty" placeholder="0" id="f-penalty" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0"> 82 <span class="small-text text-muted">Reduces repetition of existing words in the response.</span> 76 83 </div> 77 84 </div> 78 85 </div> 79 <div class="col-lg-6 ">86 <div class="col-lg-6 mb-20"> 80 87 <div class="form-group mb-0"> 81 <label class="fs-medium-14 ">P. Penalty</label>88 <label class="fs-medium-14 font-semibold">P. Penalty</label> 82 89 <div class="select-box-icon"> 83 90 <span class="field-icon"> … … 85 92 </span> 86 93 <input type="text" name="p-penalty" placeholder="0" id="p-penalty" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0"> 94 <span class="small-text text-muted">Reduces repetition of new words in the response.</span> 87 95 </div> 88 96 </div> 89 97 </div> 90 </div> 98 </div> 99 91 100 <div class="divider-light"></div> 92 101 <div class="row justify-content-center"> 93 <div class="col-lg-6" >94 <div class="api-key-icon select-box-icon d-flex " onclick="ai_app_onsite_get_openapi_data()">95 <span class=" field-icon">102 <div class="col-lg-6" id="api-key-management"> 103 <div class="api-key-icon select-box-icon d-flex justify-content-around align-items-center" onclick="ai_app_onsite_get_openapi_data()"> 104 <span class="#"> 96 105 <div class="assets-api-key-icon"></div> 97 106 </span> 98 <p class="mb-0 fs- medium-14cursor-pointer" data-bs-toggle="modal" data-bs-target="#apiinfoModal">107 <p class="mb-0 fs-6 cursor-pointer" data-bs-toggle="modal" data-bs-target="#apiinfoModal"> 99 108 API Key Management 100 109 </p> 101 110 102 111 <span class="mb-0"> 103 <p id="key-status" ></p>112 <p id="key-status" class="mb-0 font-semibold fs-6"></p> 104 113 </span> 105 114 </div> … … 129 138 <p class="fs-regular-14 neutral-black-fs-100">Please enter your OpenAI API key below. You can get an API key from your <a href="" class="neutral-black-fs-100 underline"> OpenAI account dashboard.</a></p> 130 139 <div class="form-group mb-0"> 131 <label class="fs-medium-14 ">API api-key</label>140 <label class="fs-medium-14 fw-semibold">API Key</label> 132 141 <div class="select-box-icon right-icon"> 133 <span class="field-icon " onclick="ai_app_onsite_copy_openapi_key()">142 <span class="field-icon copy-api-key"> 134 143 <div class="assets-copy-icon"></div> 135 144 </span> … … 137 146 <input type="hidden" name="openai-key-hidden" id="openai-key-hidden"> 138 147 </div> 139 <span id="maskToggle">Show</span> 140 <span id="copyButton">Copy</span> 148 <div class="d-flex justify-content-start align-items-center mt-2 key-toggle"> 149 <span id="maskToggle" class="text-muted me-3 mask__toggle">Show Key</span> 150 </div> 141 151 <p id="openai-key-error" class="fields-error"></p> 142 152 </div> 143 <p class="fs-regular-12 neutral-black-fs-60 mb-1 mt-2">Note: Your API key isstored locally and securely in your browser and never shared.</p>153 <p class="fs-regular-12 neutral-black-fs-60 mb-1 mt-2">Note: Your API key will be stored locally and securely in your browser and never shared.</p> 144 154 <div class="flex-row alignment-items-center mt-3 mb-3"> 145 155 <div class="col-50"> 146 <button class="btn remove-btn" id="key-remove-btn" onclick="ai_app_onsite_clear_openapi_Key_field()">147 <span class="btn-icon ">156 <button class="btn remove-btn align-items-center" id="key-remove-btn" onclick="ai_app_onsite_clear_openapi_Key_field()"> 157 <span class="btn-icon me-1"> 148 158 <div class="assets-delete-icon"></div> 149 159 </span> Remove API Key … … 151 161 </div> 152 162 <div class="col-50"> 153 <div class="enable-switch-box ">154 <span class="fs-medium-14 text-switch ">DISABLED</span>163 <div class="enable-switch-box d-flex justify-content-between align-items-baseline"> 164 <span class="fs-medium-14 text-switch me-2" id="text-switch">Disabled</span> 155 165 <label class="switch"> 156 166 <input type="checkbox" id="api-disable-btn" onchange="ai_app_onsite_disable_openapi_key()"> -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-plugin-settings.php
r3250856 r3272415 5 5 public static function render_plugin_settings() 6 6 { 7 $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/aiapponsite/ai-app-onsite.php'); 8 $version = $plugin_data['Version']; 7 9 ob_start(); ?> 8 10 <div class="form-wrapper"> … … 10 12 <?php wp_nonce_field('ai_app_onsite_plugin_settings_nonce', 'ai_app_onsite_plugin_settings_nonce_field'); ?> 11 13 <div class="mb-20"> 12 <p class="fs-bold-14">Get Started</p> 14 <div class="d-flex justify-content-between mb-0 align-items-center"> 15 <p class="font-bold fs-5 mb-0">Get Started</p> 16 <p class="fs-regular-14 neutral-black-fs-60 mb-0">Version: <?php echo $version; ?></p> 17 </div> 13 18 <div class="terms-form-group form-group mb-0"> 14 19 <input type="checkbox" id="terms_of_service-old" onchange="uploadTermCondition(this)"> 15 20 <label for="terms_of_service-old" data-toggle="modal" data-target=".bd-example-modal-sm" class="custom-checkbox fs-medium-14 "><span class="ml-1">Agree to Terms of Service</span></label> 16 21 </div> 17 <p class="fs-regular-14 ml-25 mb-1">You accept and agree all Terms of Services.</p> 22 <p class="fs-regular-14 ml-25 mb-1 text-muted"> 23 You must agree to the terms of service to use this plugin. Please read the terms carefully before proceeding. 24 </p> 18 25 <p id="terms_of_service-error" class="ml-25 fields-error"></p> 19 26 </div> 20 27 21 <div >28 <div class="mb-3"> 22 29 <label for="app-selector" class="d-block fs-medium-14 mb-only-4">App/Project Selector 23 30 <span class="fs-regular-14">(Multiple Apps With Premium)</span></label> … … 31 38 32 39 33 <div >40 <div class="mb-3"> 34 41 <label for="email-notification" class="d-block fs-medium-14 mb-only-4">App Email (for form data passing) 35 42 <span class="fs-regular-14"></span></label> … … 42 49 </div> 43 50 44 <div> 45 <label class="d-block fs-medium-14 mb-only-4">User Stats</label> 46 <div class="download-icon-box"> 47 <div class="select-box-icon"> 48 <span class="field-icon"> 49 <div class="assets-calendar-icon"></div> 50 </span> 51 <select id="ai_app_onsite-user-stats" class="w-100 mb-1 fs-regular-14 neutral-black-fs-60 neutral-black-10 radius-6 border-0 px-10 py-8"> 52 <option value="">Select</option> 53 <option value="1">January</option> 54 <option value="2">February</option> 55 <option value="3">March</option> 56 <option value="4">April</option> 57 <option value="5">May</option> 58 <option value="6">June</option> 59 <option value="7">July</option> 60 <option value="8">August</option> 61 <option value="9">September</option> 62 <option value="10">October</option> 63 <option value="11">November</option> 64 <option value="12">December</option> 65 </select> 66 <p id="ai_app_onsite-user-stats-error" class="fields-error"></p> 67 </div> 68 <a href="#" class="neutral-black-10 rounded-circle px-8 py-8 download-icon" onclick="ai_app_onsite_download_user_stats(event)"> 69 <div class="assets-download-icon"></div> 70 </a> 71 </div> 72 </div> 73 74 <div> 51 <div class="mb-3"> 75 52 <label class="d-block fs-medium-14 mb-only-4">Banned/blocked words (comma Separated)</label> 76 53 <div class="multi-select-container select-box-icon mb-20 fs-regular-14 neutral-black-fs-100 border border-1 radius-6 px-10 py-8"> … … 86 63 87 64 </div> 88 <div class="form-group ">65 <div class="form-group mb-3"> 89 66 <label class="fs-medium-14">Upload Banned/Block CSV</label> 90 67 <div class="file-drop-area border "> … … 113 90 <div id="Plugin-settings-msg-container" class="message-container"></div> 114 91 115 <!-- Modal -->116 <div class="modal fade bd-example-modal-sm plugin-setting" id="terms_conditions_modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">117 <div class="modal-dialog modal-dialog-centered" role="document">118 <div class="modal-content">119 <div class="modal-header">120 <h5 class="fs-bold-16" id="terms_conditions_modal_label">Terms of Services</h5>121 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>122 </div>123 <div class="modal-body mb-1">124 <div id="terms-conditions-modal-pdf">125 <p class="fs-regular-14 neutral-black-fs-100 mb-3 text-center">Terms of Services</p>126 <p class="fs-regular-14 neutral-black-fs-90">Please read these terms carefully before using our service.</p>127 <p class="fs-regular-14 neutral-black-fs-100 mb-1">1. User Responsibility</p>128 <p class="fs-regular-12 neutral-black-fs-70">If you reside in the European Economic Area, Switzerland, the UK, California or some other locations, you may be subject to special conditions and laws that govern the use of AI. These and other locales also have privacy and data protection rules and laws that may also dictate how you can leverage tools like AIappOnsite.</p>129 <p class="fs-regular-12 neutral-black-fs-70">It is important that you abide by all such applicable laws. Furthermore, you may not use the Service in a way that infringes, misappropriates or violates anyone’s rights. You may also not use the Service in a way that endangers or harms, or intends to do the same, to end users of applications built with the Service.</p>130 131 <p class="fs-regular-14 neutral-black-fs-100 mb-1">2. Using AI Services</p>132 <p class="fs-regular-12 neutral-black-fs-70">The Service requires that the site owner or their designee provide an API key which the Service will use tointegrate with an AI model provider. All AI functionality of the Service depends on one or more API keys, whichis provided by the various AI model vendors. An account must be opened with one of these vendors in order to get an API key.</p>133 <p class="fs-regular-12 neutral-black-fs-70">These AI model providers are separate companies and unaffiliated with the Service, and have their own terms and conditions. Read them carefully. The API keys and their use are bound by the terms and conditions of the AI model provider and strictly controlled by the site owner or their designee (not AIappOnsite).</p>134 135 <p class="fs-regular-14 neutral-black-fs-100 mb-1">3. Limitation of Liability</p>136 <p class="fs-regular-12 neutral-black-fs-70">Given that the site owner fully controls the use, purpose and output of any application built with it, AIappOnsite bears no responsibility or liability for how it is used, or to any consequences of its use by site owners or their site visitors.</p>137 <p class="fs-regular-12 neutral-black-fs-70">You agree that you are leveraging third party AI models and services separate from AIappOnsite, and that you have full control over and final responsibility for the prompts that will access the API as well as the end-user experience, and any representations made to them.</p>138 139 <p class="fs-regular-14 neutral-black-fs-100 mb-1">4. Paid Accounts</p>140 <p class="fs-regular-12 neutral-black-fs-70">Billing. If you purchase any services, you will provide complete and accurate billing information, including a valid payment method. For paid subscriptions, we will automatically charge your payment method on each agreed-upon periodic renewal until you cancel. You’re responsible for all applicable taxes, and we’ll charge tax when required. If your payment cannot be completed, we may downgrade your account or suspend your access to our services until payment is received.</p>141 <p class="fs-regular-12 neutral-black-fs-70">Cancellation. You can cancel your paid subscription at any time. Previous payments are non-refundable,except where required by law. These Terms do not override any mandatory local laws regarding your cancellation rights.</p>142 <p class="fs-regular-12 neutral-black-fs-70">Changes. We may change our prices from time to time. If we increase our subscription prices, we will give you at least 30 days’ notice and any price increase will take effect on your next renewal so that you can cancel if you do not agree to the price increase</p>143 144 <p class="fs-regular-14 neutral-black-fs-100 mb-1">5. Termination and Suspension</p>145 <p class="fs-regular-12 neutral-black-fs-70">Termination. You are free to stop using our Services at any time. We reserve the right to suspend or terminate your access to our Services or delete your account if we determine:146 <ul class="pl-2">147 <li class="fs-regular-12 neutral-black-fs-70">- You breached these Terms of Service.</li>148 <li class="fs-regular-12 neutral-black-fs-70">- We must do so to comply with the law.</li>149 <li class="fs-regular-12 neutral-black-fs-70">- Your use of our Services could cause risk or harm to AIappOnsite or anyone else.</li>150 </ul>151 </p>152 <p class="fs-regular-12 neutral-black-fs-70">Appeals. If you believe we have suspended or terminated your account in error, you can file an appeal with us by contacting our Support team.</p>153 154 <p class="fs-regular-14 neutral-black-fs-100 mb-1">6. Discontinuation of Services</p>155 <p class="fs-regular-12 neutral-black-fs-70">We may decide to discontinue our Services, but if we do, we will give you advance notice and a refund for any prepaid, unused services.</p>156 157 <p class="fs-regular-14 neutral-black-fs-100 mb-1">7. Disclaimer of Warranties</p>158 <p class="fs-regular-12 neutral-black-fs-70">Our services are provided “as is.” except to the extent prohibited by law, we and our affiliates and licensors make no warranties (express, implied, statutory or otherwise) with respect to the services, and disclaim all warranties including, but not limited to, warranties of merchantability, fitness for a particular purpose,satisfactory quality, non-infringement, and quiet enjoyment, and any warranties arising out of any course of dealing or trade usage. We do not warrant that the services will be uninterrupted, accurate or error free, or that any content will be secure or not lost or altered.</p>159 <p class="fs-regular-12 neutral-black-fs-70">You accept and agree that any use of the service is at your sole risk.</p>160 161 <p class="fs-regular-14 neutral-black-fs-100 mb-1">8. Limitation of liability</p>162 <p class="fs-regular-12 neutral-black-fs-70">Neither we nor any of our affiliates or licensors will be liable for any indirect,incidental, special, consequential, or exemplary damages, including damages for loss of profits, goodwill, use, or data or other losses, even if we have been advised of the possibility of such damages. Our aggregate liability under these terms will not exceed the greater of the amount you paid for the service that gave rise to the claim during the 12 months before the liability arose or one hundred dollars ($100).The limitations in this section apply only to the maximum extent permitted by applicable law.</p>163 <p class="fs-regular-12 neutral-black-fs-70">Some countries and states do not allow the disclaimer of certain warranties or the limitation of certain damages, so some or all of the terms above may not apply to you, and you may have additional rights. In that case, these Terms only limit our responsibilities to the maximum extent permissible in your country of residence.</p>164 <p class="fs-regular-12 neutral-black-fs-70">Aiapponsite’s affiliates, suppliers, licensors, and distributors are intended third party beneficiaries of this section.</p>165 166 <p class="fs-regular-14 neutral-black-fs-100 mb-1">9. Indemnity</p>167 <p class="fs-regular-12 neutral-black-fs-70">If you are a business or organization, to the extent permitted by law, you will indemnify and hold harmless us,our affiliates, and our personnel, from and against any costs, losses, liabilities, and expenses (including attorneys’ fees) from third party claims arising out of or relating to your use of the Services and Content or any violation of these Terms.</p>168 169 <div class="terms-form-group form-group mb-0">170 <input type="checkbox" id="terms_conditions">171 <label for="terms_conditions" class="fs-regular-14 pl-1 neutral-black-fs-90">Agree to Terms of Service</label>172 </div>173 </div>174 <div class="divider-light mt-2 mb-3"></div>175 <div class="button-wrap">176 <button type="button" id="download_ai_app_terms_of_service" role="button" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-white" name="save-plugin-settings" onclick="ai_app_onsite_download_terms_Of_service()">Download</button>177 <button type="button" id="accept_ai_app_terms_of_service" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-purple border-purple text-white" name="save-plugin-settings" data-bs-dismiss="modal">Accept</button>178 </div>179 </div>180 </div>181 </div>182 </div>183 184 92 185 93 <?php -
ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-prompt-editor.php
r3250856 r3272415 13 13 <?php wp_nonce_field('ai_app_onsite_prompt_editor_nonce', 'ai_app_onsite_prompt_editor_nonce_field'); ?> 14 14 <div class="form-group"> 15 <label class="d-block fs-medium-14 mb-only-4">Available Fields (<span class="important-text">IMPORTANT: </span>private user data should never be included in the prompt)</label> 16 <span class="variable-text-note m-1"> 17 NOTE: Click to copy variables in the prompt. 18 </span> 15 <div class="mb-4"> 16 <label class="d-block fw-semibold fs-5 mb-2">Available Fields</label> 17 <p class="text-danger small mb-1"> 18 <strong>IMPORTANT:</strong> Private user data should never be included in the prompt. 19 </p> 20 <p class="text-muted small"> 21 <em>Note:</em> Click on a variable to copy it into the prompt. 22 </p> 23 </div> 19 24 20 <div class="select-box-icon select-box-icon-textarea mb-30"> 25 <span id="prompt-max-token-value"></span> 26 27 <div class="select-box-icon select-box-icon-textarea mb-30 rounded shadow-sm bg-white"> 21 28 <span class="field-icon"> 22 29 <div class="assets-font-color-icon"></div> … … 25 32 </div> 26 33 <div class="form-group"> 27 <label class="d-block fs-medium-14 mb-only-4">Prompt</label> 34 <label class="d-block fs-medium-14 mb-only-4 fw-semibold"> 35 Enter your prompt below 36 </label> 28 37 <div class="select-box-icon select-box-icon-textarea mb-30"> 29 <span class="field-icon"> 30 <div class="assets-code-placeholder-icon"></div> 31 </span> 38 32 39 <?php 33 40 return ob_get_clean(); 34 41 } 42 35 43 public static function render_prompt_code_editor() 36 44 { 37 45 ob_start(); ?> 46 <div id="word-count" class="mt-2"> </div> 38 47 <p id="prompt-error" class="fields-error"></p> 39 48 </div> 40 49 </div> 41 42 <div class="divider-light"></div>43 50 <div class="mt-3 mb-3"> 44 51 <div class="col-50"> -
ai-app-onsite/trunk/ai-app-onsite.php
r3250856 r3272415 4 4 * Plugin Name: AI App Onsite 5 5 * Description: AIappOnsite - AI Web App Creator WP Plugin allows users to create their own AI-powered web app and launch it on their own site with no additional development needed. AI App Onsite web app creator is an AI web app builder for WordPress. 6 * Version: 1. 0.06 * Version: 1.1.0 7 7 * Author: By AIappOnsite 8 8 * Author URI: https://aiapponsite.com/ … … 62 62 63 63 if (!function_exists('ai_app_onsite_enqueue_admin_script')) { 64 65 function ai_app_onsite_enqueue_admin_script() 66 { 67 68 // Register jQuery script (it is already included by default in WordPress) 69 wp_enqueue_script('jquery'); 70 71 // Register JavaScript files and then enqueue them 72 wp_register_script('admin-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-admin.js', array('jquery'), time(), true); 73 wp_enqueue_script('admin-script'); 74 75 wp_register_script('ai-app-onsite-field-selector-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-field-selector.js', array('jquery'), time(), true); 76 wp_enqueue_script('ai-app-onsite-field-selector-script'); 77 78 wp_register_script('bootstrape-poper-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/popper.min.js', array('jquery'), time(), true); 79 wp_enqueue_script('bootstrape-poper-script'); 80 81 wp_register_script('bootstrape-script-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/bootstrap.min.js', array('jquery'), time(), true); 82 wp_enqueue_script('bootstrape-script-script'); 83 84 wp_register_script('email-interation-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-email-settings.js', array('jquery'), time(), true); 85 wp_enqueue_script('email-interation-script'); 86 87 wp_register_script('blockword-script-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-blockword.js', array('jquery'), time(), true); 88 wp_enqueue_script('blockword-script-script'); 89 90 wp_register_script('model_settings', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-model-settings.js', array('jquery'), time(), true); 91 wp_enqueue_script('model_settings'); 92 93 wp_register_script('plugin_settings-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-plugin-settings.js', array('jquery'), time(), true); 94 wp_enqueue_script('plugin_settings-script'); 95 96 wp_register_script('app_properties', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-app-properties.js', array('jquery'), time(), true); 97 wp_enqueue_script('app_properties'); 98 99 wp_register_script('prompt-editor-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-prompt-editor.js', array('jquery'), time(), true); 100 wp_enqueue_script('prompt-editor-script'); 101 102 wp_register_script('app-preview-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/ai-app-onsite-app-preview.js', array('jquery'), time(), true); 103 wp_enqueue_script('app-preview-script'); 104 105 wp_register_script('ai-app-onsite-jquery-sweetalert', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/sweetalert2.all.min.js', array('jquery'), time(), true); 106 wp_enqueue_script('ai-app-onsite-jquery-sweetalert'); 107 108 wp_register_script('ai-app-onsite-jquery-choice', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/choice.min.js', array('jquery'), time(), true); 109 wp_enqueue_script('ai-app-onsite-jquery-choice'); 110 111 // Localize the script with the AJAX URL 64 function ai_app_onsite_enqueue_admin_script($hook) 65 { 66 // Only load on plugin settings page - adjust this to match your plugin's actual settings page slug 67 if ($hook !== 'toplevel_page_ai-app-onsite-menu') { 68 return; 69 } 70 71 // Enqueue CSS for admin 72 wp_enqueue_style('ai-app-onsite-style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-style.css', array(), time()); 73 74 // Check if Bootstrap is already loaded 75 global $wp_scripts, $wp_styles; 76 $is_bootstrap_loaded = false; 77 78 foreach ($wp_scripts->registered as $registered_script) { 79 if (str_contains($registered_script->src, 'bootstrap')) { 80 $is_bootstrap_loaded = true; 81 break; 82 } 83 } 84 85 if (!$is_bootstrap_loaded) { 86 foreach ($wp_styles->registered as $registered_style) { 87 if (str_contains($registered_style->src, 'bootstrap')) { 88 $is_bootstrap_loaded = true; 89 break; 90 } 91 } 92 } 93 94 // Enqueue Bootstrap if not already loaded 95 if (!$is_bootstrap_loaded) { 96 wp_register_script('bootstrape-poper-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/popper.min.js', array('jquery'), time(), true); 97 wp_enqueue_script('bootstrape-poper-script'); 98 99 wp_register_script('bootstrape-script-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/bootstrap.min.js', array('jquery'), time(), true); 100 wp_enqueue_script('bootstrape-script-script'); 101 102 wp_register_style('ai_app_onsite_style_bootstrap', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/bootstrap.min.css', array(), time()); 103 wp_enqueue_style('ai_app_onsite_style_bootstrap'); 104 } 105 106 // All other scripts 107 $scripts = [ 108 'admin-script' => 'ai-app-onsite-admin.js', 109 'ai-app-onsite-field-selector-script' => 'ai-app-onsite-field-selector.js', 110 'email-interation-script' => 'ai-app-onsite-email-settings.js', 111 'blockword-script-script' => 'ai-app-onsite-blockword.js', 112 'model_settings' => 'ai-app-onsite-model-settings.js', 113 'plugin_settings-script' => 'ai-app-onsite-plugin-settings.js', 114 'app_properties' => 'ai-app-onsite-app-properties.js', 115 'prompt-editor-script' => 'ai-app-onsite-prompt-editor.js', 116 'app-preview-script' => 'ai-app-onsite-app-preview.js', 117 'ai-app-onsite-jquery-sweetalert' => 'sweetalert2.all.min.js', 118 'ai-app-onsite-jquery-choice' => 'choice.min.js', 119 'terms-of-service-script' => 'jspdf.umd.min.js', 120 ]; 121 122 foreach ($scripts as $handle => $filename) { 123 wp_register_script($handle, AI_APP_ONSITE_PLUGIN_URL . 'assets/js/' . $filename, array('jquery'), time(), true); 124 wp_enqueue_script($handle); 125 } 126 127 // Pass the fresh installation flag to JavaScript 128 $is_fresh_install = get_option('ai_app_onsite_fresh_install', false); 129 // Localize the main admin script 112 130 wp_localize_script( 113 'admin-script', // Handle of the registered script114 'myPluginAjax', // Name of the JavaScript object131 'admin-script', 132 'myPluginAjax', 115 133 array( 116 'ajaxurl' => admin_url('admin-ajax.php'), // URL for AJAX requests 117 'deleteNonce' => wp_create_nonce('ai_app_onsite_delete_field_nonce'), // Nonce for delete action 118 'downloadUserStatsNonce' => wp_create_nonce('ai_app_onsite_download_user_stats_nonce'), // Nonce for download user stats 119 'fieldSelectorOrder' => wp_create_nonce('ai_app_onsite_fields_selector_order_nonce'), // Nonce for download user stats 134 'ajaxurl' => admin_url('admin-ajax.php'), 135 'deleteNonce' => wp_create_nonce('ai_app_onsite_delete_field_nonce'), 136 'downloadUserStatsNonce' => wp_create_nonce('ai_app_onsite_download_user_stats_nonce'), 137 'fieldSelectorOrder' => wp_create_nonce('ai_app_onsite_fields_selector_order_nonce'), 138 'isFreshInstall' => $is_fresh_install, 120 139 ) 121 140 ); 122 141 123 142 124 // Pass the plugin URL to JavaScript using wp_add_inline_script() 143 // Remove the flag after it's been used 144 if ($is_fresh_install) { 145 delete_option('ai_app_onsite_fresh_install'); 146 } 147 125 148 wp_add_inline_script('admin-script', 'var AI_APP_ONSITE_PLUGIN_URL = "' . esc_url(AI_APP_ONSITE_PLUGIN_URL) . '";', 'before'); 126 127 // Download Terms of Service128 wp_register_script('terms-of-service-script', AI_APP_ONSITE_PLUGIN_URL . 'assets/js/jspdf.umd.min.js', array('jquery'), time(), true);129 wp_enqueue_script('terms-of-service-script');130 149 } 131 150 132 151 add_action('admin_enqueue_scripts', 'ai_app_onsite_enqueue_admin_script'); 133 152 } 153 134 154 135 155 … … 154 174 function AI_APP_ONSITE_My_Form_Block_Assets() 155 175 { 156 // Enqueue block editor script with file mtime for versioning (cache-busting)176 // Enqueue block editor script with file time for versioning (cache-busting) 157 177 wp_enqueue_script( 158 178 'ai-app-onsite-form-block-editor', … … 166 186 167 187 if (!function_exists('ai_app_onsite_enqueue_style')) { 168 function ai_app_onsite_enqueue_style() 169 { 170 // Enqueue styles with time() for cache-busting 171 // Register and enqueue stylesheets for the admin area 172 wp_register_style('ai_app_onsite_form_style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-form-style.css', array(), time()); 173 wp_enqueue_style('ai_app_onsite_form_style'); 174 175 wp_register_style('ai_app_onsite_style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-style.css', array(), time()); 176 wp_enqueue_style('ai_app_onsite_style'); 177 178 wp_register_style('ai_app_onsite_style_bootstrap', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/bootstrap.min.css', array(), time()); 179 wp_enqueue_style('ai_app_onsite_style_bootstrap'); 180 } 181 182 // Enqueue styles for both admin and frontend 183 add_action('admin_print_styles', 'ai_app_onsite_enqueue_style'); 184 add_action('wp_enqueue_scripts', 'ai_app_onsite_enqueue_style'); 185 } 188 function ai_app_onsite_enqueue_style() 189 { 190 // Enqueue styles with time() for cache-busting 191 // Register and enqueue stylesheets for the admin area 192 wp_register_style('ai_app_onsite_form_style', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/ai-app-onsite-form-style.css', array(), time()); 193 wp_enqueue_style('ai_app_onsite_form_style'); 194 195 196 // Check if Bootstrap is already loaded 197 global $wp_scripts, $wp_styles; 198 $is_bootstrap_loaded = false; 199 200 foreach ($wp_scripts->registered as $registered_script) { 201 if (str_contains($registered_script->src, 'bootstrap')) { 202 $is_bootstrap_loaded = true; 203 break; 204 } 205 } 206 207 if (!$is_bootstrap_loaded) { 208 foreach ($wp_styles->registered as $registered_style) { 209 if (str_contains($registered_style->src, 'bootstrap')) { 210 $is_bootstrap_loaded = true; 211 break; 212 } 213 } 214 } 215 216 // Enqueue Bootstrap if not already loaded 217 if (!$is_bootstrap_loaded) { 218 wp_register_style('ai_app_onsite_style_bootstrap', AI_APP_ONSITE_PLUGIN_URL . 'assets/css/bootstrap.min.css', array(), time()); 219 wp_enqueue_style('ai_app_onsite_style_bootstrap'); 220 } 221 222 223 } 224 225 // Enqueue styles for both admin and frontend 226 add_action('admin_print_styles', 'ai_app_onsite_enqueue_style'); 227 add_action('wp_enqueue_scripts', 'ai_app_onsite_enqueue_style'); 228 } 229 186 230 187 231 … … 192 236 { 193 237 global $wpdb; // Access the global $wpdb variable 238 239 add_option('ai_app_onsite_fresh_install', true); 240 194 241 require_once AI_APP_ONSITE_PLUGIN_DIR . 'includes/class-ai-app-onsite-db-handler.php'; 195 242 // Create an instance of the database handler class and pass $wpdb … … 202 249 203 250 251 204 252 if (! function_exists('ai_app_onsite_deactivate')) { 205 253 // Deactivation hook callback function 206 function ai_app_onsite_deactivate() {} 254 function ai_app_onsite_deactivate() 255 { 256 // Enqueue a script to delete cookies on plugin deactivation 257 add_action('admin_footer', function () { 258 echo '<script> 259 document.cookie = "ai_app_onsite_active_tab=; path=/; max-age=0"; 260 </script>'; 261 }); 262 } 207 263 } 208 264 … … 271 327 function ai_app_onsite_editor_callback() 272 328 { 273 // Check karein ki function exist karta hai ya nahi274 329 if (function_exists('wp_editor')) { 275 330 $content = ''; // Default content … … 290 345 } 291 346 } 347 348 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'ai_app_onsite_settings_link'); 349 350 function ai_app_onsite_settings_link($links) 351 { 352 $settings_link = '<a href="' . admin_url('admin.php?page=ai-app-onsite-menu') . '">Settings</a>'; 353 array_unshift($links, $settings_link); // Add it at the beginning 354 return $links; 355 } -
ai-app-onsite/trunk/assets/css/ai-app-onsite-form-style.css
r3250856 r3272415 1 1 /* start loader css */ 2 2 3 . loader {3 .ai-app-form-wrap .loader { 4 4 height: 80px; 5 5 aspect-ratio: 1; … … 7 7 } 8 8 9 . loader:before,10 . loader:after {9 .ai-app-form-wrap .loader:before, 10 .ai-app-form-wrap .loader:after { 11 11 content: ""; 12 --c: no-repeat linear-gradient( var(--purple)0 0);12 --c: no-repeat linear-gradient(#635aff 0 0); 13 13 background: var(--c), var(--c); 14 14 background-size: 25% 50%; … … 16 16 } 17 17 18 . loader:after {18 .ai-app-form-wrap .loader:after { 19 19 transform: scale(-1); 20 } 21 .ai-app-form-wrap .fields-error { 22 color: red; 23 font-size: 12px; 20 24 } 21 25 … … 40 44 } 41 45 42 #loader {46 .ai-app-form-wrap #loader { 43 47 position: fixed; 44 48 height: 100%; … … 53 57 } 54 58 55 . message-container span,59 .ai-app-form-wrap .message-container span, 56 60 .modal-message-container span { 57 61 text-align: center; … … 63 67 } 64 68 65 . select-box-icon.right-icon input[type="text"]::placeholder {69 .ai-app-form-wrap .select-box-icon.right-icon input[type="text"]::placeholder { 66 70 color: #818898 !important; 67 71 } … … 69 73 /* end loader css */ 70 74 71 . select-box-icon .ai-app-onsite-openAi-app-shortcode {75 .ai-app-form-wrap .select-box-icon .ai-app-onsite-openAi-app-shortcode { 72 76 padding-left: 38px !important; 73 77 padding-right: 38px !important; … … 86 90 } 87 91 88 . field-copy-icon {92 .ai-app-form-wrap .field-copy-icon { 89 93 position: absolute; 90 94 top: 6px; … … 100 104 border-radius: 8px; 101 105 box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); 102 margin-bottom: 32px; 103 /*max-width: 800px !important;*/ 104 width: 100%; 105 margin: auto auto 32px auto; 106 width: 100%; 107 margin: auto auto 2rem auto; 106 108 } 107 109 … … 258 260 font-weight: 600; 259 261 } 260 261 /* @media (max-width: 576px) {262 div#ai-app-openAi-app-logo {263 max-width: 180px;264 }265 } */ -
ai-app-onsite/trunk/assets/css/ai-app-onsite-style.css
r3250856 r3272415 19 19 --neutral-black-10: #f8fafc; 20 20 } 21 21 * { 22 box-sizing: border-box; 23 } 22 24 .bg-purple { 23 25 background-color: var(--purple) !important; … … 97 99 98 100 .divider-light { 99 height: 1px;101 height: 2.5px; 100 102 width: 100%; 101 103 background-color: var(--neutral-black-20); … … 332 334 333 335 /* BEGIN::Modal styles */ 334 335 * {336 box-sizing: border-box;337 }338 339 336 .container { 340 337 max-width: 50vw; … … 926 923 } 927 924 928 .api-key-icon.select-box-icon p {925 /* .api-key-icon.select-box-icon p { 929 926 padding-left: 36px; 930 927 padding-top: 8px; 931 } 928 } */ 932 929 933 930 .api-key-icon.select-box-icon { … … 1510 1507 font-weight: 400; 1511 1508 } 1509 .app-preview-content .app-preview-content__heading { 1510 width: 40%; 1511 } 1512 .app-preview-content .app-preview-content__description{ 1513 width: 60%; 1514 } 1512 1515 1513 1516 .fields-error { … … 1668 1671 1669 1672 .assets-copy-icon { 1670 width: 20px;1671 HEIGHT: 25PX;1673 width: 1.25rem; 1674 height: 1.56rem; 1672 1675 background-image: url('../media/copy-icon.png'); 1673 1676 background-repeat: no-repeat; 1674 1677 background-size: inherit; 1675 1678 background-position: center; 1676 } 1677 1679 cursor: pointer; 1680 } 1681 .icon-success { 1682 width: 1.25rem; 1683 height: 1.56rem; 1684 background-image: url('../media/copy-icon-success.png'); 1685 background-repeat: no-repeat; 1686 background-size: inherit; 1687 background-position: center; 1688 cursor: pointer; transition: color 0.3s ease; 1689 } 1690 .key-toggle .mask__toggle , .key-toggle .copy__btn { 1691 cursor: pointer; 1692 font-size: 14px; 1693 } 1694 #model-help-text{ 1695 font-size: .875em; 1696 } 1697 .small-text { 1698 font-size: .775em; 1699 } 1700 1701 .border-danger { 1702 border: 2px solid red !important; 1703 animation: shake 0.3s ease-in-out 2; 1704 } 1705 1706 @keyframes shake { 1707 0% { transform: translateX(0px); } 1708 25% { transform: translateX(-3px); } 1709 50% { transform: translateX(3px); } 1710 75% { transform: translateX(-3px); } 1711 100% { transform: translateX(0px); } 1712 } 1713 .blurred { 1714 filter: blur(2px); 1715 pointer-events: none; 1716 opacity: 0.6; 1717 position: relative; 1718 } 1719 1720 .field-copy-icon { 1721 position: absolute; 1722 top: 6px; 1723 right: 10px; 1724 cursor: pointer; 1725 } 1678 1726 #key-remove-btn { 1679 1727 display: flex; … … 1950 1998 } 1951 1999 } 2000 #ai-app-onsite-test { 2001 background-image: linear-gradient(to right, #006175 0%, #3c7bbd 100%); 2002 border-radius: 4px; 2003 box-sizing: border-box; 2004 color: #3c7bbd; 2005 display: block; 2006 font-size:1rem; 2007 height: 2.6rem; 2008 letter-spacing: 1px; 2009 padding: 1.7px; 2010 position: relative; 2011 text-decoration: none; 2012 text-transform: uppercase; 2013 width: 12.5rem; 2014 z-index: 2; 2015 } 2016 2017 #ai-app-onsite-test:hover { 2018 color: #fff; 2019 } 2020 2021 #ai-app-onsite-test span { 2022 align-items: center; 2023 background: #fff; 2024 border-radius: 4px; 2025 display: flex; 2026 justify-content: center; 2027 height: 100%; 2028 transition: background .5s ease; 2029 width: 100%; 2030 } 2031 2032 #ai-app-onsite-test:hover span { 2033 background: transparent; 2034 } -
ai-app-onsite/trunk/assets/js/ai-app-onsite-admin.js
r3250856 r3272415 1 var removeLogoBtn = document.getElementById('remove-logo-btn'); 2 var previewImage = document.getElementById('previewImage'); 3 var fileUploadDiv = document.getElementById('file-upload-div'); 4 5 // === Save & Restore Tab using Cookie === 6 7 document.addEventListener('DOMContentLoaded', function () { 8 function getCookie(name) { 9 return document.cookie 10 .split('; ') 11 .find(row => row.startsWith(name + '=')) 12 ?.split('=')[1] || ''; 13 } 14 15 function deleteCookie(name) { 16 document.cookie = name + '=; path=/; max-age=0'; 17 } 18 19 const savedTabId = getCookie('ai_app_onsite_active_tab'); 20 const fallbackTabId = 'plugin-settings-tab'; 21 22 const isFreshInstall = myPluginAjax.isFreshInstall == '1' ? true : false; 23 console.log('isFreshInstall:', isFreshInstall); 24 25 if (isFreshInstall) { 26 deleteCookie('ai_app_onsite_active_tab'); 27 handleTabClick(fallbackTabId); // Activate the default tab 28 } else if (savedTabId) { 29 handleTabClick(savedTabId); // Activate the saved tab 30 } else { 31 handleTabClick(fallbackTabId); // Activate the default tab 32 } 33 }); 34 35 // === Main Tab Click Handler === 36 1 37 function handleTabClick(tabId) { 2 // alert(tabId);3 38 event.preventDefault(); 4 39 … … 7 42 // Check if the clicked tab is already active 8 43 if (tab.classList.contains('nav-tab-active')) { 9 return; // Do nothing if the tab is already active44 return; 10 45 } 11 46 … … 25 60 tab.classList.add('nav-tab-active'); 26 61 27 // Show corresponding tab content (if applicable)62 // Show corresponding tab content 28 63 var contentId = tabId.replace("tab", "content"); 29 64 var content = document.getElementById(contentId); … … 32 67 } 33 68 34 // Your function logic goes here based on the tab ID 35 // For example: 69 // ✅ Save active tab in cookie for 7 days 70 document.cookie = "ai_app_onsite_active_tab=" + tabId + "; path=/; max-age=" + (60 * 60 * 24 * 7); 71 72 // ✅ Custom logic per tab 36 73 if (tabId === 'plugin-settings-tab') { 37 74 ai_app_onsite_get_plugin_settings(); … … 43 80 ai_app_onsite_read_field_selector(); 44 81 } else if (tabId === 'prompt-editor-tab') { 82 ai_app_onsite_get_Model_Token_field(); 45 83 ai_app_onsite_get_field_tags(); 46 84 ai_app_onsite_get_prompt_editor(); … … 69 107 //End get plugin setting from db js 70 108 109 110 function removeLogoFile(input) { 111 console.log("removeLogoFile"); 112 removeLogoBtn.style.display = 'none'; 113 previewImage.style.display = 'none'; 114 fileUploadDiv.classList.add('col-md-12'); 115 fileUploadDiv.classList.remove('col-md-8'); 116 117 var xhr = new XMLHttpRequest(); 118 119 xhr.onreadystatechange = function () { 120 if (xhr.readyState === 4) { 121 if (xhr.status === 200) { 122 123 response = JSON.parse(xhr.responseText); 124 if (response.status === '404') { 125 return; 126 } 127 console.log("image deleted"); 128 } else { 129 // Handle error response 130 console.error('Error occurred: ' + xhr.responseText); 131 } 132 } 133 }; 134 135 xhr.open('POST', myPluginAjax.ajaxurl, true); 136 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 137 xhr.send('action=ai_app_onsite_remove_app_logo'); 138 } 139 71 140 //upload file js 72 141 function validateFile(input) { … … 95 164 96 165 function uploadSiteLogo(file) { 166 removeLogoBtn.style.display = 'block'; 167 fileUploadDiv.classList.add('col-md-8'); 168 fileUploadDiv.classList.remove('col-md-12'); 97 169 var formData = new FormData(); 98 170 formData.append('app-file', file); … … 123 195 previewImage.style.width = '350px'; 124 196 previewImage.style.height = '160px'; 197 previewImage.style.position = 'relative'; 125 198 } 126 199 -
ai-app-onsite/trunk/assets/js/ai-app-onsite-app-preview.js
r3250856 r3272415 17 17 response = JSON.parse(xhr.responseText); 18 18 19 20 if (response.status === '404' ) {19 console.log('response', response); 20 if (response.status === '404' || response.status === '400') { 21 21 console.log('message', response.message); 22 22 formContainer.innerHTML = '<p>No form Field Found Please Create Form Field</p>'; … … 98 98 // Handle error response 99 99 console.error('Error occurred: ' + xhr.responseText); 100 101 formContainer.innerHTML = '<p>It looks like some required settings are missing. Please ensure that "App Properties," "Model Settings," and "Form Fields" are configured before previewing the form.</p>'; 102 openAiAppShortcode.value = ''; 103 testAppContainer.style.display = 'none'; 104 shortcodeBox.style.display = 'none'; 105 return; 100 106 } 101 107 } … … 128 134 if (xhr.status === 200) { 129 135 130 // console.log(xhr);131 136 // Handle the response from the server 132 137 var response = JSON.parse(xhr.responseText); 133 134 138 if (response.success) { 135 139 // Show success AI result -
ai-app-onsite/trunk/assets/js/ai-app-onsite-app-properties.js
r3250856 r3272415 3 3 var xhr = new XMLHttpRequest(); 4 4 5 xhr.onreadystatechange = function () {5 xhr.onreadystatechange = function () { 6 6 if (xhr.readyState === 4) { 7 7 if (xhr.status === 200) { 8 var response = JSON.parse(xhr.responseText);8 var response = JSON.parse(xhr.responseText); 9 9 // Check if status is 404 (Table does not exist or no rows found) 10 10 if (response.status === '404') { … … 12 12 return; 13 13 } 14 // Accessing the first object in the array14 // Accessing the first object in the array 15 15 var firstObject = response[0]; 16 16 console.log(firstObject, 'firstObject'); 17 var app_logo = firstObject.appLogoImagePreview;18 console.log(app_logo, 'app_logo');19 17 var app_logo = firstObject.appLogoImagePreview; 20 21 if (app_logo!= 'No preview available') { 18 console.log(app_logo, 'app_logo'); 19 var app_logo = firstObject.appLogoImagePreview; 20 var fileUploadDiv = document.getElementById('file-upload-div'); 21 var removeLogoBtn = document.getElementById('remove-logo-btn'); 22 23 if (app_logo != 'No preview available') { 22 24 var previewImage = document.getElementById('previewImage'); 23 25 previewImage.style.backgroundImage = `url('${app_logo}')`; … … 28 30 previewImage.style.width = '350px'; 29 31 previewImage.style.height = '160px'; 32 fileUploadDiv.classList.add('col-md-8'); 33 fileUploadDiv.classList.remove('col-md-12'); 34 } else { 35 var removeLogoBtn = document.getElementById('remove-logo-btn'); 36 removeLogoBtn.style.display = 'none'; 37 fileUploadDiv.classList.add('col-md-12'); 38 fileUploadDiv.classList.remove('col-md-8'); 30 39 } 31 40 … … 34 43 // Accessing properties of the first object 35 44 var app_name = firstObject.app_name; 36 45 var app_name_show = firstObject.app_name_show; 46 37 47 var app_disclaimer = firstObject.app_disclaimer; 38 48 var app_description = firstObject.app_description; 39 49 var submit_button_txt = firstObject.submit_button_txt; 40 50 //var title_color = firstObject.title_color; 41 42 var title_colors = JSON.parse(firstObject.title_color);43 44 45 // var font_color = firstObject.font_color;46 // var bg_color = firstObject.bg_color;47 48 var font_colors = JSON.parse(firstObject.font_color);49 var bg_colors = JSON.parse(firstObject.bg_color);50 51 52 51 52 var title_colors = JSON.parse(firstObject.title_color); 53 54 55 // var font_color = firstObject.font_color; 56 // var bg_color = firstObject.bg_color; 57 58 var font_colors = JSON.parse(firstObject.font_color); 59 var bg_colors = JSON.parse(firstObject.bg_color); 60 61 62 53 63 54 64 // var obj = JSON.parse(title_color); 55 56 document.getElementById('app-name').value = app_name; 65 if (app_name_show === "") { 66 document.getElementById('app-name').value = app_name; 67 } else { 68 document.getElementById('app-name').value = app_name_show; 69 var checkbox = document.getElementById('app-name-toggle'); 70 checkbox.checked = true; 71 } 72 57 73 document.getElementById('app-disclaimer').value = app_disclaimer; 58 74 document.getElementById('app-description').value = app_description; 59 75 document.getElementById('submit-btn-txt').value = submit_button_txt; 60 76 document.getElementById('preview-submit-btn-txt').textContent = submit_button_txt; 61 62 setTimeout(function() {63 var selected_title_color = getSelectedTitleColor(title_colors);64 var selected_font_colors= getSelectedFontColor(font_colors);65 var selected_bg_colors = getSelectedBgColor(bg_colors);66 var radioInputs = document.querySelectorAll('.input-group-color input[type="radio"]');67 radioInputs.forEach(function(radio) {68 var label = radio.closest('label'); // Find the parent label of the radio input69 if (radio.value === selected_title_color) {70 var colorWithoutHash = selected_title_color.replace(/^#/, '');71 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe72 label.click();73 } else {74 var colorWithoutHash = selected_title_color.replace(/^#/, '');75 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels76 }77 if (radio.value === selected_font_colors) {78 var colorWithoutHash = selected_font_colors.replace(/^#/, '');79 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe80 label.click();81 } else {82 var colorWithoutHash = selected_font_colors.replace(/^#/, '');83 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels84 }85 86 if (radio.value === selected_bg_colors) {87 var colorWithoutHash = selected_bg_colors.replace(/^#/, '');88 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe89 label.click();90 } else {91 var colorWithoutHash = selected_bg_colors.replace(/^#/, '');92 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels93 }94 95 });96 97 }, 100);77 78 setTimeout(function () { 79 var selected_title_color = getSelectedTitleColor(title_colors); 80 var selected_font_colors = getSelectedFontColor(font_colors); 81 var selected_bg_colors = getSelectedBgColor(bg_colors); 82 var radioInputs = document.querySelectorAll('.input-group-color input[type="radio"]'); 83 radioInputs.forEach(function (radio) { 84 var label = radio.closest('label'); // Find the parent label of the radio input 85 if (radio.value === selected_title_color) { 86 var colorWithoutHash = selected_title_color.replace(/^#/, ''); 87 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe 88 label.click(); 89 } else { 90 var colorWithoutHash = selected_title_color.replace(/^#/, ''); 91 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels 92 } 93 if (radio.value === selected_font_colors) { 94 var colorWithoutHash = selected_font_colors.replace(/^#/, ''); 95 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe 96 label.click(); 97 } else { 98 var colorWithoutHash = selected_font_colors.replace(/^#/, ''); 99 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels 100 } 101 102 if (radio.value === selected_bg_colors) { 103 var colorWithoutHash = selected_bg_colors.replace(/^#/, ''); 104 label.classList.add(colorWithoutHash); // Add the selected_color class to the labe 105 label.click(); 106 } else { 107 var colorWithoutHash = selected_bg_colors.replace(/^#/, ''); 108 label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels 109 } 110 111 }); 112 113 }, 100); 98 114 99 115 // Define an array of objects containing the variables and their corresponding radio button sets 100 title_colors.forEach(function (title_color) {116 title_colors.forEach(function (title_color) { 101 117 102 118 // Initialize the variableSets array … … 105 121 // Check if title_color.title_color_selected exists 106 122 if (title_color.title_color_selected) { 107 console.log(title_color.title_color_selected , 'title_color.title_color_selected');123 console.log(title_color.title_color_selected, 'title_color.title_color_selected'); 108 124 // If title_color_selected exists, add it to variableSets 109 125 variableSets.push({ … … 122 138 123 139 // Iterate over each object in the array 124 variableSets.forEach(function (variableSet) {140 variableSets.forEach(function (variableSet) { 125 141 // If the variable is an array, iterate over each object in the array 126 142 if (Array.isArray(variableSet.variable)) { 127 variableSet.variable.forEach(function (colorObject) {143 variableSet.variable.forEach(function (colorObject) { 128 144 // Iterate over each key-value pair in the object 129 Object.keys(colorObject).forEach(function (key) {145 Object.keys(colorObject).forEach(function (key) { 130 146 // Find the radio button with the value matching the key's value 131 var radioButton = Array.from(variableSet.radios).find(function (radio) {147 var radioButton = Array.from(variableSet.radios).find(function (radio) { 132 148 return radio.value === colorObject[key]; 133 149 }); … … 140 156 }); 141 157 } else { // If the variable is a string, find and set the corresponding radio button 142 var radioButton = Array.from(variableSet.radios).find(function (radio) {158 var radioButton = Array.from(variableSet.radios).find(function (radio) { 143 159 return radio.value === variableSet.variable; 144 160 }); … … 159 175 160 176 // Define an array of objects containing the variables and their corresponding radio button sets 161 font_colors.forEach(function (font_color) {162 163 177 font_colors.forEach(function (font_color) { 178 179 164 180 165 181 // Initialize the variableSets array … … 185 201 186 202 // Iterate over each object in the array 187 variableSets.forEach(function (variableSet) {203 variableSets.forEach(function (variableSet) { 188 204 // If the variable is an array, iterate over each object in the array 189 205 if (Array.isArray(variableSet.variable)) { 190 variableSet.variable.forEach(function (colorObject) {206 variableSet.variable.forEach(function (colorObject) { 191 207 // Iterate over each key-value pair in the object 192 Object.keys(colorObject).forEach(function (key) {208 Object.keys(colorObject).forEach(function (key) { 193 209 // Find the radio button with the value matching the key's value 194 var radioButton = Array.from(variableSet.radios).find(function (radio) {210 var radioButton = Array.from(variableSet.radios).find(function (radio) { 195 211 return radio.value === colorObject[key]; 196 212 }); … … 203 219 }); 204 220 } else { // If the variable is a string, find and set the corresponding radio button 205 var radioButton = Array.from(variableSet.radios).find(function (radio) {221 var radioButton = Array.from(variableSet.radios).find(function (radio) { 206 222 return radio.value === variableSet.variable; 207 223 }); … … 222 238 223 239 // Define an array of objects containing the variables and their corresponding radio button sets 224 bg_colors.forEach(function(bg_color) {240 bg_colors.forEach(function (bg_color) { 225 241 226 242 // Initialize the variableSets array … … 244 260 } 245 261 246 262 247 263 // Iterate over each object in the array 248 variableSets.forEach(function (variableSet) {264 variableSets.forEach(function (variableSet) { 249 265 // If the variable is an array, iterate over each object in the array 250 266 if (Array.isArray(variableSet.variable)) { 251 variableSet.variable.forEach(function (colorObject) {267 variableSet.variable.forEach(function (colorObject) { 252 268 // Iterate over each key-value pair in the object 253 Object.keys(colorObject).forEach(function (key) {269 Object.keys(colorObject).forEach(function (key) { 254 270 // Find the radio button with the value matching the key's value 255 var radioButton = Array.from(variableSet.radios).find(function (radio) {271 var radioButton = Array.from(variableSet.radios).find(function (radio) { 256 272 return radio.value === colorObject[key]; 257 273 }); … … 264 280 }); 265 281 } else { // If the variable is a string, find and set the corresponding radio button 266 var radioButton = Array.from(variableSet.radios).find(function (radio) {282 var radioButton = Array.from(variableSet.radios).find(function (radio) { 267 283 return radio.value === variableSet.variable; 268 284 }); … … 322 338 function ai_app_onsite_save_app_properties() { 323 339 console.log('Nonce value:', document.getElementById('ai_app_onsite_app_properties_nonce_field').value); 324 console.log('Form data:', formData);340 console.log('Form data:', formData); 325 341 // Clear all previous error messages 326 document.querySelectorAll('.fields-error').forEach(function (error) {342 document.querySelectorAll('.fields-error').forEach(function (error) { 327 343 error.textContent = ''; 328 344 }); 329 345 330 346 // Get form fields 331 var appName = document.getElementById('app-name').value.trim(); 347 var appName = document.getElementById('app-name').value.trim(); 332 348 var appDescription = document.getElementById('app-description').value.trim(); 333 349 var appDisclaimer = document.getElementById('app-disclaimer').value.trim(); 334 //var fileUpload = document.getElementById('file-upload').value.trim();335 350 var appNameToggle = document.getElementById('app-name-toggle').checked 351 336 352 // Collect error messages 337 353 var errors = []; … … 351 367 // If there are errors, display them and return 352 368 if (errors.length > 0) { 353 errors.forEach(function (error) {369 errors.forEach(function (error) { 354 370 // Find the corresponding error container and display the message 355 371 if (error === 'App Name is required.') { … … 375 391 // Create and send AJAX request 376 392 var xhr = new XMLHttpRequest(); 377 xhr.onreadystatechange = function () {393 xhr.onreadystatechange = function () { 378 394 if (xhr.readyState === 4) { 379 395 var messageContainer = document.getElementById('app-properties-msg-container'); 380 setTimeout(function () {396 setTimeout(function () { 381 397 loader.style.display = 'none'; 382 398 … … 397 413 } 398 414 // Hide message after 3 seconds 399 setTimeout(function () {415 setTimeout(function () { 400 416 messageContainer.innerHTML = ''; 401 417 }, 3000); … … 412 428 formData.append('action', 'ai_app_onsite_save_app_properties'); 413 429 formData.append('app-name', document.getElementById("app-name") ? document.getElementById("app-name").value : ''); 430 formData.append('app-name-show', document.getElementById("app-name-toggle").checked); 414 431 415 432 // Check if file is selected … … 423 440 formData.append('app-disclaimer', document.getElementById("app-disclaimer") ? document.getElementById("app-disclaimer").value : ''); 424 441 formData.append('submit-btn-txt', document.getElementById("submit-btn-txt") ? document.getElementById("submit-btn-txt").value : ''); 425 442 426 443 // Check if radio buttons are selected before accessing their value 427 444 //var titleColorRadio = document.querySelector('input[name="title-color"]:checked'); … … 429 446 var titleColorRadios = document.querySelectorAll('input[type="radio"][name="title-color"]'); 430 447 var titleColors = []; 431 432 if (titleColorRadios){433 titleColorRadios.forEach(function (titleColorRadio) {448 449 if (titleColorRadios) { 450 titleColorRadios.forEach(function (titleColorRadio) { 434 451 if (titleColorRadio.checked) { 435 452 titleColors.push({ "title_color_selected": titleColorRadio.value }); … … 447 464 var fontColorRadios = document.querySelectorAll('input[type="radio"][name="font-color"]'); 448 465 var fontColor = []; 449 450 if (fontColorRadios){451 fontColorRadios.forEach(function (fontColorRadio) {466 467 if (fontColorRadios) { 468 fontColorRadios.forEach(function (fontColorRadio) { 452 469 if (fontColorRadio.checked) { 453 470 fontColor.push({ "font_color_selected": fontColorRadio.value }); … … 464 481 var bgColorRadios = document.querySelectorAll('input[type="radio"][name="bg-color"]'); 465 482 var bgColor = []; 466 bgColor467 if (bgColorRadios){468 bgColorRadios.forEach(function (bgColorRadio) {483 bgColor 484 if (bgColorRadios) { 485 bgColorRadios.forEach(function (bgColorRadio) { 469 486 if (bgColorRadio.checked) { 470 487 bgColor.push({ "bg_color_selected": bgColorRadio.value }); -
ai-app-onsite/trunk/assets/js/ai-app-onsite-model-settings.js
r3250856 r3272415 49 49 // Handle the response from the server 50 50 var response = JSON.parse(xhr.responseText); 51 console.log(response.data.data.temperature, 'ai_app_onsite_save_model_settings');52 console.log(response.data.data.top_p, 'ai_app_onsite_save_model_settings');53 console.log(response.data.data.f_penalty, 'ai_app_onsite_save_model_settings');54 console.log(response.data.data.p_penalty, 'ai_app_onsite_save_model_settings');55 console.log(response.data.data.max_tokens, 'ai_app_onsite_save_model_settings');56 console.log(response.data.data.model, 'ai_app_onsite_save_model_settings');57 58 51 59 52 let temperatureSettings = { … … 116 109 // Handle success response 117 110 var response = JSON.parse(xhr.responseText); 111 console.log(response, 'ai_app_onsite_get_model_settings'); 118 112 if (response.status === '404') { 119 113 var saveKpenapiKeyBtn = document.getElementById('save-openapi-key'); 120 114 var apiDisableBtn = document.getElementById("api-disable-btn"); 121 122 //jQuery('#apiinfoModal').modal('show'); 123 const modalElement = document.getElementById('apiinfoModal'); 124 const modalInstance = new bootstrap.Modal(modalElement); 125 modalInstance.show(); 126 127 //saveKpenapiKeyBtn.disabled = true; 128 apiDisableBtn.disabled = true; 129 apiDisableBtn.checked = false; 115 var apiKeyMgtBtn = document.getElementById("api-key-management"); 116 117 118 const engineDropdown = document.getElementById('model'); 119 var dependentFieldsWrapper = document.getElementById('model-dependent-fields'); 120 121 // Keep default placeholder selected 122 engineDropdown.value = ''; 123 124 // Add Highlight Class 125 engineDropdown.classList.add('border-danger'); 126 127 // Show Helper Text 128 document.getElementById('model-help-text').innerHTML = 'Please select a model to continue'; 129 130 dependentFieldsWrapper.classList.add('blurred'); 131 132 //hide the api key mgt button 133 apiKeyMgtBtn.style.display = 'none'; 134 135 136 // Optional: Disable other fields until model selected 137 document.querySelectorAll('.model-dependent').forEach(function (el) { 138 el.disabled = true; 139 }); 140 141 // Listen for change 142 engineDropdown.addEventListener('change', function () { 143 if (engineDropdown.value !== '') { 144 engineDropdown.classList.remove('border-danger'); 145 document.getElementById('model-help-text').innerHTML = ''; 146 147 // Enable fields 148 dependentFieldsWrapper.classList.remove('blurred'); 149 document.querySelectorAll('#model-dependent-fields').forEach(function (el) { 150 el.disabled = false; 151 }); 152 153 const modalElement = document.getElementById('apiinfoModal'); 154 const modalInstance = new bootstrap.Modal(modalElement); 155 modalInstance.show() 156 157 apiKeyMgtBtn.style.display = 'block'; 158 159 160 //saveKpenapiKeyBtn.disabled = true; 161 apiDisableBtn.disabled = true; 162 apiDisableBtn.checked = false; 163 } 164 }); 165 130 166 131 167 return; 132 168 } 133 169 170 171 134 172 // Accessing the first object in the array 135 173 var firstObject = response[0]; 136 137 174 // Accessing properties of the first object 138 var model = firstObject.model;139 var max_tokens = firstObject.max_tokens;140 var p_penalty = firstObject.p_penalty;141 var f_penalty = firstObject.f_penalty;175 var model = firstObject.model; 176 var max_tokens = firstObject.max_tokens; 177 var p_penalty = firstObject.p_penalty; 178 var f_penalty = firstObject.f_penalty; 142 179 var temperature = firstObject.temperature; 143 var top_p = firstObject.top_p; 144 var openai_key = firstObject.openai_key; 145 var key_status = firstObject.key_status; 180 var top_p = firstObject.top_p; 181 var openai_key = firstObject.openai_key; 182 var key_status = firstObject.key_status; 183 146 184 if (key_status == 'false') { 147 document.getElementById('key-status').textContent = 'D ISABLED';185 document.getElementById('key-status').textContent = 'Disabled'; 148 186 var element = document.getElementById('key-status'); 149 element.textContent = 'D ISABLED';187 element.textContent = 'Disabled'; 150 188 element.style.color = 'red'; 189 document.getElementById("api-disable-btn").checked = false; 190 151 191 } else { 152 192 var element = document.getElementById('key-status'); 153 element.textContent = 'E NABLED';193 element.textContent = 'Enabled'; 154 194 element.style.color = 'Green'; 195 document.getElementById("api-disable-btn").checked = true; 196 155 197 } 156 var openaiKey = document.getElementById('openai-key');157 var openaiKeyHidden = document.getElementById('openai-key-hidden');198 var openaiKey = document.getElementById('openai-key'); 199 var openaiKeyHidden = document.getElementById('openai-key-hidden'); 158 200 var saveKpenapiKeyBtn = document.getElementById('save-openapi-key'); 159 var apiDisableBtn = document.getElementById("api-disable-btn");201 var apiDisableBtn = document.getElementById("api-disable-btn"); 160 202 161 203 // Check if the value is null or empty … … 172 214 openaiKey.value = maskAPIKey(openai_key); 173 215 openaiKeyHidden.value = openai_key; 174 apiDisableBtn.checked = key_status; 175 216 var element = document.getElementById('text-switch'); 217 218 if (key_status == 'false') { 219 element.textContent = 'Disabled'; 220 element.style.color = 'Red'; 221 apiDisableBtn.checked = false; 222 223 } else { 224 element.textContent = 'Enabled'; 225 element.style.color = 'Green'; 226 apiDisableBtn.checked = true; 227 228 } 176 229 177 230 } … … 237 290 var errors = []; 238 291 if (openaiKeyError === '' || openaiKeyHidden === '') { 239 errors.push('API key is req ired.');292 errors.push('API key is required.'); 240 293 } 241 294 … … 244 297 errors.forEach(function (error) { 245 298 // Find the corresponding error container and display the message 246 if (error === 'API key is req ired.') {299 if (error === 'API key is required.') { 247 300 document.getElementById('openai-key-error').textContent = error; 248 301 } … … 261 314 const api_status = document.getElementById("api-disable-btn") ? document.getElementById("api-disable-btn").checked : ""; 262 315 const api_nonce = document.getElementById("ai_app_onsite_model_settings_nonce_field") ? document.getElementById("ai_app_onsite_model_settings_nonce_field").value : ""; 263 316 const engineDropdown = document.getElementById('model'); 317 console.log(api_status); 264 318 // Send the API key to the server using an AJAX request 265 319 fetch(myPluginAjax.ajaxurl, { … … 269 323 }, 270 324 body: new URLSearchParams({ 271 action: 'ai_app_onsite_save_openai_key', // Action for the server-side function 272 api_key: api_Key, 273 api_status: api_status, 274 api_Key_nonce: api_nonce 325 action : 'ai_app_onsite_save_openai_key', // Action for the server-side function 326 api_key : api_Key, 327 api_status : api_status, 328 api_Key_nonce: api_nonce, 329 engine_model : engineDropdown.value, 275 330 }) 276 331 }) … … 302 357 } 303 358 359 document.addEventListener('DOMContentLoaded', function () { 360 const copyButton = document.querySelector('.copy-api-key'); 361 if (copyButton) { 362 copyButton.addEventListener('click', ai_app_onsite_copy_openapi_key); 363 } 364 }); 365 366 document.addEventListener('DOMContentLoaded', function () { 367 const maskToggle = document.getElementById('maskToggle'); 368 const openaiKeyInput = document.getElementById('openai-key'); 369 const openaiKeyHidden = document.getElementById('openai-key-hidden'); 370 371 if (maskToggle && openaiKeyInput && openaiKeyHidden) { 372 // Initial check to hide maskToggle text if no value is present in openaiKeyHidden 373 updateMaskToggleVisibility(); 374 375 // Add event listener for maskToggle click 376 maskToggle.addEventListener('click', function () { 377 if (maskToggle.textContent.trim() === 'Show Key') { 378 // Show the full API key 379 openaiKeyInput.value = openaiKeyHidden.value; 380 maskToggle.textContent = 'Hide Key'; 381 } else { 382 // Mask the API key 383 openaiKeyInput.value = maskAPIKey(openaiKeyHidden.value); 384 maskToggle.textContent = 'Show Key'; 385 } 386 }); 387 388 // Function to update the visibility of maskToggle text 389 function updateMaskToggleVisibility() { 390 if (!openaiKeyHidden.value.trim()) { 391 maskToggle.textContent = ''; // Hide text if no value is present 392 } else { 393 maskToggle.textContent = 'Show Key'; // Default text when value exists 394 } 395 } 396 397 // Observe changes to the value of openaiKeyHidden 398 const observer = new MutationObserver(updateMaskToggleVisibility); 399 observer.observe(openaiKeyHidden, { attributes: true, attributeFilter: ['value'] }); 400 } 401 402 // Helper function to mask the API key 403 function maskAPIKey(input) { 404 var maxLength = 40; 405 var len = input.length; 406 if (len <= 6) return input; 407 var maskedPart = input.slice(0, 2) + '*'.repeat(Math.min(len - 6, maxLength - 6)) + input.slice(len - 4); 408 return maskedPart.slice(0, maxLength); 409 } 410 }); 304 411 305 412 function ai_app_onsite_copy_openapi_key() { 306 413 var openai_key = document.getElementById('openai-key'); 307 414 var openaiKeyHidden = document.getElementById('openai-key-hidden'); 415 var copyIcon = document.querySelector('.copy-api-key .assets-copy-icon'); 416 const maskToggle = document.getElementById('maskToggle'); 417 if (!openai_key || !openaiKeyHidden || !copyIcon) { 418 console.error('Required elements not found: openai-key, openai-key-hidden, or copy-icon'); 419 return; 420 } 421 422 // Temporarily set the visible input field to the full API key 308 423 openai_key.value = openaiKeyHidden.value; 309 424 310 // Select the text field 311 openai_key.select(); 312 openai_key.setSelectionRange(0, 99999); // For mobile devices 313 314 // Copy the text inside the text field 315 document.execCommand("copy"); 316 425 try { 426 // Select the text field 427 openai_key.select(); 428 openai_key.setSelectionRange(0, openai_key.value.length); // For mobile devices 429 430 // Copy the text inside the text field 431 if (document.execCommand('copy')) { 432 console.log('API key copied to clipboard successfully.'); 433 434 // Change the icon color by adding a class 435 copyIcon.classList.add('icon-success'); 436 437 // Remove the class after 2 seconds 438 setTimeout(() => { 439 copyIcon.classList.remove('icon-success'); 440 }, 2000); 441 } else { 442 console.error('Failed to copy API key to clipboard.'); 443 } 444 } catch (err) { 445 console.error('Error copying API key:', err); 446 } 447 maskToggle.textContent = 'Hide Key'; 448 // Restore the masked API key in the visible input field 317 449 openai_key.value = maskAPIKey(openaiKeyHidden.value); 318 319 openai_key.select(); 450 maskToggle.textContent = 'Show Key'; 451 452 // Deselect the input field 453 openai_key.blur(); 320 454 } 321 455 … … 323 457 document.getElementById('openai-key').value = ""; 324 458 document.getElementById("openai-key-hidden").value = ""; 459 460 const apiDisableBtn = document.getElementById('api-disable-btn'); 461 const apiDisableTxt = document.getElementById('text-switch'); 462 463 const keyStatus = document.getElementById('key-status'); 464 465 keyStatus.textContent = 'Disabled'; 466 keyStatus.style.color = 'red'; 467 468 apiDisableTxt.textContent = 'Disabled'; 469 apiDisableTxt.style.color = 'red'; 470 471 apiDisableBtn.checked = false; 325 472 } 326 473 … … 329 476 const api_Key = document.getElementById("openai-key"); 330 477 331 if (api_status) { 332 // If api_status is checked, disable the api_Key input field 333 api_Key.disabled = true; 334 } else { 335 // If api_status is not checked, enable the api_Key input field 336 api_Key.disabled = false; 337 } 478 api_Key.disabled = !!api_status; 338 479 } 339 480 … … 358 499 console.log(key_status, 'key_status'); 359 500 if (key_status == 'false') { 360 console.log('sderfdfgfgfgfgfgf'); 361 document.getElementById('key-status').textContent = 'DISABLED'; 501 document.getElementById('key-status').textContent = 'Disabled'; 362 502 document.getElementById("api-disable-btn").checked = false; 363 document.getElementsByClassName('text-switch')[0].textContent = 'D ISABLED';503 document.getElementsByClassName('text-switch')[0].textContent = 'Disabled'; 364 504 document.getElementsByClassName('text-switch')[0].style.color = 'red'; 365 505 506 console.log('Disabled'); 507 366 508 } else { 367 document.getElementById('key-status').textContent = 'E NABLED';368 document.getElementsByClassName('text-switch')[0].textContent = 'E NABLED';509 document.getElementById('key-status').textContent = 'Enabled'; 510 document.getElementsByClassName('text-switch')[0].textContent = 'Enabled'; 369 511 document.getElementsByClassName('text-switch')[0].style.color = 'green'; 370 512 document.getElementById("api-disable-btn").checked = true; 513 514 console.log('Enabled'); 371 515 // Get the value of the element with ID 'openai-key-hidden' 372 516 } … … 407 551 // Function to initialize the modal with original API key value 408 552 function handleInputChange() { 409 var inputElement = document.getElementById('openai-key'); 410 var openaiKeyHidden = document.getElementById('openai-key-hidden'); 411 var saveKpenapiKeyBtn = document.getElementById('save-openapi-key'); 412 var apiDisableBtn = document.getElementById('api-disable-btn'); 413 var openaiKeyError = document.getElementById('openai-key-error'); 414 var maskedValue = maskAPIKey(inputElement.value); 415 553 const inputElement = document.getElementById('openai-key'); 554 const openaiKeyHidden = document.getElementById('openai-key-hidden'); 555 const openaiKeyError = document.getElementById('openai-key-error'); 556 const apiDisableText = document.getElementById('text-switch'); 557 const keyStatus = document.getElementById('key-status'); 558 const apiDisableBtn = document.getElementById('api-disable-btn'); 416 559 417 560 if (inputElement.value) { 561 // Clear error message 418 562 openaiKeyError.textContent = ''; 563 564 // Update hidden input and mask the visible input 419 565 openaiKeyHidden.value = inputElement.value; 420 inputElement.value = maskedValue; 421 //saveKpenapiKeyBtn.disabled = false; 422 apiDisableBtn.disabled = false; 423 424 } 425 426 427 } 428 566 inputElement.value = maskAPIKey(inputElement.value); 567 568 // Update status text and color 569 const statusText = 'Enabled'; 570 const statusColor = 'green'; 571 apiDisableText.textContent = statusText; 572 apiDisableText.style.color = statusColor; 573 keyStatus.textContent = statusText; 574 keyStatus.style.color = statusColor; 575 apiDisableBtn.checked = true; 576 } 577 } 578 // Function to handle the change event for the API key toggle 429 579 document.getElementById('api-disable-btn').addEventListener('change', function () { 430 console.log(this.checked); 431 if (this.checked == true) { 432 433 var switchText = document.getElementsByClassName('text-switch')[0]; 434 switchText.textContent = 'ENABLED'; 435 switchText.style.color = 'Green'; 436 var element = document.getElementById('key-status'); 437 element.textContent = 'ENABLED'; 438 element.style.color = 'Green'; 439 } else { 440 441 var switchText = document.getElementsByClassName('text-switch')[0]; 442 switchText.textContent = 'DISABLED'; 443 switchText.style.color = 'Red'; 444 var element = document.getElementById('key-status'); 445 element.textContent = 'DISABLED'; 446 element.style.color = 'Red'; 447 } 448 }) 449 580 const isChecked = this.checked; 581 const switchText = document.getElementsByClassName('text-switch')[0]; 582 const keyStatusElement = document.getElementById('key-status'); 583 584 const statusText = isChecked ? 'Enabled' : 'Disabled'; 585 const statusColor = isChecked ? 'Green' : 'Red'; 586 587 // Update switch text and key status 588 switchText.textContent = statusText; 589 switchText.style.color = statusColor; 590 keyStatusElement.textContent = statusText; 591 keyStatusElement.style.color = statusColor; 592 593 }); 594 595 // Function to handle the change event for the model selection 450 596 document.addEventListener('DOMContentLoaded', function () { 451 597 document.getElementById('model').addEventListener('change', function () { … … 474 620 }); 475 621 }); 476 477 document.getElementById('openai-key').addEventListener('blur', function (event) { 478 const checkbox = document.getElementById('api-disable-btn'); 479 checkbox.checked = true; 480 var element = document.getElementsByClassName('text-switch')[0]; 481 element.textContent = 'ENABLED'; 482 element.style.color = 'green'; 483 var elementStatus = document.getElementById('key-status'); 484 elementStatus.textContent = 'ENABLED'; 485 elementStatus.style.color = 'Green'; 486 622 document.addEventListener('DOMContentLoaded', function () { 623 const hiddenKeyInput = document.getElementById('openai-key-hidden'); 624 const removeKeyButton = document.getElementById('key-remove-btn'); 625 626 if (hiddenKeyInput && removeKeyButton) { 627 // Initial check when the page loads 628 updateRemoveButtonVisibility(); 629 630 // Periodically check if the value of the hidden input changes dynamically 631 const observer = new MutationObserver(updateRemoveButtonVisibility); 632 observer.observe(hiddenKeyInput, { attributes: true, attributeFilter: ['value'] }); 633 634 // Function to update the visibility of the remove button 635 function updateRemoveButtonVisibility() { 636 if (!hiddenKeyInput.value.trim()) { 637 removeKeyButton.style.display = 'none'; 638 } else { 639 removeKeyButton.style.display = 'flex'; 640 } 641 } 642 } 487 643 }); 644 645 // document.getElementById('openai-key').addEventListener('blur', function (event) { 646 // const checkbox = document.getElementById('api-disable-btn'); 647 // checkbox.checked = true; 648 // var element = document.getElementsByClassName('text-switch')[0]; 649 // element.textContent = 'Enabled'; 650 // element.style.color = 'green'; 651 // var elementStatus = document.getElementById('key-status'); 652 // elementStatus.textContent = 'Enabled'; 653 // elementStatus.style.color = 'Green'; 654 655 // }); -
ai-app-onsite/trunk/assets/js/ai-app-onsite-plugin-settings.js
r3250856 r3272415 1 1 // Function to setup terms of service modal 2 2 function setupTermsOfServiceModal() { 3 var termsCheckbox = document.getElementById("terms_conditions");4 var acceptButton = document.getElementById("accept_ai_app_terms_of_service");5 var oldTermsCheckbox = document.getElementById("terms_of_service-old");6 var modal = document.getElementById("terms_conditions_modal");7 var closeButton = modal.querySelector(".btn-close");8 var savePluginSetting = document.getElementById("save_ai_app_plugin_settings_data");3 var termsCheckbox = document.getElementById("terms_conditions"); 4 var acceptButton = document.getElementById("accept_ai_app_terms_of_service"); 5 var oldTermsCheckbox = document.getElementById("terms_of_service-old"); 6 var modal = document.getElementById("terms_conditions_modal"); 7 var closeButton = modal.querySelector(".btn-close"); 8 var savePluginSetting = document.getElementById("save_ai_app_plugin_settings_data"); 9 9 var termsOfServiceError = document.getElementById('terms_of_service-error'); 10 10 … … 186 186 } 187 187 188 console.log(response[0]);189 190 188 // Accessing the first object in the array 191 189 var firstObject = response[0]; 192 190 193 191 // Accessing properties of the first object 194 var id = firstObject.id;195 var agreeTerms = firstObject.agree_terms;196 var appSelector = firstObject.app_selector;197 var userStats = firstObject.user_stats;198 var bannedWords = firstObject.banned_words;192 var id = firstObject.id; 193 var agreeTerms = firstObject.agree_terms; 194 var appSelector = firstObject.app_selector; 195 var userStats = firstObject.user_stats; 196 var bannedWords = firstObject.banned_words; 199 197 var bannedWordsCSV = firstObject.banned_words_csv; 200 var appName = firstObject.appName;198 var appName = firstObject.appName; 201 199 const selectElement = document.getElementById('bannedWords'); 202 200 … … 232 230 if (agreeTerms === "1") { 233 231 document.getElementById('terms_of_service-old').checked = true; 234 // document.getElementById('save_ai_app_plugin_settings_data').disabled = false;235 } else{236 // jQuery('#terms_conditions_modal').modal('show');232 // Ensure the modal is not triggered 233 } else { 234 // Show the modal if terms are not agreed to 237 235 const modalElement = document.getElementById('terms_conditions_modal'); 238 236 const modalInstance = new bootstrap.Modal(modalElement); 239 237 modalInstance.show(); 240 241 238 } 242 239 … … 455 452 456 453 // Function to clear error message when month selection is changed 457 document.getElementById('ai_app_onsite-user-stats').addEventListener('change', function() {458 document.getElementById('ai_app_onsite-user-stats-error').textContent = '';459 });454 // document.getElementById('ai_app_onsite-user-stats').addEventListener('change', function() { 455 // document.getElementById('ai_app_onsite-user-stats-error').textContent = ''; 456 // }); 460 457 461 458 //upload file js -
ai-app-onsite/trunk/assets/js/ai-app-onsite-prompt-editor.js
r3250856 r3272415 1 1 var availableFields = document.getElementById("available-fields"); 2 2 var promptInput = document.getElementById('prompt'); 3 var promptMaxTokenValue = document.getElementById('prompt-max-token-value'); 3 4 var promptError = document.getElementById('prompt-error'); 4 5 var aiResponseStyle = document.getElementById('ai-response-style'); … … 47 48 } 48 49 49 50 // read Model_Token_field 51 function ai_app_onsite_get_Model_Token_field() { 52 var xhr = new XMLHttpRequest(); 53 54 xhr.onreadystatechange = function () { 55 if (xhr.readyState === 4) { 56 if (xhr.status === 200) { 57 58 response = JSON.parse(xhr.responseText); 59 if (response.status === '404') { 60 return; 61 } 62 promptMaxTokenValue.innerHTML = response[0].max_tokens; 63 promptMaxTokenValue.style.display = 'none'; 64 65 } else { 66 // Handle error response 67 console.error('Error occurred: ' + xhr.responseText); 68 } 69 } 70 }; 71 72 xhr.open('POST', myPluginAjax.ajaxurl, true); 73 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 74 xhr.send('action=ai_app_onsite_get_Model_Token_field'); 75 } 50 76 51 77 // read field_tags -
ai-app-onsite/trunk/handler/ai-app-onsite-app-preview.php
r3250856 r3272415 1 1 <?php 2 3 use JetBrains\PhpStorm\NoReturn; 4 2 5 if (! class_exists('AI_APP_ONSITE_App_Preview_Handler')) { 3 6 class AI_APP_ONSITE_App_Preview_Handler 4 7 { 5 private $appProperty;8 private array $appProperty; 6 9 7 10 public function __construct() … … 11 14 $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties'; 12 15 $appropriates = $wpdb->get_results("SELECT * FROM $table_appropriate", ARRAY_A); 16 if (empty($appropriates)) { 17 error_log('No data found in $appropriates'); 18 return; 19 } 13 20 $titleColors = json_decode($appropriates[0]['title_color'], true); 14 21 $fontColors = json_decode($appropriates[0]['font_color'], true); 15 22 $bgColors = json_decode($appropriates[0]['bg_color'], true); 16 23 24 17 25 $title_color_selected = null; 18 26 $font_color_selected = null; 19 27 $bg_color_selected = null; 20 28 21 foreach ($titleColors as $color) { 22 if (isset($color['title_color_selected'])) { 23 $title_color_selected = $color['title_color_selected']; 24 break; 25 } 26 } 27 28 foreach ($fontColors as $color) { 29 if (isset($color['font_color_selected'])) { 30 $font_color_selected = $color['font_color_selected']; 31 break; 32 } 33 } 34 35 foreach ($bgColors as $color) { 36 if (isset($color['bg_color_selected'])) { 37 $bg_color_selected = $color['bg_color_selected']; 38 break; 39 } 40 } 41 42 43 if ($appropriates) { 29 if(!is_null($titleColors)) { 30 foreach ($titleColors as $color) { 31 if (isset($color['title_color_selected'])) { 32 $title_color_selected = $color['title_color_selected']; 33 break; 34 } 35 } 36 } 37 38 if(!is_null($fontColors)) { 39 foreach ($fontColors as $color) { 40 if (isset($color['font_color_selected'])) { 41 $font_color_selected = $color['font_color_selected']; 42 break; 43 } 44 } 45 } 46 47 foreach ($bgColors as $color) { 48 if (isset($color['bg_color_selected'])) { 49 $bg_color_selected = $color['bg_color_selected']; 50 break; 51 } 52 } 53 54 55 44 56 45 57 $this->appProperty = [ … … 58 70 59 71 ]; 60 }61 72 62 73 // Hook the AJAX action to the appropriate method in this class … … 78 89 //TODO: Old Logic 79 90 //New Logic 80 $appName = isset($appropriates[0]['app_name']) ? $appropriates[0]['app_name'] : 'aiapp'; 91 $appName = isset($appropriates[0]['app_name']) && !empty($appropriates[0]['app_name']) ? $appropriates[0]['app_name'] : 'aiapp'; 92 if ($appName == "aiapp") { 93 $appName = $appropriates[0]['app_name_show']; 94 } 81 95 if ($appName !== "aiapp") { 82 96 … … 109 123 110 124 // AJAX callback function 111 public function ai_app_onsite_create_app_preview_form()125 public function ai_app_onsite_create_app_preview_form() 112 126 { 113 127 global $wpdb; … … 136 150 $app_logo_image_url = wp_get_attachment_url($app_logo); 137 151 138 $form_width_size = isset($results[0]['app_width']) ? $results[0]['app_width'] :'70';152 $form_width_size = $results[0]['app_width'] ?? '70'; 139 153 140 154 … … 153 167 <img src="' . $app_logo_image_url . '" alt="App Logo" style="width: 100%; height: auto;" /> 154 168 </div>'; 155 } else {156 // Show fallback text if URL is empty157 // $formHTML .= '<div class="ai-app-image-wrap form-width" id="ai-app-openAi-app-logo"></div>';158 169 } 159 170 //App Logo End … … 235 246 236 247 // Define shortcode function 237 public function ai_app_onsite_create_openAi_app_form_shortcode() 238 { 248 public function ai_app_onsite_create_openAi_app_form_shortcode(): string { 239 249 global $wpdb; 240 250 $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties'; -
ai-app-onsite/trunk/handler/ai-app-onsite-app-properties.php
r3250856 r3272415 1 1 <?php 2 if ( ! class_exists( 'AI_APP_ONSITE_App_Properties_Handler' ) ) { 3 class AI_APP_ONSITE_App_Properties_Handler { 4 public function __construct() { 2 if (! class_exists('AI_APP_ONSITE_App_Properties_Handler')) { 3 class AI_APP_ONSITE_App_Properties_Handler 4 { 5 public function __construct() 6 { 5 7 // Hook the AJAX action to the appropriate method in this class 6 8 7 9 // Ajax handler 8 add_action( 'wp_ajax_ai_app_onsite_save_app_properties', array( $this, 'ai_app_onsite_save_app_properties_callback' ) ); 9 add_action( 'wp_ajax_nopriv_ai_app_onsite_save_app_properties', array( $this, 'ai_app_onsite_save_app_properties_callback' ) ); 10 11 add_action( 'wp_ajax_ai_app_onsite_get_app_properties', array( $this, 'ai_app_onsite_get_app_properties' ) ); 12 add_action( 'wp_ajax_nopriv_ai_app_onsite_get_app_properties', array( $this, 'ai_app_onsite_get_app_properties' ) ); 13 14 add_action( 'wp_ajax_ai_app_onsite_handle_sitelogo_upload', array( $this, 'ai_app_onsite_handle_sitelogo_upload_callback' ) ); 15 add_action( 'wp_ajax_nopriv_ai_app_onsite_handle_sitelogo_upload', array( $this, 'ai_app_onsite_handle_sitelogo_upload_callback' ) ); 16 17 } 18 19 function ai_app_onsite_save_app_properties_callback() { 10 add_action('wp_ajax_ai_app_onsite_save_app_properties', array($this, 'ai_app_onsite_save_app_properties_callback')); 11 add_action('wp_ajax_nopriv_ai_app_onsite_save_app_properties', array($this, 'ai_app_onsite_save_app_properties_callback')); 12 13 add_action('wp_ajax_ai_app_onsite_get_app_properties', array($this, 'ai_app_onsite_get_app_properties')); 14 add_action('wp_ajax_nopriv_ai_app_onsite_get_app_properties', array($this, 'ai_app_onsite_get_app_properties')); 15 16 add_action('wp_ajax_ai_app_onsite_handle_sitelogo_upload', array($this, 'ai_app_onsite_handle_sitelogo_upload_callback')); 17 add_action('wp_ajax_nopriv_ai_app_onsite_handle_sitelogo_upload', array($this, 'ai_app_onsite_handle_sitelogo_upload_callback')); 18 19 add_action('wp_ajax_ai_app_onsite_remove_app_logo', array($this, 'ai_app_onsite_remove_app_logo_callback')); 20 add_action('wp_ajax_nopriv_ai_app_onsite_remove_app_logo', array($this, 'ai_app_onsite_remove_app_logo_callback')); 21 } 22 23 function ai_app_onsite_save_app_properties_callback() 24 { 20 25 21 26 … … 23 28 // Verify if the request came via AJAX 24 29 if ( 25 ! isset( $_POST['action'] ) ||26 sanitize_text_field( wp_unslash( $_POST['action'] ) ) !== 'ai_app_onsite_save_app_properties' ||27 ! isset( $_POST['ai_app_onsite_app_properties_nonce_field'] ) ||28 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['ai_app_onsite_app_properties_nonce_field'] ) ), 'ai_app_onsite_app_properties_nonce')30 ! isset($_POST['action']) || 31 sanitize_text_field(wp_unslash($_POST['action'])) !== 'ai_app_onsite_save_app_properties' || 32 ! isset($_POST['ai_app_onsite_app_properties_nonce_field']) || 33 ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_app_properties_nonce_field'])), 'ai_app_onsite_app_properties_nonce') 29 34 ) { 30 wp_send_json_error( 'Unauthorized request');35 wp_send_json_error('Unauthorized request'); 31 36 } 32 37 33 38 // Extract individual settings values 34 $app_name = isset( $_POST['app-name'] ) ? sanitize_text_field( wp_unslash($_POST['app-name']) ) : ''; 35 $app_description = isset( $_POST['app-description'] ) ? sanitize_text_field( wp_unslash($_POST['app-description']) ) : ''; 36 $app_disclaimer = isset( $_POST['app-disclaimer'] ) ? sanitize_text_field( wp_unslash($_POST['app-disclaimer']) ) : ''; 37 $submit_btn_txt = isset( $_POST['submit-btn-txt'] ) ? sanitize_text_field( wp_unslash($_POST['submit-btn-txt']) ) : ''; 39 $app_name = isset($_POST['app-name']) ? sanitize_text_field(wp_unslash($_POST['app-name'])) : ''; 40 $app_name_show = isset($_POST['app-name-show']) ? sanitize_text_field(wp_unslash($_POST['app-name-show'])) : ''; 41 $app_description = isset($_POST['app-description']) ? sanitize_text_field(wp_unslash($_POST['app-description'])) : ''; 42 $app_disclaimer = isset($_POST['app-disclaimer']) ? sanitize_text_field(wp_unslash($_POST['app-disclaimer'])) : ''; 43 $submit_btn_txt = isset($_POST['submit-btn-txt']) ? sanitize_text_field(wp_unslash($_POST['submit-btn-txt'])) : ''; 38 44 39 45 // Get the JSON string from $_POST 40 $titleColorsJson = isset( $_POST['titleColors'] ) ? sanitize_text_field( wp_unslash( $_POST['titleColors'] )) : '';46 $titleColorsJson = isset($_POST['titleColors']) ? sanitize_text_field(wp_unslash($_POST['titleColors'])) : ''; 41 47 $titleColorsJson = stripslashes($titleColorsJson); 42 48 43 $fontColorsJson = isset( $_POST['fontColor'] ) ? sanitize_text_field( wp_unslash( $_POST['fontColor'] )) : '';49 $fontColorsJson = isset($_POST['fontColor']) ? sanitize_text_field(wp_unslash($_POST['fontColor'])) : ''; 44 50 $fontColorsJson = stripslashes($fontColorsJson); 45 51 46 $bgColorsJson = isset( $_POST['bgColor'] ) ? sanitize_text_field( wp_unslash( $_POST['bgColor'] )) : '';52 $bgColorsJson = isset($_POST['bgColor']) ? sanitize_text_field(wp_unslash($_POST['bgColor'])) : ''; 47 53 $bgColorsJson = stripslashes($bgColorsJson); 48 54 … … 50 56 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; 51 57 52 $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings");58 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 53 59 54 60 // Check if a file was uploaded 55 if ( isset( $_FILES['app-file'] ) && ! empty( $_FILES['app-file']['name'] )) {61 if (isset($_FILES['app-file']) && ! empty($_FILES['app-file']['name'])) { 56 62 // Handle file upload 57 $upload_overrides = array( 'test_form' => false );58 $movefile = wp_handle_upload( $_FILES['app-file'], $upload_overrides );59 60 if ( $movefile && ! isset( $movefile['error'] )) {63 $upload_overrides = array('test_form' => false); 64 $movefile = wp_handle_upload($_FILES['app-file'], $upload_overrides); 65 66 if ($movefile && ! isset($movefile['error'])) { 61 67 $file_url = $movefile['url']; // Get the file URL 62 63 } else { 64 wp_send_json_error( 'Error uploading file: ' . $movefile['error'] ); 65 } 66 } else { 67 $file_url = $existing_settings->app_logo; 68 } 69 70 if ( $existing_settings ) { 68 69 } else { 70 wp_send_json_error('Error uploading file: ' . $movefile['error']); 71 } 72 } else { 73 $file_url = $existing_settings->app_logo; 74 } 75 76 if ($app_name_show == "true") { 77 $app_name_temp = $app_name; 78 $app_name = ""; 79 } else { 80 $app_name_temp = ""; 81 } 82 83 if ($existing_settings) { 71 84 $wpdb->update( 72 85 $table_name_settings, 73 86 array( 74 87 'app_name' => $app_name, 75 'app_logo' => $file_url, 88 'app_name_show' => $app_name_temp, 89 'app_logo' => $file_url, 76 90 'app_description' => $app_description, 77 91 'app_disclaimer' => $app_disclaimer, … … 80 94 'font_color' => $fontColorsJson, 81 95 'bg_color' => $bgColorsJson 82 83 ), 84 array( 'id' => $existing_settings->id),85 array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'),86 array( '%d')96 97 ), 98 array('id' => $existing_settings->id), 99 array('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'), 100 array('%d') 87 101 ); 88 102 … … 101 115 'app_id' => 1, 102 116 'app_name' => $app_name, 103 'app_logo' => $file_url, 117 'app_name_show' => $app_name_temp, 118 'app_logo' => $file_url, 104 119 'app_description' => $app_description, 105 120 'app_disclaimer' => $app_disclaimer, … … 109 124 'bg_color' => $bgColorsJson 110 125 ), 111 array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')126 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 112 127 ); 113 128 … … 122 137 } 123 138 124 public static function ai_app_onsite_get_app_properties() { 125 139 public static function ai_app_onsite_get_app_properties() 140 { 141 126 142 global $wpdb; 127 143 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; … … 149 165 150 166 $generateURLForID = $results[0]['app_logo']; 151 $appLogoImagePreview = wp_get_attachment_url( $generateURLForID);152 153 if ( $appLogoImagePreview) {154 // Add the image preview URL to the $results array155 $results[0]['appLogoImagePreview'] = $appLogoImagePreview;167 $appLogoImagePreview = wp_get_attachment_url($generateURLForID); 168 169 if ($appLogoImagePreview) { 170 // Add the image preview URL to the $results array 171 $results[0]['appLogoImagePreview'] = $appLogoImagePreview; 156 172 } else { 157 173 $results[0]['appLogoImagePreview'] = 'No preview available'; // Handle cases where no URL is found … … 163 179 } 164 180 165 function ai_app_onsite_handle_sitelogo_upload_callback(){ 181 function ai_app_onsite_handle_sitelogo_upload_callback() 182 { 166 183 global $wpdb; 167 168 169 // Verify nonce to ensure the request is valid170 if (184 185 186 // Verify nonce to ensure the request is valid 187 if ( 171 188 !isset($_POST['ai_app_onsite_app_properties_logo_field_nonce_field']) || 172 189 !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_app_properties_logo_field_nonce_field'])), 'ai_app_onsite_app_properties_nonce') … … 175 192 return; 176 193 } 177 178 194 195 179 196 // Check for file upload 180 if ( isset( $_FILES['app-file'] ) && ! empty( $_FILES['app-file']['name'] )) {181 $upload_overrides = array( 'test_form' => false );182 $movefile = wp_handle_upload( $_FILES['app-file'], $upload_overrides);183 if ( $movefile && ! isset( $movefile['error'] )) {197 if (isset($_FILES['app-file']) && ! empty($_FILES['app-file']['name'])) { 198 $upload_overrides = array('test_form' => false); 199 $movefile = wp_handle_upload($_FILES['app-file'], $upload_overrides); 200 if ($movefile && ! isset($movefile['error'])) { 184 201 // File uploaded successfully 185 202 $file_path = $movefile['file']; // Local file path 186 203 $file_url = $movefile['url']; // File URL 187 204 188 205 // Create attachment 189 $filetype = wp_check_filetype( $file_path, null);206 $filetype = wp_check_filetype($file_path, null); 190 207 $attachment = array( 191 208 'post_mime_type' => $filetype['type'], 192 'post_title' => sanitize_file_name( basename( $file_path )),209 'post_title' => sanitize_file_name(basename($file_path)), 193 210 'post_content' => '', 194 211 'post_status' => 'inherit' 195 212 ); 196 213 197 $attachment_id = wp_insert_attachment( $attachment, $file_path);214 $attachment_id = wp_insert_attachment($attachment, $file_path); 198 215 199 216 // Include the image handling functions … … 201 218 202 219 // Generate metadata and update attachment 203 $attach_data = wp_generate_attachment_metadata( $attachment_id, $file_path ); 204 wp_update_attachment_metadata( $attachment_id, $attach_data ); 205 206 207 } else { 208 wp_send_json_error( 'Error uploading file: ' . $movefile['error'] ); 209 } 210 } else { 211 wp_send_json_error( 'No file uploaded.' ); 220 $attach_data = wp_generate_attachment_metadata($attachment_id, $file_path); 221 wp_update_attachment_metadata($attachment_id, $attach_data); 222 } else { 223 wp_send_json_error('Error uploading file: ' . $movefile['error']); 224 } 225 } else { 226 wp_send_json_error('No file uploaded.'); 212 227 } 213 228 214 229 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; 215 230 216 $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings");217 if ( $existing_settings) {231 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 232 if ($existing_settings) { 218 233 219 234 $wpdb->update( 220 $table_name_settings,221 array(235 $table_name_settings, 236 array( 222 237 'app_logo' => $attachment_id 223 ),224 array( 'id' => $existing_settings->id),225 array('%s'),226 array( '%d')227 );228 229 // Check if the database operation was successful230 if ($wpdb->last_error) {231 wp_send_json_error('Error updating data: ' . $wpdb->last_error);232 } else {233 // Return success message for update234 wp_send_json_success(array(238 ), 239 array('id' => $existing_settings->id), 240 array('%s'), 241 array('%d') 242 ); 243 244 // Check if the database operation was successful 245 if ($wpdb->last_error) { 246 wp_send_json_error('Error updating data: ' . $wpdb->last_error); 247 } else { 248 // Return success message for update 249 wp_send_json_success(array( 235 250 'attachment_id' => $attachment_id, 236 251 'file_url' => $file_url, 237 ) ); 238 } 239 } else { 240 // Insert new row 241 $wpdb->insert( 242 $table_name_settings, 243 array( 244 'app_id' => 1, 245 'app_name' => '', 246 'app_logo' => $attachment_id, 247 'app_description' => '', 248 'app_disclaimer' => '', 249 'submit_button_txt' => '', 250 'title_color' => '', 251 'font_color' => '', 252 'bg_color' => '' 253 ), 254 array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 255 ); 256 } 257 258 $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings" ); 252 )); 253 } 254 } else { 255 // Insert new row 256 $wpdb->insert( 257 $table_name_settings, 258 array( 259 'app_id' => 1, 260 'app_name' => '', 261 'app_name_show' => '', 262 'app_logo' => $attachment_id, 263 'app_description' => '', 264 'app_disclaimer' => '', 265 'submit_button_txt' => '', 266 'title_color' => '', 267 'font_color' => '', 268 'bg_color' => '' 269 ), 270 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 271 ); 272 } 273 274 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 259 275 $file_url = $existing_settings->app_logo; 260 276 // Check if the database operation was successful 261 if ($wpdb->last_error) { 262 wp_send_json_error('Error saving data: ' . $wpdb->last_error); 263 } else { 264 265 // Send response with the attachment ID 266 wp_send_json_success( array( 267 'attachment_id' => $attachment_id, 268 'file_url' => $file_url, 269 ) ); 270 271 } 272 273 } 274 275 276 277 277 if ($wpdb->last_error) { 278 wp_send_json_error('Error saving data: ' . $wpdb->last_error); 279 } else { 280 281 // Send response with the attachment ID 282 wp_send_json_success(array( 283 'attachment_id' => $attachment_id, 284 'file_url' => $file_url, 285 )); 286 } 287 } 288 289 public static function ai_app_onsite_remove_app_logo_callback() 290 { 291 global $wpdb; 292 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties'; 293 294 // Check if the table exists 295 if ($wpdb->get_var("SHOW TABLES LIKE '$table_name_settings'") != $table_name_settings) { 296 die('Table does not exist.'); 297 } 298 299 $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings"); 300 if ($existing_settings) { 301 302 $wpdb->update( 303 $table_name_settings, 304 array( 305 'app_logo' => '' 306 ), 307 array('id' => $existing_settings->id), 308 array('%s'), 309 array('%d') 310 ); 311 312 // Check if the database operation was successful 313 if ($wpdb->last_error) { 314 wp_send_json_error('Error updating data: ' . $wpdb->last_error); 315 } else { 316 // Return success message for update 317 wp_send_json_success(array( 318 'status' => '200', 319 'message' => 'Logo removed', 320 )); 321 } 322 } 323 // Don't forget to exit 324 exit; 325 } 278 326 } 279 327 … … 285 333 new AI_APP_ONSITE_App_Properties_Handler(); // Instantiate the class 286 334 } 287 -
ai-app-onsite/trunk/handler/ai-app-onsite-model-settings.php
r3250856 r3272415 40 40 41 41 // Extract individual settings values openai-iv 42 $model = isset($_POST['model']) ? sanitize_text_field(wp_unslash($_POST['model'])) : '';43 $max_tokens = isset($_POST['max-tokens']) ? sanitize_text_field(wp_unslash($_POST['max-tokens'])) : '';42 $model = isset($_POST['model']) ? sanitize_text_field(wp_unslash($_POST['model'])) : ''; 43 $max_tokens = isset($_POST['max-tokens']) ? sanitize_text_field(wp_unslash($_POST['max-tokens'])) : ''; 44 44 $temperature = isset($_POST['temperature']) ? sanitize_text_field(wp_unslash($_POST['temperature'])) : ''; 45 $top_p = isset($_POST['top-p']) ? floatval(sanitize_text_field(wp_unslash($_POST['top-p']))) : 0;46 $f_penalty = isset($_POST['f-penalty']) ? sanitize_text_field(wp_unslash($_POST['f-penalty'])) : '';47 $p_penalty = isset($_POST['p-penalty']) ? sanitize_text_field(wp_unslash($_POST['p-penalty'])) : '';45 $top_p = isset($_POST['top-p']) ? floatval(sanitize_text_field(wp_unslash($_POST['top-p']))) : 0; 46 $f_penalty = isset($_POST['f-penalty']) ? sanitize_text_field(wp_unslash($_POST['f-penalty'])) : ''; 47 $p_penalty = isset($_POST['p-penalty']) ? sanitize_text_field(wp_unslash($_POST['p-penalty'])) : ''; 48 48 49 49 … … 58 58 $table_name_settings, 59 59 array( 60 'model' => $model,60 'model' => $model, 61 61 'temperature' => $temperature, 62 'f_penalty' => $f_penalty,63 'p_penalty' => $p_penalty,64 'max_tokens' => $max_tokens,65 'top_p' => $top_p62 'f_penalty' => $f_penalty, 63 'p_penalty' => $p_penalty, 64 'max_tokens' => $max_tokens, 65 'top_p' => $top_p 66 66 67 67 ), … … 84 84 $table_name_settings, 85 85 array( 86 'app_id' => 1,87 'model' => $model,86 'app_id' => 1, 87 'model' => $model, 88 88 'temperature' => $temperature, 89 'f_penalty' => $f_penalty,90 'p_penalty' => $p_penalty,91 'max_tokens' => $max_tokens,92 'top_p' => $top_p89 'f_penalty' => $f_penalty, 90 'p_penalty' => $p_penalty, 91 'max_tokens' => $max_tokens, 92 'top_p' => $top_p 93 93 ), 94 94 array('%d', '%s', '%d', '%d', '%d', '%d', '%d') … … 188 188 $openai_key = isset($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : ''; 189 189 $api_status = isset($_POST['api_status']) ? sanitize_text_field(wp_unslash($_POST['api_status'])) : ''; 190 191 $engine_model = isset($_POST['engine_model']) ? sanitize_text_field(wp_unslash($_POST['engine_model'])) : ''; 190 192 191 193 … … 221 223 $table_name_settings, 222 224 array( 223 'app_id' => 1, 224 'openai_key' => $openai_key, 225 'key_status' => $api_status, 225 'app_id' => 1, 226 'openai_key' => $openai_key, 227 'key_status' => $api_status, 228 'model' => $engine_model, 226 229 'temperature' => '0.7', 227 'f_penalty' => '0',228 'p_penalty' => '0',229 'max_tokens' => '3000',230 'top_p' => '1',230 'f_penalty' => '0', 231 'p_penalty' => '0', 232 'max_tokens' => '3000', 233 'top_p' => '1', 231 234 ), 232 235 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s') -
ai-app-onsite/trunk/handler/ai-app-onsite-prompt-editor.php
r3250856 r3272415 8 8 add_action('wp_ajax_ai_app_onsite_get_field_tags', array($this, 'ai_app_onsite_get_field_tags')); 9 9 add_action('wp_ajax_nopriv_ai_app_onsite_get_field_tags', array($this, 'ai_app_onsite_get_field_tags')); 10 11 add_action('wp_ajax_ai_app_onsite_get_Model_Token_field', array($this, 'ai_app_onsite_get_Model_Token_field')); 12 add_action('wp_ajax_nopriv_ai_app_onsite_get_Model_Token_field', array($this, 'ai_app_onsite_get_Model_Token_field')); 10 13 11 14 add_action('wp_ajax_ai_app_onsite_save_prompt_editor', array($this, 'ai_app_onstie_save_prompt_editor_callback')); … … 134 137 } 135 138 136 public static function ai_app_onsite_get_prompt_editor() 137 { 139 public static function ai_app_onsite_get_Model_Token_field() 140 { 141 138 142 global $wpdb; 139 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_ prompt_editor';143 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_model_settings'; 140 144 141 145 // Check if the table exists … … 147 151 $rows_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name_settings"); 148 152 if ($rows_count == 0) { 149 150 153 $results = array('status' => '404', 'message' => 'No rows found in the table.'); 151 154 … … 165 168 exit; 166 169 } 170 171 public static function ai_app_onsite_get_prompt_editor() 172 { 173 global $wpdb; 174 $table_name_settings = $wpdb->prefix . 'ai_app_onsite_prompt_editor'; 175 176 // Check if the table exists 177 if ($wpdb->get_var("SHOW TABLES LIKE '$table_name_settings'") != $table_name_settings) { 178 die('Table does not exist.'); 179 } 180 181 // Check if the table has rows 182 $rows_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name_settings"); 183 if ($rows_count == 0) { 184 185 $results = array('status' => '404', 'message' => 'No rows found in the table.'); 186 187 // Return the data 188 wp_send_json($results); 189 190 die(); 191 } 192 193 // Fetch the data 194 $results = $wpdb->get_results("SELECT * FROM $table_name_settings", ARRAY_A); 195 196 // Return the data 197 wp_send_json($results); 198 199 // Don't forget to exit 200 exit; 201 } 167 202 } 168 203 -
ai-app-onsite/trunk/handler/ai-app-onsite-user-stats.php
r3250856 r3272415 11 11 } 12 12 13 public function ai_app_onsite_save_user_stats($result, $prompt, $formData) { 13 public function ai_app_onsite_save_user_stats($result, $prompt, $formData): void 14 { 14 15 global $wpdb; 15 16 16 // Get user IP address and geolocation using ipinfo.io 17 $user_ip = ''; 18 $user_geolocation = ''; 17 $ipinfo_token = '83cebbc0b4b378'; // Replace with your IPinfo API token 18 $ipinfo_url = "https://ipinfo.io?token={$ipinfo_token}"; 19 19 20 $ipinfo_token = '83cebbc0b4b378'; // Replace with your IPinfo API token 21 $ipinfo_url = "https://ipinfo.io?token={$ipinfo_token}"; 20 $response = wp_remote_get($ipinfo_url); 22 21 23 // Use WordPress HTTP API instead of CURL 24 $response = wp_remote_get($ipinfo_url); 22 if (!is_wp_error($response)) { 23 $body = wp_remote_retrieve_body($response); 24 $data = json_decode($body, true); 25 25 26 if (!is_wp_error($response)) { 27 $body = wp_remote_retrieve_body($response); 28 $data = json_decode($body, true); 26 $user_ip = !empty($data['ip']) ? sanitize_text_field($data['ip']) : 'Unknown'; 27 $user_geolocation = wp_json_encode($data); 28 } else { 29 // Fallback: Get IP using PHP if ipinfo fails 30 if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 31 $user_ip = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']); 32 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 33 // Sometimes contains multiple IPs (first is original) 34 $forwarded_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); 35 $user_ip = sanitize_text_field(trim($forwarded_ips[0])); 36 } elseif (!empty($_SERVER['REMOTE_ADDR'])) { 37 $user_ip = sanitize_text_field($_SERVER['REMOTE_ADDR']); 38 } else { 39 $user_ip = 'Unknown'; 40 } 29 41 30 if (!empty($data['ip'])) { 31 $user_ip = sanitize_text_field($data['ip']); 32 } 33 $user_geolocation = wp_json_encode($data); 34 } else { 35 wp_send_json_error('Error fetching IP info: ' . $response->get_error_message());36 }42 // Optional fallback message 43 $user_geolocation = wp_json_encode(array( 44 'ip' => $user_ip, 45 'source' => 'fallback-php', 46 'error' => $response->get_error_message() 47 )); 48 } 37 49 38 50 // Extract individual settings values 39 $formData = isset($formData) ? wp_json_encode($formData) : '';40 $used_token = isset($result['usage']['total_tokens']) ? sanitize_text_field($result['usage']['total_tokens']) : '';51 $formData = isset($formData) ? wp_json_encode($formData) : ''; 52 $used_token = isset($result['usage']['total_tokens']) ? sanitize_text_field($result['usage']['total_tokens']) : ''; 41 53 $response_Id = isset($result['id']) ? sanitize_text_field($result['id']) : ''; 42 $prompt = isset($prompt) ? sanitize_text_field($prompt) : '';54 $prompt = isset($prompt) ? sanitize_text_field($prompt) : ''; 43 55 44 56 // Insert new row … … 47 59 $table_name_stats, 48 60 array( 49 'app_id' => 1,50 'response_id' => $response_Id,51 'user_ip' => $user_ip,61 'app_id' => 1, 62 'response_id' => $response_Id, 63 'user_ip' => $user_ip, 52 64 'user_geolocation' => $user_geolocation, 53 'prompt' => $prompt,54 'data' => $formData,55 'used_token' => $used_token,56 'created_at' => current_time('mysql'),57 'updated_at' => current_time('mysql')65 'prompt' => $prompt, 66 'data' => $formData, 67 'used_token' => $used_token, 68 'created_at' => current_time('mysql'), 69 'updated_at' => current_time('mysql') 58 70 ), 59 71 array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') -
ai-app-onsite/trunk/includes/class-ai-app-onsite-admin.php
r3250856 r3272415 35 35 </h5> 36 36 </div> 37 <div class="ai-app-onsite-tab-content-box ">37 <div class="ai-app-onsite-tab-content-box shadow-sm rounded"> 38 38 <!-- Tab navigation --> 39 39 <h2 class="nav-tab-wrapper"> … … 78 78 <div class="assets-preview-icon-blue-icon"></div> 79 79 </div> 80 AppPreview80 Style & Preview 81 81 </a> 82 82 </h2> … … 204 204 ); 205 205 ?> 206 <div id="plugin-settings-content" class="tab-content ">206 <div id="plugin-settings-content" class="tab-content plugin-settings-tab-section"> 207 207 <?php echo wp_kses(AI_App_Onsite_Plugin_Settings::render_plugin_settings(), $allowed_html); ?> 208 208 </div> 209 209 210 <div id="app-properties-content" class="tab-content " style="display: none;">210 <div id="app-properties-content" class="tab-content app-properties-tab-section" style="display: none;"> 211 211 <?php 212 212 echo wp_kses(AI_App_Onsite_App_Properties::render_app_properties(), $allowed_html); … … 214 214 </div> 215 215 216 <div id="model-settings-content" class="tab-content " style="display: none;">216 <div id="model-settings-content" class="tab-content model-settings-tab-section" style="display: none;"> 217 217 <?php echo wp_kses(AI_App_Onsite_Model_Settings::render_model_settings(), $allowed_html); ?> 218 218 </div> 219 219 220 <div id="field-selector-content" class="tab-content " style="display: none;">220 <div id="field-selector-content" class="tab-content field-selector-tab-section" style="display: none;"> 221 221 <?php echo wp_kses(AI_App_Onsite_Field_Selector::render_field_selector(), $allowed_html); ?> 222 222 </div> 223 223 224 <div id="prompt-editor-content" class="tab-content " style="display: none;">224 <div id="prompt-editor-content" class="tab-content prompt-editor-tab-section" style="display: none;"> 225 225 <?php 226 226 //echo AI_App_Onsite_Prompt_Editor::render_prompt_editor(); … … 233 233 'textarea_rows' => 10, // Number of rows for the editor. 234 234 'teeny' => false, // Full TinyMCE editor. 235 'quicktags' => false, // Disable the Visual and Text tabs. 236 'menubar' => false, 235 237 ); 236 238 … … 240 242 241 243 ?> 242 </div> 243 244 <div id="app-preview-content" class="tab-content" style="display: none;"> 244 <script type="text/javascript"> 245 // Wait until TinyMCE is initialized 246 jQuery(document).ready(function($) { 247 // Access TinyMCE editor instance 248 var editor = tinymce.get('prompt'); // 'prompt' is the editor ID 249 250 // Function to update the word count 251 function updateWordCount() { 252 var content = editor.getContent({ 253 format: 'text' 254 }); // Get plain text content 255 var wordCount = content.split(/\s+/).filter(function(word) { 256 return Boolean(word); 257 258 }).length; // Count words 259 var maxToken = document.getElementById("prompt-max-token-value").innerHTML 260 let estimatedTokens = Math.ceil(wordCount * 1.33); 261 let percentage = Math.ceil((estimatedTokens / maxToken) * 100); 262 $('#word-count') 263 .text(estimatedTokens + ' / ' + maxToken + ' Est. Tokens Used') 264 .css({ 265 'color': percentage < 50 ? 'green' : percentage < 80 ? 'orange' : 'red', 266 'font-weight': '600', 267 'margin-bottom': '10px', 268 'font-size': '13px' 269 }); 270 // Update the word count display 271 } 272 273 // Bind keyup event to editor content change (every time user types) 274 editor.on('keyup', function() { 275 updateWordCount(); // Update word count on keyup 276 }); 277 }); 278 </script> 279 </div> 280 281 <div id="app-preview-content" class="tab-content app-preview-tab-section" style="display: none;"> 245 282 <?php echo wp_kses(AI_App_Onsite_App_Preview::render_app_preview_content(), $allowed_html); ?> 246 283 </div> 247 284 </div> 248 285 </div> 286 287 <!-- Modal --> 288 <div class="modal fade bd-example-modal-sm plugin-setting" id="terms_conditions_modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"> 289 <div class="modal-dialog modal-dialog-centered" role="document"> 290 <div class="modal-content"> 291 <div class="modal-header"> 292 <h5 class="fs-bold-16" id="terms_conditions_modal_label">Terms of Services</h5> 293 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 294 </div> 295 <div class="modal-body mb-1"> 296 <div id="terms-conditions-modal-pdf"> 297 <p class="fs-regular-14 neutral-black-fs-100 mb-3 text-center">Terms of Services</p> 298 <p class="fs-regular-14 neutral-black-fs-90">Please read these terms carefully before using our service.</p> 299 <p class="fs-regular-14 neutral-black-fs-100 mb-1">1. User Responsibility</p> 300 <p class="fs-regular-12 neutral-black-fs-70">If you reside in the European Economic Area, Switzerland, the UK, California or some other locations, you may be subject to special conditions and laws that govern the use of AI. These and other locales also have privacy and data protection rules and laws that may also dictate how you can leverage tools like AIappOnsite.</p> 301 <p class="fs-regular-12 neutral-black-fs-70">It is important that you abide by all such applicable laws. Furthermore, you may not use the Service in a way that infringes, misappropriates or violates anyone’s rights. You may also not use the Service in a way that endangers or harms, or intends to do the same, to end users of applications built with the Service.</p> 302 303 <p class="fs-regular-14 neutral-black-fs-100 mb-1">2. Using AI Services</p> 304 <p class="fs-regular-12 neutral-black-fs-70">The Service requires that the site owner or their designee provide an API key which the Service will use tointegrate with an AI model provider. All AI functionality of the Service depends on one or more API keys, whichis provided by the various AI model vendors. An account must be opened with one of these vendors in order to get an API key.</p> 305 <p class="fs-regular-12 neutral-black-fs-70">These AI model providers are separate companies and unaffiliated with the Service, and have their own terms and conditions. Read them carefully. The API keys and their use are bound by the terms and conditions of the AI model provider and strictly controlled by the site owner or their designee (not AIappOnsite).</p> 306 307 <p class="fs-regular-14 neutral-black-fs-100 mb-1">3. Limitation of Liability</p> 308 <p class="fs-regular-12 neutral-black-fs-70">Given that the site owner fully controls the use, purpose and output of any application built with it, AIappOnsite bears no responsibility or liability for how it is used, or to any consequences of its use by site owners or their site visitors.</p> 309 <p class="fs-regular-12 neutral-black-fs-70">You agree that you are leveraging third party AI models and services separate from AIappOnsite, and that you have full control over and final responsibility for the prompts that will access the API as well as the end-user experience, and any representations made to them.</p> 310 311 <p class="fs-regular-14 neutral-black-fs-100 mb-1">4. Paid Accounts</p> 312 <p class="fs-regular-12 neutral-black-fs-70">Billing. If you purchase any services, you will provide complete and accurate billing information, including a valid payment method. For paid subscriptions, we will automatically charge your payment method on each agreed-upon periodic renewal until you cancel. You’re responsible for all applicable taxes, and we’ll charge tax when required. If your payment cannot be completed, we may downgrade your account or suspend your access to our services until payment is received.</p> 313 <p class="fs-regular-12 neutral-black-fs-70">Cancellation. You can cancel your paid subscription at any time. Previous payments are non-refundable,except where required by law. These Terms do not override any mandatory local laws regarding your cancellation rights.</p> 314 <p class="fs-regular-12 neutral-black-fs-70">Changes. We may change our prices from time to time. If we increase our subscription prices, we will give you at least 30 days’ notice and any price increase will take effect on your next renewal so that you can cancel if you do not agree to the price increase</p> 315 316 <p class="fs-regular-14 neutral-black-fs-100 mb-1">5. Termination and Suspension</p> 317 <p class="fs-regular-12 neutral-black-fs-70">Termination. You are free to stop using our Services at any time. We reserve the right to suspend or terminate your access to our Services or delete your account if we determine: 318 <ul class="pl-2"> 319 <li class="fs-regular-12 neutral-black-fs-70">- You breached these Terms of Service.</li> 320 <li class="fs-regular-12 neutral-black-fs-70">- We must do so to comply with the law.</li> 321 <li class="fs-regular-12 neutral-black-fs-70">- Your use of our Services could cause risk or harm to AIappOnsite or anyone else.</li> 322 </ul> 323 </p> 324 <p class="fs-regular-12 neutral-black-fs-70">Appeals. If you believe we have suspended or terminated your account in error, you can file an appeal with us by contacting our Support team.</p> 325 326 <p class="fs-regular-14 neutral-black-fs-100 mb-1">6. Discontinuation of Services</p> 327 <p class="fs-regular-12 neutral-black-fs-70">We may decide to discontinue our Services, but if we do, we will give you advance notice and a refund for any prepaid, unused services.</p> 328 329 <p class="fs-regular-14 neutral-black-fs-100 mb-1">7. Disclaimer of Warranties</p> 330 <p class="fs-regular-12 neutral-black-fs-70">Our services are provided “as is.” except to the extent prohibited by law, we and our affiliates and licensors make no warranties (express, implied, statutory or otherwise) with respect to the services, and disclaim all warranties including, but not limited to, warranties of merchantability, fitness for a particular purpose,satisfactory quality, non-infringement, and quiet enjoyment, and any warranties arising out of any course of dealing or trade usage. We do not warrant that the services will be uninterrupted, accurate or error free, or that any content will be secure or not lost or altered.</p> 331 <p class="fs-regular-12 neutral-black-fs-70">You accept and agree that any use of the service is at your sole risk.</p> 332 333 <p class="fs-regular-14 neutral-black-fs-100 mb-1">8. Limitation of liability</p> 334 <p class="fs-regular-12 neutral-black-fs-70">Neither we nor any of our affiliates or licensors will be liable for any indirect,incidental, special, consequential, or exemplary damages, including damages for loss of profits, goodwill, use, or data or other losses, even if we have been advised of the possibility of such damages. Our aggregate liability under these terms will not exceed the greater of the amount you paid for the service that gave rise to the claim during the 12 months before the liability arose or one hundred dollars ($100).The limitations in this section apply only to the maximum extent permitted by applicable law.</p> 335 <p class="fs-regular-12 neutral-black-fs-70">Some countries and states do not allow the disclaimer of certain warranties or the limitation of certain damages, so some or all of the terms above may not apply to you, and you may have additional rights. In that case, these Terms only limit our responsibilities to the maximum extent permissible in your country of residence.</p> 336 <p class="fs-regular-12 neutral-black-fs-70">Aiapponsite’s affiliates, suppliers, licensors, and distributors are intended third party beneficiaries of this section.</p> 337 338 <p class="fs-regular-14 neutral-black-fs-100 mb-1">9. Indemnity</p> 339 <p class="fs-regular-12 neutral-black-fs-70">If you are a business or organization, to the extent permitted by law, you will indemnify and hold harmless us,our affiliates, and our personnel, from and against any costs, losses, liabilities, and expenses (including attorneys’ fees) from third party claims arising out of or relating to your use of the Services and Content or any violation of these Terms.</p> 340 341 <div class="terms-form-group form-group mb-0"> 342 <input type="checkbox" id="terms_conditions"> 343 <label for="terms_conditions" class="fs-regular-14 pl-1 neutral-black-fs-90">Agree to Terms of Service</label> 344 </div> 345 </div> 346 <div class="divider-light mt-2 mb-3"></div> 347 <div class="button-wrap"> 348 <button type="button" id="download_ai_app_terms_of_service" role="button" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-white" name="save-plugin-settings" onclick="ai_app_onsite_download_terms_Of_service()">Download</button> 349 <button type="button" id="accept_ai_app_terms_of_service" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-purple border-purple text-white" name="save-plugin-settings" data-bs-dismiss="modal">Accept</button> 350 </div> 351 </div> 352 </div> 353 </div> 354 </div> 249 355 250 356 <?php -
ai-app-onsite/trunk/includes/class-ai-app-onsite-app-preview.php
r3250856 r3272415 11 11 <div class="app-preview-content"> 12 12 <div class="form-wrapper"> 13 <p class="fs-bold-14">Add App To Website</p> 13 <div class="#"> 14 <div class="d-flex align-items-baseline justify-content-between mb-2"> 15 <p class="font-bold fs-5 mb-0 app-preview-content__heading">Add App To Website</p> 16 <p class="font-regular mb-0 app-preview-content__description">Use the Shortcode or Name Block to add your app to a page or do more customization and test your app prompt below.</p> 17 </div> 18 </div> 14 19 <div> 15 20 <div class="row" id="shortcode-box"> 16 21 <div class="col-lg-6"> 17 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 ">Shortcode</label>22 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 text-muted">Shortcode</label> 18 23 <div class="select-box-icon"> 19 24 <span class="field-icon"> 20 25 <div class="assets-shortcode-icon"></div> 21 26 </span> 22 <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_shortcode()"> 23 <div class="assets-copy-icon"></div> 24 </span> 25 <input type="text" id="ai-app-onsite-openAi-app-shortcode" class="ai-app-onsite-openAi-app-shortcode" data-target="#ai-app-onsite-openAi-app-shortcode" readonly> 27 <div class="select-box-icon"> 28 <span class="field-icon"> 29 <div class="assets-shortcode-icon"></div> 30 </span> 31 <input type="text" id="ai-app-onsite-openAi-app-shortcode" class="ai-app-onsite-openAi-app-shortcode" data-target="#ai-app-onsite-openAi-app-shortcode" readonly> 32 <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_shortcode()"> 33 <div class="assets-copy-icon"></div> 34 </span> 35 </div> 26 36 </div> 27 37 <p class="neutral-black-fs-60 fs-regular-12 mb-0">Copy to add in Wordpress Classic Editor</p> 28 38 </div> 29 39 <div class="col-lg-6"> 30 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 ">Name Block</label>40 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 text-muted">Name Block</label> 31 41 <div class="select-box-icon"> 32 42 <span class="field-icon"> 33 43 <div class="assets-shortcode-icon"></div> 34 44 </span> 45 <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly> 35 46 <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_gutenberg_block()"> 36 47 <div class="assets-copy-icon"></div> 37 48 </span> 38 <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly>39 49 </div> 40 50 <p class="neutral-black-fs-60 fs-regular-12 mb-0">Name block to add in Gutenberg</p> … … 48 58 49 59 <div class="form-group mt-2" id="test-app-container"> 50 <div class="d-flex justify-content-between align-items-center"> 51 <label class="d-block fs-medium-16 mb-only-4 mt-2">Test Response</label> 52 <button type="button" class="btn fs-medium-14 neutral-black-fs-100 radius-6 py-8 px-16 border border-2 bg-white" name="ai-app-onsite-test" id="ai-app-onsite-test" onclick="ai_app_onsite_test_from()">Test App</button> 60 <div class="d-flex justify-content-between align-items-center mb-2"> 61 <label class="d-block fs-medium-16 mb-only-4 mt-2 text-muted">Test Response</label> 62 <button type="button" class="#" name="ai-app-onsite-test" id="ai-app-onsite-test" onclick="ai_app_onsite_test_from()"> 63 <span>Click To Test App</span> 64 </button> 53 65 </div> 54 66 <div class="select-box-icon select-box-icon-textarea mb-30"> -
ai-app-onsite/trunk/includes/class-ai-app-onsite-app-properties.php
r3250856 r3272415 14 14 <div class="form-group mb-20"> 15 15 <label class="fs-medium-14">App Name<span class="text-danger">*</span></label> 16 <div class="select-box-icon"> 17 <span class="field-icon"> 18 <div class="assets-folder-icon"></div> 19 </span> 20 <input type="text" name="app-name" id="app-name" class="border border-1 w-100 mb-1 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8"> 21 <p id="app-name-error" class="fields-error"></p> 22 </div> 16 <div class="col-12 d-flex flex-column flex-md-row"> 17 <!-- First div with the text input --> 18 <div class="col-12 col-md-7 select-box-icon mb-3 mb-md-0 me-md-2"> 19 <span class="field-icon"> 20 <div class="assets-folder-icon"></div> 21 </span> 22 <input type="text" name="app-name" id="app-name" class="border border-1 w-100 mb-1 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8"> 23 <p id="app-name-error" class="fields-error"></p> 24 </div> 25 26 <!-- Second div with the checkbox --> 27 <div class="col-12 col-md-5 m-2"> 28 <label for="app-name-toggle" class="d-flex align-items-center"> 29 <input type="checkbox" name="app-name-toggle" id="app-name-toggle" class="me-2"> 30 <span>Disable app name display</span> 31 </label> 32 </div> 33 </div> 34 23 35 </div> 24 36 <div class="form-group"> 25 <label class="fs-medium-14">App Logo/Image</label> 26 <div class="preview-img-box"> 27 <div id="previewImage"></div> 28 <div class="file-drop-area border "> 29 <span class="fake-btn"> 30 <div class="assets-upload-file-icon"></div> 31 </span> 32 <div> 33 <p class="file-msg-top mb-0 neutral-black-fs-110"><span class="text-purple">Click to upload</span> or drag and drop</p> 34 <p class="neutral-black-fs-50 mb-0 fs-regular-12">SVG, PNG, JPG or GIF (max. 800x400px)</p> 35 </div> 36 <input class="file-input" type="file" id="file-upload" name="fileUpload" accept=".svg, .png, .jpg, .gif" onchange="validateFile(this)"> 37 </div> 38 </div> 39 <p id="fileError" class="mt-1 fields-error"></p> 37 <label class="fs-medium-14 mb-1">App Logo/Image</label> 38 <div class="col-12 d-flex flex-column flex-md-row"> 39 <!-- First div with the file input and preview --> 40 <div class="col-12 col-md-12 select-box-icon mb-3 mb-md-0 me-md-2"> 41 <div id="previewImage"></div> 42 <div class="row d-flex align-items-center mt-2"> 43 <div class="col-md-8" id="file-upload-div"> 44 <div class="file-drop-area border "> 45 <span class="fake-btn"> 46 <div class="assets-upload-file-icon"></div> 47 </span> 48 <div> 49 <p class="file-msg-top mb-0 neutral-black-fs-110"><span class="text-purple">Click to upload</span> or drag and drop</p> 50 <p class="neutral-black-fs-50 mb-0 fs-regular-12">SVG, PNG, JPG or GIF (max. 800x400px)</p> 51 </div> 52 <input class="file-input" type="file" id="file-upload" name="fileUpload" accept=".svg, .png, .jpg, .gif" onchange="validateFile(this)"> 53 </div> 54 </div> 55 <!-- Second div with the button and cross icon --> 56 <div class="col-md-4" id="remove-logo-btn"> 57 <button type="button" class="btn btn-outline-danger d-flex align-items-center" onclick="removeLogoFile(this)"> 58 <span class="me-2"> 59 <div class="assets-cross-icon"></div> <!-- You can replace this with an actual cross icon --> 60 </span> 61 <span>Remove Logo</span> 62 </button> 63 64 </div> 65 66 </div> 67 <p id="fileError" class="mt-1 fields-error"></p> 68 69 70 </div> 71 </div> 40 72 </div> 41 73 <div class="form-group"> -
ai-app-onsite/trunk/includes/class-ai-app-onsite-db-handler.php
r3250856 r3272415 64 64 app_name TEXT, 65 65 app_logo TEXT, 66 app_name_show TEXT, 66 67 app_disclaimer VARCHAR(300), 67 68 app_description VARCHAR(1000), -
ai-app-onsite/trunk/includes/class-ai-app-onsite-model-settings.php
r3250856 r3272415 14 14 <?php wp_nonce_field('ai_app_onsite_model_settings_nonce', 'ai_app_onsite_model_settings_nonce_field'); ?> 15 15 <div class="row"> 16 <div class="col-lg- 6">17 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 ">Engine/Model </label>16 <div class="col-lg-12"> 17 <label for="app-selector" class="d-block fs-medium-14 mb-only-4 font-semibold">Choose Engine/Model </label> 18 18 <div class="select-box-icon mb-20"> 19 19 <span class="field-icon"> … … 21 21 </span> 22 22 <select id="model" class="border border-1 w-100 mb-1 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8"> 23 <option >Select</option>23 <option value="">Please Select Model</option> 24 24 <option value="gpt-4o">Open AI - gpt-4o</option> 25 25 <option value="gpt-4-turbo">Open AI - gpt-4-turbo</option> … … 29 29 <option value="gpt-3.5-turbo">Open AI - gpt-3.5-turbo</option> 30 30 </select> 31 31 <span id="model-help-text" class="text-danger"></span> 32 32 <p id="model-error" class="fields-error"></p> 33 33 </div> 34 34 </div> 35 <div class="col-lg-6"> 35 </div> 36 <div id="model-dependent-fields" class="row"> 37 38 <div class="col-lg-6 mb-20"> 36 39 <div class="form-group"> 37 <label class="fs-medium-14 ">Max Tokens</label>40 <label class="fs-medium-14 font-semibold">Max Tokens</label> 38 41 <div class="select-box-icon"> 39 42 <span class="field-icon"> 40 43 <div class="assets-token-icon"></div> 41 44 </span> 42 <input type="text" name="" placeholder="3000" id="max-tokens" class="border border-1 w-100 mb-20 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="3000"> 45 <input type="text" name="" placeholder="3000" id="max-tokens" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="3000"> 46 <span class="small-text text-muted">Maximum number of tokens (words & characters) allowed in response.</span> 43 47 </div> 44 48 </div> 45 49 </div> 46 <div class="col-lg-6 ">50 <div class="col-lg-6 mb-20"> 47 51 <div class="form-group"> 48 <label class="fs-medium-14 ">Temperature</label>52 <label class="fs-medium-14 font-semibold">Temperature</label> 49 53 <div class="select-box-icon"> 50 54 <span class="field-icon"> 51 55 <div class="assets-temprature-icon"></div> 52 56 </span> 53 <input type="text" name="temperature" placeholder="1" id="temperature" class="border border-1 w-100 mb-20 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0.7"> 57 <input type="text" name="temperature" placeholder="1" id="temperature" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0.7"> 58 <span class="small-text text-muted">Controls creativity — higher value = more random responses.</span> 54 59 </div> 55 60 </div> 56 61 </div> 57 <div class="col-lg-6 ">62 <div class="col-lg-6 mb-20"> 58 63 <div class="form-group"> 59 <label class="fs-medium-14 ">Top P</label>64 <label class="fs-medium-14 font-semibold">Top P</label> 60 65 <div class="select-box-icon"> 61 66 <span class="field-icon"> 62 67 <div class="assets-temprature-icon"></div> 63 68 </span> 64 <input type="text" name="top-p" placeholder="1" id="top-p" class="border border-1 w-100 mb-20 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="1"> 69 <input type="text" name="top-p" placeholder="1" id="top-p" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="1"> 70 <span class="small-text text-muted">Controls diversity — lower value = more focused responses.</span> 65 71 </div> 66 72 </div> 67 73 </div> 68 <div class="col-lg-6 ">74 <div class="col-lg-6 mb-20"> 69 75 <div class="form-group mb-0"> 70 <label class="fs-medium-14 ">F. Penalty</label>76 <label class="fs-medium-14 font-semibold">F. Penalty</label> 71 77 <div class="select-box-icon"> 72 78 <span class="field-icon"> … … 74 80 </span> 75 81 <input type="text" name="f-penalty" placeholder="0" id="f-penalty" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0"> 82 <span class="small-text text-muted">Reduces repetition of existing words in the response.</span> 76 83 </div> 77 84 </div> 78 85 </div> 79 <div class="col-lg-6 ">86 <div class="col-lg-6 mb-20"> 80 87 <div class="form-group mb-0"> 81 <label class="fs-medium-14 ">P. Penalty</label>88 <label class="fs-medium-14 font-semibold">P. Penalty</label> 82 89 <div class="select-box-icon"> 83 90 <span class="field-icon"> … … 85 92 </span> 86 93 <input type="text" name="p-penalty" placeholder="0" id="p-penalty" class="border border-1 w-100 fs-regular-14 neutral-black-fs-60 radius-6 px-10 py-8" value="0"> 94 <span class="small-text text-muted">Reduces repetition of new words in the response.</span> 87 95 </div> 88 96 </div> 89 97 </div> 90 </div> 98 </div> 99 91 100 <div class="divider-light"></div> 92 101 <div class="row justify-content-center"> 93 <div class="col-lg-6" >94 <div class="api-key-icon select-box-icon d-flex " onclick="ai_app_onsite_get_openapi_data()">95 <span class=" field-icon">102 <div class="col-lg-6" id="api-key-management"> 103 <div class="api-key-icon select-box-icon d-flex justify-content-around align-items-center" onclick="ai_app_onsite_get_openapi_data()"> 104 <span class="#"> 96 105 <div class="assets-api-key-icon"></div> 97 106 </span> 98 <p class="mb-0 fs- medium-14cursor-pointer" data-bs-toggle="modal" data-bs-target="#apiinfoModal">107 <p class="mb-0 fs-6 cursor-pointer" data-bs-toggle="modal" data-bs-target="#apiinfoModal"> 99 108 API Key Management 100 109 </p> 101 110 102 111 <span class="mb-0"> 103 <p id="key-status" ></p>112 <p id="key-status" class="mb-0 font-semibold fs-6"></p> 104 113 </span> 105 114 </div> … … 129 138 <p class="fs-regular-14 neutral-black-fs-100">Please enter your OpenAI API key below. You can get an API key from your <a href="" class="neutral-black-fs-100 underline"> OpenAI account dashboard.</a></p> 130 139 <div class="form-group mb-0"> 131 <label class="fs-medium-14 ">API api-key</label>140 <label class="fs-medium-14 fw-semibold">API Key</label> 132 141 <div class="select-box-icon right-icon"> 133 <span class="field-icon " onclick="ai_app_onsite_copy_openapi_key()">142 <span class="field-icon copy-api-key"> 134 143 <div class="assets-copy-icon"></div> 135 144 </span> … … 137 146 <input type="hidden" name="openai-key-hidden" id="openai-key-hidden"> 138 147 </div> 139 <span id="maskToggle">Show</span> 140 <span id="copyButton">Copy</span> 148 <div class="d-flex justify-content-start align-items-center mt-2 key-toggle"> 149 <span id="maskToggle" class="text-muted me-3 mask__toggle">Show Key</span> 150 </div> 141 151 <p id="openai-key-error" class="fields-error"></p> 142 152 </div> 143 <p class="fs-regular-12 neutral-black-fs-60 mb-1 mt-2">Note: Your API key isstored locally and securely in your browser and never shared.</p>153 <p class="fs-regular-12 neutral-black-fs-60 mb-1 mt-2">Note: Your API key will be stored locally and securely in your browser and never shared.</p> 144 154 <div class="flex-row alignment-items-center mt-3 mb-3"> 145 155 <div class="col-50"> 146 <button class="btn remove-btn" id="key-remove-btn" onclick="ai_app_onsite_clear_openapi_Key_field()">147 <span class="btn-icon ">156 <button class="btn remove-btn align-items-center" id="key-remove-btn" onclick="ai_app_onsite_clear_openapi_Key_field()"> 157 <span class="btn-icon me-1"> 148 158 <div class="assets-delete-icon"></div> 149 159 </span> Remove API Key … … 151 161 </div> 152 162 <div class="col-50"> 153 <div class="enable-switch-box ">154 <span class="fs-medium-14 text-switch ">DISABLED</span>163 <div class="enable-switch-box d-flex justify-content-between align-items-baseline"> 164 <span class="fs-medium-14 text-switch me-2" id="text-switch">Disabled</span> 155 165 <label class="switch"> 156 166 <input type="checkbox" id="api-disable-btn" onchange="ai_app_onsite_disable_openapi_key()"> -
ai-app-onsite/trunk/includes/class-ai-app-onsite-plugin-settings.php
r3250856 r3272415 5 5 public static function render_plugin_settings() 6 6 { 7 $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/aiapponsite/ai-app-onsite.php'); 8 $version = $plugin_data['Version']; 7 9 ob_start(); ?> 8 10 <div class="form-wrapper"> … … 10 12 <?php wp_nonce_field('ai_app_onsite_plugin_settings_nonce', 'ai_app_onsite_plugin_settings_nonce_field'); ?> 11 13 <div class="mb-20"> 12 <p class="fs-bold-14">Get Started</p> 14 <div class="d-flex justify-content-between mb-0 align-items-center"> 15 <p class="font-bold fs-5 mb-0">Get Started</p> 16 <p class="fs-regular-14 neutral-black-fs-60 mb-0">Version: <?php echo $version; ?></p> 17 </div> 13 18 <div class="terms-form-group form-group mb-0"> 14 19 <input type="checkbox" id="terms_of_service-old" onchange="uploadTermCondition(this)"> 15 20 <label for="terms_of_service-old" data-toggle="modal" data-target=".bd-example-modal-sm" class="custom-checkbox fs-medium-14 "><span class="ml-1">Agree to Terms of Service</span></label> 16 21 </div> 17 <p class="fs-regular-14 ml-25 mb-1">You accept and agree all Terms of Services.</p> 22 <p class="fs-regular-14 ml-25 mb-1 text-muted"> 23 You must agree to the terms of service to use this plugin. Please read the terms carefully before proceeding. 24 </p> 18 25 <p id="terms_of_service-error" class="ml-25 fields-error"></p> 19 26 </div> 20 27 21 <div >28 <div class="mb-3"> 22 29 <label for="app-selector" class="d-block fs-medium-14 mb-only-4">App/Project Selector 23 30 <span class="fs-regular-14">(Multiple Apps With Premium)</span></label> … … 31 38 32 39 33 <div >40 <div class="mb-3"> 34 41 <label for="email-notification" class="d-block fs-medium-14 mb-only-4">App Email (for form data passing) 35 42 <span class="fs-regular-14"></span></label> … … 42 49 </div> 43 50 44 <div> 45 <label class="d-block fs-medium-14 mb-only-4">User Stats</label> 46 <div class="download-icon-box"> 47 <div class="select-box-icon"> 48 <span class="field-icon"> 49 <div class="assets-calendar-icon"></div> 50 </span> 51 <select id="ai_app_onsite-user-stats" class="w-100 mb-1 fs-regular-14 neutral-black-fs-60 neutral-black-10 radius-6 border-0 px-10 py-8"> 52 <option value="">Select</option> 53 <option value="1">January</option> 54 <option value="2">February</option> 55 <option value="3">March</option> 56 <option value="4">April</option> 57 <option value="5">May</option> 58 <option value="6">June</option> 59 <option value="7">July</option> 60 <option value="8">August</option> 61 <option value="9">September</option> 62 <option value="10">October</option> 63 <option value="11">November</option> 64 <option value="12">December</option> 65 </select> 66 <p id="ai_app_onsite-user-stats-error" class="fields-error"></p> 67 </div> 68 <a href="#" class="neutral-black-10 rounded-circle px-8 py-8 download-icon" onclick="ai_app_onsite_download_user_stats(event)"> 69 <div class="assets-download-icon"></div> 70 </a> 71 </div> 72 </div> 73 74 <div> 51 <div class="mb-3"> 75 52 <label class="d-block fs-medium-14 mb-only-4">Banned/blocked words (comma Separated)</label> 76 53 <div class="multi-select-container select-box-icon mb-20 fs-regular-14 neutral-black-fs-100 border border-1 radius-6 px-10 py-8"> … … 86 63 87 64 </div> 88 <div class="form-group ">65 <div class="form-group mb-3"> 89 66 <label class="fs-medium-14">Upload Banned/Block CSV</label> 90 67 <div class="file-drop-area border "> … … 113 90 <div id="Plugin-settings-msg-container" class="message-container"></div> 114 91 115 <!-- Modal -->116 <div class="modal fade bd-example-modal-sm plugin-setting" id="terms_conditions_modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">117 <div class="modal-dialog modal-dialog-centered" role="document">118 <div class="modal-content">119 <div class="modal-header">120 <h5 class="fs-bold-16" id="terms_conditions_modal_label">Terms of Services</h5>121 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>122 </div>123 <div class="modal-body mb-1">124 <div id="terms-conditions-modal-pdf">125 <p class="fs-regular-14 neutral-black-fs-100 mb-3 text-center">Terms of Services</p>126 <p class="fs-regular-14 neutral-black-fs-90">Please read these terms carefully before using our service.</p>127 <p class="fs-regular-14 neutral-black-fs-100 mb-1">1. User Responsibility</p>128 <p class="fs-regular-12 neutral-black-fs-70">If you reside in the European Economic Area, Switzerland, the UK, California or some other locations, you may be subject to special conditions and laws that govern the use of AI. These and other locales also have privacy and data protection rules and laws that may also dictate how you can leverage tools like AIappOnsite.</p>129 <p class="fs-regular-12 neutral-black-fs-70">It is important that you abide by all such applicable laws. Furthermore, you may not use the Service in a way that infringes, misappropriates or violates anyone’s rights. You may also not use the Service in a way that endangers or harms, or intends to do the same, to end users of applications built with the Service.</p>130 131 <p class="fs-regular-14 neutral-black-fs-100 mb-1">2. Using AI Services</p>132 <p class="fs-regular-12 neutral-black-fs-70">The Service requires that the site owner or their designee provide an API key which the Service will use tointegrate with an AI model provider. All AI functionality of the Service depends on one or more API keys, whichis provided by the various AI model vendors. An account must be opened with one of these vendors in order to get an API key.</p>133 <p class="fs-regular-12 neutral-black-fs-70">These AI model providers are separate companies and unaffiliated with the Service, and have their own terms and conditions. Read them carefully. The API keys and their use are bound by the terms and conditions of the AI model provider and strictly controlled by the site owner or their designee (not AIappOnsite).</p>134 135 <p class="fs-regular-14 neutral-black-fs-100 mb-1">3. Limitation of Liability</p>136 <p class="fs-regular-12 neutral-black-fs-70">Given that the site owner fully controls the use, purpose and output of any application built with it, AIappOnsite bears no responsibility or liability for how it is used, or to any consequences of its use by site owners or their site visitors.</p>137 <p class="fs-regular-12 neutral-black-fs-70">You agree that you are leveraging third party AI models and services separate from AIappOnsite, and that you have full control over and final responsibility for the prompts that will access the API as well as the end-user experience, and any representations made to them.</p>138 139 <p class="fs-regular-14 neutral-black-fs-100 mb-1">4. Paid Accounts</p>140 <p class="fs-regular-12 neutral-black-fs-70">Billing. If you purchase any services, you will provide complete and accurate billing information, including a valid payment method. For paid subscriptions, we will automatically charge your payment method on each agreed-upon periodic renewal until you cancel. You’re responsible for all applicable taxes, and we’ll charge tax when required. If your payment cannot be completed, we may downgrade your account or suspend your access to our services until payment is received.</p>141 <p class="fs-regular-12 neutral-black-fs-70">Cancellation. You can cancel your paid subscription at any time. Previous payments are non-refundable,except where required by law. These Terms do not override any mandatory local laws regarding your cancellation rights.</p>142 <p class="fs-regular-12 neutral-black-fs-70">Changes. We may change our prices from time to time. If we increase our subscription prices, we will give you at least 30 days’ notice and any price increase will take effect on your next renewal so that you can cancel if you do not agree to the price increase</p>143 144 <p class="fs-regular-14 neutral-black-fs-100 mb-1">5. Termination and Suspension</p>145 <p class="fs-regular-12 neutral-black-fs-70">Termination. You are free to stop using our Services at any time. We reserve the right to suspend or terminate your access to our Services or delete your account if we determine:146 <ul class="pl-2">147 <li class="fs-regular-12 neutral-black-fs-70">- You breached these Terms of Service.</li>148 <li class="fs-regular-12 neutral-black-fs-70">- We must do so to comply with the law.</li>149 <li class="fs-regular-12 neutral-black-fs-70">- Your use of our Services could cause risk or harm to AIappOnsite or anyone else.</li>150 </ul>151 </p>152 <p class="fs-regular-12 neutral-black-fs-70">Appeals. If you believe we have suspended or terminated your account in error, you can file an appeal with us by contacting our Support team.</p>153 154 <p class="fs-regular-14 neutral-black-fs-100 mb-1">6. Discontinuation of Services</p>155 <p class="fs-regular-12 neutral-black-fs-70">We may decide to discontinue our Services, but if we do, we will give you advance notice and a refund for any prepaid, unused services.</p>156 157 <p class="fs-regular-14 neutral-black-fs-100 mb-1">7. Disclaimer of Warranties</p>158 <p class="fs-regular-12 neutral-black-fs-70">Our services are provided “as is.” except to the extent prohibited by law, we and our affiliates and licensors make no warranties (express, implied, statutory or otherwise) with respect to the services, and disclaim all warranties including, but not limited to, warranties of merchantability, fitness for a particular purpose,satisfactory quality, non-infringement, and quiet enjoyment, and any warranties arising out of any course of dealing or trade usage. We do not warrant that the services will be uninterrupted, accurate or error free, or that any content will be secure or not lost or altered.</p>159 <p class="fs-regular-12 neutral-black-fs-70">You accept and agree that any use of the service is at your sole risk.</p>160 161 <p class="fs-regular-14 neutral-black-fs-100 mb-1">8. Limitation of liability</p>162 <p class="fs-regular-12 neutral-black-fs-70">Neither we nor any of our affiliates or licensors will be liable for any indirect,incidental, special, consequential, or exemplary damages, including damages for loss of profits, goodwill, use, or data or other losses, even if we have been advised of the possibility of such damages. Our aggregate liability under these terms will not exceed the greater of the amount you paid for the service that gave rise to the claim during the 12 months before the liability arose or one hundred dollars ($100).The limitations in this section apply only to the maximum extent permitted by applicable law.</p>163 <p class="fs-regular-12 neutral-black-fs-70">Some countries and states do not allow the disclaimer of certain warranties or the limitation of certain damages, so some or all of the terms above may not apply to you, and you may have additional rights. In that case, these Terms only limit our responsibilities to the maximum extent permissible in your country of residence.</p>164 <p class="fs-regular-12 neutral-black-fs-70">Aiapponsite’s affiliates, suppliers, licensors, and distributors are intended third party beneficiaries of this section.</p>165 166 <p class="fs-regular-14 neutral-black-fs-100 mb-1">9. Indemnity</p>167 <p class="fs-regular-12 neutral-black-fs-70">If you are a business or organization, to the extent permitted by law, you will indemnify and hold harmless us,our affiliates, and our personnel, from and against any costs, losses, liabilities, and expenses (including attorneys’ fees) from third party claims arising out of or relating to your use of the Services and Content or any violation of these Terms.</p>168 169 <div class="terms-form-group form-group mb-0">170 <input type="checkbox" id="terms_conditions">171 <label for="terms_conditions" class="fs-regular-14 pl-1 neutral-black-fs-90">Agree to Terms of Service</label>172 </div>173 </div>174 <div class="divider-light mt-2 mb-3"></div>175 <div class="button-wrap">176 <button type="button" id="download_ai_app_terms_of_service" role="button" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-white" name="save-plugin-settings" onclick="ai_app_onsite_download_terms_Of_service()">Download</button>177 <button type="button" id="accept_ai_app_terms_of_service" class="btn fs-medium-14 neutral-black-fs-60 radius-6 py-6 px-16 border border-2 bg-purple border-purple text-white" name="save-plugin-settings" data-bs-dismiss="modal">Accept</button>178 </div>179 </div>180 </div>181 </div>182 </div>183 184 92 185 93 <?php -
ai-app-onsite/trunk/includes/class-ai-app-onsite-prompt-editor.php
r3250856 r3272415 13 13 <?php wp_nonce_field('ai_app_onsite_prompt_editor_nonce', 'ai_app_onsite_prompt_editor_nonce_field'); ?> 14 14 <div class="form-group"> 15 <label class="d-block fs-medium-14 mb-only-4">Available Fields (<span class="important-text">IMPORTANT: </span>private user data should never be included in the prompt)</label> 16 <span class="variable-text-note m-1"> 17 NOTE: Click to copy variables in the prompt. 18 </span> 15 <div class="mb-4"> 16 <label class="d-block fw-semibold fs-5 mb-2">Available Fields</label> 17 <p class="text-danger small mb-1"> 18 <strong>IMPORTANT:</strong> Private user data should never be included in the prompt. 19 </p> 20 <p class="text-muted small"> 21 <em>Note:</em> Click on a variable to copy it into the prompt. 22 </p> 23 </div> 19 24 20 <div class="select-box-icon select-box-icon-textarea mb-30"> 25 <span id="prompt-max-token-value"></span> 26 27 <div class="select-box-icon select-box-icon-textarea mb-30 rounded shadow-sm bg-white"> 21 28 <span class="field-icon"> 22 29 <div class="assets-font-color-icon"></div> … … 25 32 </div> 26 33 <div class="form-group"> 27 <label class="d-block fs-medium-14 mb-only-4">Prompt</label> 34 <label class="d-block fs-medium-14 mb-only-4 fw-semibold"> 35 Enter your prompt below 36 </label> 28 37 <div class="select-box-icon select-box-icon-textarea mb-30"> 29 <span class="field-icon"> 30 <div class="assets-code-placeholder-icon"></div> 31 </span> 38 32 39 <?php 33 40 return ob_get_clean(); 34 41 } 42 35 43 public static function render_prompt_code_editor() 36 44 { 37 45 ob_start(); ?> 46 <div id="word-count" class="mt-2"> </div> 38 47 <p id="prompt-error" class="fields-error"></p> 39 48 </div> 40 49 </div> 41 42 <div class="divider-light"></div>43 50 <div class="mt-3 mb-3"> 44 51 <div class="col-50">
Note: See TracChangeset
for help on using the changeset viewer.