Plugin Directory

Changeset 3475631


Ignore:
Timestamp:
03/05/2026 12:29:18 PM (4 weeks ago)
Author:
adsimple
Message:

Release 1.1.3 - Fix single-category FAQ widget filter bar

Location:
chatreact
Files:
18 edited
1 copied

Legend:

Unmodified
Added
Removed
  • chatreact/tags/1.1.3/admin/class-admin.php

    r3472173 r3475631  
    319319               
    320320                // Found an "Everywhere" assignment - render the widget on all pages
    321                 ChatReact::render_chat_widget( $assignment['chatbot_id'] );
     321                ChatReact::render_chat_widget( $assignment['chatbot_id'], array(
     322                    'language' => ChatReact::get_current_language(),
     323                ) );
    322324                return; // "Everywhere" takes precedence
    323325            }
     
    332334            if ( isset( $assignment['post_id'] ) && $assignment['post_id'] === $current_post_id ) {
    333335                // Found a matching assignment - render the widget
    334                 ChatReact::render_chat_widget( $assignment['chatbot_id'] );
     336                ChatReact::render_chat_widget( $assignment['chatbot_id'], array(
     337                    'language' => ChatReact::get_current_language(),
     338                ) );
    335339                break; // Only one widget per page
    336340            }
  • chatreact/tags/1.1.3/blocks/chat-widget/block.json

    r3468481 r3475631  
    1414            "type": "string",
    1515            "default": ""
     16        },
     17        "language": {
     18            "type": "string",
     19            "default": ""
    1620        }
    1721    },
  • chatreact/tags/1.1.3/chatreact.php

    r3472173 r3475631  
    44 * Plugin URI:        https://www.chatreact.ai/docs/de/wordpress
    55 * Description:       Embed AI-powered chat widgets, contact forms, and FAQ accordions on your WordPress site.
    6  * Version:           1.1.2
     6 * Version:           1.1.3
    77 * Requires at least: 5.8
    88 * Requires PHP:      7.4
     
    2121
    2222// Plugin constants
    23 define( 'CHATREACT_VERSION', '1.1.2' );
     23define( 'CHATREACT_VERSION', '1.1.3' );
    2424define( 'CHATREACT_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2525define( 'CHATREACT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
  • chatreact/tags/1.1.3/elementor/widgets/class-chat-widget.php

    r3468481 r3475631  
    8383        );
    8484
     85        $this->add_control(
     86            'language',
     87            array(
     88                'label'       => __( 'Language', 'chatreact' ),
     89                'type'        => \Elementor\Controls_Manager::TEXT,
     90                'placeholder' => __( 'e.g. de, fr, en', 'chatreact' ),
     91                'description' => __( 'Optional. 2-letter language code (e.g. "de", "fr"). Leave empty to auto-detect from the current page language.', 'chatreact' ),
     92            )
     93        );
     94
    8595        $this->end_controls_section();
    8696    }
     
    101111        }
    102112
    103         ChatReact::render_chat_widget( sanitize_text_field( $settings['chatbot_id'] ) );
     113        ChatReact::render_chat_widget(
     114            sanitize_text_field( $settings['chatbot_id'] ),
     115            array(
     116                'language' => sanitize_text_field( isset( $settings['language'] ) ? $settings['language'] : '' ),
     117            )
     118        );
    104119    }
    105120
  • chatreact/tags/1.1.3/includes/class-blocks.php

    r3468481 r3475631  
    127127        }
    128128
    129         return ChatReact::render_chat_widget( $chatbot_id );
     129        return ChatReact::render_chat_widget(
     130            $chatbot_id,
     131            array(
     132                'language' => isset( $attributes['language'] ) ? $attributes['language'] : '',
     133            )
     134        );
    130135    }
    131136
  • chatreact/tags/1.1.3/includes/class-chatreact.php

    r3472173 r3475631  
    382382     * @return string <style> block.
    383383     */
     384    private static function get_readable_badge_colors( $primary_hex ) {
     385        $hex = ltrim( $primary_hex, '#' );
     386        if ( strlen( $hex ) === 3 ) {
     387            $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
     388        }
     389        $r = hexdec( substr( $hex, 0, 2 ) );
     390        $g = hexdec( substr( $hex, 2, 2 ) );
     391        $b = hexdec( substr( $hex, 4, 2 ) );
     392        $luminance = ( 0.299 * $r + 0.587 * $g + 0.114 * $b ) / 255;
     393
     394        if ( $luminance > 0.6 ) {
     395            $dark_r = (int) round( $r * 0.35 );
     396            $dark_g = (int) round( $g * 0.35 );
     397            $dark_b = (int) round( $b * 0.35 );
     398            return array(
     399                'text' => sprintf( '#%02x%02x%02x', $dark_r, $dark_g, $dark_b ),
     400                'bg'   => $primary_hex . '30',
     401            );
     402        }
     403
     404        return array(
     405            'text' => $primary_hex,
     406            'bg'   => $primary_hex . '20',
     407        );
     408    }
     409
    384410    private static function get_ssr_faq_styles( $primary, $text, $bg, $border, $radius ) {
    385411        $primary_15 = $primary . '15';
    386         $primary_bg = $primary . '20';
     412        $badge      = self::get_readable_badge_colors( $primary );
     413        $badge_text = $badge['text'];
     414        $badge_bg   = $badge['bg'];
     415        $active_text = ( $badge_text === $primary ) ? '#ffffff' : $badge_text;
    387416
    388417        return '<style>
     
    391420.cr-faq-categories{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.5rem;justify-content:center}
    392421.cr-faq-category-btn{font-family:inherit;padding:.5rem 1rem;border-radius:' . intval( $radius / 2 ) . 'px;border:1px solid ' . esc_attr( $border ) . ';background:' . esc_attr( $bg ) . ';color:' . esc_attr( $text ) . ';font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}
    393 .cr-faq-category-btn:hover{border-color:' . esc_attr( $primary ) . '}
    394 .cr-faq-category-btn.active{background:' . esc_attr( $primary ) . ';border-color:' . esc_attr( $primary ) . ';color:#fff}
     422.cr-faq-category-btn:hover{border-color:' . esc_attr( $primary ) . ';color:' . esc_attr( $badge_text ) . '}
     423.cr-faq-category-btn.active{background:' . esc_attr( $primary ) . ';border-color:' . esc_attr( $primary ) . ';color:' . esc_attr( $active_text ) . '}
    395424.cr-faq-list{display:flex;flex-direction:column;gap:.75rem}
    396425.cr-faq-item{background:' . esc_attr( $bg ) . ';border:1px solid ' . esc_attr( $border ) . ';border-radius:' . intval( $radius ) . 'px;overflow:hidden;transition:box-shadow .2s ease}
     
    400429.cr-faq-item.open .cr-faq-question{background:' . esc_attr( $primary_15 ) . '}
    401430.cr-faq-question-text{flex:1}
    402 .cr-faq-category-badge{font-size:.7rem;padding:.2rem .5rem;border-radius:999px;background:' . esc_attr( $primary_bg ) . ';color:' . esc_attr( $primary ) . ';font-weight:500;flex-shrink:0}
     431.cr-faq-category-badge{font-size:.7rem;padding:.2rem .5rem;border-radius:999px;background:' . esc_attr( $badge_bg ) . ';color:' . esc_attr( $badge_text ) . ';font-weight:500;flex-shrink:0}
    403432.cr-faq-icon{flex-shrink:0;width:20px;height:20px;transition:transform .2s ease;color:' . esc_attr( $primary ) . '}
    404433.cr-faq-item.open .cr-faq-icon{transform:rotate(180deg)}
     
    599628
    600629    /**
     630     * Detect the current page language as a 2-letter code.
     631     *
     632     * Priority:
     633     * 1. WPML (global $sitepress)
     634     * 2. Polylang (pll_current_language())
     635     * 3. WordPress locale (get_locale(), e.g. "de_DE" → "de")
     636     *
     637     * @return string 2-letter language code, e.g. "de", "fr", "en".
     638     */
     639    public static function get_current_language() {
     640        // WPML
     641        if ( defined( 'ICL_LANGUAGE_CODE' ) && ICL_LANGUAGE_CODE ) {
     642            return sanitize_key( ICL_LANGUAGE_CODE );
     643        }
     644
     645        // Polylang
     646        if ( function_exists( 'pll_current_language' ) ) {
     647            $pll_lang = pll_current_language( 'slug' );
     648            if ( $pll_lang ) {
     649                return sanitize_key( $pll_lang );
     650            }
     651        }
     652
     653        // WordPress locale fallback (e.g. "de_DE" → "de", "en_US" → "en")
     654        $locale = get_locale();
     655        return sanitize_key( substr( $locale, 0, 2 ) );
     656    }
     657
     658    /**
    601659     * Render a chat widget
    602660     *
    603661     * All widget settings (position, colors, etc.) are configured in the ChatReact dashboard.
    604662     *
    605      * @param string $chatbot_id The chatbot ID
    606      * @return string HTML output (empty string, script is enqueued)
    607      */
    608     public static function render_chat_widget( $chatbot_id ) {
     663     * @param string $chatbot_id The chatbot ID.
     664     * @param array  $options    Optional widget options (e.g. 'language').
     665     * @return string HTML output (empty string, script is enqueued).
     666     */
     667    public static function render_chat_widget( $chatbot_id, $options = array() ) {
    609668        if ( empty( $chatbot_id ) ) {
    610669            return '';
     
    612671
    613672        self::maybe_add_filter();
     673
     674        $defaults = array(
     675            'language' => '',
     676        );
     677        $options = wp_parse_args( $options, $defaults );
     678
     679        // Auto-detect language if not explicitly set
     680        if ( empty( $options['language'] ) ) {
     681            $options['language'] = self::get_current_language();
     682        }
    614683
    615684        $api_url = self::get_api_url();
     
    626695
    627696        // Store data attributes to be added via script_loader_tag filter
    628         self::$script_data[ $handle ] = array(
     697        $data = array(
    629698            'data-chatbot-id' => $chatbot_id,
    630699            'data-api-url'    => $api_url,
    631700        );
     701
     702        if ( ! empty( $options['language'] ) ) {
     703            $data['data-language'] = $options['language'];
     704        }
     705
     706        self::$script_data[ $handle ] = $data;
    632707
    633708        return '';
     
    660735
    661736        $options = wp_parse_args( $options, $defaults );
     737
     738        // Auto-detect language if not explicitly set
     739        if ( empty( $options['language'] ) ) {
     740            $options['language'] = self::get_current_language();
     741        }
    662742
    663743        // Enqueue the external form script
     
    719799        $options = wp_parse_args( $options, $defaults );
    720800
     801        // Auto-detect language if not explicitly set
     802        if ( empty( $options['language'] ) ) {
     803            $options['language'] = self::get_current_language();
     804        }
     805
    721806        // Use custom container or generate one
    722807        $container_id = ! empty( $options['container'] )
     
    780865            }
    781866
    782             // Group FAQs by category for category pill rendering
     867            // Group FAQs by category for category pill rendering (hide filter when single category)
    783868            $categories = isset( $faq_data['categories'] ) ? $faq_data['categories'] : array();
    784             if ( ! empty( $categories ) ) {
     869            if ( count( $categories ) > 1 ) {
    785870                $ssr_html .= '<div class="cr-faq-categories">';
    786871                $all_label = isset( $settings['i18n']['all'] ) ? $settings['i18n']['all'] : __( 'All', 'chatreact' );
     
    800885                $ssr_html .= '<button class="cr-faq-question" onclick="this.parentElement.classList.toggle(\'open\')">';
    801886                $ssr_html .= '<span class="cr-faq-question-text">' . esc_html( $faq['question'] ) . '</span>';
    802                 if ( $cat_name ) {
     887                if ( $cat_name && count( $categories ) > 1 ) {
    803888                    $ssr_html .= '<span class="cr-faq-category-badge">' . esc_html( $cat_name ) . '</span>';
    804889                }
  • chatreact/tags/1.1.3/includes/class-meta-boxes.php

    r3468481 r3475631  
    286286        // If custom widget is enabled, render it
    287287        if ( ! empty( $settings['enabled'] ) && ! empty( $settings['chatbot_id'] ) ) {
    288             ChatReact::render_chat_widget( $settings['chatbot_id'] );
     288            ChatReact::render_chat_widget( $settings['chatbot_id'], array(
     289                'language' => ChatReact::get_current_language(),
     290            ) );
    289291        }
    290292    }
  • chatreact/tags/1.1.3/includes/class-shortcodes.php

    r3468481 r3475631  
    5454     * Render chat widget shortcode
    5555     *
    56      * Usage: [chatreact id="CHATBOT_ID"]
     56     * Usage: [chatreact id="CHATBOT_ID" language="de"]
    5757     * All widget settings (position, colors, etc.) are configured in your ChatReact dashboard.
     58     * If language is omitted, the current page language is detected automatically.
    5859     *
    5960     * @param array $atts Shortcode attributes
     
    6364        $atts = shortcode_atts(
    6465            array(
    65                 'id' => '',
     66                'id'       => '',
     67                'language' => '',
    6668            ),
    6769            $atts,
     
    7880        }
    7981
    80         return ChatReact::render_chat_widget( $atts['id'] );
     82        return ChatReact::render_chat_widget(
     83            $atts['id'],
     84            array(
     85                'language' => $atts['language'],
     86            )
     87        );
    8188    }
    8289
  • chatreact/tags/1.1.3/readme.txt

    r3472173 r3475631  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.1.2
     7Stable tag: 1.1.3
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    168168
    169169== Changelog ==
     170
     171= 1.1.3 =
     172* Fixed: Single-category FAQ widgets no longer show unnecessary "All" filter button and category badges
     173* Fixed: SSR category filter bar now correctly hidden when only one category is displayed
    170174
    171175= 1.1.2 =
  • chatreact/trunk/admin/class-admin.php

    r3472173 r3475631  
    319319               
    320320                // Found an "Everywhere" assignment - render the widget on all pages
    321                 ChatReact::render_chat_widget( $assignment['chatbot_id'] );
     321                ChatReact::render_chat_widget( $assignment['chatbot_id'], array(
     322                    'language' => ChatReact::get_current_language(),
     323                ) );
    322324                return; // "Everywhere" takes precedence
    323325            }
     
    332334            if ( isset( $assignment['post_id'] ) && $assignment['post_id'] === $current_post_id ) {
    333335                // Found a matching assignment - render the widget
    334                 ChatReact::render_chat_widget( $assignment['chatbot_id'] );
     336                ChatReact::render_chat_widget( $assignment['chatbot_id'], array(
     337                    'language' => ChatReact::get_current_language(),
     338                ) );
    335339                break; // Only one widget per page
    336340            }
  • chatreact/trunk/blocks/chat-widget/block.json

    r3468481 r3475631  
    1414            "type": "string",
    1515            "default": ""
     16        },
     17        "language": {
     18            "type": "string",
     19            "default": ""
    1620        }
    1721    },
  • chatreact/trunk/chatreact.php

    r3472173 r3475631  
    44 * Plugin URI:        https://www.chatreact.ai/docs/de/wordpress
    55 * Description:       Embed AI-powered chat widgets, contact forms, and FAQ accordions on your WordPress site.
    6  * Version:           1.1.2
     6 * Version:           1.1.3
    77 * Requires at least: 5.8
    88 * Requires PHP:      7.4
     
    2121
    2222// Plugin constants
    23 define( 'CHATREACT_VERSION', '1.1.2' );
     23define( 'CHATREACT_VERSION', '1.1.3' );
    2424define( 'CHATREACT_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
    2525define( 'CHATREACT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
  • chatreact/trunk/elementor/widgets/class-chat-widget.php

    r3468481 r3475631  
    8383        );
    8484
     85        $this->add_control(
     86            'language',
     87            array(
     88                'label'       => __( 'Language', 'chatreact' ),
     89                'type'        => \Elementor\Controls_Manager::TEXT,
     90                'placeholder' => __( 'e.g. de, fr, en', 'chatreact' ),
     91                'description' => __( 'Optional. 2-letter language code (e.g. "de", "fr"). Leave empty to auto-detect from the current page language.', 'chatreact' ),
     92            )
     93        );
     94
    8595        $this->end_controls_section();
    8696    }
     
    101111        }
    102112
    103         ChatReact::render_chat_widget( sanitize_text_field( $settings['chatbot_id'] ) );
     113        ChatReact::render_chat_widget(
     114            sanitize_text_field( $settings['chatbot_id'] ),
     115            array(
     116                'language' => sanitize_text_field( isset( $settings['language'] ) ? $settings['language'] : '' ),
     117            )
     118        );
    104119    }
    105120
  • chatreact/trunk/includes/class-blocks.php

    r3468481 r3475631  
    127127        }
    128128
    129         return ChatReact::render_chat_widget( $chatbot_id );
     129        return ChatReact::render_chat_widget(
     130            $chatbot_id,
     131            array(
     132                'language' => isset( $attributes['language'] ) ? $attributes['language'] : '',
     133            )
     134        );
    130135    }
    131136
  • chatreact/trunk/includes/class-chatreact.php

    r3472173 r3475631  
    382382     * @return string <style> block.
    383383     */
     384    private static function get_readable_badge_colors( $primary_hex ) {
     385        $hex = ltrim( $primary_hex, '#' );
     386        if ( strlen( $hex ) === 3 ) {
     387            $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
     388        }
     389        $r = hexdec( substr( $hex, 0, 2 ) );
     390        $g = hexdec( substr( $hex, 2, 2 ) );
     391        $b = hexdec( substr( $hex, 4, 2 ) );
     392        $luminance = ( 0.299 * $r + 0.587 * $g + 0.114 * $b ) / 255;
     393
     394        if ( $luminance > 0.6 ) {
     395            $dark_r = (int) round( $r * 0.35 );
     396            $dark_g = (int) round( $g * 0.35 );
     397            $dark_b = (int) round( $b * 0.35 );
     398            return array(
     399                'text' => sprintf( '#%02x%02x%02x', $dark_r, $dark_g, $dark_b ),
     400                'bg'   => $primary_hex . '30',
     401            );
     402        }
     403
     404        return array(
     405            'text' => $primary_hex,
     406            'bg'   => $primary_hex . '20',
     407        );
     408    }
     409
    384410    private static function get_ssr_faq_styles( $primary, $text, $bg, $border, $radius ) {
    385411        $primary_15 = $primary . '15';
    386         $primary_bg = $primary . '20';
     412        $badge      = self::get_readable_badge_colors( $primary );
     413        $badge_text = $badge['text'];
     414        $badge_bg   = $badge['bg'];
     415        $active_text = ( $badge_text === $primary ) ? '#ffffff' : $badge_text;
    387416
    388417        return '<style>
     
    391420.cr-faq-categories{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.5rem;justify-content:center}
    392421.cr-faq-category-btn{font-family:inherit;padding:.5rem 1rem;border-radius:' . intval( $radius / 2 ) . 'px;border:1px solid ' . esc_attr( $border ) . ';background:' . esc_attr( $bg ) . ';color:' . esc_attr( $text ) . ';font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s ease}
    393 .cr-faq-category-btn:hover{border-color:' . esc_attr( $primary ) . '}
    394 .cr-faq-category-btn.active{background:' . esc_attr( $primary ) . ';border-color:' . esc_attr( $primary ) . ';color:#fff}
     422.cr-faq-category-btn:hover{border-color:' . esc_attr( $primary ) . ';color:' . esc_attr( $badge_text ) . '}
     423.cr-faq-category-btn.active{background:' . esc_attr( $primary ) . ';border-color:' . esc_attr( $primary ) . ';color:' . esc_attr( $active_text ) . '}
    395424.cr-faq-list{display:flex;flex-direction:column;gap:.75rem}
    396425.cr-faq-item{background:' . esc_attr( $bg ) . ';border:1px solid ' . esc_attr( $border ) . ';border-radius:' . intval( $radius ) . 'px;overflow:hidden;transition:box-shadow .2s ease}
     
    400429.cr-faq-item.open .cr-faq-question{background:' . esc_attr( $primary_15 ) . '}
    401430.cr-faq-question-text{flex:1}
    402 .cr-faq-category-badge{font-size:.7rem;padding:.2rem .5rem;border-radius:999px;background:' . esc_attr( $primary_bg ) . ';color:' . esc_attr( $primary ) . ';font-weight:500;flex-shrink:0}
     431.cr-faq-category-badge{font-size:.7rem;padding:.2rem .5rem;border-radius:999px;background:' . esc_attr( $badge_bg ) . ';color:' . esc_attr( $badge_text ) . ';font-weight:500;flex-shrink:0}
    403432.cr-faq-icon{flex-shrink:0;width:20px;height:20px;transition:transform .2s ease;color:' . esc_attr( $primary ) . '}
    404433.cr-faq-item.open .cr-faq-icon{transform:rotate(180deg)}
     
    599628
    600629    /**
     630     * Detect the current page language as a 2-letter code.
     631     *
     632     * Priority:
     633     * 1. WPML (global $sitepress)
     634     * 2. Polylang (pll_current_language())
     635     * 3. WordPress locale (get_locale(), e.g. "de_DE" → "de")
     636     *
     637     * @return string 2-letter language code, e.g. "de", "fr", "en".
     638     */
     639    public static function get_current_language() {
     640        // WPML
     641        if ( defined( 'ICL_LANGUAGE_CODE' ) && ICL_LANGUAGE_CODE ) {
     642            return sanitize_key( ICL_LANGUAGE_CODE );
     643        }
     644
     645        // Polylang
     646        if ( function_exists( 'pll_current_language' ) ) {
     647            $pll_lang = pll_current_language( 'slug' );
     648            if ( $pll_lang ) {
     649                return sanitize_key( $pll_lang );
     650            }
     651        }
     652
     653        // WordPress locale fallback (e.g. "de_DE" → "de", "en_US" → "en")
     654        $locale = get_locale();
     655        return sanitize_key( substr( $locale, 0, 2 ) );
     656    }
     657
     658    /**
    601659     * Render a chat widget
    602660     *
    603661     * All widget settings (position, colors, etc.) are configured in the ChatReact dashboard.
    604662     *
    605      * @param string $chatbot_id The chatbot ID
    606      * @return string HTML output (empty string, script is enqueued)
    607      */
    608     public static function render_chat_widget( $chatbot_id ) {
     663     * @param string $chatbot_id The chatbot ID.
     664     * @param array  $options    Optional widget options (e.g. 'language').
     665     * @return string HTML output (empty string, script is enqueued).
     666     */
     667    public static function render_chat_widget( $chatbot_id, $options = array() ) {
    609668        if ( empty( $chatbot_id ) ) {
    610669            return '';
     
    612671
    613672        self::maybe_add_filter();
     673
     674        $defaults = array(
     675            'language' => '',
     676        );
     677        $options = wp_parse_args( $options, $defaults );
     678
     679        // Auto-detect language if not explicitly set
     680        if ( empty( $options['language'] ) ) {
     681            $options['language'] = self::get_current_language();
     682        }
    614683
    615684        $api_url = self::get_api_url();
     
    626695
    627696        // Store data attributes to be added via script_loader_tag filter
    628         self::$script_data[ $handle ] = array(
     697        $data = array(
    629698            'data-chatbot-id' => $chatbot_id,
    630699            'data-api-url'    => $api_url,
    631700        );
     701
     702        if ( ! empty( $options['language'] ) ) {
     703            $data['data-language'] = $options['language'];
     704        }
     705
     706        self::$script_data[ $handle ] = $data;
    632707
    633708        return '';
     
    660735
    661736        $options = wp_parse_args( $options, $defaults );
     737
     738        // Auto-detect language if not explicitly set
     739        if ( empty( $options['language'] ) ) {
     740            $options['language'] = self::get_current_language();
     741        }
    662742
    663743        // Enqueue the external form script
     
    719799        $options = wp_parse_args( $options, $defaults );
    720800
     801        // Auto-detect language if not explicitly set
     802        if ( empty( $options['language'] ) ) {
     803            $options['language'] = self::get_current_language();
     804        }
     805
    721806        // Use custom container or generate one
    722807        $container_id = ! empty( $options['container'] )
     
    780865            }
    781866
    782             // Group FAQs by category for category pill rendering
     867            // Group FAQs by category for category pill rendering (hide filter when single category)
    783868            $categories = isset( $faq_data['categories'] ) ? $faq_data['categories'] : array();
    784             if ( ! empty( $categories ) ) {
     869            if ( count( $categories ) > 1 ) {
    785870                $ssr_html .= '<div class="cr-faq-categories">';
    786871                $all_label = isset( $settings['i18n']['all'] ) ? $settings['i18n']['all'] : __( 'All', 'chatreact' );
     
    800885                $ssr_html .= '<button class="cr-faq-question" onclick="this.parentElement.classList.toggle(\'open\')">';
    801886                $ssr_html .= '<span class="cr-faq-question-text">' . esc_html( $faq['question'] ) . '</span>';
    802                 if ( $cat_name ) {
     887                if ( $cat_name && count( $categories ) > 1 ) {
    803888                    $ssr_html .= '<span class="cr-faq-category-badge">' . esc_html( $cat_name ) . '</span>';
    804889                }
  • chatreact/trunk/includes/class-meta-boxes.php

    r3468481 r3475631  
    286286        // If custom widget is enabled, render it
    287287        if ( ! empty( $settings['enabled'] ) && ! empty( $settings['chatbot_id'] ) ) {
    288             ChatReact::render_chat_widget( $settings['chatbot_id'] );
     288            ChatReact::render_chat_widget( $settings['chatbot_id'], array(
     289                'language' => ChatReact::get_current_language(),
     290            ) );
    289291        }
    290292    }
  • chatreact/trunk/includes/class-shortcodes.php

    r3468481 r3475631  
    5454     * Render chat widget shortcode
    5555     *
    56      * Usage: [chatreact id="CHATBOT_ID"]
     56     * Usage: [chatreact id="CHATBOT_ID" language="de"]
    5757     * All widget settings (position, colors, etc.) are configured in your ChatReact dashboard.
     58     * If language is omitted, the current page language is detected automatically.
    5859     *
    5960     * @param array $atts Shortcode attributes
     
    6364        $atts = shortcode_atts(
    6465            array(
    65                 'id' => '',
     66                'id'       => '',
     67                'language' => '',
    6668            ),
    6769            $atts,
     
    7880        }
    7981
    80         return ChatReact::render_chat_widget( $atts['id'] );
     82        return ChatReact::render_chat_widget(
     83            $atts['id'],
     84            array(
     85                'language' => $atts['language'],
     86            )
     87        );
    8188    }
    8289
  • chatreact/trunk/readme.txt

    r3472173 r3475631  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.1.2
     7Stable tag: 1.1.3
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    168168
    169169== Changelog ==
     170
     171= 1.1.3 =
     172* Fixed: Single-category FAQ widgets no longer show unnecessary "All" filter button and category badges
     173* Fixed: SSR category filter bar now correctly hidden when only one category is displayed
    170174
    171175= 1.1.2 =
Note: See TracChangeset for help on using the changeset viewer.