PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.3.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.3.0
2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 All 65 releases
subscription / includes / Admin / views / health-preview.php

health-preview.php in Subscriptions for WooCommerce with Stripe Recurring Payments 2.3.0, at includes/Admin/views/health-preview.php

364 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Subscription Health page โ€” interactive preview with sample data (shown when Pro is not active).
4 *
5 * @package SpringDevs\Subscription\Admin
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 $upgrade_url = 'https://wpsubscription.co/?utm_source=plugin&utm_medium=admin&utm_campaign=upgrade_pro';
11 $currency = function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : '$';
12
13 $dummy_subs = array(
14 array(
15 'id' => 1042,
16 'product' => 'Monthly Wellness Box',
17 'customer' => 'Sarah Johnson',
18 'email' => '[email protected]',
19 'amount' => 29.99,
20 'period' => 'month',
21 'renewal' => '2026-05-20',
22 'days_since' => 18,
23 'issue' => 'failed_payment',
24 ),
25 array(
26 'id' => 1087,
27 'product' => 'Annual Premium Plan',
28 'customer' => 'Marcus Williams',
29 'email' => '[email protected]',
30 'amount' => 199.00,
31 'period' => 'year',
32 'renewal' => '2026-05-28',
33 'days_since' => 10,
34 'issue' => 'overdue_renewal',
35 ),
36 array(
37 'id' => 1103,
38 'product' => 'Basic Weekly Kit',
39 'customer' => 'Emma Clarke',
40 'email' => '[email protected]',
41 'amount' => 9.99,
42 'period' => 'week',
43 'renewal' => '2026-06-01',
44 'days_since' => 6,
45 'issue' => 'retry_needed',
46 ),
47 array(
48 'id' => 1124,
49 'product' => 'Pro Content Access',
50 'customer' => 'David Park',
51 'email' => '[email protected]',
52 'amount' => 59.99,
53 'period' => 'month',
54 'renewal' => '2026-05-15',
55 'days_since' => 23,
56 'issue' => 'stalled_renewal',
57 ),
58 array(
59 'id' => 1155,
60 'product' => 'Monthly Wellness Box',
61 'customer' => 'Linda Zhao',
62 'email' => '[email protected]',
63 'amount' => 29.99,
64 'period' => 'month',
65 'renewal' => '2026-06-03',
66 'days_since' => 4,
67 'issue' => 'failed_payment',
68 ),
69 array(
70 'id' => 1189,
71 'product' => 'Starter Bundle',
72 'customer' => 'James O\'Brien',
73 'email' => '[email protected]',
74 'amount' => 14.99,
75 'period' => 'month',
76 'renewal' => '2026-05-30',
77 'days_since' => 8,
78 'issue' => 'overdue_renewal',
79 ),
80 );
81
82 $revenue_at_risk = 0.0;
83 foreach ( $dummy_subs as $s ) {
84 $revenue_at_risk += $s['amount'];
85 }
86
87 $issue_badge_map = array(
88 'failed_payment' => array(
89 'mod' => 'expired',
90 'label' => __( 'Payment failed', 'subscription' ),
91 'tooltip' => __( 'The last payment attempt was declined.', 'subscription' ),
92 ),
93 'overdue_renewal' => array(
94 'mod' => 'pending-cancel',
95 'label' => __( 'Overdue renewal', 'subscription' ),
96 'tooltip' => __( 'The renewal date passed with no order created.', 'subscription' ),
97 ),
98 'retry_needed' => array(
99 'mod' => 'pending',
100 'label' => __( 'Retry needed', 'subscription' ),
101 'tooltip' => __( 'A payment failed and still needs a retry.', 'subscription' ),
102 ),
103 'stalled_renewal' => array(
104 'mod' => 'cancelled',
105 'label' => __( 'Stalled renewal', 'subscription' ),
106 'tooltip' => __( 'A renewal order has stayed pending too long.', 'subscription' ),
107 ),
108 );
109 ?>
110
111 <div class="wp-subscription-admin-content list-page">
112
113 <!-- Disclaimer banner -->
114 <div style="background:#fffbeb;border:1px solid #fcd34d;border-radius:8px;padding:12px 16px;margin-bottom:20px;display:flex;align-items:flex-start;gap:10px;">
115 <svg width="18" height="18" fill="none" viewBox="0 0 24 24" stroke="#d97706" style="flex-shrink:0;margin-top:1px;" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
116 <p style="margin:0;font-size:13px;color:#92400e;line-height:1.5;">
117 <strong><?php esc_html_e( 'Preview with sample data.', 'subscription' ); ?></strong>
118 <?php esc_html_e( 'This page shows example data to illustrate the feature.', 'subscription' ); ?>
119 <a href="<?php echo esc_url( $upgrade_url ); ?>" target="_blank" rel="noreferrer noopener" style="color:#b45309;font-weight:600;text-decoration:underline;"><?php esc_html_e( 'Upgrade to Pro', 'subscription' ); ?></a>
120 <?php esc_html_e( 'to monitor and recover real subscriptions.', 'subscription' ); ?>
121 </p>
122 </div>
123
124 <!-- Page header -->
125 <div style="display:flex;align-items:flex-start;margin-bottom:20px;gap:24px;flex-wrap:wrap;">
126
127 <div style="flex:1;min-width:200px;">
128 <?php
129 wpsubs_render_page_header(
130 array(
131 'title' => __( 'Subscription Health', 'subscription' ),
132 'description' => __( 'Monitor and recover subscriptions that need attention.', 'subscription' ),
133 'actions' => '<button type="button" class="wpsubs-btn wpsubs-btn--outline" style="height:28px;padding:0 10px;font-size:12px;cursor:not-allowed;opacity:0.6;" disabled><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" /></svg>' . esc_html__( 'Refresh', 'subscription' ) . '</button>',
134 )
135 );
136 ?>
137 </div>
138
139 <div style="display:flex;gap:12px;flex-shrink:0;">
140 <div style="width:140px;border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
141 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
142 <div style="font-size:1.875rem;font-weight:700;color:#111827;line-height:1;"><?php echo esc_html( count( $dummy_subs ) ); ?></div>
143 <span style="display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:8px;background:#eef2ff;flex-shrink:0;color:#6366f1;">
144 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /></svg>
145 </span>
146 </div>
147 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Subscriptions', 'subscription' ); ?></div>
148 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'are at risk zone', 'subscription' ); ?></div>
149 </div>
150 <div style="width:180px;border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
151 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
152 <div style="font-size:1.875rem;font-weight:700;color:#ef4444;line-height:1;"><?php echo esc_html( $currency . number_format_i18n( $revenue_at_risk, 2 ) ); ?></div>
153 <span style="display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:8px;background:#fef2f2;flex-shrink:0;color:#ef4444;">
154 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" /></svg>
155 </span>
156 </div>
157 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Revenue at Risk', 'subscription' ); ?></div>
158 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Across active issues', 'subscription' ); ?></div>
159 </div>
160 </div>
161 </div>
162
163 <!-- Toolbar -->
164 <div class="wpsubs-toolbar" style="margin-top:16px;">
165 <?php
166 wpsubs_render_adv_select(
167 array(
168 'name' => 'filter',
169 'value' => 'all',
170 'placeholder' => __( 'All issues', 'subscription' ),
171 'align' => 'left',
172 'options' => array(
173 array(
174 'value' => 'all',
175 'label' => __( 'All issues', 'subscription' ),
176 ),
177 array(
178 'value' => 'overdue_renewal',
179 'label' => __( 'Overdue Renewal', 'subscription' ),
180 ),
181 array(
182 'value' => 'failed_payment',
183 'label' => __( 'Failed Payment', 'subscription' ),
184 ),
185 array(
186 'value' => 'retry_needed',
187 'label' => __( 'Retry Needed', 'subscription' ),
188 ),
189 array(
190 'value' => 'stalled_renewal',
191 'label' => __( 'Stalled Renewal', 'subscription' ),
192 ),
193 array(
194 'value' => 'skipped',
195 'label' => __( 'Skipped', 'subscription' ),
196 ),
197 ),
198 )
199 );
200 ?>
201 <div class="wpsubs-search">
202 <div class="wpsubs-input-wrap wpsubs-input-wrap--icon-l">
203 <svg class="wpsubs-input-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-4.35-4.35M17 11A6 6 0 105 11a6 6 0 0012 0z"/></svg>
204 <input type="search" class="wpsubs-input" placeholder="<?php esc_attr_e( 'Search ID, product, customer...', 'subscription' ); ?>" disabled style="cursor:not-allowed;" />
205 </div>
206 </div>
207 <button type="button" class="wpsubs-btn wpsubs-btn--outline" disabled style="cursor:not-allowed;opacity:0.6;"><?php esc_html_e( 'Filter', 'subscription' ); ?></button>
208 <div class="wpsubs-toolbar__spacer"></div>
209 <?php
210 wpsubs_render_adv_select(
211 array(
212 'name' => 'per_page',
213 'value' => '20',
214 'placeholder' => '20 per page',
215 'align' => 'right',
216 'options' => array(
217 array(
218 'value' => '10',
219 'label' => __( '10 per page', 'subscription' ),
220 ),
221 array(
222 'value' => '20',
223 'label' => __( '20 per page', 'subscription' ),
224 ),
225 array(
226 'value' => '50',
227 'label' => __( '50 per page', 'subscription' ),
228 ),
229 array(
230 'value' => '100',
231 'label' => __( '100 per page', 'subscription' ),
232 ),
233 ),
234 )
235 );
236 wpsubs_render_adv_select(
237 array(
238 'name' => 'bulk_action',
239 'value' => '',
240 'placeholder' => __( 'Bulk actions', 'subscription' ),
241 'align' => 'right',
242 'options' => array(
243 array(
244 'value' => 'create_renewal',
245 'label' => __( 'Create Renewal', 'subscription' ),
246 ),
247 array(
248 'value' => 'retry',
249 'label' => __( 'Retry Payment', 'subscription' ),
250 ),
251 array(
252 'value' => 'send_email',
253 'label' => __( 'Send Email', 'subscription' ),
254 ),
255 array( 'divider' => true ),
256 array(
257 'value' => 'skip',
258 'label' => __( 'Skip', 'subscription' ),
259 'danger' => true,
260 ),
261 ),
262 )
263 );
264 ?>
265 <span class="wpsubs-btn wpsubs-btn--outline" style="cursor:not-allowed;opacity:0.6;white-space:nowrap;">
266 <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true" style="flex-shrink:0;"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
267 <?php esc_html_e( 'Export CSV', 'subscription' ); ?>
268 </span>
269 </div>
270
271 <div class="wpsubs-table-card">
272 <table class="wpsubs-table">
273 <thead>
274 <tr>
275 <th class="wpsubs-col--check">
276 <input type="checkbox" class="wpsubs-checkbox" disabled />
277 </th>
278 <th><?php esc_html_e( 'Subscription', 'subscription' ); ?></th>
279 <th><?php esc_html_e( 'Customer', 'subscription' ); ?></th>
280 <th style="white-space:nowrap;"><?php esc_html_e( 'Amount', 'subscription' ); ?></th>
281 <th class="wpsubs-col--nowrap"><?php esc_html_e( 'Renew Date', 'subscription' ); ?></th>
282 <th><?php esc_html_e( 'Renewal Order', 'subscription' ); ?></th>
283 <th><?php esc_html_e( 'Issue', 'subscription' ); ?></th>
284 <th class="wpsubs-col--actions"><?php esc_html_e( 'Actions', 'subscription' ); ?></th>
285 </tr>
286 </thead>
287 <tbody>
288 <?php foreach ( $dummy_subs as $sub ) : ?>
289 <?php
290 $name_parts = array_values( array_filter( explode( ' ', $sub['customer'] ) ) );
291 $initials = '';
292 foreach ( array_slice( $name_parts, 0, 2 ) as $part ) {
293 $initials .= strtoupper( $part[0] );
294 }
295 $color_slot = ord( strtolower( $initials[0] ?? 'a' ) ) % 8;
296 $issue_cfg = $issue_badge_map[ $sub['issue'] ] ?? array(
297 'mod' => 'cancelled',
298 'label' => $sub['issue'],
299 'tooltip' => '',
300 );
301 $days = (int) $sub['days_since'];
302 $date_style = $days > 14 ? 'color:#dc2626;' : ( $days > 7 ? 'color:#f97316;' : '' );
303 ?>
304 <tr>
305 <td class="wpsubs-col--check">
306 <input type="checkbox" class="wpsubs-checkbox" disabled />
307 </td>
308 <td>
309 <span class="wpsubs-cell-title" style="font-weight:600;"><?php echo esc_html( $sub['product'] ); ?></span>
310 <span class="wpsubs-cell-id">#<?php echo esc_html( $sub['id'] ); ?></span>
311 </td>
312 <td>
313 <div class="wpsubs-customer">
314 <div class="wpsubs-avatar" data-color="<?php echo (int) $color_slot; ?>"><?php echo esc_html( $initials ); ?></div>
315 <div class="wpsubs-customer__info">
316 <span class="wpsubs-customer__name"><?php echo esc_html( $sub['customer'] ); ?></span>
317 <span class="wpsubs-customer__sub"><?php echo esc_html( $sub['email'] ); ?></span>
318 </div>
319 </div>
320 </td>
321 <td style="white-space:nowrap;">
322 <span class="wpsubs-cell-title" style="font-variant-numeric:tabular-nums;"><?php echo esc_html( $currency . number_format_i18n( $sub['amount'], 2 ) ); ?></span>
323 <span class="wpsubs-cell-id">/ <?php echo esc_html( $sub['period'] ); ?></span>
324 </td>
325 <td class="wpsubs-col--nowrap">
326 <span class="wpsubs-cell-title" style="font-weight:400;<?php echo esc_attr( $date_style ); ?>"><?php echo esc_html( $sub['renewal'] ); ?></span>
327 <?php if ( $days > 0 ) : ?>
328 <span class="wpsubs-cell-id">
329 <?php
330 printf(
331 /* translators: %d: days overdue */
332 esc_html__( '%d days overdue', 'subscription' ),
333 (int) $days
334 );
335 ?>
336 </span>
337 <?php endif; ?>
338 </td>
339 <td>
340 <span class="wpsubs-badge wpsubs-badge--cancelled"><?php esc_html_e( 'Not created', 'subscription' ); ?></span>
341 </td>
342 <td>
343 <span class="wpsubs-badge wpsubs-badge--<?php echo esc_attr( $issue_cfg['mod'] ); ?>" title="<?php echo esc_attr( $issue_cfg['tooltip'] ); ?>">
344 <?php echo esc_html( $issue_cfg['label'] ); ?>
345 </span>
346 </td>
347 <td class="wpsubs-cell--actions">
348 <div class="wpsubs-row-actions">
349 <button type="button" class="wpsubs-row-actions__trigger" style="cursor:not-allowed;opacity:0.6;" disabled>ยทยทยท</button>
350 </div>
351 </td>
352 </tr>
353 <?php endforeach; ?>
354 </tbody>
355 </table>
356 </div>
357
358 </div>
359
360 <?php
361 $modal_title = __( 'Unlock Subscription Health', 'subscription' );
362 $modal_desc = __( 'Subscription Health requires WPSubscription Pro. Unlock advanced features, priority support, and more with WPSubscription Pro.', 'subscription' );
363 require __DIR__ . '/pro-upgrade-modal.php';
364