__( 'AI Opportunities', 'ai-eshop-optimizer' ), 'description' => __( 'The engine scans your customer base nightly and proposes the next-best campaigns — audience, offer, timing and channel — ranked by deterministic predicted value. Accept one and it drafts the campaign for you.', 'ai-eshop-optimizer' ), 'bullets' => array( __( 'Instigator, reactivation, win-back, replenishment, loyalist and deal-driven opportunity miners', 'ai-eshop-optimizer' ), __( 'Deterministic predicted value over the contactable audience', 'ai-eshop-optimizer' ), __( 'One click turns a proposal into a ready-to-review draft campaign', 'ai-eshop-optimizer' ), ), ); } public function register_hooks() { add_action( 'wp_ajax_aieo_dmm_proposals_scan', array( $this, 'ajax_scan' ) ); add_action( 'wp_ajax_aieo_dmm_proposals_accept', array( $this, 'ajax_accept' ) ); add_action( 'wp_ajax_aieo_dmm_proposals_dismiss', array( $this, 'ajax_dismiss' ) ); add_action( 'wp_ajax_aieo_dmm_proposals_narrate_toggle', array( $this, 'ajax_narrate_toggle' ) ); } public function ajax_narrate_toggle() { AIEO_DMM::verify_ajax_request(); if ( ! self::is_aieo_pro_user() ) { wp_send_json_error( array( 'message' => __( 'This feature requires the Pro version.', 'ai-eshop-optimizer' ) ) ); } $on = ( isset( $_POST['on'] ) && '1' === (string) $_POST['on'] ) ? 'yes' : 'no'; update_option( 'aieo_proposals_narrate', $on, false ); wp_send_json_success( array( 'narrate' => $on ) ); } public function ajax_scan() { AIEO_DMM::verify_ajax_request(); if ( ! self::is_aieo_pro_user() ) { wp_send_json_error( array( 'message' => __( 'This feature requires the Pro version.', 'ai-eshop-optimizer' ) ) ); } if ( ! class_exists( 'AIEO_Proposal_Engine' ) ) { wp_send_json_error( array( 'message' => 'Proposal engine unavailable.' ) ); } wp_send_json_success( AIEO_Proposal_Engine::scan() ); } public function ajax_accept() { AIEO_DMM::verify_ajax_request(); if ( ! self::is_aieo_pro_user() ) { wp_send_json_error( array( 'message' => __( 'This feature requires the Pro version.', 'ai-eshop-optimizer' ) ) ); } $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; $res = AIEO_Proposal_Engine::accept( $id ); if ( is_wp_error( $res ) ) { wp_send_json_error( array( 'message' => $res->get_error_message() ) ); } $res['edit_url'] = add_query_arg( array( 'page' => AIEO_DMM::MENU_SLUG, 'dmm_tab' => 'workflows' ), admin_url( 'admin.php' ) ); wp_send_json_success( $res ); } public function ajax_dismiss() { AIEO_DMM::verify_ajax_request(); if ( ! self::is_aieo_pro_user() ) { wp_send_json_error( array( 'message' => __( 'This feature requires the Pro version.', 'ai-eshop-optimizer' ) ) ); } $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; wp_send_json_success( array( 'dismissed' => (bool) AIEO_Proposal_Engine::dismiss( $id ) ) ); } public function enqueue_admin_assets() { $css = 'assets/css/aieo-proposals-admin.css'; wp_enqueue_style( 'aieo-proposals-admin', plugins_url( $css, AIEO_FILE ), array(), file_exists( AIEO_DIR . $css ) ? (string) filemtime( AIEO_DIR . $css ) : '1' ); } public function render_subtab() { $proposals = class_exists( 'AIEO_Proposal_Engine' ) ? AIEO_Proposal_Engine::list_new( 50 ) : array(); $last = get_option( 'aieo_proposals_last_scan', '' ); $nonce = wp_create_nonce( AIEO_DMM::NONCE_ACTION ); ?> 'proposals-campaign-opportunities', 'icon' => 'lightbulb', 'title' => __( 'Campaign opportunities', 'ai-eshop-optimizer' ), 'description' => __( 'The engine scans your customer base nightly and proposes the next-best campaigns — audience, offer, timing and channel — ranked by predicted value. The maths is deterministic; AI only names each idea. Accepting creates a DRAFT campaign you review and activate yourself. Nothing sends automatically.', 'ai-eshop-optimizer' ), 'class' => 'aieo-proposals', ) ); echo $aieo_pr_open; ?> 'aieo-prop-job', 'state' => $last ? 'done' : 'not-run', 'run' => __( 'Scan now', 'ai-eshop-optimizer' ), 'run_attrs' => array( 'id' => 'aieo-prop-scan' ), 'primary' => false, 'facts' => $last ? array( sprintf( __( 'Last scan: %s UTC', 'ai-eshop-optimizer' ), $last ) ) : array(), ); $aieo_pr_narrate = \Rooster\Admin\Ui::toggle( 'on', class_exists( 'AIEO_Proposal_Engine' ) ? AIEO_Proposal_Engine::narrate_on() : 'yes' === get_option( 'aieo_proposals_narrate', 'no' ), array( 'id' => 'aieo-prop-narrate', 'label' => __( 'Name proposals with AI (uses credits)', 'ai-eshop-optimizer' ), 'hidden' => false, 'attrs' => \Rooster\Admin\States::save_attrs( admin_url( 'admin-ajax.php' ), array( 'data' => array( 'action' => 'aieo_dmm_proposals_narrate_toggle', 'nonce' => $nonce ) ) ), ) ); ?>