PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / trunk
Subscriptions for WooCommerce with Stripe Recurring Payments vtrunk
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 1.4.1 1.4.2 1.5.0 1.5.1 All 61 releases
subscription / includes / Admin / views / reports-preview.php

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

612 lines 31.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Reports 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 // Enqueue Chart.js
11 \SpringDevs\Subscription\Assets::enqueue_chart_js();
12
13 // ---------------------------------------------------------------------------------------------------------- //
14
15 $upgrade_url = 'https://wpsubscription.co/?utm_source=plugin&utm_medium=admin&utm_campaign=upgrade_pro';
16 $currency = function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : '$';
17
18 // --- Dummy data ---
19 $dummy_metrics = array(
20 'active_subscriptions' => 142,
21 'cancelled_subscriptions' => 28,
22 'trial_subscriptions' => 19,
23 'total_products' => 8,
24 'churn_rate' => 8.4,
25 'trial_conversion_rate' => 64.7,
26 'average_subscription_value' => 24.99,
27 );
28 $dummy_revenue = array(
29 'total_revenue' => 18420.00,
30 'mrr' => 2847.00,
31 'arr' => 34164.00,
32 'net_revenue' => 17090.00,
33 );
34 $dummy_revenue_at_risk = 580.00;
35 $dummy_trials = array(
36 'total_trials' => 47,
37 'converted_trials' => 31,
38 'active_trials' => 19,
39 'trial_revenue' => 2240.00,
40 );
41 $dummy_popular = array(
42 array(
43 'product_name' => 'Monthly Wellness Box',
44 'subscription_count' => 56,
45 'total_revenue' => 6720.00,
46 'average_revenue' => 120.00,
47 ),
48 array(
49 'product_name' => 'Annual Premium Plan',
50 'subscription_count' => 38,
51 'total_revenue' => 7220.00,
52 'average_revenue' => 190.00,
53 ),
54 array(
55 'product_name' => 'Basic Weekly Kit',
56 'subscription_count' => 29,
57 'total_revenue' => 2320.00,
58 'average_revenue' => 80.00,
59 ),
60 array(
61 'product_name' => 'Pro Content Access',
62 'subscription_count' => 19,
63 'total_revenue' => 1140.00,
64 'average_revenue' => 60.00,
65 ),
66 array(
67 'product_name' => 'Starter Bundle',
68 'subscription_count' => 12,
69 'total_revenue' => 480.00,
70 'average_revenue' => 40.00,
71 ),
72 );
73 $dummy_trends = array(
74 array(
75 'label' => 'Jan',
76 'revenue' => 2200,
77 'active' => 118,
78 'total' => 130,
79 'cancelled' => 5,
80 'trials' => 12,
81 'conversions' => 8,
82 ),
83 array(
84 'label' => 'Feb',
85 'revenue' => 2380,
86 'active' => 122,
87 'total' => 135,
88 'cancelled' => 4,
89 'trials' => 14,
90 'conversions' => 9,
91 ),
92 array(
93 'label' => 'Mar',
94 'revenue' => 2510,
95 'active' => 126,
96 'total' => 140,
97 'cancelled' => 6,
98 'trials' => 16,
99 'conversions' => 11,
100 ),
101 array(
102 'label' => 'Apr',
103 'revenue' => 2650,
104 'active' => 130,
105 'total' => 144,
106 'cancelled' => 3,
107 'trials' => 18,
108 'conversions' => 12,
109 ),
110 array(
111 'label' => 'May',
112 'revenue' => 2730,
113 'active' => 134,
114 'total' => 148,
115 'cancelled' => 5,
116 'trials' => 17,
117 'conversions' => 14,
118 ),
119 array(
120 'label' => 'Jun',
121 'revenue' => 2847,
122 'active' => 142,
123 'total' => 155,
124 'cancelled' => 4,
125 'trials' => 19,
126 'conversions' => 13,
127 ),
128 );
129
130 if ( ! function_exists( 'subscrpt_preview_format_price' ) ) {
131 /**
132 * Format a dummy price for display in the preview.
133 *
134 * @param float $amount Amount to format.
135 * @return string Formatted price HTML.
136 */
137 function subscrpt_preview_format_price( float $amount ): string {
138 return function_exists( 'wc_price' ) ? wc_price( $amount ) : esc_html( '$' . number_format( $amount, 2 ) );
139 }
140 }
141
142 // Sample cancellation reasons, shaped exactly like Pro's real query result so
143 // the preview and the real report render from the same structure.
144 $dummy_cancellation_reasons = array(
145 'reasons' => array(
146 array(
147 'reason' => __( 'Too expensive', 'subscription' ),
148 'count' => 14,
149 'percent' => 38.9,
150 ),
151 array(
152 'reason' => __( 'Missing features I need', 'subscription' ),
153 'count' => 9,
154 'percent' => 25.0,
155 ),
156 array(
157 'reason' => __( 'Found a better alternative', 'subscription' ),
158 'count' => 7,
159 'percent' => 19.4,
160 ),
161 array(
162 'reason' => __( 'No longer needed', 'subscription' ),
163 'count' => 4,
164 'percent' => 11.1,
165 ),
166 array(
167 'reason' => __( 'Technical issues', 'subscription' ),
168 'count' => 2,
169 'percent' => 5.6,
170 ),
171 ),
172 'total' => 36,
173 );
174 ?>
175
176 <!-- Page content -->
177 <div class="wp-subscription-admin-content list-page">
178
179 <!-- Disclaimer banner -->
180 <div style="max-width:1240px;margin:20px auto 0;padding:0;">
181 <div style="background:#fffbeb;border:1px solid #fcd34d;border-radius:8px;padding:12px 16px;display:flex;align-items:flex-start;gap:10px;">
182 <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>
183 <p style="margin:0;font-size:13px;color:#92400e;line-height:1.5;">
184 <strong><?php esc_html_e( 'Preview with sample data.', 'subscription' ); ?></strong>
185 <?php esc_html_e( 'This page shows example data to illustrate the feature.', 'subscription' ); ?>
186 <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>
187 <?php esc_html_e( 'to unlock real subscription analytics.', 'subscription' ); ?>
188 </p>
189 </div>
190 </div>
191
192 <!-- Page header -->
193 <div style="max-width:1240px;margin:20px auto 0;">
194 <?php
195 wpsubs_render_page_header(
196 array(
197 'title' => __( 'Subscription Reports', 'subscription' ),
198 'description' => __( 'Data-driven insights for your subscription business.', 'subscription' ),
199 '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" style="flex-shrink:0;"><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>',
200 )
201 );
202 ?>
203 </div>
204
205 <div class="wpsubs-tabs" data-tabs-query="report" style="max-width:1240px;margin:0 auto;">
206 <div class="wpsubs-tabs__list" role="tablist">
207 <button class="wpsubs-tabs__tab" role="tab" id="subscrpt-report-tab-overview" data-tab-key="overview" aria-controls="subscrpt-report-panel-overview" aria-selected="true">
208 <?php esc_html_e( 'Overview', 'subscription' ); ?>
209 </button>
210 <button class="wpsubs-tabs__tab" role="tab" id="subscrpt-report-tab-cancellation" data-tab-key="cancellation" aria-controls="subscrpt-report-panel-cancellation" aria-selected="false">
211 <?php esc_html_e( 'Cancellation', 'subscription' ); ?>
212 </button>
213 </div>
214
215 <div class="wpsubs-tab-panel" role="tabpanel" id="subscrpt-report-panel-overview" aria-labelledby="subscrpt-report-tab-overview">
216
217 <!-- KPI stat cards -->
218 <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:16px;margin-bottom:16px;">
219
220 <div style="border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
221 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
222 <div style="font-size:1.875rem;font-weight:700;color:#111827;line-height:1;"><?php echo esc_html( number_format_i18n( $dummy_metrics['active_subscriptions'] ) ); ?></div>
223 <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;">
224 <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>
225 </span>
226 </div>
227 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Active Subscriptions', 'subscription' ); ?></div>
228 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Recurring revenue base', 'subscription' ); ?></div>
229 </div>
230
231 <div style="border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
232 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
233 <div style="font-size:1.875rem;font-weight:700;color:#111827;line-height:1;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_revenue['mrr'] ) ); ?></div>
234 <span style="display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:8px;background:#f0fdf4;flex-shrink:0;color:#16a34a;">
235 <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 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
236 </span>
237 </div>
238 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Monthly Recurring Revenue', 'subscription' ); ?></div>
239 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Predictable monthly income', 'subscription' ); ?></div>
240 </div>
241
242 <div style="border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
243 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
244 <div style="font-size:1.875rem;font-weight:700;color:#ef4444;line-height:1;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_revenue_at_risk ) ); ?></div>
245 <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;">
246 <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>
247 </span>
248 </div>
249 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Revenue at Risk', 'subscription' ); ?></div>
250 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Needs attention', 'subscription' ); ?></div>
251 </div>
252
253 <div style="border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
254 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
255 <div style="font-size:1.875rem;font-weight:700;color:#111827;line-height:1;"><?php echo esc_html( number_format_i18n( $dummy_metrics['churn_rate'], 1 ) ); ?>%</div>
256 <span style="display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:8px;background:#fff7ed;flex-shrink:0;color:#f97316;">
257 <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="M13 17h8m0 0V9m0 8l-8-8-4 4-6-6" /></svg>
258 </span>
259 </div>
260 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Churn Rate', 'subscription' ); ?></div>
261 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Customer retention indicator', 'subscription' ); ?></div>
262 </div>
263
264 <div style="border:1px solid var(--wpsubs-border);border-radius:12px;padding:20px;background:var(--wpsubs-surface);">
265 <div style="display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:8px;">
266 <div style="font-size:1.875rem;font-weight:700;color:#111827;line-height:1;"><?php echo esc_html( number_format_i18n( $dummy_metrics['trial_conversion_rate'], 1 ) ); ?>%</div>
267 <span style="display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:8px;background:#faf5ff;flex-shrink:0;color:#8b5cf6;">
268 <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 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
269 </span>
270 </div>
271 <div style="font-size:14px;font-weight:500;color:var(--wpsubs-text);"><?php esc_html_e( 'Trial Conversion', 'subscription' ); ?></div>
272 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Trial to paid success', 'subscription' ); ?></div>
273 </div>
274
275 </div>
276
277 <!-- Revenue & Trends chart -->
278 <div class="wpsubs-table-card" style="margin-bottom:16px;">
279 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
280 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Revenue & Subscription Trends', 'subscription' ); ?></h2>
281 </div>
282 <div style="padding:20px;display:grid;grid-template-columns:1fr 260px;gap:24px;align-items:start;">
283 <div>
284 <canvas id="subscrpt-preview-trends-chart" style="width:100%;height:280px;"></canvas>
285 </div>
286 <div>
287 <p style="font-size:12px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0 0 10px;"><?php esc_html_e( 'Quick Insights', 'subscription' ); ?></p>
288 <div style="display:flex;flex-direction:column;gap:10px;">
289 <div style="padding:12px;border-radius:8px;border:1px solid #86efac;background:#f0fdf4;">
290 <div style="font-size:12px;font-weight:600;color:#166534;margin-bottom:4px;"><?php esc_html_e( 'Revenue Growth', 'subscription' ); ?></div>
291 <div style="font-size:12px;color:#15803d;"><?php esc_html_e( 'MRR is growing steadily — great foundation!', 'subscription' ); ?></div>
292 </div>
293 <div style="padding:12px;border-radius:8px;border:1px solid var(--wpsubs-border);background:var(--wpsubs-surface-muted);">
294 <div style="font-size:12px;font-weight:600;color:var(--wpsubs-text);margin-bottom:4px;"><?php esc_html_e( 'Pro Tip', 'subscription' ); ?></div>
295 <div style="font-size:12px;color:var(--wpsubs-text-muted);"><?php esc_html_e( 'Focus on top-performing products and optimise trial conversions.', 'subscription' ); ?></div>
296 </div>
297 </div>
298 </div>
299 </div>
300 </div>
301
302 <!-- Performance metrics: 3 cards -->
303 <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:16px;">
304
305 <div class="wpsubs-table-card">
306 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
307 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Revenue Performance', 'subscription' ); ?></h2>
308 </div>
309 <div style="padding:20px;display:grid;grid-template-columns:1fr 1fr;gap:16px;">
310 <div>
311 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_revenue['total_revenue'] ) ); ?></div>
312 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Total Revenue', 'subscription' ); ?></div>
313 </div>
314 <div>
315 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_revenue['arr'] ) ); ?></div>
316 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Annual Recurring', 'subscription' ); ?></div>
317 </div>
318 <div>
319 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_revenue['net_revenue'] ) ); ?></div>
320 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Net Revenue', 'subscription' ); ?></div>
321 </div>
322 <div>
323 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_metrics['average_subscription_value'] ) ); ?></div>
324 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Avg. Value', 'subscription' ); ?></div>
325 </div>
326 </div>
327 </div>
328
329 <div class="wpsubs-table-card">
330 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
331 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Trial Performance', 'subscription' ); ?></h2>
332 </div>
333 <div style="padding:20px;display:grid;grid-template-columns:1fr 1fr;gap:16px;">
334 <div>
335 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_trials['total_trials'] ) ); ?></div>
336 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Total Trials', 'subscription' ); ?></div>
337 </div>
338 <div>
339 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_trials['converted_trials'] ) ); ?></div>
340 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Converted', 'subscription' ); ?></div>
341 </div>
342 <div>
343 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_trials['active_trials'] ) ); ?></div>
344 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Active Trials', 'subscription' ); ?></div>
345 </div>
346 <div>
347 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_trials['trial_revenue'] ) ); ?></div>
348 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Trial Revenue', 'subscription' ); ?></div>
349 </div>
350 </div>
351 </div>
352
353 <div class="wpsubs-table-card">
354 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
355 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Subscription Breakdown', 'subscription' ); ?></h2>
356 </div>
357 <div style="padding:20px;display:grid;grid-template-columns:1fr 1fr;gap:16px;">
358 <div>
359 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_metrics['active_subscriptions'] ) ); ?></div>
360 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Active', 'subscription' ); ?></div>
361 </div>
362 <div>
363 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_metrics['cancelled_subscriptions'] ) ); ?></div>
364 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Cancelled', 'subscription' ); ?></div>
365 </div>
366 <div>
367 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_metrics['trial_subscriptions'] ) ); ?></div>
368 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Trials', 'subscription' ); ?></div>
369 </div>
370 <div>
371 <div style="font-size:1.125rem;font-weight:700;color:#111827;"><?php echo esc_html( number_format_i18n( $dummy_metrics['total_products'] ) ); ?></div>
372 <div style="font-size:12px;color:var(--wpsubs-text-muted);margin-top:2px;"><?php esc_html_e( 'Products', 'subscription' ); ?></div>
373 </div>
374 </div>
375 </div>
376
377 </div>
378
379 <!-- Top Products + Action Items -->
380 <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px;">
381
382 <div class="wpsubs-table-card">
383 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
384 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Top Performing Products', 'subscription' ); ?></h2>
385 </div>
386 <?php foreach ( array_slice( $dummy_popular, 0, 5 ) as $index => $sub_product ) : ?>
387 <div style="display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 20px;border-bottom:1px solid var(--wpsubs-border);">
388 <div style="display:flex;align-items:center;gap:12px;min-width:0;">
389 <span style="display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:<?php echo $index < 3 ? '#eef2ff' : 'var(--wpsubs-surface-muted)'; ?>;color:<?php echo $index < 3 ? '#6366f1' : 'var(--wpsubs-text-muted)'; ?>;font-size:11px;font-weight:700;flex-shrink:0;">
390 <?php echo esc_html( $index + 1 ); ?>
391 </span>
392 <div style="min-width:0;">
393 <div class="wpsubs-cell-title" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"><?php echo esc_html( $sub_product['product_name'] ); ?></div>
394 <div class="wpsubs-cell-id">
395 <?php
396 printf(
397 /* translators: %s: number of subscriptions */
398 esc_html__( '%s subscriptions', 'subscription' ),
399 esc_html( number_format_i18n( $sub_product['subscription_count'] ) )
400 );
401 ?>
402 </div>
403 </div>
404 </div>
405 <div style="text-align:right;flex-shrink:0;">
406 <div class="wpsubs-cell-title"><?php echo wp_kses_post( subscrpt_preview_format_price( $sub_product['total_revenue'] ) ); ?></div>
407 <div class="wpsubs-cell-id">
408 <?php
409 printf(
410 /* translators: %s: average revenue */
411 esc_html__( '%s avg', 'subscription' ),
412 wp_kses_post( subscrpt_preview_format_price( $sub_product['average_revenue'] ) )
413 );
414 ?>
415 </div>
416 </div>
417 </div>
418 <?php endforeach; ?>
419 </div>
420
421 <div class="wpsubs-table-card">
422 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
423 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Action Items', 'subscription' ); ?></h2>
424 </div>
425 <div style="padding:16px 20px;display:flex;flex-direction:column;gap:12px;">
426 <div style="padding:14px;border-radius:8px;border:1px solid #86efac;background:#f0fdf4;">
427 <div style="font-size:13px;font-weight:600;color:#166534;margin-bottom:6px;"><?php esc_html_e( 'Best Performers', 'subscription' ); ?></div>
428 <ul style="margin:0;padding-left:16px;font-size:12px;color:#15803d;line-height:1.8;">
429 <li><?php echo esc_html( $dummy_popular[0]['product_name'] ); ?> — <?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_popular[0]['total_revenue'] ) ); ?></li>
430 <li><?php echo esc_html( $dummy_popular[1]['product_name'] ); ?> — <?php echo wp_kses_post( subscrpt_preview_format_price( $dummy_popular[1]['total_revenue'] ) ); ?></li>
431 </ul>
432 </div>
433 <div style="padding:14px;border-radius:8px;border:1px solid var(--wpsubs-border);background:var(--wpsubs-surface-muted);">
434 <div style="font-size:13px;font-weight:600;color:var(--wpsubs-text);margin-bottom:6px;"><?php esc_html_e( 'Recommended Next Steps', 'subscription' ); ?></div>
435 <ul style="margin:0;padding-left:16px;font-size:12px;color:var(--wpsubs-text-muted);line-height:1.8;">
436 <li><?php esc_html_e( 'Analyse customer feedback', 'subscription' ); ?></li>
437 <li><?php esc_html_e( 'Optimise pricing strategy', 'subscription' ); ?></li>
438 <li><?php esc_html_e( 'Expand product offerings', 'subscription' ); ?></li>
439 </ul>
440 </div>
441 </div>
442 </div>
443
444 </div>
445
446 <!-- Detailed Analytics chart -->
447 <div class="wpsubs-table-card">
448 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
449 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Detailed Analytics', 'subscription' ); ?></h2>
450 </div>
451 <div style="padding:20px;">
452 <canvas id="subscrpt-preview-detailed-chart" style="width:100%;height:360px;"></canvas>
453 </div>
454 </div>
455
456 </div><!-- /overview panel -->
457
458 <div class="wpsubs-tab-panel" role="tabpanel" id="subscrpt-report-panel-cancellation" aria-labelledby="subscrpt-report-tab-cancellation" hidden>
459
460 <div class="wpsubs-table-card">
461 <div style="padding:16px 20px;border-bottom:1px solid var(--wpsubs-border);">
462 <h2 style="font-size:13px;font-weight:600;color:var(--wpsubs-text-muted);text-transform:uppercase;letter-spacing:0.07em;margin:0;"><?php esc_html_e( 'Cancellation Reasons', 'subscription' ); ?></h2>
463 <p style="font-size:12px;color:var(--wpsubs-text-muted);margin:4px 0 0;"><?php esc_html_e( 'Why customers cancelled, based on submitted feedback.', 'subscription' ); ?></p>
464 </div>
465 <div style="padding:10px 20px 14px;">
466 <?php
467 foreach ( $dummy_cancellation_reasons['reasons'] as $subscrpt_reason_row ) :
468 $subscrpt_reason_fill = max( 2, min( 100, (float) $subscrpt_reason_row['percent'] ) );
469 ?>
470 <div style="display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:11px 14px;margin-bottom:6px;border-radius:8px;border:1px solid var(--wpsubs-border);background:linear-gradient(to left, var(--wpsubs-brand-light) 0, var(--wpsubs-brand-light) calc(<?php echo esc_attr( $subscrpt_reason_fill ); ?>% - 2px), var(--wpsubs-brand) calc(<?php echo esc_attr( $subscrpt_reason_fill ); ?>% - 2px), var(--wpsubs-brand) <?php echo esc_attr( $subscrpt_reason_fill ); ?>%, transparent <?php echo esc_attr( $subscrpt_reason_fill ); ?>%);">
471 <span style="font-size:13px;font-weight:600;color:var(--wpsubs-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;"><?php echo esc_html( $subscrpt_reason_row['reason'] ); ?></span>
472 <span style="flex-shrink:0;">
473 <span style="font-size:14px;font-weight:700;color:var(--wpsubs-text);"><?php echo esc_html( $subscrpt_reason_row['percent'] ); ?>%</span>
474 <span style="font-size:12px;color:var(--wpsubs-text-muted);margin-left:4px;">
475 <?php
476 printf(
477 /* translators: %s: number of subscriptions. */
478 esc_html__( '%s subs', 'subscription' ),
479 esc_html( number_format_i18n( $subscrpt_reason_row['count'] ) )
480 );
481 ?>
482 </span>
483 </span>
484 </div>
485 <?php endforeach; ?>
486 </div>
487 <div style="padding:12px 20px;border-top:1px solid var(--wpsubs-border);font-size:12px;color:var(--wpsubs-text-muted);">
488 <?php
489 printf(
490 /* translators: %s: total number of cancellations with feedback. */
491 esc_html__( 'Total cancellations with feedback: %s', 'subscription' ),
492 esc_html( number_format_i18n( $dummy_cancellation_reasons['total'] ) )
493 );
494 ?>
495 </div>
496 </div>
497
498 <p style="margin:14px 0 0;font-size:13px;color:var(--wpsubs-text-muted);text-align:center;">
499 <?php esc_html_e( 'Sample data. Pro reports the reasons your own customers gave.', 'subscription' ); ?>
500 </p>
501
502 </div><!-- /cancellation panel -->
503 </div><!-- /tabs -->
504
505 </div>
506
507 <script>
508 document.addEventListener('DOMContentLoaded', function() {
509 var months = <?php echo wp_json_encode( array_column( $dummy_trends, 'label' ) ); ?>;
510 var revenue = <?php echo wp_json_encode( array_column( $dummy_trends, 'revenue' ) ); ?>;
511 var actives = <?php echo wp_json_encode( array_column( $dummy_trends, 'active' ) ); ?>;
512 var totals = <?php echo wp_json_encode( array_column( $dummy_trends, 'total' ) ); ?>;
513 var cancelled = <?php echo wp_json_encode( array_column( $dummy_trends, 'cancelled' ) ); ?>;
514 var trials = <?php echo wp_json_encode( array_column( $dummy_trends, 'trials' ) ); ?>;
515 var conversions = <?php echo wp_json_encode( array_column( $dummy_trends, 'conversions' ) ); ?>;
516
517 var trendsCtx = document.getElementById('subscrpt-preview-trends-chart');
518 if (trendsCtx) {
519 new Chart(trendsCtx.getContext('2d'), {
520 type: 'bar',
521 data: {
522 labels: months,
523 datasets: [
524 {
525 label: '<?php echo esc_js( __( 'Revenue', 'subscription' ) ); ?>',
526 data: revenue,
527 type: 'bar',
528 backgroundColor: 'rgba(99,102,241,0.8)',
529 borderColor: '#6366f1',
530 borderWidth: 2,
531 borderRadius: 6,
532 borderSkipped: false,
533 yAxisID: 'y1'
534 },
535 {
536 label: '<?php echo esc_js( __( 'Active Subscriptions', 'subscription' ) ); ?>',
537 data: actives,
538 type: 'line',
539 borderColor: '#22c55e',
540 backgroundColor: 'rgba(34,197,94,0.1)',
541 borderWidth: 3,
542 fill: true,
543 tension: 0.4,
544 pointRadius: 6,
545 pointHoverRadius: 9,
546 pointBackgroundColor: '#22c55e',
547 pointBorderColor: '#fff',
548 pointBorderWidth: 2,
549 yAxisID: 'y'
550 }
551 ]
552 },
553 options: {
554 responsive: true,
555 interaction: { mode: 'index', intersect: false },
556 plugins: {
557 legend: { position: 'top', labels: { usePointStyle: true, padding: 20, font: { size: 12 } } },
558 title: { display: false }
559 },
560 scales: {
561 x: { grid: { color: 'rgba(0,0,0,0.04)' }, ticks: { font: { size: 11 }, color: '#94a3b8' } },
562 y: { type: 'linear', display: true, position: 'left', beginAtZero: true, grid: { color: 'rgba(0,0,0,0.04)' }, ticks: { font: { size: 11 }, color: '#94a3b8' } },
563 y1: { type: 'linear', display: true, position: 'right', beginAtZero: true, grid: { drawOnChartArea: false }, ticks: { font: { size: 11 }, color: '#94a3b8', callback: function(v) { return '$' + v.toLocaleString(); } } }
564 }
565 }
566 });
567 }
568
569 var detailedCtx = document.getElementById('subscrpt-preview-detailed-chart');
570 if (detailedCtx) {
571 var palette = ['#6366f1','#22c55e','#ef4444','#f59e0b','#8b5cf6','#06b6d4'];
572 var bubbleData = months.map(function(month, i) {
573 return { x: i, y: totals[i], r: Math.max(5, (actives[i] / Math.max.apply(null, actives)) * 20), month: month, active: actives[i], cancelled: cancelled[i], trial: trials[i], conversion: conversions[i] };
574 });
575 new Chart(detailedCtx.getContext('2d'), {
576 type: 'bubble',
577 data: {
578 datasets: [{
579 label: '<?php echo esc_js( __( 'Subscription Performance', 'subscription' ) ); ?>',
580 data: bubbleData,
581 backgroundColor: bubbleData.map(function(_, i) { return palette[i % palette.length]; }),
582 borderColor: bubbleData.map(function(_, i) { return palette[i % palette.length]; }),
583 borderWidth: 2
584 }]
585 },
586 options: {
587 responsive: true,
588 plugins: {
589 legend: { display: false },
590 tooltip: {
591 backgroundColor: 'rgba(15,23,42,0.92)', titleColor: '#fff', bodyColor: '#cbd5e1', cornerRadius: 8, displayColors: false, padding: 12,
592 callbacks: {
593 title: function(ctx) { return ctx[0].raw.month; },
594 label: function(ctx) { var d = ctx.raw; return ['<?php echo esc_js( __( 'Total', 'subscription' ) ); ?>: ' + d.y, '<?php echo esc_js( __( 'Active', 'subscription' ) ); ?>: ' + d.active, '<?php echo esc_js( __( 'Cancelled', 'subscription' ) ); ?>: ' + d.cancelled]; }
595 }
596 }
597 },
598 scales: {
599 x: { type: 'linear', ticks: { stepSize: 1, callback: function(v) { return (v >= 0 && v < months.length) ? months[v] : ''; }, font: { size: 11 }, color: '#94a3b8' }, grid: { color: 'rgba(0,0,0,0.04)' } },
600 y: { ticks: { font: { size: 11 }, color: '#94a3b8' }, grid: { color: 'rgba(0,0,0,0.04)' } }
601 }
602 }
603 });
604 }
605 });
606 </script>
607
608 <?php
609 $modal_title = __( 'Unlock Reports', 'subscription' );
610 $modal_desc = __( 'Reports requires WPSubscription Pro. Unlock advanced features, priority support, and more with WPSubscription Pro.', 'subscription' );
611 require __DIR__ . '/pro-upgrade-modal.php';
612