Plugin Directory

Changeset 3272415


Ignore:
Timestamp:
04/14/2025 12:40:44 PM (10 months ago)
Author:
aiapponsite
Message:

Creating version 1.1.0 with enhanced functionality and performance improvements

Location:
ai-app-onsite
Files:
42 edited
1 copied

Legend:

Unmodified
Added
Removed
  • ai-app-onsite/tags/1.1.0/ai-app-onsite.php

    r3250856 r3272415  
    44 * Plugin Name: AI App Onsite
    55 * 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.0
     6 * Version: 1.1.0
    77 * Author: By AIappOnsite
    88 * Author URI: https://aiapponsite.com/
     
    6262
    6363if (!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
    112130        wp_localize_script(
    113             'admin-script', // Handle of the registered script
    114             'myPluginAjax', // Name of the JavaScript object
     131            'admin-script',
     132            'myPluginAjax',
    115133            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,
    120139            )
    121140        );
    122141
    123142
    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
    125148        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 Service
    128         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');
    130149    }
    131150
    132151    add_action('admin_enqueue_scripts', 'ai_app_onsite_enqueue_admin_script');
    133152}
     153
    134154
    135155
     
    154174function AI_APP_ONSITE_My_Form_Block_Assets()
    155175{
    156     // Enqueue block editor script with filemtime for versioning (cache-busting)
     176    // Enqueue block editor script with file time for versioning (cache-busting)
    157177    wp_enqueue_script(
    158178        'ai-app-onsite-form-block-editor',
     
    166186
    167187if (!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
    186230
    187231
     
    192236    {
    193237        global $wpdb; // Access the global $wpdb variable
     238
     239        add_option('ai_app_onsite_fresh_install', true);
     240
    194241        require_once AI_APP_ONSITE_PLUGIN_DIR . 'includes/class-ai-app-onsite-db-handler.php';
    195242        // Create an instance of the database handler class and pass $wpdb
     
    202249
    203250
     251
    204252if (! function_exists('ai_app_onsite_deactivate')) {
    205253    // 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    }
    207263}
    208264
     
    271327function ai_app_onsite_editor_callback()
    272328{
    273     // Check karein ki function exist karta hai ya nahi
    274329    if (function_exists('wp_editor')) {
    275330        $content = ''; // Default content
     
    290345    }
    291346}
     347
     348add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'ai_app_onsite_settings_link');
     349
     350function 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  
    11/* start loader css */
    22
    3 .loader {
     3.ai-app-form-wrap .loader {
    44  height: 80px;
    55  aspect-ratio: 1;
     
    77}
    88
    9 .loader:before,
    10 .loader:after {
     9.ai-app-form-wrap .loader:before,
     10.ai-app-form-wrap .loader:after {
    1111  content: "";
    12   --c: no-repeat linear-gradient(var(--purple) 0 0);
     12  --c: no-repeat linear-gradient(#635aff 0 0);
    1313  background: var(--c), var(--c);
    1414  background-size: 25% 50%;
     
    1616}
    1717
    18 .loader:after {
     18.ai-app-form-wrap .loader:after {
    1919  transform: scale(-1);
     20}
     21.ai-app-form-wrap .fields-error {
     22  color: red;
     23  font-size: 12px;
    2024}
    2125
     
    4044}
    4145
    42 #loader {
     46.ai-app-form-wrap #loader {
    4347  position: fixed;
    4448  height: 100%;
     
    5357}
    5458
    55 .message-container span,
     59.ai-app-form-wrap .message-container span,
    5660.modal-message-container span {
    5761  text-align: center;
     
    6367}
    6468
    65 .select-box-icon.right-icon input[type="text"]::placeholder {
     69.ai-app-form-wrap .select-box-icon.right-icon input[type="text"]::placeholder {
    6670  color: #818898 !important;
    6771}
     
    6973/* end loader css  */
    7074
    71 .select-box-icon .ai-app-onsite-openAi-app-shortcode {
     75.ai-app-form-wrap .select-box-icon .ai-app-onsite-openAi-app-shortcode {
    7276  padding-left: 38px !important;
    7377  padding-right: 38px !important;
     
    8690}
    8791
    88 .field-copy-icon {
     92.ai-app-form-wrap .field-copy-icon {
    8993  position: absolute;
    9094  top: 6px;
     
    100104  border-radius: 8px;
    101105  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;
    106108}
    107109
     
    258260  font-weight: 600;
    259261}
    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  
    1919  --neutral-black-10: #f8fafc;
    2020}
    21 
     21* {
     22  box-sizing: border-box;
     23}
    2224.bg-purple {
    2325  background-color: var(--purple) !important;
     
    9799
    98100.divider-light {
    99   height: 1px;
     101  height: 2.5px;
    100102  width: 100%;
    101103  background-color: var(--neutral-black-20);
     
    332334
    333335/* BEGIN::Modal styles */
    334 
    335 * {
    336   box-sizing: border-box;
    337 }
    338 
    339336.container {
    340337  max-width: 50vw;
     
    926923}
    927924
    928 .api-key-icon.select-box-icon p {
     925/* .api-key-icon.select-box-icon p {
    929926  padding-left: 36px;
    930927  padding-top: 8px;
    931 }
     928} */
    932929
    933930.api-key-icon.select-box-icon {
     
    15101507  font-weight: 400;
    15111508}
     1509.app-preview-content .app-preview-content__heading {
     1510  width: 40%;
     1511}
     1512.app-preview-content .app-preview-content__description{
     1513  width: 60%;
     1514}
    15121515
    15131516.fields-error {
     
    16681671
    16691672.assets-copy-icon {
    1670   width: 20px;
    1671   HEIGHT: 25PX;
     1673  width: 1.25rem;
     1674  height: 1.56rem;
    16721675  background-image: url('../media/copy-icon.png');
    16731676  background-repeat: no-repeat;
    16741677  background-size: inherit;
    16751678  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}
    16781726#key-remove-btn {
    16791727  display: flex;
     
    19501998  }
    19511999}
     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  
     1var removeLogoBtn = document.getElementById('remove-logo-btn');
     2var previewImage = document.getElementById('previewImage');
     3var fileUploadDiv = document.getElementById('file-upload-div');
     4
     5// === Save & Restore Tab using Cookie ===
     6
     7document.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
    137function handleTabClick(tabId) {
    2     // alert(tabId);
    338    event.preventDefault();
    439
     
    742    // Check if the clicked tab is already active
    843    if (tab.classList.contains('nav-tab-active')) {
    9         return; // Do nothing if the tab is already active
     44        return;
    1045    }
    1146
     
    2560    tab.classList.add('nav-tab-active');
    2661
    27     // Show corresponding tab content (if applicable)
     62    // Show corresponding tab content
    2863    var contentId = tabId.replace("tab", "content");
    2964    var content = document.getElementById(contentId);
     
    3267    }
    3368
    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
    3673    if (tabId === 'plugin-settings-tab') {
    3774        ai_app_onsite_get_plugin_settings();
     
    4380        ai_app_onsite_read_field_selector();
    4481    } else if (tabId === 'prompt-editor-tab') {
     82        ai_app_onsite_get_Model_Token_field();
    4583        ai_app_onsite_get_field_tags();
    4684        ai_app_onsite_get_prompt_editor();
     
    69107//End get plugin setting from db js
    70108
     109
     110function 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
    71140//upload file js
    72141function validateFile(input) {
     
    95164
    96165function uploadSiteLogo(file) {
     166    removeLogoBtn.style.display = 'block';
     167    fileUploadDiv.classList.add('col-md-8');
     168    fileUploadDiv.classList.remove('col-md-12');
    97169    var formData = new FormData();
    98170    formData.append('app-file', file);
     
    123195                            previewImage.style.width = '350px';
    124196                            previewImage.style.height = '160px';
     197                            previewImage.style.position = 'relative';
    125198                        }
    126199
  • ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-app-preview.js

    r3250856 r3272415  
    1717                response = JSON.parse(xhr.responseText);
    1818
    19 
    20                 if (response.status === '404') {
     19                console.log('response', response);
     20                if (response.status === '404' || response.status === '400') {
    2121                    console.log('message', response.message);
    2222                    formContainer.innerHTML = '<p>No form Field Found Please Create Form Field</p>';
     
    9898                // Handle error response
    9999                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;
    100106            }
    101107        }
     
    128134                if (xhr.status === 200) {
    129135
    130                     // console.log(xhr);
    131136                    // Handle the response from the server
    132137                    var response = JSON.parse(xhr.responseText);
    133 
    134138                    if (response.success) {
    135139                        // Show success AI result
  • ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-app-properties.js

    r3250856 r3272415  
    33    var xhr = new XMLHttpRequest();
    44
    5     xhr.onreadystatechange = function() {
     5    xhr.onreadystatechange = function () {
    66        if (xhr.readyState === 4) {
    77            if (xhr.status === 200) {
    8                var response = JSON.parse(xhr.responseText);
     8                var response = JSON.parse(xhr.responseText);
    99                // Check if status is 404 (Table does not exist or no rows found)
    1010                if (response.status === '404') {
     
    1212                    return;
    1313                }
    14                   // Accessing the first object in the array
     14                // Accessing the first object in the array
    1515                var firstObject = response[0];
    1616                console.log(firstObject, 'firstObject');
    17                  var app_logo = firstObject.appLogoImagePreview;
    18                   console.log(app_logo, 'app_logo');
    1917                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') {
    2224                    var previewImage = document.getElementById('previewImage');
    2325                    previewImage.style.backgroundImage = `url('${app_logo}')`;
     
    2830                    previewImage.style.width = '350px';
    2931                    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');
    3039                }
    3140
     
    3443                // Accessing properties of the first object
    3544                var app_name = firstObject.app_name;
    36              
     45                var app_name_show = firstObject.app_name_show;
     46
    3747                var app_disclaimer = firstObject.app_disclaimer;
    3848                var app_description = firstObject.app_description;
    3949                var submit_button_txt = firstObject.submit_button_txt;
    4050                //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
    5363
    5464                // 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
    5773                document.getElementById('app-disclaimer').value = app_disclaimer;
    5874                document.getElementById('app-description').value = app_description;
    5975                document.getElementById('submit-btn-txt').value = submit_button_txt;
    6076                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 input
    69                     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 labe
    72                           label.click();
    73                     } else {
    74                          var colorWithoutHash = selected_title_color.replace(/^#/, '');
    75                         label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels
    76                     }
    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 labe
    80                           label.click();
    81                     } else {
    82                          var colorWithoutHash = selected_font_colors.replace(/^#/, '');
    83                         label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels
    84                     }
    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 labe
    89                           label.click();
    90                     } else {
    91                          var colorWithoutHash = selected_bg_colors.replace(/^#/, '');
    92                         label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels
    93                     }
    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);
    98114
    99115                // 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) {
    101117
    102118                    // Initialize the variableSets array
     
    105121                    // Check if title_color.title_color_selected exists
    106122                    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');
    108124                        // If title_color_selected exists, add it to variableSets
    109125                        variableSets.push({
     
    122138
    123139                    // Iterate over each object in the array
    124                     variableSets.forEach(function(variableSet) {
     140                    variableSets.forEach(function (variableSet) {
    125141                        // If the variable is an array, iterate over each object in the array
    126142                        if (Array.isArray(variableSet.variable)) {
    127                             variableSet.variable.forEach(function(colorObject) {
     143                            variableSet.variable.forEach(function (colorObject) {
    128144                                // Iterate over each key-value pair in the object
    129                                 Object.keys(colorObject).forEach(function(key) {
     145                                Object.keys(colorObject).forEach(function (key) {
    130146                                    // 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) {
    132148                                        return radio.value === colorObject[key];
    133149                                    });
     
    140156                            });
    141157                        } 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) {
    143159                                return radio.value === variableSet.variable;
    144160                            });
     
    159175
    160176                // 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
    164180
    165181                    // Initialize the variableSets array
     
    185201
    186202                    // Iterate over each object in the array
    187                     variableSets.forEach(function(variableSet) {
     203                    variableSets.forEach(function (variableSet) {
    188204                        // If the variable is an array, iterate over each object in the array
    189205                        if (Array.isArray(variableSet.variable)) {
    190                             variableSet.variable.forEach(function(colorObject) {
     206                            variableSet.variable.forEach(function (colorObject) {
    191207                                // Iterate over each key-value pair in the object
    192                                 Object.keys(colorObject).forEach(function(key) {
     208                                Object.keys(colorObject).forEach(function (key) {
    193209                                    // 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) {
    195211                                        return radio.value === colorObject[key];
    196212                                    });
     
    203219                            });
    204220                        } 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) {
    206222                                return radio.value === variableSet.variable;
    207223                            });
     
    222238
    223239                // 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) {
    225241
    226242                    // Initialize the variableSets array
     
    244260                    }
    245261
    246                    
     262
    247263                    // Iterate over each object in the array
    248                     variableSets.forEach(function(variableSet) {
     264                    variableSets.forEach(function (variableSet) {
    249265                        // If the variable is an array, iterate over each object in the array
    250266                        if (Array.isArray(variableSet.variable)) {
    251                             variableSet.variable.forEach(function(colorObject) {
     267                            variableSet.variable.forEach(function (colorObject) {
    252268                                // Iterate over each key-value pair in the object
    253                                 Object.keys(colorObject).forEach(function(key) {
     269                                Object.keys(colorObject).forEach(function (key) {
    254270                                    // 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) {
    256272                                        return radio.value === colorObject[key];
    257273                                    });
     
    264280                            });
    265281                        } 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) {
    267283                                return radio.value === variableSet.variable;
    268284                            });
     
    322338function ai_app_onsite_save_app_properties() {
    323339    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);
    325341    // Clear all previous error messages
    326     document.querySelectorAll('.fields-error').forEach(function(error) {
     342    document.querySelectorAll('.fields-error').forEach(function (error) {
    327343        error.textContent = '';
    328344    });
    329345
    330346    // Get form fields
    331     var appName = document.getElementById('app-name').value.trim(); 
     347    var appName = document.getElementById('app-name').value.trim();
    332348    var appDescription = document.getElementById('app-description').value.trim();
    333349    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
    336352    // Collect error messages
    337353    var errors = [];
     
    351367    // If there are errors, display them and return
    352368    if (errors.length > 0) {
    353         errors.forEach(function(error) {
     369        errors.forEach(function (error) {
    354370            // Find the corresponding error container and display the message
    355371            if (error === 'App Name is required.') {
     
    375391    // Create and send AJAX request
    376392    var xhr = new XMLHttpRequest();
    377     xhr.onreadystatechange = function() {
     393    xhr.onreadystatechange = function () {
    378394        if (xhr.readyState === 4) {
    379395            var messageContainer = document.getElementById('app-properties-msg-container');
    380             setTimeout(function() {
     396            setTimeout(function () {
    381397                loader.style.display = 'none';
    382398
     
    397413                }
    398414                // Hide message after 3 seconds
    399                 setTimeout(function() {
     415                setTimeout(function () {
    400416                    messageContainer.innerHTML = '';
    401417                }, 3000);
     
    412428    formData.append('action', 'ai_app_onsite_save_app_properties');
    413429    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);
    414431
    415432    // Check if file is selected
     
    423440    formData.append('app-disclaimer', document.getElementById("app-disclaimer") ? document.getElementById("app-disclaimer").value : '');
    424441    formData.append('submit-btn-txt', document.getElementById("submit-btn-txt") ? document.getElementById("submit-btn-txt").value : '');
    425    
     442
    426443    // Check if radio buttons are selected before accessing their value
    427444    //var titleColorRadio = document.querySelector('input[name="title-color"]:checked');
     
    429446    var titleColorRadios = document.querySelectorAll('input[type="radio"][name="title-color"]');
    430447    var titleColors = [];
    431    
    432     if(titleColorRadios){
    433         titleColorRadios.forEach(function(titleColorRadio) {
     448
     449    if (titleColorRadios) {
     450        titleColorRadios.forEach(function (titleColorRadio) {
    434451            if (titleColorRadio.checked) {
    435452                titleColors.push({ "title_color_selected": titleColorRadio.value });
     
    447464    var fontColorRadios = document.querySelectorAll('input[type="radio"][name="font-color"]');
    448465    var fontColor = [];
    449    
    450     if(fontColorRadios){
    451         fontColorRadios.forEach(function(fontColorRadio) {
     466
     467    if (fontColorRadios) {
     468        fontColorRadios.forEach(function (fontColorRadio) {
    452469            if (fontColorRadio.checked) {
    453470                fontColor.push({ "font_color_selected": fontColorRadio.value });
     
    464481    var bgColorRadios = document.querySelectorAll('input[type="radio"][name="bg-color"]');
    465482    var bgColor = [];
    466      bgColor
    467     if(bgColorRadios){
    468         bgColorRadios.forEach(function(bgColorRadio) {
     483    bgColor
     484    if (bgColorRadios) {
     485        bgColorRadios.forEach(function (bgColorRadio) {
    469486            if (bgColorRadio.checked) {
    470487                bgColor.push({ "bg_color_selected": bgColorRadio.value });
  • ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-model-settings.js

    r3250856 r3272415  
    4949                    // Handle the response from the server
    5050                    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 
    5851
    5952                    let temperatureSettings = {
     
    116109                // Handle success response
    117110                var response = JSON.parse(xhr.responseText);
     111                console.log(response, 'ai_app_onsite_get_model_settings');
    118112                if (response.status === '404') {
    119113                    var saveKpenapiKeyBtn = document.getElementById('save-openapi-key');
    120114                    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               
    130166
    131167                    return;
    132168                }
    133169
     170   
     171
    134172                // Accessing the first object in the array
    135173                var firstObject = response[0];
    136 
    137174                // 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;
    142179                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
    146184                if (key_status == 'false') {
    147                     document.getElementById('key-status').textContent = 'DISABLED';
     185                    document.getElementById('key-status').textContent = 'Disabled';
    148186                    var element = document.getElementById('key-status');
    149                     element.textContent = 'DISABLED';
     187                    element.textContent = 'Disabled';
    150188                    element.style.color = 'red';
     189                    document.getElementById("api-disable-btn").checked = false;
     190
    151191                } else {
    152192                    var element = document.getElementById('key-status');
    153                     element.textContent = 'ENABLED';
     193                    element.textContent = 'Enabled';
    154194                    element.style.color = 'Green';
     195                    document.getElementById("api-disable-btn").checked = true;
     196
    155197                }
    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');
    158200                var saveKpenapiKeyBtn = document.getElementById('save-openapi-key');
    159                 var apiDisableBtn = document.getElementById("api-disable-btn");
     201                var apiDisableBtn     = document.getElementById("api-disable-btn");
    160202
    161203                // Check if the value is null or empty
     
    172214                    openaiKey.value = maskAPIKey(openai_key);
    173215                    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                    }
    176229
    177230                }
     
    237290    var errors = [];
    238291    if (openaiKeyError === '' || openaiKeyHidden === '') {
    239         errors.push('API key is reqired.');
     292        errors.push('API key is required.');
    240293    }
    241294
     
    244297        errors.forEach(function (error) {
    245298            // Find the corresponding error container and display the message
    246             if (error === 'API key is reqired.') {
     299            if (error === 'API key is required.') {
    247300                document.getElementById('openai-key-error').textContent = error;
    248301            }
     
    261314    const api_status = document.getElementById("api-disable-btn") ? document.getElementById("api-disable-btn").checked : "";
    262315    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);
    264318    // Send the API key to the server using an AJAX request
    265319    fetch(myPluginAjax.ajaxurl, {
     
    269323        },
    270324        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,
    275330        })
    276331    })
     
    302357}
    303358
     359document.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
     366document.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});
    304411
    305412function ai_app_onsite_copy_openapi_key() {
    306413    var openai_key = document.getElementById('openai-key');
    307414    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
    308423    openai_key.value = openaiKeyHidden.value;
    309424
    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
    317449    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();
    320454}
    321455
     
    323457    document.getElementById('openai-key').value = "";
    324458    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;
    325472}
    326473
     
    329476    const api_Key = document.getElementById("openai-key");
    330477
    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;
    338479}
    339480
     
    358499                console.log(key_status, 'key_status');
    359500                if (key_status == 'false') {
    360                     console.log('sderfdfgfgfgfgfgf');
    361                     document.getElementById('key-status').textContent = 'DISABLED';
     501                    document.getElementById('key-status').textContent = 'Disabled';
    362502                    document.getElementById("api-disable-btn").checked = false;
    363                     document.getElementsByClassName('text-switch')[0].textContent = 'DISABLED';
     503                    document.getElementsByClassName('text-switch')[0].textContent = 'Disabled';
    364504                    document.getElementsByClassName('text-switch')[0].style.color = 'red';
    365505
     506                    console.log('Disabled');
     507
    366508                } else {
    367                     document.getElementById('key-status').textContent = 'ENABLED';
    368                     document.getElementsByClassName('text-switch')[0].textContent = 'ENABLED';
     509                    document.getElementById('key-status').textContent = 'Enabled';
     510                    document.getElementsByClassName('text-switch')[0].textContent = 'Enabled';
    369511                    document.getElementsByClassName('text-switch')[0].style.color = 'green';
    370512                    document.getElementById("api-disable-btn").checked = true;
     513
     514                    console.log('Enabled');
    371515                    // Get the value of the element with ID 'openai-key-hidden'
    372516                }
     
    407551// Function to initialize the modal with original API key value
    408552function 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');
    416559
    417560    if (inputElement.value) {
     561        // Clear error message
    418562        openaiKeyError.textContent = '';
     563
     564        // Update hidden input and mask the visible input
    419565        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
    429579document.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
    450596document.addEventListener('DOMContentLoaded', function () {
    451597    document.getElementById('model').addEventListener('change', function () {
     
    474620    });
    475621});
    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 
     622document.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    }
    487643});
     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  
    11// Function to setup terms of service modal
    22function 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");
    99  var termsOfServiceError = document.getElementById('terms_of_service-error');
    1010
     
    186186                  }
    187187
    188                   console.log(response[0]);
    189 
    190188                    // Accessing the first object in the array
    191189                    var firstObject = response[0];
    192190
    193191                    // 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;
    199197                    var bannedWordsCSV = firstObject.banned_words_csv;
    200                     var appName = firstObject.appName;
     198                    var appName        = firstObject.appName;
    201199                    const selectElement = document.getElementById('bannedWords');
    202200
     
    232230                    if (agreeTerms === "1") {
    233231                        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
    237235                        const modalElement = document.getElementById('terms_conditions_modal');
    238236                        const modalInstance = new bootstrap.Modal(modalElement);
    239237                        modalInstance.show();
    240 
    241238                    }
    242239               
     
    455452
    456453// 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// });
    460457
    461458//upload file js
  • ai-app-onsite/tags/1.1.0/assets/js/ai-app-onsite-prompt-editor.js

    r3250856 r3272415  
    11var availableFields = document.getElementById("available-fields");
    22var promptInput = document.getElementById('prompt');
     3var promptMaxTokenValue = document.getElementById('prompt-max-token-value');
    34var promptError = document.getElementById('prompt-error');
    45var aiResponseStyle = document.getElementById('ai-response-style');
     
    4748}
    4849
    49 
     50// read Model_Token_field
     51function 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}
    5076
    5177// read field_tags
  • ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-app-preview.php

    r3250856 r3272415  
    11<?php
     2
     3use JetBrains\PhpStorm\NoReturn;
     4
    25if (! class_exists('AI_APP_ONSITE_App_Preview_Handler')) {
    36    class AI_APP_ONSITE_App_Preview_Handler
    47    {
    5         private $appProperty;
     8        private array $appProperty;
    69
    710        public function __construct()
     
    1114            $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties';
    1215            $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            }
    1320            $titleColors = json_decode($appropriates[0]['title_color'], true);
    1421            $fontColors = json_decode($appropriates[0]['font_color'], true);
    1522            $bgColors = json_decode($appropriates[0]['bg_color'], true);
    1623
     24
    1725            $title_color_selected = null;
    1826            $font_color_selected = null;
    1927            $bg_color_selected = null;
    2028
    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
    4456
    4557                $this->appProperty = [
     
    5870
    5971                ];
    60             }
    6172
    6273            // Hook the AJAX action to the appropriate method in this class
     
    7889            //TODO: Old Logic
    7990            //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            }
    8195            if ($appName !== "aiapp") {
    8296
     
    109123
    110124        // AJAX callback function
    111         public function ai_app_onsite_create_app_preview_form()
     125       public function ai_app_onsite_create_app_preview_form()
    112126        {
    113127            global $wpdb;
     
    136150            $app_logo_image_url = wp_get_attachment_url($app_logo);
    137151
    138             $form_width_size = isset($results[0]['app_width']) ? $results[0]['app_width'] : '70';
     152            $form_width_size = $results[0]['app_width'] ?? '70';
    139153
    140154
     
    153167                    <img src="' . $app_logo_image_url . '" alt="App Logo" style="width: 100%; height: auto;" />
    154168                </div>';
    155             } else {
    156                 // Show fallback text if URL is empty
    157                 // $formHTML .= '<div class="ai-app-image-wrap form-width" id="ai-app-openAi-app-logo"></div>';
    158169            }
    159170            //App Logo End
     
    235246
    236247        // 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 {
    239249            global $wpdb;
    240250            $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  
    11<?php
    2 if ( ! class_exists( 'AI_APP_ONSITE_App_Properties_Handler' ) ) {
    3     class AI_APP_ONSITE_App_Properties_Handler {
    4         public function __construct() {
     2if (! class_exists('AI_APP_ONSITE_App_Properties_Handler')) {
     3    class AI_APP_ONSITE_App_Properties_Handler
     4    {
     5        public function __construct()
     6        {
    57            // Hook the AJAX action to the appropriate method in this class
    6          
     8
    79            // 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        {
    2025
    2126
     
    2328            // Verify if the request came via AJAX
    2429            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')
    2934            ) {
    30                 wp_send_json_error( 'Unauthorized request' );
     35                wp_send_json_error('Unauthorized request');
    3136            }
    3237
    3338            // 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'])) : '';
    3844
    3945            // 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'])) : '';
    4147            $titleColorsJson = stripslashes($titleColorsJson);
    4248
    43             $fontColorsJson = isset( $_POST['fontColor'] ) ? sanitize_text_field( wp_unslash( $_POST['fontColor'] ) ) : '';
     49            $fontColorsJson = isset($_POST['fontColor']) ? sanitize_text_field(wp_unslash($_POST['fontColor'])) : '';
    4450            $fontColorsJson = stripslashes($fontColorsJson);
    4551
    46             $bgColorsJson = isset( $_POST['bgColor'] ) ? sanitize_text_field( wp_unslash( $_POST['bgColor'] ) ) : '';
     52            $bgColorsJson = isset($_POST['bgColor']) ? sanitize_text_field(wp_unslash($_POST['bgColor'])) : '';
    4753            $bgColorsJson = stripslashes($bgColorsJson);
    4854
     
    5056            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties';
    5157
    52             $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings" );
     58            $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings");
    5359
    5460            // 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'])) {
    5662                // 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'])) {
    6167                    $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) {
    7184                $wpdb->update(
    7285                    $table_name_settings,
    7386                    array(
    7487                        'app_name' => $app_name,
    75                         'app_logo' => $file_url,
     88                        'app_name_show' => $app_name_temp,
     89                        'app_logo' => $file_url,
    7690                        'app_description' => $app_description,
    7791                        'app_disclaimer' => $app_disclaimer,
     
    8094                        'font_color' => $fontColorsJson,
    8195                        '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')
    87101                );
    88102
     
    101115                        'app_id'   => 1,
    102116                        'app_name' => $app_name,
    103                         'app_logo' => $file_url,
     117                        'app_name_show' => $app_name_temp,
     118                        'app_logo' => $file_url,
    104119                        'app_description' => $app_description,
    105120                        'app_disclaimer' => $app_disclaimer,
     
    109124                        'bg_color' => $bgColorsJson
    110125                    ),
    111                     array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
     126                    array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
    112127                );
    113128
     
    122137        }
    123138
    124         public static function ai_app_onsite_get_app_properties() {
    125            
     139        public static function ai_app_onsite_get_app_properties()
     140        {
     141
    126142            global $wpdb;
    127143            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties';
     
    149165
    150166            $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 array
    155             $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;
    156172            } else {
    157173                $results[0]['appLogoImagePreview'] = 'No preview available'; // Handle cases where no URL is found
     
    163179        }
    164180
    165         function ai_app_onsite_handle_sitelogo_upload_callback(){
     181        function ai_app_onsite_handle_sitelogo_upload_callback()
     182        {
    166183            global $wpdb;
    167            
    168        
    169              // Verify nonce to ensure the request is valid
    170              if (
     184
     185
     186            // Verify nonce to ensure the request is valid
     187            if (
    171188                !isset($_POST['ai_app_onsite_app_properties_logo_field_nonce_field']) ||
    172189                !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_app_properties_logo_field_nonce_field'])), 'ai_app_onsite_app_properties_nonce')
     
    175192                return;
    176193            }
    177            
    178            
     194
     195
    179196            // 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'])) {
    184201                    // File uploaded successfully
    185202                    $file_path = $movefile['file']; // Local file path
    186203                    $file_url = $movefile['url'];   // File URL
    187                    
     204
    188205                    // Create attachment
    189                     $filetype = wp_check_filetype( $file_path, null );
     206                    $filetype = wp_check_filetype($file_path, null);
    190207                    $attachment = array(
    191208                        'post_mime_type' => $filetype['type'],
    192                         'post_title'     => sanitize_file_name( basename( $file_path ) ),
     209                        'post_title'     => sanitize_file_name(basename($file_path)),
    193210                        'post_content'   => '',
    194211                        'post_status'    => 'inherit'
    195212                    );
    196213
    197                     $attachment_id = wp_insert_attachment( $attachment, $file_path );
     214                    $attachment_id = wp_insert_attachment($attachment, $file_path);
    198215
    199216                    // Include the image handling functions
     
    201218
    202219                    // 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.');
    212227            }
    213228
    214229            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties';
    215230
    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) {
    218233
    219234                $wpdb->update(
    220                   $table_name_settings,
    221                   array(
     235                    $table_name_settings,
     236                    array(
    222237                        '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 successful
    230               if ($wpdb->last_error) {
    231                   wp_send_json_error('Error updating data: ' . $wpdb->last_error);
    232               } else {
    233                   // Return success message for update
    234                  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(
    235250                        'attachment_id' => $attachment_id,
    236251                        '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");
    259275            $file_url = $existing_settings->app_logo;
    260276            // 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        }
    278326    }
    279327
     
    285333    new AI_APP_ONSITE_App_Properties_Handler(); // Instantiate the class
    286334}
    287 
  • ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-model-settings.php

    r3250856 r3272415  
    4040
    4141            // 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'])) : '';
    4444            $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'])) : '';
    4848
    4949
     
    5858                    $table_name_settings,
    5959                    array(
    60                         'model' => $model,
     60                        'model'       => $model,
    6161                        'temperature' => $temperature,
    62                         'f_penalty' => $f_penalty,
    63                         'p_penalty' => $p_penalty,
    64                         'max_tokens' => $max_tokens,
    65                         'top_p' => $top_p
     62                        'f_penalty'   => $f_penalty,
     63                        'p_penalty'   => $p_penalty,
     64                        'max_tokens'  => $max_tokens,
     65                        'top_p'       => $top_p
    6666
    6767                    ),
     
    8484                    $table_name_settings,
    8585                    array(
    86                         'app_id'   => 1,
    87                         'model' => $model,
     86                        'app_id'      => 1,
     87                        'model'       => $model,
    8888                        'temperature' => $temperature,
    89                         'f_penalty' => $f_penalty,
    90                         'p_penalty' => $p_penalty,
    91                         'max_tokens' => $max_tokens,
    92                         'top_p' => $top_p
     89                        'f_penalty'   => $f_penalty,
     90                        'p_penalty'   => $p_penalty,
     91                        'max_tokens'  => $max_tokens,
     92                        'top_p'       => $top_p
    9393                    ),
    9494                    array('%d', '%s', '%d', '%d', '%d', '%d', '%d')
     
    188188            $openai_key = isset($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : '';
    189189            $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'])) : '';
    190192
    191193
     
    221223                    $table_name_settings,
    222224                    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,
    226229                        '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',
    231234                    ),
    232235                    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  
    88            add_action('wp_ajax_ai_app_onsite_get_field_tags', array($this, 'ai_app_onsite_get_field_tags'));
    99            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'));
    1013
    1114            add_action('wp_ajax_ai_app_onsite_save_prompt_editor', array($this, 'ai_app_onstie_save_prompt_editor_callback'));
     
    134137        }
    135138
    136         public static function ai_app_onsite_get_prompt_editor()
    137         {
     139        public static function ai_app_onsite_get_Model_Token_field()
     140        {
     141
    138142            global $wpdb;
    139             $table_name_settings = $wpdb->prefix . 'ai_app_onsite_prompt_editor';
     143            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_model_settings';
    140144
    141145            // Check if the table exists
     
    147151            $rows_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name_settings");
    148152            if ($rows_count == 0) {
    149 
    150153                $results = array('status' => '404',  'message' => 'No rows found in the table.');
    151154
     
    165168            exit;
    166169        }
     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        }
    167202    }
    168203
  • ai-app-onsite/tags/1.1.0/handler/ai-app-onsite-user-stats.php

    r3250856 r3272415  
    1111        }
    1212
    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        {
    1415            global $wpdb;
    1516
    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}";
    1919
    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);
    2221
    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);
    2525
    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                }
    2941
    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            }
    3749
    3850            // 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']) : '';
    4153            $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) : '';
    4355
    4456            // Insert new row
     
    4759                $table_name_stats,
    4860                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,
    5264                    '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')
    5870                ),
    5971                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  
    3535                    </h5>
    3636                </div>
    37                 <div class="ai-app-onsite-tab-content-box">
     37                <div class="ai-app-onsite-tab-content-box shadow-sm rounded">
    3838                    <!-- Tab navigation -->
    3939                    <h2 class="nav-tab-wrapper">
     
    7878                                <div class="assets-preview-icon-blue-icon"></div>
    7979                            </div>
    80                             App Preview
     80                            Style & Preview
    8181                        </a>
    8282                    </h2>
     
    204204                    );
    205205                    ?>
    206                     <div id="plugin-settings-content" class="tab-content">
     206                    <div id="plugin-settings-content" class="tab-content plugin-settings-tab-section">
    207207                        <?php echo wp_kses(AI_App_Onsite_Plugin_Settings::render_plugin_settings(), $allowed_html); ?>
    208208                    </div>
    209209
    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;">
    211211                        <?php
    212212                        echo wp_kses(AI_App_Onsite_App_Properties::render_app_properties(), $allowed_html);
     
    214214                    </div>
    215215
    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;">
    217217                        <?php echo wp_kses(AI_App_Onsite_Model_Settings::render_model_settings(), $allowed_html); ?>
    218218                    </div>
    219219
    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;">
    221221                        <?php echo wp_kses(AI_App_Onsite_Field_Selector::render_field_selector(), $allowed_html); ?>
    222222                    </div>
    223223
    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;">
    225225                        <?php
    226226                        //echo AI_App_Onsite_Prompt_Editor::render_prompt_editor();
     
    233233                            'textarea_rows' => 10,  // Number of rows for the editor.
    234234                            'teeny'         => false,  // Full TinyMCE editor.
     235                            'quicktags'     => false,  // Disable the Visual and Text tabs.
     236                            'menubar'          => false,
    235237                        );
    236238
     
    240242
    241243                        ?>
    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;">
    245282                        <?php echo wp_kses(AI_App_Onsite_App_Preview::render_app_preview_content(), $allowed_html); ?>
    246283                    </div>
    247284                </div>
    248285            </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>
    249355
    250356<?php
  • ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-app-preview.php

    r3250856 r3272415  
    1111            <div class="app-preview-content">
    1212                <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>
    1419                    <div>
    1520                        <div class="row" id="shortcode-box">
    1621                            <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>
    1823                                <div class="select-box-icon">
    1924                                    <span class="field-icon">
    2025                                        <div class="assets-shortcode-icon"></div>
    2126                                    </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>
    2636                                </div>
    2737                                <p class="neutral-black-fs-60 fs-regular-12 mb-0">Copy to add in Wordpress Classic Editor</p>
    2838                            </div>
    2939                            <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>
    3141                                <div class="select-box-icon">
    3242                                    <span class="field-icon">
    3343                                        <div class="assets-shortcode-icon"></div>
    3444                                    </span>
     45                                    <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly>
    3546                                    <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_gutenberg_block()">
    3647                                        <div class="assets-copy-icon"></div>
    3748                                    </span>
    38                                     <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly>
    3949                                </div>
    4050                                <p class="neutral-black-fs-60 fs-regular-12 mb-0">Name block to add in Gutenberg</p>
     
    4858
    4959                    <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>
    5365                        </div>
    5466                        <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  
    1414          <div class="form-group mb-20">
    1515            <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
    2335          </div>
    2436          <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>
    4072          </div>
    4173          <div class="form-group">
  • ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-db-handler.php

    r3250856 r3272415  
    6464                   app_name TEXT,
    6565                   app_logo TEXT,
     66                   app_name_show TEXT,
    6667                   app_disclaimer VARCHAR(300),
    6768                   app_description VARCHAR(1000),
  • ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-model-settings.php

    r3250856 r3272415  
    1414                    <?php wp_nonce_field('ai_app_onsite_model_settings_nonce', 'ai_app_onsite_model_settings_nonce_field'); ?>
    1515                    <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>
    1818                            <div class="select-box-icon mb-20">
    1919                                <span class="field-icon">
     
    2121                                </span>
    2222                                <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>
    2424                                    <option value="gpt-4o">Open AI - gpt-4o</option>
    2525                                    <option value="gpt-4-turbo">Open AI - gpt-4-turbo</option>
     
    2929                                    <option value="gpt-3.5-turbo">Open AI - gpt-3.5-turbo</option>
    3030                                </select>
    31 
     31                                <span id="model-help-text" class="text-danger"></span>
    3232                                <p id="model-error" class="fields-error"></p>
    3333                            </div>
    3434                        </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">
    3639                            <div class="form-group">
    37                                 <label class="fs-medium-14">Max Tokens</label>
     40                                <label class="fs-medium-14 font-semibold">Max Tokens</label>
    3841                                <div class="select-box-icon">
    3942                                    <span class="field-icon">
    4043                                        <div class="assets-token-icon"></div>
    4144                                    </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>
    4347                                </div>
    4448                            </div>
    4549                        </div>
    46                         <div class="col-lg-6">
     50                        <div class="col-lg-6 mb-20">
    4751                            <div class="form-group">
    48                                 <label class="fs-medium-14">Temperature</label>
     52                                <label class="fs-medium-14 font-semibold">Temperature</label>
    4953                                <div class="select-box-icon">
    5054                                    <span class="field-icon">
    5155                                        <div class="assets-temprature-icon"></div>
    5256                                    </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>
    5459                                </div>
    5560                            </div>
    5661                        </div>
    57                         <div class="col-lg-6">
     62                        <div class="col-lg-6 mb-20">
    5863                            <div class="form-group">
    59                                 <label class="fs-medium-14">Top P</label>
     64                                <label class="fs-medium-14 font-semibold">Top P</label>
    6065                                <div class="select-box-icon">
    6166                                    <span class="field-icon">
    6267                                        <div class="assets-temprature-icon"></div>
    6368                                    </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>
    6571                                </div>
    6672                            </div>
    6773                        </div>
    68                         <div class="col-lg-6">
     74                        <div class="col-lg-6 mb-20">
    6975                            <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>
    7177                                <div class="select-box-icon">
    7278                                    <span class="field-icon">
     
    7480                                    </span>
    7581                                    <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>
    7683                                </div>
    7784                            </div>
    7885                        </div>
    79                         <div class="col-lg-6">
     86                        <div class="col-lg-6 mb-20">
    8087                            <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>
    8289                                <div class="select-box-icon">
    8390                                    <span class="field-icon">
     
    8592                                    </span>
    8693                                    <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>
    8795                                </div>
    8896                            </div>
    8997                        </div>
    90                     </div>
     98            </div>
     99               
    91100                    <div class="divider-light"></div>
    92101                    <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="#">
    96105                                    <div class="assets-api-key-icon"></div>
    97106                                </span>
    98                                 <p class="mb-0 fs-medium-14 cursor-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">
    99108                                    API Key Management
    100109                                </p>
    101110
    102111                                <span class="mb-0">
    103                                     <p id="key-status"></p>
     112                                    <p id="key-status" class="mb-0 font-semibold fs-6"></p>
    104113                                </span>
    105114                            </div>
     
    129138                                <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>
    130139                                <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>
    132141                                    <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">
    134143                                            <div class="assets-copy-icon"></div>
    135144                                        </span>
     
    137146                                        <input type="hidden" name="openai-key-hidden" id="openai-key-hidden">
    138147                                    </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>
    141151                                    <p id="openai-key-error" class="fields-error"></p>
    142152                                </div>
    143                                 <p class="fs-regular-12 neutral-black-fs-60 mb-1 mt-2">Note: Your API key is stored 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>
    144154                                <div class="flex-row alignment-items-center mt-3 mb-3">
    145155                                    <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">
    148158                                                <div class="assets-delete-icon"></div>
    149159                                            </span> Remove API Key
     
    151161                                    </div>
    152162                                    <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>
    155165                                            <label class="switch">
    156166                                                <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  
    55    public static function render_plugin_settings()
    66    {
     7      $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/aiapponsite/ai-app-onsite.php');
     8      $version = $plugin_data['Version'];
    79      ob_start(); ?>
    810      <div class="form-wrapper">
     
    1012          <?php wp_nonce_field('ai_app_onsite_plugin_settings_nonce', 'ai_app_onsite_plugin_settings_nonce_field'); ?>
    1113          <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>
    1318            <div class="terms-form-group form-group mb-0">
    1419              <input type="checkbox" id="terms_of_service-old" onchange="uploadTermCondition(this)">
    1520              <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>
    1621            </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>
    1825            <p id="terms_of_service-error" class="ml-25 fields-error"></p>
    1926          </div>
    2027
    21           <div>
     28          <div class="mb-3">
    2229            <label for="app-selector" class="d-block fs-medium-14 mb-only-4">App/Project Selector
    2330              <span class="fs-regular-14">(Multiple Apps With Premium)</span></label>
     
    3138
    3239
    33           <div>
     40          <div class="mb-3">
    3441            <label for="email-notification" class="d-block fs-medium-14 mb-only-4">App Email (for form data passing)
    3542              <span class="fs-regular-14"></span></label>
     
    4249          </div>
    4350
    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">
    7552            <label class="d-block fs-medium-14 mb-only-4">Banned/blocked words (comma Separated)</label>
    7653            <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">
     
    8663
    8764          </div>
    88           <div class="form-group">
     65          <div class="form-group mb-3">
    8966            <label class="fs-medium-14">Upload Banned/Block CSV</label>
    9067            <div class="file-drop-area border ">
     
    11390      <div id="Plugin-settings-msg-container" class="message-container"></div>
    11491
    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 
    18492
    18593<?php
  • ai-app-onsite/tags/1.1.0/includes/class-ai-app-onsite-prompt-editor.php

    r3250856 r3272415  
    1313                    <?php wp_nonce_field('ai_app_onsite_prompt_editor_nonce', 'ai_app_onsite_prompt_editor_nonce_field'); ?>
    1414                    <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>
    1924
    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">
    2128                            <span class="field-icon">
    2229                                <div class="assets-font-color-icon"></div>
     
    2532                        </div>
    2633                        <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>
    2837                            <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
    3239                            <?php
    3340                            return ob_get_clean();
    3441                        }
     42
    3543                        public static function render_prompt_code_editor()
    3644                        {
    3745                            ob_start(); ?>
     46                                <div id="word-count" class="mt-2"> </div>
    3847                                <p id="prompt-error" class="fields-error"></p>
    3948                            </div>
    4049                        </div>
    41 
    42                         <div class="divider-light"></div>
    4350                        <div class="mt-3 mb-3">
    4451                            <div class="col-50">
  • ai-app-onsite/trunk/ai-app-onsite.php

    r3250856 r3272415  
    44 * Plugin Name: AI App Onsite
    55 * 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.0
     6 * Version: 1.1.0
    77 * Author: By AIappOnsite
    88 * Author URI: https://aiapponsite.com/
     
    6262
    6363if (!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
    112130        wp_localize_script(
    113             'admin-script', // Handle of the registered script
    114             'myPluginAjax', // Name of the JavaScript object
     131            'admin-script',
     132            'myPluginAjax',
    115133            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,
    120139            )
    121140        );
    122141
    123142
    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
    125148        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 Service
    128         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');
    130149    }
    131150
    132151    add_action('admin_enqueue_scripts', 'ai_app_onsite_enqueue_admin_script');
    133152}
     153
    134154
    135155
     
    154174function AI_APP_ONSITE_My_Form_Block_Assets()
    155175{
    156     // Enqueue block editor script with filemtime for versioning (cache-busting)
     176    // Enqueue block editor script with file time for versioning (cache-busting)
    157177    wp_enqueue_script(
    158178        'ai-app-onsite-form-block-editor',
     
    166186
    167187if (!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
    186230
    187231
     
    192236    {
    193237        global $wpdb; // Access the global $wpdb variable
     238
     239        add_option('ai_app_onsite_fresh_install', true);
     240
    194241        require_once AI_APP_ONSITE_PLUGIN_DIR . 'includes/class-ai-app-onsite-db-handler.php';
    195242        // Create an instance of the database handler class and pass $wpdb
     
    202249
    203250
     251
    204252if (! function_exists('ai_app_onsite_deactivate')) {
    205253    // 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    }
    207263}
    208264
     
    271327function ai_app_onsite_editor_callback()
    272328{
    273     // Check karein ki function exist karta hai ya nahi
    274329    if (function_exists('wp_editor')) {
    275330        $content = ''; // Default content
     
    290345    }
    291346}
     347
     348add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'ai_app_onsite_settings_link');
     349
     350function 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  
    11/* start loader css */
    22
    3 .loader {
     3.ai-app-form-wrap .loader {
    44  height: 80px;
    55  aspect-ratio: 1;
     
    77}
    88
    9 .loader:before,
    10 .loader:after {
     9.ai-app-form-wrap .loader:before,
     10.ai-app-form-wrap .loader:after {
    1111  content: "";
    12   --c: no-repeat linear-gradient(var(--purple) 0 0);
     12  --c: no-repeat linear-gradient(#635aff 0 0);
    1313  background: var(--c), var(--c);
    1414  background-size: 25% 50%;
     
    1616}
    1717
    18 .loader:after {
     18.ai-app-form-wrap .loader:after {
    1919  transform: scale(-1);
     20}
     21.ai-app-form-wrap .fields-error {
     22  color: red;
     23  font-size: 12px;
    2024}
    2125
     
    4044}
    4145
    42 #loader {
     46.ai-app-form-wrap #loader {
    4347  position: fixed;
    4448  height: 100%;
     
    5357}
    5458
    55 .message-container span,
     59.ai-app-form-wrap .message-container span,
    5660.modal-message-container span {
    5761  text-align: center;
     
    6367}
    6468
    65 .select-box-icon.right-icon input[type="text"]::placeholder {
     69.ai-app-form-wrap .select-box-icon.right-icon input[type="text"]::placeholder {
    6670  color: #818898 !important;
    6771}
     
    6973/* end loader css  */
    7074
    71 .select-box-icon .ai-app-onsite-openAi-app-shortcode {
     75.ai-app-form-wrap .select-box-icon .ai-app-onsite-openAi-app-shortcode {
    7276  padding-left: 38px !important;
    7377  padding-right: 38px !important;
     
    8690}
    8791
    88 .field-copy-icon {
     92.ai-app-form-wrap .field-copy-icon {
    8993  position: absolute;
    9094  top: 6px;
     
    100104  border-radius: 8px;
    101105  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;
    106108}
    107109
     
    258260  font-weight: 600;
    259261}
    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  
    1919  --neutral-black-10: #f8fafc;
    2020}
    21 
     21* {
     22  box-sizing: border-box;
     23}
    2224.bg-purple {
    2325  background-color: var(--purple) !important;
     
    9799
    98100.divider-light {
    99   height: 1px;
     101  height: 2.5px;
    100102  width: 100%;
    101103  background-color: var(--neutral-black-20);
     
    332334
    333335/* BEGIN::Modal styles */
    334 
    335 * {
    336   box-sizing: border-box;
    337 }
    338 
    339336.container {
    340337  max-width: 50vw;
     
    926923}
    927924
    928 .api-key-icon.select-box-icon p {
     925/* .api-key-icon.select-box-icon p {
    929926  padding-left: 36px;
    930927  padding-top: 8px;
    931 }
     928} */
    932929
    933930.api-key-icon.select-box-icon {
     
    15101507  font-weight: 400;
    15111508}
     1509.app-preview-content .app-preview-content__heading {
     1510  width: 40%;
     1511}
     1512.app-preview-content .app-preview-content__description{
     1513  width: 60%;
     1514}
    15121515
    15131516.fields-error {
     
    16681671
    16691672.assets-copy-icon {
    1670   width: 20px;
    1671   HEIGHT: 25PX;
     1673  width: 1.25rem;
     1674  height: 1.56rem;
    16721675  background-image: url('../media/copy-icon.png');
    16731676  background-repeat: no-repeat;
    16741677  background-size: inherit;
    16751678  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}
    16781726#key-remove-btn {
    16791727  display: flex;
     
    19501998  }
    19511999}
     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  
     1var removeLogoBtn = document.getElementById('remove-logo-btn');
     2var previewImage = document.getElementById('previewImage');
     3var fileUploadDiv = document.getElementById('file-upload-div');
     4
     5// === Save & Restore Tab using Cookie ===
     6
     7document.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
    137function handleTabClick(tabId) {
    2     // alert(tabId);
    338    event.preventDefault();
    439
     
    742    // Check if the clicked tab is already active
    843    if (tab.classList.contains('nav-tab-active')) {
    9         return; // Do nothing if the tab is already active
     44        return;
    1045    }
    1146
     
    2560    tab.classList.add('nav-tab-active');
    2661
    27     // Show corresponding tab content (if applicable)
     62    // Show corresponding tab content
    2863    var contentId = tabId.replace("tab", "content");
    2964    var content = document.getElementById(contentId);
     
    3267    }
    3368
    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
    3673    if (tabId === 'plugin-settings-tab') {
    3774        ai_app_onsite_get_plugin_settings();
     
    4380        ai_app_onsite_read_field_selector();
    4481    } else if (tabId === 'prompt-editor-tab') {
     82        ai_app_onsite_get_Model_Token_field();
    4583        ai_app_onsite_get_field_tags();
    4684        ai_app_onsite_get_prompt_editor();
     
    69107//End get plugin setting from db js
    70108
     109
     110function 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
    71140//upload file js
    72141function validateFile(input) {
     
    95164
    96165function uploadSiteLogo(file) {
     166    removeLogoBtn.style.display = 'block';
     167    fileUploadDiv.classList.add('col-md-8');
     168    fileUploadDiv.classList.remove('col-md-12');
    97169    var formData = new FormData();
    98170    formData.append('app-file', file);
     
    123195                            previewImage.style.width = '350px';
    124196                            previewImage.style.height = '160px';
     197                            previewImage.style.position = 'relative';
    125198                        }
    126199
  • ai-app-onsite/trunk/assets/js/ai-app-onsite-app-preview.js

    r3250856 r3272415  
    1717                response = JSON.parse(xhr.responseText);
    1818
    19 
    20                 if (response.status === '404') {
     19                console.log('response', response);
     20                if (response.status === '404' || response.status === '400') {
    2121                    console.log('message', response.message);
    2222                    formContainer.innerHTML = '<p>No form Field Found Please Create Form Field</p>';
     
    9898                // Handle error response
    9999                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;
    100106            }
    101107        }
     
    128134                if (xhr.status === 200) {
    129135
    130                     // console.log(xhr);
    131136                    // Handle the response from the server
    132137                    var response = JSON.parse(xhr.responseText);
    133 
    134138                    if (response.success) {
    135139                        // Show success AI result
  • ai-app-onsite/trunk/assets/js/ai-app-onsite-app-properties.js

    r3250856 r3272415  
    33    var xhr = new XMLHttpRequest();
    44
    5     xhr.onreadystatechange = function() {
     5    xhr.onreadystatechange = function () {
    66        if (xhr.readyState === 4) {
    77            if (xhr.status === 200) {
    8                var response = JSON.parse(xhr.responseText);
     8                var response = JSON.parse(xhr.responseText);
    99                // Check if status is 404 (Table does not exist or no rows found)
    1010                if (response.status === '404') {
     
    1212                    return;
    1313                }
    14                   // Accessing the first object in the array
     14                // Accessing the first object in the array
    1515                var firstObject = response[0];
    1616                console.log(firstObject, 'firstObject');
    17                  var app_logo = firstObject.appLogoImagePreview;
    18                   console.log(app_logo, 'app_logo');
    1917                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') {
    2224                    var previewImage = document.getElementById('previewImage');
    2325                    previewImage.style.backgroundImage = `url('${app_logo}')`;
     
    2830                    previewImage.style.width = '350px';
    2931                    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');
    3039                }
    3140
     
    3443                // Accessing properties of the first object
    3544                var app_name = firstObject.app_name;
    36              
     45                var app_name_show = firstObject.app_name_show;
     46
    3747                var app_disclaimer = firstObject.app_disclaimer;
    3848                var app_description = firstObject.app_description;
    3949                var submit_button_txt = firstObject.submit_button_txt;
    4050                //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
    5363
    5464                // 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
    5773                document.getElementById('app-disclaimer').value = app_disclaimer;
    5874                document.getElementById('app-description').value = app_description;
    5975                document.getElementById('submit-btn-txt').value = submit_button_txt;
    6076                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 input
    69                     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 labe
    72                           label.click();
    73                     } else {
    74                          var colorWithoutHash = selected_title_color.replace(/^#/, '');
    75                         label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels
    76                     }
    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 labe
    80                           label.click();
    81                     } else {
    82                          var colorWithoutHash = selected_font_colors.replace(/^#/, '');
    83                         label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels
    84                     }
    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 labe
    89                           label.click();
    90                     } else {
    91                          var colorWithoutHash = selected_bg_colors.replace(/^#/, '');
    92                         label.classList.remove(colorWithoutHash); // Remove the selected_color class from non-matching labels
    93                     }
    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);
    98114
    99115                // 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) {
    101117
    102118                    // Initialize the variableSets array
     
    105121                    // Check if title_color.title_color_selected exists
    106122                    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');
    108124                        // If title_color_selected exists, add it to variableSets
    109125                        variableSets.push({
     
    122138
    123139                    // Iterate over each object in the array
    124                     variableSets.forEach(function(variableSet) {
     140                    variableSets.forEach(function (variableSet) {
    125141                        // If the variable is an array, iterate over each object in the array
    126142                        if (Array.isArray(variableSet.variable)) {
    127                             variableSet.variable.forEach(function(colorObject) {
     143                            variableSet.variable.forEach(function (colorObject) {
    128144                                // Iterate over each key-value pair in the object
    129                                 Object.keys(colorObject).forEach(function(key) {
     145                                Object.keys(colorObject).forEach(function (key) {
    130146                                    // 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) {
    132148                                        return radio.value === colorObject[key];
    133149                                    });
     
    140156                            });
    141157                        } 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) {
    143159                                return radio.value === variableSet.variable;
    144160                            });
     
    159175
    160176                // 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
    164180
    165181                    // Initialize the variableSets array
     
    185201
    186202                    // Iterate over each object in the array
    187                     variableSets.forEach(function(variableSet) {
     203                    variableSets.forEach(function (variableSet) {
    188204                        // If the variable is an array, iterate over each object in the array
    189205                        if (Array.isArray(variableSet.variable)) {
    190                             variableSet.variable.forEach(function(colorObject) {
     206                            variableSet.variable.forEach(function (colorObject) {
    191207                                // Iterate over each key-value pair in the object
    192                                 Object.keys(colorObject).forEach(function(key) {
     208                                Object.keys(colorObject).forEach(function (key) {
    193209                                    // 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) {
    195211                                        return radio.value === colorObject[key];
    196212                                    });
     
    203219                            });
    204220                        } 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) {
    206222                                return radio.value === variableSet.variable;
    207223                            });
     
    222238
    223239                // 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) {
    225241
    226242                    // Initialize the variableSets array
     
    244260                    }
    245261
    246                    
     262
    247263                    // Iterate over each object in the array
    248                     variableSets.forEach(function(variableSet) {
     264                    variableSets.forEach(function (variableSet) {
    249265                        // If the variable is an array, iterate over each object in the array
    250266                        if (Array.isArray(variableSet.variable)) {
    251                             variableSet.variable.forEach(function(colorObject) {
     267                            variableSet.variable.forEach(function (colorObject) {
    252268                                // Iterate over each key-value pair in the object
    253                                 Object.keys(colorObject).forEach(function(key) {
     269                                Object.keys(colorObject).forEach(function (key) {
    254270                                    // 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) {
    256272                                        return radio.value === colorObject[key];
    257273                                    });
     
    264280                            });
    265281                        } 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) {
    267283                                return radio.value === variableSet.variable;
    268284                            });
     
    322338function ai_app_onsite_save_app_properties() {
    323339    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);
    325341    // Clear all previous error messages
    326     document.querySelectorAll('.fields-error').forEach(function(error) {
     342    document.querySelectorAll('.fields-error').forEach(function (error) {
    327343        error.textContent = '';
    328344    });
    329345
    330346    // Get form fields
    331     var appName = document.getElementById('app-name').value.trim(); 
     347    var appName = document.getElementById('app-name').value.trim();
    332348    var appDescription = document.getElementById('app-description').value.trim();
    333349    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
    336352    // Collect error messages
    337353    var errors = [];
     
    351367    // If there are errors, display them and return
    352368    if (errors.length > 0) {
    353         errors.forEach(function(error) {
     369        errors.forEach(function (error) {
    354370            // Find the corresponding error container and display the message
    355371            if (error === 'App Name is required.') {
     
    375391    // Create and send AJAX request
    376392    var xhr = new XMLHttpRequest();
    377     xhr.onreadystatechange = function() {
     393    xhr.onreadystatechange = function () {
    378394        if (xhr.readyState === 4) {
    379395            var messageContainer = document.getElementById('app-properties-msg-container');
    380             setTimeout(function() {
     396            setTimeout(function () {
    381397                loader.style.display = 'none';
    382398
     
    397413                }
    398414                // Hide message after 3 seconds
    399                 setTimeout(function() {
     415                setTimeout(function () {
    400416                    messageContainer.innerHTML = '';
    401417                }, 3000);
     
    412428    formData.append('action', 'ai_app_onsite_save_app_properties');
    413429    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);
    414431
    415432    // Check if file is selected
     
    423440    formData.append('app-disclaimer', document.getElementById("app-disclaimer") ? document.getElementById("app-disclaimer").value : '');
    424441    formData.append('submit-btn-txt', document.getElementById("submit-btn-txt") ? document.getElementById("submit-btn-txt").value : '');
    425    
     442
    426443    // Check if radio buttons are selected before accessing their value
    427444    //var titleColorRadio = document.querySelector('input[name="title-color"]:checked');
     
    429446    var titleColorRadios = document.querySelectorAll('input[type="radio"][name="title-color"]');
    430447    var titleColors = [];
    431    
    432     if(titleColorRadios){
    433         titleColorRadios.forEach(function(titleColorRadio) {
     448
     449    if (titleColorRadios) {
     450        titleColorRadios.forEach(function (titleColorRadio) {
    434451            if (titleColorRadio.checked) {
    435452                titleColors.push({ "title_color_selected": titleColorRadio.value });
     
    447464    var fontColorRadios = document.querySelectorAll('input[type="radio"][name="font-color"]');
    448465    var fontColor = [];
    449    
    450     if(fontColorRadios){
    451         fontColorRadios.forEach(function(fontColorRadio) {
     466
     467    if (fontColorRadios) {
     468        fontColorRadios.forEach(function (fontColorRadio) {
    452469            if (fontColorRadio.checked) {
    453470                fontColor.push({ "font_color_selected": fontColorRadio.value });
     
    464481    var bgColorRadios = document.querySelectorAll('input[type="radio"][name="bg-color"]');
    465482    var bgColor = [];
    466      bgColor
    467     if(bgColorRadios){
    468         bgColorRadios.forEach(function(bgColorRadio) {
     483    bgColor
     484    if (bgColorRadios) {
     485        bgColorRadios.forEach(function (bgColorRadio) {
    469486            if (bgColorRadio.checked) {
    470487                bgColor.push({ "bg_color_selected": bgColorRadio.value });
  • ai-app-onsite/trunk/assets/js/ai-app-onsite-model-settings.js

    r3250856 r3272415  
    4949                    // Handle the response from the server
    5050                    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 
    5851
    5952                    let temperatureSettings = {
     
    116109                // Handle success response
    117110                var response = JSON.parse(xhr.responseText);
     111                console.log(response, 'ai_app_onsite_get_model_settings');
    118112                if (response.status === '404') {
    119113                    var saveKpenapiKeyBtn = document.getElementById('save-openapi-key');
    120114                    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               
    130166
    131167                    return;
    132168                }
    133169
     170   
     171
    134172                // Accessing the first object in the array
    135173                var firstObject = response[0];
    136 
    137174                // 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;
    142179                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
    146184                if (key_status == 'false') {
    147                     document.getElementById('key-status').textContent = 'DISABLED';
     185                    document.getElementById('key-status').textContent = 'Disabled';
    148186                    var element = document.getElementById('key-status');
    149                     element.textContent = 'DISABLED';
     187                    element.textContent = 'Disabled';
    150188                    element.style.color = 'red';
     189                    document.getElementById("api-disable-btn").checked = false;
     190
    151191                } else {
    152192                    var element = document.getElementById('key-status');
    153                     element.textContent = 'ENABLED';
     193                    element.textContent = 'Enabled';
    154194                    element.style.color = 'Green';
     195                    document.getElementById("api-disable-btn").checked = true;
     196
    155197                }
    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');
    158200                var saveKpenapiKeyBtn = document.getElementById('save-openapi-key');
    159                 var apiDisableBtn = document.getElementById("api-disable-btn");
     201                var apiDisableBtn     = document.getElementById("api-disable-btn");
    160202
    161203                // Check if the value is null or empty
     
    172214                    openaiKey.value = maskAPIKey(openai_key);
    173215                    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                    }
    176229
    177230                }
     
    237290    var errors = [];
    238291    if (openaiKeyError === '' || openaiKeyHidden === '') {
    239         errors.push('API key is reqired.');
     292        errors.push('API key is required.');
    240293    }
    241294
     
    244297        errors.forEach(function (error) {
    245298            // Find the corresponding error container and display the message
    246             if (error === 'API key is reqired.') {
     299            if (error === 'API key is required.') {
    247300                document.getElementById('openai-key-error').textContent = error;
    248301            }
     
    261314    const api_status = document.getElementById("api-disable-btn") ? document.getElementById("api-disable-btn").checked : "";
    262315    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);
    264318    // Send the API key to the server using an AJAX request
    265319    fetch(myPluginAjax.ajaxurl, {
     
    269323        },
    270324        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,
    275330        })
    276331    })
     
    302357}
    303358
     359document.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
     366document.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});
    304411
    305412function ai_app_onsite_copy_openapi_key() {
    306413    var openai_key = document.getElementById('openai-key');
    307414    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
    308423    openai_key.value = openaiKeyHidden.value;
    309424
    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
    317449    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();
    320454}
    321455
     
    323457    document.getElementById('openai-key').value = "";
    324458    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;
    325472}
    326473
     
    329476    const api_Key = document.getElementById("openai-key");
    330477
    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;
    338479}
    339480
     
    358499                console.log(key_status, 'key_status');
    359500                if (key_status == 'false') {
    360                     console.log('sderfdfgfgfgfgfgf');
    361                     document.getElementById('key-status').textContent = 'DISABLED';
     501                    document.getElementById('key-status').textContent = 'Disabled';
    362502                    document.getElementById("api-disable-btn").checked = false;
    363                     document.getElementsByClassName('text-switch')[0].textContent = 'DISABLED';
     503                    document.getElementsByClassName('text-switch')[0].textContent = 'Disabled';
    364504                    document.getElementsByClassName('text-switch')[0].style.color = 'red';
    365505
     506                    console.log('Disabled');
     507
    366508                } else {
    367                     document.getElementById('key-status').textContent = 'ENABLED';
    368                     document.getElementsByClassName('text-switch')[0].textContent = 'ENABLED';
     509                    document.getElementById('key-status').textContent = 'Enabled';
     510                    document.getElementsByClassName('text-switch')[0].textContent = 'Enabled';
    369511                    document.getElementsByClassName('text-switch')[0].style.color = 'green';
    370512                    document.getElementById("api-disable-btn").checked = true;
     513
     514                    console.log('Enabled');
    371515                    // Get the value of the element with ID 'openai-key-hidden'
    372516                }
     
    407551// Function to initialize the modal with original API key value
    408552function 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');
    416559
    417560    if (inputElement.value) {
     561        // Clear error message
    418562        openaiKeyError.textContent = '';
     563
     564        // Update hidden input and mask the visible input
    419565        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
    429579document.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
    450596document.addEventListener('DOMContentLoaded', function () {
    451597    document.getElementById('model').addEventListener('change', function () {
     
    474620    });
    475621});
    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 
     622document.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    }
    487643});
     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  
    11// Function to setup terms of service modal
    22function 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");
    99  var termsOfServiceError = document.getElementById('terms_of_service-error');
    1010
     
    186186                  }
    187187
    188                   console.log(response[0]);
    189 
    190188                    // Accessing the first object in the array
    191189                    var firstObject = response[0];
    192190
    193191                    // 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;
    199197                    var bannedWordsCSV = firstObject.banned_words_csv;
    200                     var appName = firstObject.appName;
     198                    var appName        = firstObject.appName;
    201199                    const selectElement = document.getElementById('bannedWords');
    202200
     
    232230                    if (agreeTerms === "1") {
    233231                        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
    237235                        const modalElement = document.getElementById('terms_conditions_modal');
    238236                        const modalInstance = new bootstrap.Modal(modalElement);
    239237                        modalInstance.show();
    240 
    241238                    }
    242239               
     
    455452
    456453// 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// });
    460457
    461458//upload file js
  • ai-app-onsite/trunk/assets/js/ai-app-onsite-prompt-editor.js

    r3250856 r3272415  
    11var availableFields = document.getElementById("available-fields");
    22var promptInput = document.getElementById('prompt');
     3var promptMaxTokenValue = document.getElementById('prompt-max-token-value');
    34var promptError = document.getElementById('prompt-error');
    45var aiResponseStyle = document.getElementById('ai-response-style');
     
    4748}
    4849
    49 
     50// read Model_Token_field
     51function 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}
    5076
    5177// read field_tags
  • ai-app-onsite/trunk/handler/ai-app-onsite-app-preview.php

    r3250856 r3272415  
    11<?php
     2
     3use JetBrains\PhpStorm\NoReturn;
     4
    25if (! class_exists('AI_APP_ONSITE_App_Preview_Handler')) {
    36    class AI_APP_ONSITE_App_Preview_Handler
    47    {
    5         private $appProperty;
     8        private array $appProperty;
    69
    710        public function __construct()
     
    1114            $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties';
    1215            $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            }
    1320            $titleColors = json_decode($appropriates[0]['title_color'], true);
    1421            $fontColors = json_decode($appropriates[0]['font_color'], true);
    1522            $bgColors = json_decode($appropriates[0]['bg_color'], true);
    1623
     24
    1725            $title_color_selected = null;
    1826            $font_color_selected = null;
    1927            $bg_color_selected = null;
    2028
    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
    4456
    4557                $this->appProperty = [
     
    5870
    5971                ];
    60             }
    6172
    6273            // Hook the AJAX action to the appropriate method in this class
     
    7889            //TODO: Old Logic
    7990            //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            }
    8195            if ($appName !== "aiapp") {
    8296
     
    109123
    110124        // AJAX callback function
    111         public function ai_app_onsite_create_app_preview_form()
     125       public function ai_app_onsite_create_app_preview_form()
    112126        {
    113127            global $wpdb;
     
    136150            $app_logo_image_url = wp_get_attachment_url($app_logo);
    137151
    138             $form_width_size = isset($results[0]['app_width']) ? $results[0]['app_width'] : '70';
     152            $form_width_size = $results[0]['app_width'] ?? '70';
    139153
    140154
     
    153167                    <img src="' . $app_logo_image_url . '" alt="App Logo" style="width: 100%; height: auto;" />
    154168                </div>';
    155             } else {
    156                 // Show fallback text if URL is empty
    157                 // $formHTML .= '<div class="ai-app-image-wrap form-width" id="ai-app-openAi-app-logo"></div>';
    158169            }
    159170            //App Logo End
     
    235246
    236247        // 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 {
    239249            global $wpdb;
    240250            $table_appropriate = $wpdb->prefix . 'ai_app_onsite_app_properties';
  • ai-app-onsite/trunk/handler/ai-app-onsite-app-properties.php

    r3250856 r3272415  
    11<?php
    2 if ( ! class_exists( 'AI_APP_ONSITE_App_Properties_Handler' ) ) {
    3     class AI_APP_ONSITE_App_Properties_Handler {
    4         public function __construct() {
     2if (! class_exists('AI_APP_ONSITE_App_Properties_Handler')) {
     3    class AI_APP_ONSITE_App_Properties_Handler
     4    {
     5        public function __construct()
     6        {
    57            // Hook the AJAX action to the appropriate method in this class
    6          
     8
    79            // 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        {
    2025
    2126
     
    2328            // Verify if the request came via AJAX
    2429            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')
    2934            ) {
    30                 wp_send_json_error( 'Unauthorized request' );
     35                wp_send_json_error('Unauthorized request');
    3136            }
    3237
    3338            // 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'])) : '';
    3844
    3945            // 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'])) : '';
    4147            $titleColorsJson = stripslashes($titleColorsJson);
    4248
    43             $fontColorsJson = isset( $_POST['fontColor'] ) ? sanitize_text_field( wp_unslash( $_POST['fontColor'] ) ) : '';
     49            $fontColorsJson = isset($_POST['fontColor']) ? sanitize_text_field(wp_unslash($_POST['fontColor'])) : '';
    4450            $fontColorsJson = stripslashes($fontColorsJson);
    4551
    46             $bgColorsJson = isset( $_POST['bgColor'] ) ? sanitize_text_field( wp_unslash( $_POST['bgColor'] ) ) : '';
     52            $bgColorsJson = isset($_POST['bgColor']) ? sanitize_text_field(wp_unslash($_POST['bgColor'])) : '';
    4753            $bgColorsJson = stripslashes($bgColorsJson);
    4854
     
    5056            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties';
    5157
    52             $existing_settings = $wpdb->get_row( "SELECT * FROM $table_name_settings" );
     58            $existing_settings = $wpdb->get_row("SELECT * FROM $table_name_settings");
    5359
    5460            // 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'])) {
    5662                // 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'])) {
    6167                    $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) {
    7184                $wpdb->update(
    7285                    $table_name_settings,
    7386                    array(
    7487                        'app_name' => $app_name,
    75                         'app_logo' => $file_url,
     88                        'app_name_show' => $app_name_temp,
     89                        'app_logo' => $file_url,
    7690                        'app_description' => $app_description,
    7791                        'app_disclaimer' => $app_disclaimer,
     
    8094                        'font_color' => $fontColorsJson,
    8195                        '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')
    87101                );
    88102
     
    101115                        'app_id'   => 1,
    102116                        'app_name' => $app_name,
    103                         'app_logo' => $file_url,
     117                        'app_name_show' => $app_name_temp,
     118                        'app_logo' => $file_url,
    104119                        'app_description' => $app_description,
    105120                        'app_disclaimer' => $app_disclaimer,
     
    109124                        'bg_color' => $bgColorsJson
    110125                    ),
    111                     array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
     126                    array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
    112127                );
    113128
     
    122137        }
    123138
    124         public static function ai_app_onsite_get_app_properties() {
    125            
     139        public static function ai_app_onsite_get_app_properties()
     140        {
     141
    126142            global $wpdb;
    127143            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties';
     
    149165
    150166            $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 array
    155             $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;
    156172            } else {
    157173                $results[0]['appLogoImagePreview'] = 'No preview available'; // Handle cases where no URL is found
     
    163179        }
    164180
    165         function ai_app_onsite_handle_sitelogo_upload_callback(){
     181        function ai_app_onsite_handle_sitelogo_upload_callback()
     182        {
    166183            global $wpdb;
    167            
    168        
    169              // Verify nonce to ensure the request is valid
    170              if (
     184
     185
     186            // Verify nonce to ensure the request is valid
     187            if (
    171188                !isset($_POST['ai_app_onsite_app_properties_logo_field_nonce_field']) ||
    172189                !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_app_properties_logo_field_nonce_field'])), 'ai_app_onsite_app_properties_nonce')
     
    175192                return;
    176193            }
    177            
    178            
     194
     195
    179196            // 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'])) {
    184201                    // File uploaded successfully
    185202                    $file_path = $movefile['file']; // Local file path
    186203                    $file_url = $movefile['url'];   // File URL
    187                    
     204
    188205                    // Create attachment
    189                     $filetype = wp_check_filetype( $file_path, null );
     206                    $filetype = wp_check_filetype($file_path, null);
    190207                    $attachment = array(
    191208                        'post_mime_type' => $filetype['type'],
    192                         'post_title'     => sanitize_file_name( basename( $file_path ) ),
     209                        'post_title'     => sanitize_file_name(basename($file_path)),
    193210                        'post_content'   => '',
    194211                        'post_status'    => 'inherit'
    195212                    );
    196213
    197                     $attachment_id = wp_insert_attachment( $attachment, $file_path );
     214                    $attachment_id = wp_insert_attachment($attachment, $file_path);
    198215
    199216                    // Include the image handling functions
     
    201218
    202219                    // 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.');
    212227            }
    213228
    214229            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_app_properties';
    215230
    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) {
    218233
    219234                $wpdb->update(
    220                   $table_name_settings,
    221                   array(
     235                    $table_name_settings,
     236                    array(
    222237                        '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 successful
    230               if ($wpdb->last_error) {
    231                   wp_send_json_error('Error updating data: ' . $wpdb->last_error);
    232               } else {
    233                   // Return success message for update
    234                  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(
    235250                        'attachment_id' => $attachment_id,
    236251                        '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");
    259275            $file_url = $existing_settings->app_logo;
    260276            // 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        }
    278326    }
    279327
     
    285333    new AI_APP_ONSITE_App_Properties_Handler(); // Instantiate the class
    286334}
    287 
  • ai-app-onsite/trunk/handler/ai-app-onsite-model-settings.php

    r3250856 r3272415  
    4040
    4141            // 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'])) : '';
    4444            $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'])) : '';
    4848
    4949
     
    5858                    $table_name_settings,
    5959                    array(
    60                         'model' => $model,
     60                        'model'       => $model,
    6161                        'temperature' => $temperature,
    62                         'f_penalty' => $f_penalty,
    63                         'p_penalty' => $p_penalty,
    64                         'max_tokens' => $max_tokens,
    65                         'top_p' => $top_p
     62                        'f_penalty'   => $f_penalty,
     63                        'p_penalty'   => $p_penalty,
     64                        'max_tokens'  => $max_tokens,
     65                        'top_p'       => $top_p
    6666
    6767                    ),
     
    8484                    $table_name_settings,
    8585                    array(
    86                         'app_id'   => 1,
    87                         'model' => $model,
     86                        'app_id'      => 1,
     87                        'model'       => $model,
    8888                        'temperature' => $temperature,
    89                         'f_penalty' => $f_penalty,
    90                         'p_penalty' => $p_penalty,
    91                         'max_tokens' => $max_tokens,
    92                         'top_p' => $top_p
     89                        'f_penalty'   => $f_penalty,
     90                        'p_penalty'   => $p_penalty,
     91                        'max_tokens'  => $max_tokens,
     92                        'top_p'       => $top_p
    9393                    ),
    9494                    array('%d', '%s', '%d', '%d', '%d', '%d', '%d')
     
    188188            $openai_key = isset($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : '';
    189189            $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'])) : '';
    190192
    191193
     
    221223                    $table_name_settings,
    222224                    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,
    226229                        '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',
    231234                    ),
    232235                    array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
  • ai-app-onsite/trunk/handler/ai-app-onsite-prompt-editor.php

    r3250856 r3272415  
    88            add_action('wp_ajax_ai_app_onsite_get_field_tags', array($this, 'ai_app_onsite_get_field_tags'));
    99            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'));
    1013
    1114            add_action('wp_ajax_ai_app_onsite_save_prompt_editor', array($this, 'ai_app_onstie_save_prompt_editor_callback'));
     
    134137        }
    135138
    136         public static function ai_app_onsite_get_prompt_editor()
    137         {
     139        public static function ai_app_onsite_get_Model_Token_field()
     140        {
     141
    138142            global $wpdb;
    139             $table_name_settings = $wpdb->prefix . 'ai_app_onsite_prompt_editor';
     143            $table_name_settings = $wpdb->prefix . 'ai_app_onsite_model_settings';
    140144
    141145            // Check if the table exists
     
    147151            $rows_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name_settings");
    148152            if ($rows_count == 0) {
    149 
    150153                $results = array('status' => '404',  'message' => 'No rows found in the table.');
    151154
     
    165168            exit;
    166169        }
     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        }
    167202    }
    168203
  • ai-app-onsite/trunk/handler/ai-app-onsite-user-stats.php

    r3250856 r3272415  
    1111        }
    1212
    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        {
    1415            global $wpdb;
    1516
    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}";
    1919
    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);
    2221
    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);
    2525
    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                }
    2941
    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            }
    3749
    3850            // 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']) : '';
    4153            $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) : '';
    4355
    4456            // Insert new row
     
    4759                $table_name_stats,
    4860                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,
    5264                    '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')
    5870                ),
    5971                array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
  • ai-app-onsite/trunk/includes/class-ai-app-onsite-admin.php

    r3250856 r3272415  
    3535                    </h5>
    3636                </div>
    37                 <div class="ai-app-onsite-tab-content-box">
     37                <div class="ai-app-onsite-tab-content-box shadow-sm rounded">
    3838                    <!-- Tab navigation -->
    3939                    <h2 class="nav-tab-wrapper">
     
    7878                                <div class="assets-preview-icon-blue-icon"></div>
    7979                            </div>
    80                             App Preview
     80                            Style & Preview
    8181                        </a>
    8282                    </h2>
     
    204204                    );
    205205                    ?>
    206                     <div id="plugin-settings-content" class="tab-content">
     206                    <div id="plugin-settings-content" class="tab-content plugin-settings-tab-section">
    207207                        <?php echo wp_kses(AI_App_Onsite_Plugin_Settings::render_plugin_settings(), $allowed_html); ?>
    208208                    </div>
    209209
    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;">
    211211                        <?php
    212212                        echo wp_kses(AI_App_Onsite_App_Properties::render_app_properties(), $allowed_html);
     
    214214                    </div>
    215215
    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;">
    217217                        <?php echo wp_kses(AI_App_Onsite_Model_Settings::render_model_settings(), $allowed_html); ?>
    218218                    </div>
    219219
    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;">
    221221                        <?php echo wp_kses(AI_App_Onsite_Field_Selector::render_field_selector(), $allowed_html); ?>
    222222                    </div>
    223223
    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;">
    225225                        <?php
    226226                        //echo AI_App_Onsite_Prompt_Editor::render_prompt_editor();
     
    233233                            'textarea_rows' => 10,  // Number of rows for the editor.
    234234                            'teeny'         => false,  // Full TinyMCE editor.
     235                            'quicktags'     => false,  // Disable the Visual and Text tabs.
     236                            'menubar'          => false,
    235237                        );
    236238
     
    240242
    241243                        ?>
    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;">
    245282                        <?php echo wp_kses(AI_App_Onsite_App_Preview::render_app_preview_content(), $allowed_html); ?>
    246283                    </div>
    247284                </div>
    248285            </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>
    249355
    250356<?php
  • ai-app-onsite/trunk/includes/class-ai-app-onsite-app-preview.php

    r3250856 r3272415  
    1111            <div class="app-preview-content">
    1212                <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>
    1419                    <div>
    1520                        <div class="row" id="shortcode-box">
    1621                            <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>
    1823                                <div class="select-box-icon">
    1924                                    <span class="field-icon">
    2025                                        <div class="assets-shortcode-icon"></div>
    2126                                    </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>
    2636                                </div>
    2737                                <p class="neutral-black-fs-60 fs-regular-12 mb-0">Copy to add in Wordpress Classic Editor</p>
    2838                            </div>
    2939                            <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>
    3141                                <div class="select-box-icon">
    3242                                    <span class="field-icon">
    3343                                        <div class="assets-shortcode-icon"></div>
    3444                                    </span>
     45                                    <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly>
    3546                                    <span class="field-copy-icon" onclick="ai_app_onsite_openAi_app_gutenberg_block()">
    3647                                        <div class="assets-copy-icon"></div>
    3748                                    </span>
    38                                     <input type="text" id="openAi-app-gutenberg-block" class="openAi-app-gutenberg-block" data-target="#openAi-app-gutenberg-block" readonly>
    3949                                </div>
    4050                                <p class="neutral-black-fs-60 fs-regular-12 mb-0">Name block to add in Gutenberg</p>
     
    4858
    4959                    <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>
    5365                        </div>
    5466                        <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  
    1414          <div class="form-group mb-20">
    1515            <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
    2335          </div>
    2436          <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>
    4072          </div>
    4173          <div class="form-group">
  • ai-app-onsite/trunk/includes/class-ai-app-onsite-db-handler.php

    r3250856 r3272415  
    6464                   app_name TEXT,
    6565                   app_logo TEXT,
     66                   app_name_show TEXT,
    6667                   app_disclaimer VARCHAR(300),
    6768                   app_description VARCHAR(1000),
  • ai-app-onsite/trunk/includes/class-ai-app-onsite-model-settings.php

    r3250856 r3272415  
    1414                    <?php wp_nonce_field('ai_app_onsite_model_settings_nonce', 'ai_app_onsite_model_settings_nonce_field'); ?>
    1515                    <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>
    1818                            <div class="select-box-icon mb-20">
    1919                                <span class="field-icon">
     
    2121                                </span>
    2222                                <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>
    2424                                    <option value="gpt-4o">Open AI - gpt-4o</option>
    2525                                    <option value="gpt-4-turbo">Open AI - gpt-4-turbo</option>
     
    2929                                    <option value="gpt-3.5-turbo">Open AI - gpt-3.5-turbo</option>
    3030                                </select>
    31 
     31                                <span id="model-help-text" class="text-danger"></span>
    3232                                <p id="model-error" class="fields-error"></p>
    3333                            </div>
    3434                        </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">
    3639                            <div class="form-group">
    37                                 <label class="fs-medium-14">Max Tokens</label>
     40                                <label class="fs-medium-14 font-semibold">Max Tokens</label>
    3841                                <div class="select-box-icon">
    3942                                    <span class="field-icon">
    4043                                        <div class="assets-token-icon"></div>
    4144                                    </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>
    4347                                </div>
    4448                            </div>
    4549                        </div>
    46                         <div class="col-lg-6">
     50                        <div class="col-lg-6 mb-20">
    4751                            <div class="form-group">
    48                                 <label class="fs-medium-14">Temperature</label>
     52                                <label class="fs-medium-14 font-semibold">Temperature</label>
    4953                                <div class="select-box-icon">
    5054                                    <span class="field-icon">
    5155                                        <div class="assets-temprature-icon"></div>
    5256                                    </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>
    5459                                </div>
    5560                            </div>
    5661                        </div>
    57                         <div class="col-lg-6">
     62                        <div class="col-lg-6 mb-20">
    5863                            <div class="form-group">
    59                                 <label class="fs-medium-14">Top P</label>
     64                                <label class="fs-medium-14 font-semibold">Top P</label>
    6065                                <div class="select-box-icon">
    6166                                    <span class="field-icon">
    6267                                        <div class="assets-temprature-icon"></div>
    6368                                    </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>
    6571                                </div>
    6672                            </div>
    6773                        </div>
    68                         <div class="col-lg-6">
     74                        <div class="col-lg-6 mb-20">
    6975                            <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>
    7177                                <div class="select-box-icon">
    7278                                    <span class="field-icon">
     
    7480                                    </span>
    7581                                    <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>
    7683                                </div>
    7784                            </div>
    7885                        </div>
    79                         <div class="col-lg-6">
     86                        <div class="col-lg-6 mb-20">
    8087                            <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>
    8289                                <div class="select-box-icon">
    8390                                    <span class="field-icon">
     
    8592                                    </span>
    8693                                    <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>
    8795                                </div>
    8896                            </div>
    8997                        </div>
    90                     </div>
     98            </div>
     99               
    91100                    <div class="divider-light"></div>
    92101                    <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="#">
    96105                                    <div class="assets-api-key-icon"></div>
    97106                                </span>
    98                                 <p class="mb-0 fs-medium-14 cursor-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">
    99108                                    API Key Management
    100109                                </p>
    101110
    102111                                <span class="mb-0">
    103                                     <p id="key-status"></p>
     112                                    <p id="key-status" class="mb-0 font-semibold fs-6"></p>
    104113                                </span>
    105114                            </div>
     
    129138                                <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>
    130139                                <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>
    132141                                    <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">
    134143                                            <div class="assets-copy-icon"></div>
    135144                                        </span>
     
    137146                                        <input type="hidden" name="openai-key-hidden" id="openai-key-hidden">
    138147                                    </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>
    141151                                    <p id="openai-key-error" class="fields-error"></p>
    142152                                </div>
    143                                 <p class="fs-regular-12 neutral-black-fs-60 mb-1 mt-2">Note: Your API key is stored 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>
    144154                                <div class="flex-row alignment-items-center mt-3 mb-3">
    145155                                    <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">
    148158                                                <div class="assets-delete-icon"></div>
    149159                                            </span> Remove API Key
     
    151161                                    </div>
    152162                                    <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>
    155165                                            <label class="switch">
    156166                                                <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  
    55    public static function render_plugin_settings()
    66    {
     7      $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/aiapponsite/ai-app-onsite.php');
     8      $version = $plugin_data['Version'];
    79      ob_start(); ?>
    810      <div class="form-wrapper">
     
    1012          <?php wp_nonce_field('ai_app_onsite_plugin_settings_nonce', 'ai_app_onsite_plugin_settings_nonce_field'); ?>
    1113          <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>
    1318            <div class="terms-form-group form-group mb-0">
    1419              <input type="checkbox" id="terms_of_service-old" onchange="uploadTermCondition(this)">
    1520              <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>
    1621            </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>
    1825            <p id="terms_of_service-error" class="ml-25 fields-error"></p>
    1926          </div>
    2027
    21           <div>
     28          <div class="mb-3">
    2229            <label for="app-selector" class="d-block fs-medium-14 mb-only-4">App/Project Selector
    2330              <span class="fs-regular-14">(Multiple Apps With Premium)</span></label>
     
    3138
    3239
    33           <div>
     40          <div class="mb-3">
    3441            <label for="email-notification" class="d-block fs-medium-14 mb-only-4">App Email (for form data passing)
    3542              <span class="fs-regular-14"></span></label>
     
    4249          </div>
    4350
    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">
    7552            <label class="d-block fs-medium-14 mb-only-4">Banned/blocked words (comma Separated)</label>
    7653            <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">
     
    8663
    8764          </div>
    88           <div class="form-group">
     65          <div class="form-group mb-3">
    8966            <label class="fs-medium-14">Upload Banned/Block CSV</label>
    9067            <div class="file-drop-area border ">
     
    11390      <div id="Plugin-settings-msg-container" class="message-container"></div>
    11491
    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 
    18492
    18593<?php
  • ai-app-onsite/trunk/includes/class-ai-app-onsite-prompt-editor.php

    r3250856 r3272415  
    1313                    <?php wp_nonce_field('ai_app_onsite_prompt_editor_nonce', 'ai_app_onsite_prompt_editor_nonce_field'); ?>
    1414                    <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>
    1924
    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">
    2128                            <span class="field-icon">
    2229                                <div class="assets-font-color-icon"></div>
     
    2532                        </div>
    2633                        <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>
    2837                            <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
    3239                            <?php
    3340                            return ob_get_clean();
    3441                        }
     42
    3543                        public static function render_prompt_code_editor()
    3644                        {
    3745                            ob_start(); ?>
     46                                <div id="word-count" class="mt-2"> </div>
    3847                                <p id="prompt-error" class="fields-error"></p>
    3948                            </div>
    4049                        </div>
    41 
    42                         <div class="divider-light"></div>
    4350                        <div class="mt-3 mb-3">
    4451                            <div class="col-50">
Note: See TracChangeset for help on using the changeset viewer.