| 1 |
<?php |
| 2 |
/** |
| 3 |
* Plans list view. Built on the shared wpsubs-* components. |
| 4 |
* |
| 5 |
* @var array $plans Plans keyed by id (PlanPresenter shape). |
| 6 |
* @var string $list_url Base list URL. |
| 7 |
* |
| 8 |
* @package SpringDevs\Subscription\Admin |
| 9 |
*/ |
| 10 |
|
| 11 |
if ( ! defined( 'ABSPATH' ) ) { |
| 12 |
exit; |
| 13 |
} |
| 14 |
|
| 15 |
use SpringDevs\Subscription\Admin\Plans; |
| 16 |
?> |
| 17 |
<div class="wp-subscription-admin-content list-page"> |
| 18 |
|
| 19 |
<?php |
| 20 |
wpsubs_render_page_header( |
| 21 |
array( |
| 22 |
'title' => __( 'Plans', 'subscription' ), |
| 23 |
'description' => __( 'Set up a plan and connect it to your products. Manage billing from one place.', 'subscription' ), |
| 24 |
'actions' => sprintf( |
| 25 |
'<button type="button" class="wpsubs-btn wpsubs-btn--primary" data-wpsubs-modal-open="subscrpt-create-plan"><span class="dashicons dashicons-plus-alt2" style="font-size:14px;width:14px;height:14px;line-height:1;"></span>%s</button>', |
| 26 |
esc_html__( 'Create Plan', 'subscription' ) |
| 27 |
), |
| 28 |
) |
| 29 |
); |
| 30 |
?> |
| 31 |
|
| 32 |
<?php if ( empty( $plans ) ) : ?> |
| 33 |
|
| 34 |
<div class="wpsubs-empty"> |
| 35 |
<div class="wpsubs-empty__icon">🗂️</div> |
| 36 |
<h3 class="wpsubs-empty__title"><?php esc_html_e( 'No plans yet', 'subscription' ); ?></h3> |
| 37 |
<p class="wpsubs-empty__desc"><?php esc_html_e( 'Set up a plan and connect it to your products. Manage billing from one place.', 'subscription' ); ?></p> |
| 38 |
<button type="button" class="wpsubs-btn wpsubs-btn--primary" style="margin-top:20px;" data-wpsubs-modal-open="subscrpt-create-plan"> |
| 39 |
<?php esc_html_e( 'Create your first plan', 'subscription' ); ?> |
| 40 |
</button> |
| 41 |
</div> |
| 42 |
|
| 43 |
<?php else : ?> |
| 44 |
|
| 45 |
<div data-subscrpt-browse data-per-page="20"> |
| 46 |
|
| 47 |
<!-- Search + per-page + bulk actions --> |
| 48 |
<div class="wpsubs-toolbar" style="display:flex;align-items:center;gap:8px;margin-bottom:14px;"> |
| 49 |
<div class="wpsubs-search"> |
| 50 |
<div class="wpsubs-input-wrap wpsubs-input-wrap--icon-l"> |
| 51 |
<svg class="wpsubs-input-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z"/></svg> |
| 52 |
<input type="search" class="wpsubs-input" placeholder="<?php esc_attr_e( 'Search plans...', 'subscription' ); ?>" data-subscrpt-browse-search /> |
| 53 |
</div> |
| 54 |
</div> |
| 55 |
<span style="flex:1 1 auto;"></span> |
| 56 |
<?php |
| 57 |
wpsubs_render_per_page_select( |
| 58 |
array( |
| 59 |
'name' => 'subscrpt_groups_per_page', |
| 60 |
'value' => '20', |
| 61 |
'attrs' => array( 'data-subscrpt-browse-perpage' => '1' ), |
| 62 |
) |
| 63 |
); |
| 64 |
wpsubs_render_adv_select( |
| 65 |
array( |
| 66 |
'name' => 'subscrpt_bulk_action', |
| 67 |
'placeholder' => __( 'Bulk actions', 'subscription' ), |
| 68 |
'options' => array( |
| 69 |
array( |
| 70 |
'value' => 'delete', |
| 71 |
'label' => __( 'Delete', 'subscription' ), |
| 72 |
'danger' => true, |
| 73 |
), |
| 74 |
), |
| 75 |
'attrs' => array( 'data-subscrpt-bulk-select' => '1' ), |
| 76 |
) |
| 77 |
); |
| 78 |
?> |
| 79 |
</div> |
| 80 |
|
| 81 |
<div class="wpsubs-table-card"> |
| 82 |
<table class="wpsubs-table"> |
| 83 |
<thead> |
| 84 |
<tr> |
| 85 |
<th class="wpsubs-col--check"><input type="checkbox" class="wpsubs-checkbox" data-subscrpt-select-all aria-label="<?php esc_attr_e( 'Select all plans', 'subscription' ); ?>" /></th> |
| 86 |
<th><?php esc_html_e( 'Plan', 'subscription' ); ?></th> |
| 87 |
<th><?php esc_html_e( 'Type', 'subscription' ); ?></th> |
| 88 |
<th><?php esc_html_e( 'Durations', 'subscription' ); ?></th> |
| 89 |
<th><?php esc_html_e( 'Products', 'subscription' ); ?></th> |
| 90 |
<th><?php esc_html_e( 'Last Edited', 'subscription' ); ?></th> |
| 91 |
<th style="width:48px;"></th> |
| 92 |
</tr> |
| 93 |
</thead> |
| 94 |
<tbody> |
| 95 |
<?php |
| 96 |
foreach ( $plans as $plan ) : |
| 97 |
$detail_url = add_query_arg( |
| 98 |
array( |
| 99 |
'view' => 'detail', |
| 100 |
'plan' => $plan['id'], |
| 101 |
), |
| 102 |
$list_url |
| 103 |
); |
| 104 |
$term_count = count( $plan['terms'] ); |
| 105 |
$product_count = count( $plan['products'] ); |
| 106 |
?> |
| 107 |
<tr class="wpsubs-plan-row" data-subscrpt-browse-item data-name="<?php echo esc_attr( strtolower( $plan['name'] ) ); ?>" data-plan-id="<?php echo esc_attr( $plan['id'] ); ?>" data-href="<?php echo esc_url( $detail_url ); ?>" style="cursor:pointer;"> |
| 108 |
<td class="wpsubs-col--check"> |
| 109 |
<input type="checkbox" class="wpsubs-checkbox wpsubs-row-check" value="<?php echo esc_attr( $plan['id'] ); ?>" aria-label="<?php echo esc_attr( sprintf( /* translators: %s: plan name. */ __( 'Select %s', 'subscription' ), $plan['name'] ) ); ?>" /> |
| 110 |
</td> |
| 111 |
<td> |
| 112 |
<?php |
| 113 |
$subscrpt_full = $plan['name']; |
| 114 |
$subscrpt_short = subscrpt_truncate_text( $subscrpt_full ); |
| 115 |
?> |
| 116 |
<a href="<?php echo esc_url( $detail_url ); ?>" style="display:inline-flex;align-items:center;vertical-align:middle;gap:8px;font-weight:600;text-decoration:none;color:var(--wpsubs-text);"<?php echo $subscrpt_short !== $subscrpt_full ? ' title="' . esc_attr( $subscrpt_full ) . '"' : ''; ?>> |
| 117 |
<span class="dashicons <?php echo esc_attr( Plans::type_icon( $plan['type'] ) ); ?>" style="flex:0 0 auto;color:var(--wpsubs-text-subtle);"></span> |
| 118 |
<?php echo esc_html( $subscrpt_short ); ?> |
| 119 |
</a> |
| 120 |
<?php if ( 'draft' === $plan['status'] ) : ?> |
| 121 |
<span class="wpsubs-badge wpsubs-badge--draft" style="margin-left:4px;"><?php esc_html_e( 'Draft', 'subscription' ); ?></span> |
| 122 |
<?php endif; ?> |
| 123 |
</td> |
| 124 |
<td> |
| 125 |
<span class="wpsubs-badge wpsubs-badge--neutral"><?php echo esc_html( Plans::type_label( $plan['type'] ) ); ?></span> |
| 126 |
</td> |
| 127 |
<td> |
| 128 |
<?php |
| 129 |
echo $term_count > 0 |
| 130 |
/* translators: %d: number of durations. */ |
| 131 |
? esc_html( sprintf( _n( '%d duration', '%d durations', $term_count, 'subscription' ), $term_count ) ) |
| 132 |
: '<span style="color:var(--wpsubs-text-subtle);">' . esc_html__( 'None', 'subscription' ) . '</span>'; |
| 133 |
?> |
| 134 |
</td> |
| 135 |
<td> |
| 136 |
<?php |
| 137 |
echo $product_count > 0 |
| 138 |
/* translators: %d: number of connected products. */ |
| 139 |
? esc_html( sprintf( _n( '%d product', '%d products', $product_count, 'subscription' ), $product_count ) ) |
| 140 |
: '<span style="color:var(--wpsubs-text-subtle);">' . esc_html__( 'None', 'subscription' ) . '</span>'; |
| 141 |
?> |
| 142 |
</td> |
| 143 |
<td><?php echo esc_html( $plan['edited'] ); ?></td> |
| 144 |
<td> |
| 145 |
<?php // The title already opens the plan; the row keeps only the action that is not on screen. plans.js confirms and deletes on data-subscrpt-delete-plan. ?> |
| 146 |
<button type="button" class="wpsubs-icon-action wpsubs-icon-action--danger" data-subscrpt-delete-plan="<?php echo esc_attr( $plan['id'] ); ?>" title="<?php esc_attr_e( 'Delete plan', 'subscription' ); ?>" aria-label="<?php echo esc_attr( sprintf( /* translators: %s: plan name. */ __( 'Delete %s', 'subscription' ), $plan['name'] ) ); ?>"> |
| 147 |
<span class="dashicons dashicons-trash" aria-hidden="true"></span> |
| 148 |
</button> |
| 149 |
</td> |
| 150 |
</tr> |
| 151 |
<?php endforeach; ?> |
| 152 |
</tbody> |
| 153 |
</table> |
| 154 |
</div> |
| 155 |
|
| 156 |
<p data-subscrpt-browse-empty style="display:none;padding:20px 4px;color:var(--wpsubs-text-subtle);font-size:13px;text-align:center;"><?php esc_html_e( 'No plans match your search.', 'subscription' ); ?></p> |
| 157 |
<div data-subscrpt-browse-pager style="margin-top:14px;"></div> |
| 158 |
|
| 159 |
</div> |
| 160 |
|
| 161 |
<?php endif; ?> |
| 162 |
|
| 163 |
</div> |
| 164 |
|
| 165 |
<?php require __DIR__ . '/modal-create.php'; ?> |
| 166 |
|