@@ -381,7 +423,7 @@ public static function delete_account_modal() {
'id' => 'delete-account',
'title' => __( 'Delete account', 'newspack-plugin' ),
'content' => $content_send_email,
- 'size' => 'medium',
+ 'size' => 'small',
'actions' => [
'confirm' => [
'label' => __( 'Delete account', 'newspack-plugin' ),
@@ -616,6 +658,88 @@ public static function redirect_payment_information_endpoint() {
}
}
+ /**
+ * Redirect the Orders endpoint to the My Account dashboard for group members with no orders.
+ * Pairs with hiding the menu item in `my_account_menu_items()` so bookmarks / typed URLs
+ * don't dead-end on the empty state.
+ */
+ public static function redirect_empty_orders_endpoint() {
+ self::maybe_redirect_dead_end_endpoint( 'orders' );
+ }
+
+ /**
+ * Redirect the Payment Methods endpoint to the dashboard for group members with no orders.
+ */
+ public static function redirect_empty_payment_methods_endpoint() {
+ self::maybe_redirect_dead_end_endpoint( 'payment-methods' );
+ }
+
+ /**
+ * Shared redirect helper: bounce a My Account endpoint to the dashboard when the current
+ * user is a group-only member (no orders of their own).
+ *
+ * @param string $endpoint WooCommerce account endpoint slug.
+ */
+ private static function maybe_redirect_dead_end_endpoint( $endpoint ) {
+ if ( ! function_exists( 'is_account_page' ) || ! \is_account_page() ) {
+ return;
+ }
+ global $wp;
+ $current_url = \trailingslashit( \home_url( $wp->request ) );
+ if ( \trailingslashit( \wc_get_account_endpoint_url( $endpoint ) ) !== $current_url ) {
+ return;
+ }
+ if ( ! self::current_user_is_group_member_without_orders() ) {
+ return;
+ }
+ \wp_safe_redirect( \wc_get_page_permalink( 'myaccount' ) );
+ exit;
+ }
+
+ /**
+ * Whether the current user belongs to at least one group subscription and has never
+ * placed an order of their own. Per-request memoized.
+ *
+ * @return bool
+ */
+ private static function current_user_is_group_member_without_orders() {
+ $user_id = \get_current_user_id();
+ if ( ! $user_id || ! class_exists( __NAMESPACE__ . '\\Group_Subscription' ) ) {
+ return false;
+ }
+ $group_subscription_ids = Group_Subscription::get_group_subscriptions_for_user( $user_id, true );
+ if ( empty( $group_subscription_ids ) ) {
+ return false;
+ }
+ return ! self::current_user_has_orders();
+ }
+
+ /**
+ * Whether the current user has any orders. Per-request memoized.
+ *
+ * @return bool
+ */
+ private static function current_user_has_orders() {
+ static $cached = null;
+ if ( null !== $cached ) {
+ return $cached;
+ }
+ $user_id = \get_current_user_id();
+ if ( ! $user_id || ! function_exists( 'wc_get_orders' ) ) {
+ $cached = false;
+ return $cached;
+ }
+ $cached = (bool) \wc_get_orders(
+ [
+ 'customer_id' => $user_id,
+ 'limit' => 1,
+ 'return' => 'ids',
+ 'status' => 'any',
+ ]
+ );
+ return $cached;
+ }
+
/**
* Render confirmation modals for deleting saved payment methods.
*
diff --git a/includes/plugins/woocommerce/my-account/class-woocommerce-my-account.php b/includes/plugins/woocommerce/my-account/class-woocommerce-my-account.php
index aa50e015e8..ce6012a79d 100644
--- a/includes/plugins/woocommerce/my-account/class-woocommerce-my-account.php
+++ b/includes/plugins/woocommerce/my-account/class-woocommerce-my-account.php
@@ -432,10 +432,13 @@ public static function my_account_menu_items( $items ) {
}
}
- // Move "Account Details" and "Subscriptions" to the top of the menu.
+ // Move "Account settings", "Newsletters", and "Subscriptions" to the top of the menu (in that order).
if ( isset( $items['subscriptions'] ) ) {
$items = [ 'subscriptions' => $items['subscriptions'] ] + $items;
}
+ if ( isset( $items['newsletters'] ) ) {
+ $items = [ 'newsletters' => $items['newsletters'] ] + $items;
+ }
if ( isset( $items['edit-account'] ) ) {
$items = [ 'edit-account' => $items['edit-account'] ] + $items;
}
diff --git a/includes/plugins/woocommerce/my-account/templates/v1/group-picker.php b/includes/plugins/woocommerce/my-account/templates/v1/group-picker.php
new file mode 100644
index 0000000000..1a41f20dd4
--- /dev/null
+++ b/includes/plugins/woocommerce/my-account/templates/v1/group-picker.php
@@ -0,0 +1,87 @@
+get_date_created() ? $a->get_date_created()->getTimestamp() : 0;
+ $tb = $b->get_date_created() ? $b->get_date_created()->getTimestamp() : 0;
+ return $tb <=> $ta;
+ }
+);
+?>
+
+
+
+
+
+ 0 ? $settings['limit'] : null;
+ $count_label = $limit
+ ? sprintf(
+ /* translators: 1: member count, 2: member limit */
+ _x( '%1$d of %2$d members', 'group member count', 'newspack-plugin' ),
+ $member_count,
+ $limit
+ )
+ : sprintf(
+ /* translators: %d: member count */
+ _n( '%d member', '%d members', $member_count, 'newspack-plugin' ),
+ $member_count
+ );
+ $subscription_status = $subscription->get_status();
+ $status_classes = [ 'newspack-ui__badge' ];
+ if ( in_array( $subscription_status, [ 'cancelled', 'expired', 'pending-cancel' ], true ) ) {
+ $status_classes[] = 'newspack-ui__badge--error';
+ } elseif ( in_array( $subscription_status, [ 'on-hold', 'pending', 'processing' ], true ) ) {
+ $status_classes[] = 'newspack-ui__badge--warning';
+ } elseif ( 'active' === $subscription_status ) {
+ $status_classes[] = 'newspack-ui__badge--success';
+ } else {
+ $status_classes[] = 'newspack-ui__badge--secondary';
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/includes/plugins/woocommerce/my-account/templates/v1/group-subscription-members.php b/includes/plugins/woocommerce/my-account/templates/v1/group-subscription-members.php
index a5aa0bedd5..3a4884afca 100644
--- a/includes/plugins/woocommerce/my-account/templates/v1/group-subscription-members.php
+++ b/includes/plugins/woocommerce/my-account/templates/v1/group-subscription-members.php
@@ -10,7 +10,6 @@
namespace Newspack;
-use Newspack\WooCommerce_Subscriptions;
use Newspack\Newspack_UI_Icons;
defined( 'ABSPATH' ) || exit;
@@ -24,108 +23,57 @@
$current_user_id = get_current_user_id();
$invite_link = Group_Subscription_Invite::get_link_invite( $subscription, $current_user_id );
$invite_link_url = $invite_link ? Group_Subscription_Invite::get_link_invite_url( $subscription->get_id(), $current_user_id, $invite_link['key'] ) : '';
-$is_at_limit = $member_limit > 0 && ( count( $members ) + count( $pending_invites ) ) >= $member_limit;
-$active_tab = ( isset( $_GET['activeTab'] ) && 'invites' === sanitize_key( wp_unslash( $_GET['activeTab'] ) ) ) ? 'invites' : 'members'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+$is_at_limit = $member_limit > 0 && ( count( $members ) + count( $pending_invites ) ) >= $member_limit;
+$is_manageable = Group_Subscription_MyAccount::is_subscription_manageable( $subscription );
+$active_tab = ( isset( $_GET['activeTab'] ) && 'invites' === sanitize_key( wp_unslash( $_GET['activeTab'] ) ) ) ? 'invites' : 'members'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+$group_label_lower = mb_strtolower( Group_Subscription::get_label( 'singular' ) );
+$is_completely_empty = empty( $members ) && empty( $all_invites );
?>
-