Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,41 @@ public static function get_expiration_time() {
return apply_filters( 'newspack_group_subscription_invite_expiration_time', 30 * DAY_IN_SECONDS );
}

/**
* Get the expiration window as a human-readable label (e.g. "30 days", "1 hour").
*
* @return string Localized label.
*/
public static function get_expiration_label() {
$seconds = (int) self::get_expiration_time();

if ( $seconds <= 0 ) {
$seconds = 1;
}

if ( $seconds >= WEEK_IN_SECONDS && 0 === $seconds % WEEK_IN_SECONDS ) {
$weeks = (int) ( $seconds / WEEK_IN_SECONDS );
/* translators: %s: number of weeks. */
return sprintf( _n( '%s week', '%s weeks', $weeks, 'newspack-plugin' ), number_format_i18n( $weeks ) );
}

if ( $seconds >= DAY_IN_SECONDS && 0 === $seconds % DAY_IN_SECONDS ) {
$days = (int) ( $seconds / DAY_IN_SECONDS );
/* translators: %s: number of days. */
return sprintf( _n( '%s day', '%s days', $days, 'newspack-plugin' ), number_format_i18n( $days ) );
}

if ( $seconds >= HOUR_IN_SECONDS && 0 === $seconds % HOUR_IN_SECONDS ) {
$hours = (int) ( $seconds / HOUR_IN_SECONDS );
/* translators: %s: number of hours. */
return sprintf( _n( '%s hour', '%s hours', $hours, 'newspack-plugin' ), number_format_i18n( $hours ) );
}

$minutes = max( 1, (int) floor( $seconds / MINUTE_IN_SECONDS ) );
/* translators: %s: number of minutes. */
return sprintf( _n( '%s minute', '%s minutes', $minutes, 'newspack-plugin' ), number_format_i18n( $minutes ) );
}
Comment thread
thomasguillot marked this conversation as resolved.

/**
* Check if a group subscription invitation has expired.
* Expiration timestamps are stored as an array map keyed by invite key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ public static function enqueue_assets() {
'change_payment_method_title' => __( 'Change payment method', 'newspack-plugin' ),
'switch_subscription_title' => __( 'Change Subscription', 'newspack-plugin' ),
'invite_link_copied' => __( 'Invite link copied.', 'newspack-plugin' ),
'invite_link_regenerated' => __( 'New invite link copied. Previous link is no longer valid.', 'newspack-plugin' ),
'invite_link_disabled' => __( 'Invite link disabled.', 'newspack-plugin' ),
'invite_link_regenerated' => __( 'New invite link copied. The old one no longer works.', 'newspack-plugin' ),
'invite_link_copy_failed' => __( 'Couldn\'t copy the invite link to your clipboard. Copy it manually:', 'newspack-plugin' ),
'invite_link_disabled' => __( 'Invite link disabled. You can create a new link any time.', 'newspack-plugin' ),
],
'rest' => [
'base_url' => get_rest_url(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
$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
?>
<header class="newspack-my-account__subscription--header">
<?php
Expand Down Expand Up @@ -122,32 +123,41 @@
</div>
</header>

<div class="newspack-my-account__group_subscription__content" data-active-tab="members" data-subscription-id="<?php echo esc_attr( $subscription->get_id() ); ?>" data-invite-link="<?php echo esc_attr( $invite_link_url ); ?>">
<p class="newspack-my-account__group_subscription__tabs">
<a href="#" data-tab="members" class="newspack-my-account__group_subscription__tabs--members">
<?php
echo wp_kses_post(
sprintf(
// translators: %d: The number of members.
__( 'Members (<span class="newspack-group-subscription--members-count">%d</span>)', 'newspack-plugin' ),
count( $managers_and_members )
)
);
?>
</a>
|
<a href="#" data-tab="invites" class="newspack-my-account__group_subscription__tabs--invites">
<?php
echo wp_kses_post(
sprintf(
// translators: %d: The number of members.
__( 'Invitations (<span class="newspack-group-subscription--invitations-count">%d</span>)', 'newspack-plugin' ),
count( $all_invites )
)
);
?>
</a>
</p>
<div class="newspack-my-account__group_subscription__content" data-subscription-id="<?php echo esc_attr( $subscription->get_id() ); ?>" data-invite-link="<?php echo esc_attr( $invite_link_url ); ?>">
<div class="newspack-ui__segmented-control newspack-my-account__group_subscription__segmented-control">
<div class="newspack-ui__segmented-control__tabs" role="tablist">
<button
type="button"
role="tab"
id="newspack-my-account__group_subscription__tab-members"
aria-controls="newspack-my-account__group_subscription__panel-members"
aria-selected="<?php echo 'members' === $active_tab ? 'true' : 'false'; ?>"
tabindex="<?php echo 'members' === $active_tab ? '0' : '-1'; ?>"
class="newspack-ui__button newspack-ui__button--small<?php echo 'members' === $active_tab ? ' selected' : ''; ?>"
>
<?php esc_html_e( 'Members', 'newspack-plugin' ); ?>
<span class="newspack-ui__badge newspack-ui__badge--outline newspack-group-subscription--members-count"><?php echo esc_html( count( $managers_and_members ) ); ?></span>
</button>
<button
type="button"
role="tab"
id="newspack-my-account__group_subscription__tab-invites"
aria-controls="newspack-my-account__group_subscription__panel-invites"
aria-selected="<?php echo 'invites' === $active_tab ? 'true' : 'false'; ?>"
tabindex="<?php echo 'invites' === $active_tab ? '0' : '-1'; ?>"
class="newspack-ui__button newspack-ui__button--small<?php echo 'invites' === $active_tab ? ' selected' : ''; ?>"
>
<?php esc_html_e( 'Invitations', 'newspack-plugin' ); ?>
<span class="newspack-ui__badge newspack-ui__badge--outline newspack-group-subscription--invitations-count"><?php echo esc_html( count( $all_invites ) ); ?></span>
</button>
</div>
<div class="newspack-ui__segmented-control__content">
<div
id="newspack-my-account__group_subscription__panel-members"
role="tabpanel"
aria-labelledby="newspack-my-account__group_subscription__tab-members"
class="newspack-ui__segmented-control__panel<?php echo 'members' === $active_tab ? ' selected' : ''; ?>"
>
<table class="shop_table shop_table_responsive newspack-my-account__group_subscription__members">
<thead>
<tr>
Expand Down Expand Up @@ -211,7 +221,8 @@
<?php endforeach; ?>
</tbody>
</table>

</div><!-- .newspack-ui__segmented-control__panel (members) -->
<div class="newspack-ui__segmented-control__panel<?php echo 'invites' === $active_tab ? ' selected' : ''; ?>">
<table class="shop_table shop_table_responsive newspack-my-account__group_subscription__invites">
<thead>
<tr>
Expand Down Expand Up @@ -268,6 +279,9 @@
<?php endforeach; ?>
</tbody>
</table>
</div><!-- .newspack-ui__segmented-control__panel (invites) -->
</div><!-- .newspack-ui__segmented-control__content -->
</div><!-- .newspack-ui__segmented-control -->

<!-- .newspack-ui__modal: invite by email -->
<div id="newspack-my-account__group_subscription--invite-member" class="newspack-ui__modal-container">
Expand All @@ -289,7 +303,15 @@
</p>
<?php else : ?>
<p>
<?php esc_html_e( 'Invite a member by email, or share a link to let multiple members join.', 'newspack-plugin' ); ?>
<?php
echo esc_html(
sprintf(
// translators: %s is a duration label like "30 days" or "1 hour".
__( 'They\'ll get an email with a link to join the group. The link expires in %s.', 'newspack-plugin' ),
Group_Subscription_Invite::get_expiration_label()
)
);
?>
</p>
<form name="newspack-group-subscription-invite-member" method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<input type="hidden" name="action" value="newspack_group_subscription_invite">
Expand Down Expand Up @@ -322,10 +344,10 @@

<section class="newspack-ui__modal__content">
<p>
<?php esc_html_e( 'The existing link will no longer allow users to join the group. Create a new link?', 'newspack-plugin' ); ?>
<?php esc_html_e( 'The current link will stop working. You\'ll get a new link to share, and anyone who hasn\'t joined yet will need the new link.', 'newspack-plugin' ); ?>
</p>

<button type="button" class="newspack-ui__button newspack-ui__button--primary newspack-ui__button--wide newspack-ui__button--destructive newspack-my-account__group_subscription__invite-link__regenerate" data-error-text="<?php echo esc_attr( __( 'Could not regenerate. Please try again.', 'newspack-plugin' ) ); ?>"><span><?php esc_html_e( 'OK', 'newspack-plugin' ); ?></span></button>
<button type="button" class="newspack-ui__button newspack-ui__button--primary newspack-ui__button--wide newspack-my-account__group_subscription__invite-link__regenerate" data-error-text="<?php echo esc_attr( __( 'Could not regenerate. Please try again.', 'newspack-plugin' ) ); ?>"><span><?php esc_html_e( 'Regenerate link', 'newspack-plugin' ); ?></span></button>
<button type="button" class="newspack-ui__button newspack-ui__button--ghost newspack-ui__button--wide newspack-ui__modal__close"><?php esc_html_e( 'Cancel', 'newspack-plugin' ); ?></button>
</section>
</div><!-- .newspack-ui__modal__small -->
Expand All @@ -346,10 +368,10 @@

<section class="newspack-ui__modal__content">
<p>
<?php esc_html_e( 'The existing link will no longer allow users to join the group. Disable the link?', 'newspack-plugin' ); ?>
<?php esc_html_e( 'The current link will stop working. Anyone who hasn\'t joined yet will no longer be able to. You can create a new link at any time.', 'newspack-plugin' ); ?>
</p>

<button type="button" class="newspack-ui__button newspack-ui__button--primary newspack-ui__button--wide newspack-ui__button--destructive newspack-my-account__group_subscription__invite-link__disable" data-error-text="<?php echo esc_attr( __( 'Could not disable. Please try again.', 'newspack-plugin' ) ); ?>"><span><?php esc_html_e( 'OK', 'newspack-plugin' ); ?></span></button>
<button type="button" class="newspack-ui__button newspack-ui__button--primary newspack-ui__button--wide newspack-ui__button--destructive newspack-my-account__group_subscription__invite-link__disable" data-error-text="<?php echo esc_attr( __( 'Could not disable. Please try again.', 'newspack-plugin' ) ); ?>"><span><?php esc_html_e( 'Disable link', 'newspack-plugin' ); ?></span></button>
<button type="button" class="newspack-ui__button newspack-ui__button--ghost newspack-ui__button--wide newspack-ui__modal__close"><?php esc_html_e( 'Cancel', 'newspack-plugin' ); ?></button>
</section>
</div><!-- .newspack-ui__modal__small -->
Expand Down
62 changes: 37 additions & 25 deletions src/my-account/v1/_group-subscriptions.scss
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
.newspack-ui .newspack-my-account__group_subscription {
&__tabs {
display: flex;
gap: 16px;
margin-bottom: 16px;
}
&__content {
.newspack-my-account__group_subscription__members,
.newspack-my-account__group_subscription__invites {
display: none;
}
&[data-active-tab="members"] {
.newspack-my-account__group_subscription__tabs--members {
font-weight: 600;
}
.newspack-my-account__group_subscription__members {
display: table;
}
&__segmented-control {
align-items: flex-start;
margin-bottom: var(--newspack-ui-spacer-5);

.newspack-ui__button {
display: inline-flex;
align-items: center;
gap: var(--newspack-ui-spacer-2);
}
&[data-active-tab="invites"] {
.newspack-my-account__group_subscription__tabs--invites {
font-weight: 600;
}
.newspack-my-account__group_subscription__invites {
display: table;
}
}

// Enter animation for invite-link controls revealed after the link is created.
&__entering {
animation: newspack-group-subscription-enter 125ms ease both;
Comment thread
thomasguillot marked this conversation as resolved.

@media (prefers-reduced-motion: reduce) {
Comment thread
thomasguillot marked this conversation as resolved.
animation: none;
}
}

&__members,
&__invites {
margin-top: var(--newspack-ui-spacer-5);

// Match populated row height for empty-state cells.
td[colspan]::after {
content: '';
display: inline-block;
vertical-align: middle;
min-height: var(--newspack-ui-spacer-7);
}
}
&__members--actions,
&__invites--actions {
Expand All @@ -40,9 +41,20 @@
content: '';
display: inline-block;
vertical-align: middle;
min-height: 36px;
min-height: var(--newspack-ui-spacer-7);
}
}
}
}
}

@keyframes newspack-group-subscription-enter {
from {
opacity: 0;
transform: translateY(-4px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Loading
Loading