hook = AddsynapseMenu::add_page( __( 'Store Assistant settings', 'addsynapse-store-assistant' ), __( 'Settings', 'addsynapse-store-assistant' ), Config::settings_capability(), self::SLUG, array( $this, 'render_page' ) ); } /** * The small stylesheet + the «are you sure?» script (this screen only). * * @param string $hook_suffix Current screen hook. */ public function enqueue( $hook_suffix ): void { if ( '' === $this->hook || $hook_suffix !== $this->hook ) { return; } AdminPage::enqueue_admin_css(); $script = ADDSYNAPSE_ASSISTANT_PLUGIN_DIR . 'assets/settings.js'; wp_enqueue_script( 'addsynapse-assistant-settings', ADDSYNAPSE_ASSISTANT_PLUGIN_URL . 'assets/settings.js', array(), ADDSYNAPSE_ASSISTANT_VERSION . '.' . ( is_readable( $script ) ? (int) filemtime( $script ) : 0 ), true ); } /** * The Settings screen (or its «Approval log» view). */ public function render_page(): void { if ( ! current_user_can( Config::settings_capability() ) ) { wp_die( esc_html__( 'You are not allowed to access this page.', 'addsynapse-store-assistant' ) ); } if ( 'log' === self::query_flag( 'view' ) ) { echo '
' . esc_html__( '← Settings', 'addsynapse-store-assistant' ) . '
'; echo '' . esc_html__( 'Every change AddSynapse wrote on this site after you approved it in Claude.', 'addsynapse-store-assistant' ) . '
'; ConnectPage::render_log(); echo '' . esc_html__( 'Almost done: choose how you want to use Store Assistant — from Claude, or in a chat here in WordPress.', 'addsynapse-store-assistant' ) . ' '; echo '' . esc_html__( 'Start setup', 'addsynapse-store-assistant' ) . '
' . esc_html__( 'Settings saved.', 'addsynapse-store-assistant' ) . '
' . esc_html__( 'The assistant answers in the chat with your own AI key (Anthropic or OpenAI). Slash commands (type /help in the chat), previews, Approve and Undo work without it.', 'addsynapse-store-assistant' ) . '
'; OwnKeySection::render( $notice ); OptIn::render( 'settings' ); OptIn::render_settings(); Usage::render_settings(); /** * Extra Settings sections of extensions (rendered after the AI connection). */ do_action( 'addsynapse_assistant_settings_sections' ); self::render_images(); self::render_voice(); self::render_needs_human(); } /** * «Claude»: the state of the AddSynapse connection, the setup steps and the approval log. */ private static function render_mcp(): void { $status = SetupStatus::connection(); echo '' . esc_html( sprintf( __( 'Connected. Approved by %s.', 'addsynapse-store-assistant' ), (string) $status['detail']['user'] ) ) . '
'; echo '' . esc_html__( 'Setup steps', 'addsynapse-store-assistant' ) . ' '; } else { echo '
' . esc_html( 'site' === Environment::site_type() ? __( 'Not connected yet. Use your site from Claude or ChatGPT, without an API key.', 'addsynapse-store-assistant' ) : __( 'Not connected yet. Use your store from Claude or ChatGPT, without an API key.', 'addsynapse-store-assistant' ) ) . '
'; echo '' . esc_html__( 'Connect to Claude or ChatGPT', 'addsynapse-store-assistant' ) . ' '; } /* translators: %d: number of entries */ echo '' . esc_html( sprintf( _n( 'Approval log (%d entry)', 'Approval log (%d entries)', (int) $status['log_count'], 'addsynapse-store-assistant' ), (int) $status['log_count'] ) ) . '
'; } /** * Images uploaded in the chat: whether the AI may see them (default ON). */ private static function render_images(): void { echo '' . esc_html__( 'Images you attach with the paperclip, by dragging them onto the chat or by pasting them go to the media library (without their location/camera data) and are deleted automatically if no approved change uses them within 24 hours. The assistant can use one as a product\'s main or gallery image, as a preview you approve.', 'addsynapse-store-assistant' ) . '
'; echo ''; } /** * Voice input (microphone button in the chat): opt-in, default OFF. */ private static function render_voice(): void { echo '' . esc_html__( 'Pages the assistant was asked to show or change but cannot edit (a page builder it does not support yet, the classic editor, or content it cannot read safely). Nothing was changed on them; edit them in WordPress or ask your developer.', 'addsynapse-store-assistant' ) . '
'; if ( ! $rows ) { echo '' . esc_html__( 'Nothing yet.', 'addsynapse-store-assistant' ) . '
'; return; } echo '| ' . esc_html__( 'Page', 'addsynapse-store-assistant' ) . ' | ' . esc_html__( 'Builder', 'addsynapse-store-assistant' ) . ' | ' . esc_html__( 'Reason', 'addsynapse-store-assistant' ) . ' | ' . esc_html__( 'Requests', 'addsynapse-store-assistant' ) . ' | ' . esc_html__( 'Last', 'addsynapse-store-assistant' ) . ' |
|---|---|---|---|---|
' . ( $link ? '' . esc_html( (string) $row['title'] ) . '' : esc_html( (string) $row['title'] ) ) . ' #' . (int) $row['page_id'] . ' | ';
echo '' . esc_html( (string) $row['builder'] ) . ' | ' . esc_html( (string) $row['reason'] ) . ' | ' . (int) $row['count'] . ' | '; echo '' . esc_html( get_date_from_gmt( (string) $row['at'], 'Y-m-d H:i' ) ) . ' |