'Optimize Products', 'optimize_categories' => 'Optimize Categories', 'approval_import' => 'Approval/Import', 'connection' => 'Settings', ); /** * Register submenu entry for Parallax settings. * * @return void */ public static function register(): void { add_submenu_page( 'woocommerce', __( 'Parallax AI Settings', 'ai-content-by-parallax' ), __( 'Parallax', 'ai-content-by-parallax' ), 'manage_options', 'ai-content-by-parallax', array( self::class, 'render' ) ); } /** * Render the settings page wrapper and current tab content. * * @return void */ public static function render(): void { $current_tab = filter_input( INPUT_GET, 'tab', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ? filter_input( INPUT_GET, 'tab', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : self::$default_tab; $client = Client::load(); ?>

'; if ( ! empty( Settings::get( 'enable_tag_support' ) ) ) { $tabs = array(); $i = 0; foreach ( self::$tabs as $key => $label ) { $tabs[ $key ] = $label; ++$i; if ( 2 === $i ) { $tabs['optimize_tags'] = 'Optimize Product Tags'; } } self::$tabs = $tabs; } foreach ( self::$tabs as $tab => $label ) { $active = $current_tab === $tab ? ' nav-tab-active' : ''; printf( '%s', esc_url( add_query_arg( 'tab', $tab, admin_url( 'admin.php?page=ai-content-by-parallax' ) ) ), esc_attr( $active ), esc_html( $label ) ); } echo ''; } /** * Render the active tab content. * * @param string $current_tab Active tab key. * @param Client $client Loaded client instance. * @return void */ private static function display_current_tab( string $current_tab, Client $client ): void { switch ( $current_tab ) { case 'optimize_products': OptimizeTable::display( 'Products', Filtered_Products::class, $client->get_credits() ); break; case 'optimize_categories': OptimizeTable::display( 'Product Categories', Filtered_Categories::class, $client->get_credits() ); break; case 'optimize_tags': OptimizeTable::display( 'Product Tags', Filtered_Tags::class, $client->get_credits() ); break; case 'approval_import': self::display_approval_import_tab(); break; case 'connection': self::display_credentials_form(); break; default: echo '

' . esc_html__( 'Select a tab to manage settings.', 'ai-content-by-parallax' ) . '

'; } } /** * Render the connection settings form. * * @return void */ private static function display_credentials_form(): void { ?>

' . esc_html__( 'No Optimization Batch Requests Found', 'ai-content-by-parallax' ) . '

'; return; } $placeholders = array( array( 'key' => 'product_batch_requests', 'label' => __( 'Product Optimization Batch Requests', 'ai-content-by-parallax' ), 'empty' => __( 'No product batch requests found.', 'ai-content-by-parallax' ), ), array( 'key' => 'category_batch_requests', 'label' => __( 'Category Optimization Batch Requests', 'ai-content-by-parallax' ), 'empty' => __( 'No category batch requests found.', 'ai-content-by-parallax' ), ), array( 'key' => 'product_batch_request_details', 'label' => __( 'Product Batch Request Details', 'ai-content-by-parallax' ), 'empty' => __( 'No product batch request details found.', 'ai-content-by-parallax' ), ), array( 'key' => 'category_batch_request_details', 'label' => __( 'Category Batch Request Details', 'ai-content-by-parallax' ), 'empty' => __( 'No category batch request details found.', 'ai-content-by-parallax' ), ), ); foreach ( $placeholders as $placeholder ) { self::render_ajax_table_placeholder( (string) $placeholder['key'], (string) $placeholder['label'], (string) $placeholder['empty'] ); } } /** * Output markup placeholder for an AJAX-loaded table. * * @param string $table_key Table identifier key. * @param string $label Loading label. * @param string $empty_text Empty state text. * @return void */ private static function render_ajax_table_placeholder( string $table_key, string $label, string $empty_text ): void { printf( '

%2$s

', esc_attr( $table_key ), /* translators: %s: loading label */ esc_html( sprintf( __( 'Loading %s...', 'ai-content-by-parallax' ), $label ) ), esc_attr( $empty_text ) ); } }