AISP_Customer_Activity_Tracker::is_online( $c->ID ) ) ); // Slice to widget limit for display. $customers = array_slice( $all_customers, 0, $limit ); // Summary bar. echo '

'; echo ' 🟢 ' . esc_html__( 'Online now', 'aisp-customer-activity' ) . ': ' . esc_html( $total_online ); echo '

'; if ( empty( $customers ) ) { echo '

' . esc_html__( 'No customers with an active cart right now.', 'aisp-customer-activity' ) . '

'; return; } echo ''; // Show remaining count if list is truncated. $remaining = $total_carts - count( $customers ); $page_url = admin_url( 'admin.php?page=aisp-customer-activity' ); echo '

'; if ( $remaining > 0 ) { echo ''; echo esc_html( sprintf( /* translators: %d: number of additional customers not shown in widget. */ _n( '+ %d more', '+ %d more', $remaining, 'aisp-customer-activity' ), $remaining ) ); echo ''; } else { echo ''; } echo '' . esc_html__( 'View full list →', 'aisp-customer-activity' ) . ''; echo '

'; } private static function render_widget_row( object $customer, array $columns ) { $company = get_user_meta( $customer->ID, 'billing_company', true ); $first = get_user_meta( $customer->ID, 'billing_first_name', true ); $last = get_user_meta( $customer->ID, 'billing_last_name', true ); $full_name = trim( "$first $last" ); $last_activity = (int) get_user_meta( $customer->ID, 'aisp_ca_last_activity', true ); $cart_count = (int) get_user_meta( $customer->ID, 'aisp_ca_cart_count', true ); $cart_total = get_user_meta( $customer->ID, 'aisp_ca_cart_total', true ); $is_online = AISP_Customer_Activity_Tracker::is_online( $customer->ID ); $edit_url = get_edit_user_link( $customer->ID ); $hide_url = AISP_Customer_Activity_Tracker::hide_url( $customer->ID, admin_url( 'index.php' ) ); // Fallback to WordPress native first_name / last_name if billing is empty. if ( empty( $full_name ) ) { $first = get_user_meta( $customer->ID, 'first_name', true ); $last = get_user_meta( $customer->ID, 'last_name', true ); $full_name = trim( "$first $last" ); } $activity_time = $last_activity ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $last_activity ) : '-'; // Resolve primary display name. if ( in_array( 'company', $columns, true ) && ! empty( $company ) ) { $primary = $company; $secondary = $full_name; } elseif ( ! empty( $full_name ) ) { $primary = $full_name; $secondary = ''; } else { $primary = $customer->display_name; $secondary = ''; } echo '
  • '; // online_status — always shown. if ( $is_online ) { echo '🟢 ' . esc_html__( 'Online', 'aisp-customer-activity' ) . ' — '; } else { echo '⚪ ' . esc_html__( 'Offline', 'aisp-customer-activity' ) . ' — '; } // name — always shown as link header. echo '' . esc_html( $primary ) . ''; if ( $secondary ) { echo '
    ' . esc_html( $secondary ) . ''; } // Conditional fields. if ( in_array( 'last_activity', $columns, true ) ) { echo '
    👀 ' . esc_html__( 'Last activity', 'aisp-customer-activity' ) . ': ' . esc_html( $activity_time ); } if ( in_array( 'cart_items', $columns, true ) || in_array( 'cart_total', $columns, true ) ) { echo '
    🛒 '; if ( in_array( 'cart_items', $columns, true ) ) { echo esc_html( sprintf( // translators: %d: number of cart items. _n( '%d item', '%d items', $cart_count, 'aisp-customer-activity' ), $cart_count ) ); } if ( in_array( 'cart_items', $columns, true ) && in_array( 'cart_total', $columns, true ) ) { echo ' — '; } if ( in_array( 'cart_total', $columns, true ) ) { echo wp_kses_post( wc_price( $cart_total ) ); } } echo '
    '; echo esc_html__( 'Remove from list', 'aisp-customer-activity' ); echo ''; // Note / Reminder — read only in widget. $note_data = AISP_Customer_Activity_Notes::get_bulk( [ (int) $customer->ID ] ); $note = $note_data[ (int) $customer->ID ]['note'] ?? ''; $reminder = $note_data[ (int) $customer->ID ]['reminder'] ?? ''; if ( $reminder ) { $is_overdue = strtotime( $reminder ) < strtotime( 'today' ); $reminder_fmt = date_i18n( get_option( 'date_format' ), strtotime( $reminder ) ); $color = $is_overdue ? '#c0392b' : '#2271b1'; echo '
    📅 ' . esc_html( $reminder_fmt ) . ''; } if ( $note ) { $preview = implode( ' ', array_slice( explode( ' ', $note ), 0, 6 ) ); if ( str_word_count( $note ) > 6 ) { $preview .= '…'; } echo '
    📝 ' . esc_html( $preview ) . ''; } echo '
  • '; } }