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
← All changes | includes/Admin/views/onboarding-wizard.php +497 -482 1.11.0 → 2.3.0 View file →
@@ -1,9 +1,15 @@
1 1 <?php
2 2 /**
3 - * Onboarding Wizard Template
4 - * SPA-style: all pages rendered at once, JS controls visibility
3 + * Onboarding Wizard Template.
5 4 *
5 + * SPA-style: every section is rendered at once and JS toggles visibility.
6 + * Flow: Create Plan (type + name) -> Set Frequency (duration) ->
7 + * Connect to a Product -> Finish. A persistent right-rail preview shows the
8 + * plan → durations → products flow and fills in live as each step is filled.
9 + * The plan (group), duration (term) and product relation are created through
10 + * the Plans REST API; only product creation uses admin-ajax.
11 + *
6 12 * @package SpringDevs\Subscription\Admin
7 13 */
8 14
9 15 if ( ! defined( 'ABSPATH' ) ) {
@@ -9,562 +15,571 @@
9 15 if ( ! defined( 'ABSPATH' ) ) {
10 16 exit;
11 17 }
12 18
13 -// Get wizard data from session
14 -$session_data = isset( $_SESSION['subscrpt_onboarding_wizard'] ) ? $_SESSION['subscrpt_onboarding_wizard'] : array();
15 -$wizard_page = isset( $session_data['page'] ) ? (int) $session_data['page'] : 1;
16 -$product_id = isset( $session_data['product_id'] ) ? (int) $session_data['product_id'] : 0;
17 -$subscriptions_url = admin_url( 'admin.php?page=wp-subscription' );
18 -$is_pro = subscrpt_pro_activated();
19 +$is_pro = subscrpt_pro_activated();
20 +$currency_symbol = get_woocommerce_currency_symbol();
19 21
20 -// Get existing products for dropdown
21 -$args = array(
22 - 'post_type' => 'product',
23 - 'posts_per_page' => -1,
24 - 'post_status' => 'any',
25 - 'orderby' => 'title',
26 - 'order' => 'ASC',
22 +// Whether the store has any product at all — decides the connect step's shape.
23 +$has_products = (bool) wc_get_products(
24 + array(
25 + 'status' => array( 'publish', 'draft', 'pending', 'private' ),
26 + 'limit' => 1,
27 + 'return' => 'ids',
28 + )
27 29 );
28 -$products = get_posts( $args );
29 30
30 -// Load product if exists
31 -$product = null;
32 -if ( $product_id > 0 ) {
33 - $product = wc_get_product( $product_id );
34 -}
31 +// Plan types. Only "recurring" is available on the free plugin; the others are
32 +// shown Pro-locked so the choice is visible but not selectable without Pro.
33 +$plan_types = array(
34 + array(
35 + 'key' => 'recurring',
36 + 'label' => __( 'Recurring', 'subscription' ),
37 + 'desc' => __( 'Charge on a repeating schedule.', 'subscription' ),
38 + 'name' => __( 'Recurring Subscription', 'subscription' ),
39 + 'pro' => false,
40 + 'icon' => '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',
41 + ),
42 + array(
43 + 'key' => 'subscribe_save',
44 + 'label' => __( 'Subscribe & Save', 'subscription' ),
45 + 'desc' => __( 'Recurring with a discount.', 'subscription' ),
46 + 'name' => __( 'Subscribe & Save', 'subscription' ),
47 + 'pro' => true,
48 + 'icon' => '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/><line x1="7" y1="7" x2="7.01" y2="7"/></svg>',
49 + ),
50 + array(
51 + 'key' => 'installments',
52 + 'label' => __( 'Installments', 'subscription' ),
53 + 'desc' => __( 'Split a price into payments.', 'subscription' ),
54 + 'name' => __( 'Installment Plan', 'subscription' ),
55 + 'pro' => true,
56 + 'icon' => '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg>',
57 + ),
58 +);
59 +
60 +$interval_options = array(
61 + array(
62 + 'value' => 'day',
63 + 'label' => __( 'Day(s)', 'subscription' ),
64 + ),
65 + array(
66 + 'value' => 'week',
67 + 'label' => __( 'Week(s)', 'subscription' ),
68 + ),
69 + array(
70 + 'value' => 'month',
71 + 'label' => __( 'Month(s)', 'subscription' ),
72 + ),
73 + array(
74 + 'value' => 'year',
75 + 'label' => __( 'Year(s)', 'subscription' ),
76 + ),
77 +);
78 +
79 +$avatar_palette = array(
80 + array(
81 + 'bg' => '#fde8d8',
82 + 'fg' => '#b85c20',
83 + ),
84 + array(
85 + 'bg' => '#dbeafe',
86 + 'fg' => '#1d4ed8',
87 + ),
88 + array(
89 + 'bg' => '#ede9fe',
90 + 'fg' => '#6d28d9',
91 + ),
92 + array(
93 + 'bg' => '#d1fae5',
94 + 'fg' => '#065f46',
95 + ),
96 + array(
97 + 'bg' => '#fce7f3',
98 + 'fg' => '#9d174d',
99 + ),
100 +);
101 +
102 +// Small SVG icons reused inside the preview graph nodes.
103 +$subscrpt_icon_cal = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>';
104 +$subscrpt_icon_box = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>';
105 +$subscrpt_icon_plan = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>';
35 106 ?>
36 107 <div class="wpsubs-layout" id="subscrpt-onboarding-wizard">
37 - <!-- Page 2+ only: stepper indicator -->
38 - <div class="wpsubs-wizard-stepper" id="subscrpt-stepper" style="display:none;">
39 - <div class="wpsubs-wizard-stepper__step active" data-step="1">
108 +
109 + <!-- Step indicator -->
110 + <div class="wpsubs-wizard-stepper" id="subscrpt-stepper">
111 + <div class="wpsubs-wizard-stepper__step" data-step="1">
40 112 <div class="wpsubs-wizard-stepper__num">1</div>
41 - <div class="wpsubs-wizard-stepper__label">Welcome</div>
113 + <div class="wpsubs-wizard-stepper__label"><?php esc_html_e( 'Plan', 'subscription' ); ?></div>
42 114 </div>
43 115 <div class="wpsubs-wizard-stepper__line"></div>
44 116 <div class="wpsubs-wizard-stepper__step" data-step="2">
45 117 <div class="wpsubs-wizard-stepper__num">2</div>
46 - <div class="wpsubs-wizard-stepper__label">Product Setup</div>
118 + <div class="wpsubs-wizard-stepper__label"><?php esc_html_e( 'Durations', 'subscription' ); ?></div>
47 119 </div>
48 120 <div class="wpsubs-wizard-stepper__line"></div>
49 121 <div class="wpsubs-wizard-stepper__step" data-step="3">
50 122 <div class="wpsubs-wizard-stepper__num">3</div>
51 - <div class="wpsubs-wizard-stepper__label"><?php esc_html_e( 'Done', 'subscription' ); ?></div>
123 + <div class="wpsubs-wizard-stepper__label"><?php esc_html_e( 'Product', 'subscription' ); ?></div>
52 124 </div>
125 + <div class="wpsubs-wizard-stepper__line"></div>
126 + <div class="wpsubs-wizard-stepper__step" data-step="4">
127 + <div class="wpsubs-wizard-stepper__num">4</div>
128 + <div class="wpsubs-wizard-stepper__label"><?php esc_html_e( 'Finish', 'subscription' ); ?></div>
129 + </div>
53 130 </div>
54 131
55 132 <!-- Hidden state -->
56 - <input type="hidden" name="subscrpt_wizard_page" id="subscrpt-wizard-page" value="<?php echo esc_attr( $wizard_page ); ?>">
57 - <input type="hidden" name="subscrpt_product_id" id="subscrpt-product-id" value="<?php echo esc_attr( $product_id ); ?>">
58 - <input type="hidden" id="subscrpt-ajax-url" value="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>">
59 - <input type="hidden" id="subscrpt-subscriptions-url" value="<?php echo esc_url( admin_url( 'admin.php?page=wp-subscription' ) ); ?>">
133 + <input type="hidden" id="subscrpt-wizard-page" value="0">
134 + <input type="hidden" id="subscrpt-has-products" value="<?php echo $has_products ? '1' : '0'; ?>">
135 + <input type="hidden" id="subscrpt-plan-type" value="recurring">
60 136 <?php wp_nonce_field( 'subscrpt_onboarding_wizard', 'subscrpt_wizard_nonce' ); ?>
61 137
62 - <!-- =========================================== -->
63 - <!-- SECTION 1: Welcome -->
64 - <!-- =========================================== -->
65 - <div class="wpsubs-wizard-section <?php echo 1 === $wizard_page ? 'active' : ''; ?>" data-page="1" id="subscrpt-section-1">
66 - <div class="wpsubs-wizard-card">
67 - <!-- Left: content -->
68 - <div class="wpsubs-p1-left">
69 - <div class="wpsubs-p1-badge">
70 - <span class="wpsubs-p1-badge__dot"></span>
71 - <?php esc_html_e( 'Getting started', 'subscription' ); ?>
72 - </div>
73 - <h1 class="wpsubs-p1-heading">
74 - <?php esc_html_e( 'Your first subscription', 'subscription' ); ?>
75 - <span class="wpsubs-p1-heading__accent"><?php esc_html_e( 'starts here', 'subscription' ); ?></span>
76 - </h1>
77 - <p class="wpsubs-p1-desc"><?php esc_html_e( 'Set up your first subscription product in minutes. Start from scratch or convert a product you already sell.', 'subscription' ); ?></p>
78 - <ul class="wpsubs-p1-bullets">
79 - <li><span class="wpsubs-p1-bullet-dot"></span><?php esc_html_e( 'Daily, weekly, monthly, or annual billing', 'subscription' ); ?></li>
80 - <li><span class="wpsubs-p1-bullet-dot"></span><?php esc_html_e( 'Free trials and one-time sign-up fees', 'subscription' ); ?></li>
138 + <div class="wpsubs-wizard-layout">
139 +
140 + <!-- ======================= Steps (left) ======================= -->
141 + <div class="wpsubs-wizard-steps">
142 +
143 + <!-- PAGE 0: Welcome (no preview / no footer — button lives in the card) -->
144 + <div class="wpsubs-wizard-section active" data-page="0" id="subscrpt-section-0">
145 + <div class="wpsubs-welcome-bg" aria-hidden="true"></div>
146 + <div class="wpsubs-wizard-card wpsubs-welcome">
147 + <img class="wpsubs-welcome__logo" src="<?php echo esc_url( SUBSCRPT_ASSETS . '/images/logo.png' ); ?>" width="64" height="64" alt="<?php esc_attr_e( 'WPSubscription', 'subscription' ); ?>">
148 + <h1 class="wpsubs-welcome__title"><?php esc_html_e( 'Thank you for installing WPSubscription!', 'subscription' ); ?></h1>
149 + <p class="wpsubs-welcome__lead"><?php esc_html_e( "Let's set up your first subscription plan. A plan decides how customers are billed and connects to a product they can subscribe to.", 'subscription' ); ?></p>
150 + <ul class="wpsubs-welcome__steps">
151 + <li><span class="wpsubs-welcome__num">1</span><?php esc_html_e( 'Create a plan and choose how customers are billed', 'subscription' ); ?></li>
152 + <li><span class="wpsubs-welcome__num">2</span><?php esc_html_e( 'Add one or more billing durations', 'subscription' ); ?></li>
153 + <li><span class="wpsubs-welcome__num">3</span><?php esc_html_e( 'Connect it to a product', 'subscription' ); ?></li>
81 154 </ul>
82 - <div class="wpsubs-p1-actions">
83 - <button type="button" id="subscrpt-btn-start" class="wpsubs-btn wpsubs-btn--primary">
84 - <?php esc_html_e( 'Create my first subscription', 'subscription' ); ?> &rsaquo;
85 - </button>
86 - <button type="button" id="subscrpt-btn-skip" class="wpsubs-p1-skip">
87 - <?php esc_html_e( 'Skip the intro', 'subscription' ); ?>
88 - </button>
155 + <div class="wpsubs-welcome__actions">
156 + <button type="button" id="subscrpt-btn-start" class="wpsubs-btn wpsubs-btn--primary wpsubs-btn--lg">
157 + <?php esc_html_e( "Let's go", 'subscription' ); ?> &rsaquo;
158 + </button>
159 + <button type="button" id="subscrpt-btn-skip" class="wpsubs-welcome__skip">
160 + <?php esc_html_e( 'Skip setup', 'subscription' ); ?>
161 + </button>
162 + </div>
89 163 </div>
90 164 </div>
91 - <!-- Right: product preview mockup -->
92 - <div class="wpsubs-p1-right" aria-hidden="true">
93 - <p class="wpsubs-p1-preview-label"><?php esc_html_e( 'Your shop', 'subscription' ); ?></p>
94 - <p class="wpsubs-p1-preview-sublabel"><?php esc_html_e( 'How customers see the product', 'subscription' ); ?></p>
95 - <div class="wpsubs-p1-preview-card">
96 - <div class="wpsubs-p1-preview-img">
97 - <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
98 - <path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path>
99 - <line x1="3" y1="6" x2="21" y2="6"></line>
100 - <path d="M16 10a4 4 0 0 1-8 0"></path>
101 - </svg>
102 - <div class="wpsubs-p1-preview-img__dots">
103 - <span></span><span></span><span></span>
104 - </div>
165 +
166 + <!-- PAGE 1: Create Plan (type + name) -->
167 + <div class="wpsubs-wizard-section" data-page="1" id="subscrpt-section-1">
168 + <div class="wpsubs-wizard-card">
169 + <h1 class="wpsubs-p2-page-title"><?php esc_html_e( 'Create a plan', 'subscription' ); ?></h1>
170 + <p class="wpsubs-p2-page-subtitle"><?php esc_html_e( 'Choose how customers are billed, then name your plan.', 'subscription' ); ?></p>
171 +
172 + <div class="wpsubs-p2-section-block">
173 + <p class="wpsubs-p2-section-label"><?php esc_html_e( '1. Plan type', 'subscription' ); ?></p>
174 + <div class="wpsubs-p2-option-cards wpsubs-p2-option-cards--list">
175 + <?php foreach ( $plan_types as $subscrpt_type ) : ?>
176 + <?php $subscrpt_locked = $subscrpt_type['pro'] && ! $is_pro; ?>
177 + <button type="button"
178 + class="wpsubs-p2-option-card wpsubs-plan-type-card<?php echo 'recurring' === $subscrpt_type['key'] ? ' active' : ''; ?>"
179 + data-type="<?php echo esc_attr( $subscrpt_type['key'] ); ?>"
180 + data-name="<?php echo esc_attr( $subscrpt_type['name'] ); ?>"
181 + data-label="<?php echo esc_attr( $subscrpt_type['label'] ); ?>"
182 + <?php echo $subscrpt_locked ? 'disabled' : ''; ?>>
183 + <div class="wpsubs-p2-option-card__icon"><?php echo $subscrpt_type['icon']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG defined above. ?></div>
184 + <div class="wpsubs-p2-option-card__text">
185 + <p class="wpsubs-p2-option-card__title">
186 + <?php echo esc_html( $subscrpt_type['label'] ); ?>
187 + <?php if ( $subscrpt_locked ) : ?>
188 + <span class="wpsubs-p2-pro-badge" title="<?php esc_attr_e( 'WPSubscription Pro required', 'subscription' ); ?>"><?php esc_html_e( 'Pro', 'subscription' ); ?></span>
189 + <?php endif; ?>
190 + </p>
191 + <p class="wpsubs-p2-option-card__desc"><?php echo esc_html( $subscrpt_type['desc'] ); ?></p>
192 + </div>
193 + </button>
194 + <?php endforeach; ?>
105 195 </div>
106 - <div class="wpsubs-p1-preview-body">
107 - <p class="wpsubs-p1-preview-name"><?php esc_html_e( 'Monthly Subscription Box', 'subscription' ); ?></p>
108 - <p class="wpsubs-p1-preview-price">24.00$ <span>/ <?php esc_html_e( 'month', 'subscription' ); ?></span></p>
109 - <div class="wpsubs-p1-preview-btn"><?php esc_html_e( 'Sign up', 'subscription' ); ?></div>
110 - <div class="wpsubs-p1-preview-skeletons">
111 - <div class="wpsubs-p1-preview-skeleton"></div>
112 - <div class="wpsubs-p1-preview-skeleton"></div>
113 - </div>
196 + </div>
197 +
198 + <div class="wpsubs-p2-section-block" style="margin-bottom:0;">
199 + <p class="wpsubs-p2-section-label"><?php esc_html_e( '2. Plan name', 'subscription' ); ?></p>
200 + <div class="wpsubs-form-row" style="margin-bottom:0;max-width:420px;">
201 + <input type="text" id="subscrpt_plan_title" class="wpsubs-input" autocomplete="off" value="<?php esc_attr_e( 'Recurring Subscription', 'subscription' ); ?>" placeholder="<?php esc_attr_e( 'e.g. Monthly Box', 'subscription' ); ?>">
114 202 </div>
203 + </div>
115 204 </div>
116 - </div>
117 - </div>
118 - </div>
205 + </div>
119 206
120 - <!-- =========================================== -->
121 - <!-- SECTION 2: Product & Subscription Setup -->
122 - <!-- =========================================== -->
123 - <div class="wpsubs-wizard-section <?php echo 2 === $wizard_page ? 'active' : ''; ?>" id="subscrpt-section-2">
124 - <div class="wpsubs-wizard-card">
125 - <h1 class="wpsubs-p2-page-title"><?php esc_html_e( 'Create your subscription product', 'subscription' ); ?></h1>
126 - <p class="wpsubs-p2-page-subtitle"><?php esc_html_e( 'Set the basics now. Once published, customers can subscribe from your shop and you can fine-tune everything later in the product editor.', 'subscription' ); ?></p>
207 + <!-- PAGE 2: Set Frequency (duration) -->
208 + <div class="wpsubs-wizard-section" data-page="2" id="subscrpt-section-2">
209 + <div class="wpsubs-wizard-card">
210 + <h1 class="wpsubs-p2-page-title"><?php esc_html_e( 'Add billing durations', 'subscription' ); ?></h1>
211 + <p class="wpsubs-p2-page-subtitle"><?php esc_html_e( 'How often a customer is charged. Add one or more to offer a choice.', 'subscription' ); ?></p>
127 212
128 - <!-- 1. Pick a starting point -->
129 - <div class="wpsubs-p2-section-block">
130 - <p class="wpsubs-p2-section-label"><?php esc_html_e( '1. Pick a starting point', 'subscription' ); ?></p>
131 - <p class="wpsubs-p2-section-desc"><?php esc_html_e( 'Build a fresh subscription product, or convert one you already sell.', 'subscription' ); ?></p>
213 + <div id="subscrpt-durations" data-durations></div>
132 214
133 - <div class="wpsubs-p2-option-cards">
134 - <button type="button"
135 - class="wpsubs-p2-option-card product-toggle-btn <?php echo 'existing' !== ( isset( $session_data['product_mode'] ) ? $session_data['product_mode'] : 'new' ) ? 'active' : ''; ?>"
136 - id="subscrpt-btn-create-new" data-mode="new">
137 - <div class="wpsubs-p2-option-card__check">✓</div>
138 - <div class="wpsubs-p2-option-card__icon">
139 - <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
140 - </div>
141 - <p class="wpsubs-p2-option-card__title"><?php esc_html_e( 'Create a new product', 'subscription' ); ?></p>
142 - <p class="wpsubs-p2-option-card__desc"><?php esc_html_e( 'Start with a blank subscription product.', 'subscription' ); ?></p>
215 + <button type="button" id="subscrpt-btn-add-duration" class="wpsubs-btn wpsubs-btn--outline" style="width:100%;justify-content:center;margin-top:4px;">
216 + <span class="dashicons dashicons-plus-alt2" style="font-size:15px;width:15px;height:15px;line-height:1;"></span>
217 + <?php esc_html_e( 'Add another duration', 'subscription' ); ?>
143 218 </button>
144 219
145 - <?php if ( ! empty( $products ) ) : ?>
146 - <button type="button"
147 - class="wpsubs-p2-option-card product-toggle-btn <?php echo 'existing' === ( isset( $session_data['product_mode'] ) ? $session_data['product_mode'] : '' ) ? 'active' : ''; ?>"
148 - id="subscrpt-btn-use-existing" data-mode="existing">
149 - <div class="wpsubs-p2-option-card__check">✓</div>
150 - <div class="wpsubs-p2-option-card__icon">
151 - <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
152 - </div>
153 - <p class="wpsubs-p2-option-card__title"><?php esc_html_e( 'Use an existing product', 'subscription' ); ?></p>
154 - <p class="wpsubs-p2-option-card__desc"><?php esc_html_e( 'Convert a WooCommerce product into a subscription.', 'subscription' ); ?></p>
155 - </button>
156 - <?php endif; ?>
157 - </div>
158 -
159 - <!-- Existing product selector -->
160 - <?php if ( ! empty( $products ) ) : ?>
161 - <div id="subscrpt-existing-product-fields" style="<?php echo 'existing' !== ( isset( $session_data['product_mode'] ) ? $session_data['product_mode'] : '' ) ? 'display:none;' : ''; ?>">
162 - <div id="subscrpt-product-select-wrap">
163 - <?php
164 - $avatar_palette = array(
165 - array(
166 - 'bg' => '#fde8d8',
167 - 'fg' => '#b85c20',
168 - ),
169 - array(
170 - 'bg' => '#dbeafe',
171 - 'fg' => '#1d4ed8',
172 - ),
173 - array(
174 - 'bg' => '#ede9fe',
175 - 'fg' => '#6d28d9',
176 - ),
177 - array(
178 - 'bg' => '#d1fae5',
179 - 'fg' => '#065f46',
180 - ),
181 - array(
182 - 'bg' => '#fce7f3',
183 - 'fg' => '#9d174d',
184 - ),
185 - array(
186 - 'bg' => '#fef9c3',
187 - 'fg' => '#854d0e',
188 - ),
189 - );
190 - ?>
191 - <div class="wpsubs-p2-product-search">
192 - <div class="wpsubs-p2-product-search__input-wrap">
193 - <svg class="wpsubs-p2-product-search__icon" width="15" height="15" 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>
194 - <input type="text" class="wpsubs-p2-product-search__input wpsubs-input" id="subscrpt-product-search-input"
195 - placeholder="<?php esc_attr_e( 'Search WooCommerce products by name or SKU...', 'subscription' ); ?>"
196 - autocomplete="off">
220 + <template id="subscrpt-duration-tpl">
221 + <div class="wpsubs-dur is-open" data-dur>
222 + <div class="wpsubs-dur__head" data-dur-toggle>
223 + <span class="wpsubs-dur__icon"><?php echo $subscrpt_icon_cal; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
224 + <span class="wpsubs-dur__title" data-dur-title></span>
225 + <button type="button" class="wpsubs-dur__remove" data-dur-remove title="<?php esc_attr_e( 'Remove duration', 'subscription' ); ?>" aria-label="<?php esc_attr_e( 'Remove duration', 'subscription' ); ?>">&times;</button>
226 + <svg class="wpsubs-dur__chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"></polyline></svg>
197 227 </div>
198 - <div class="wpsubs-p2-product-search__dropdown" id="subscrpt-product-search-dropdown" style="display:none;">
199 - <?php
200 - foreach ( $products as $i => $p ) :
201 - $wc_p = wc_get_product( $p->ID );
202 - $price = $wc_p ? $wc_p->get_price() : '';
203 - $type = $wc_p ? ucfirst( $wc_p->get_type() ) . ' ' . __( 'product', 'subscription' ) : '';
204 - $sku = $wc_p ? $wc_p->get_sku() : '';
205 - $billing_period_meta = $wc_p ? $wc_p->get_meta( '_subscrpt_timing_option' ) : '';
206 - $billing_per_meta = $wc_p ? $wc_p->get_meta( '_subscrpt_timing_per' ) : '';
207 - $trial_per_meta = $wc_p ? $wc_p->get_meta( '_subscrpt_trial_timing_per' ) : '';
208 - $signup_fee_meta = $wc_p ? $wc_p->get_meta( '_subscrpt_signup_fee' ) : '';
209 - $words = array_filter( explode( ' ', $p->post_title ) );
210 - $initials = implode(
211 - '',
212 - array_slice(
213 - array_map(
214 - function ( $w ) {
215 - return mb_strtoupper( mb_substr( $w, 0, 1 ) );
216 - },
217 - $words
218 - ),
219 - 0,
220 - 2
221 - )
222 - );
223 - $color = $avatar_palette[ $i % count( $avatar_palette ) ];
224 - ?>
225 - <?php $is_variable_locked = ( $wc_p && 'variable' === $wc_p->get_type() && ! $is_pro ); ?>
226 - <div class="wpsubs-p2-product-search__item<?php echo $is_variable_locked ? ' wpsubs-p2-product-search__item--locked' : ''; ?>"
227 - data-id="<?php echo esc_attr( $p->ID ); ?>"
228 - data-price="<?php echo esc_attr( $price ); ?>"
229 - data-type="<?php echo esc_attr( $type ); ?>"
230 - data-product-type="<?php echo esc_attr( $wc_p ? $wc_p->get_type() : '' ); ?>"
231 - data-sku="<?php echo esc_attr( $sku ); ?>"
232 - data-name="<?php echo esc_attr( $p->post_title ); ?>"
233 - data-billing-period="<?php echo esc_attr( $billing_period_meta ); ?>"
234 - data-billing-per="<?php echo esc_attr( $billing_per_meta ?: '1' ); ?>"
235 - data-trial-per="<?php echo esc_attr( $trial_per_meta ); ?>"
236 - data-signup-fee="<?php echo esc_attr( $signup_fee_meta ); ?>">
237 - <div class="wpsubs-p2-product-search__avatar" style="background:<?php echo esc_attr( $color['bg'] ); ?>;color:<?php echo esc_attr( $color['fg'] ); ?>">
238 - <?php echo esc_html( $initials ?: '?' ); ?>
228 + <div class="wpsubs-dur__body">
229 + <div class="wpsubs-form-row">
230 + <label><?php esc_html_e( 'Billing every', 'subscription' ); ?></label>
231 + <div class="wpsubs-p2-billing-group">
232 + <input type="number" class="wpsubs-input wpsubs-p2-billing-per-input" autocomplete="off" min="1" value="1" data-dur-freq
233 + <?php echo $is_pro ? '' : 'readonly max="1" title="' . esc_attr__( 'Upgrade to Pro to bill every few periods.', 'subscription' ) . '"'; ?>>
234 +<?php
235 + wpsubs_render_adv_select(
236 + array(
237 + 'name' => 'subscrpt_dur_interval',
238 + 'value' => 'month',
239 + 'options' => $interval_options,
240 + 'class' => 'wpsubs-dur__interval',
241 + 'attrs' => array( 'data-dur-interval' => '1' ),
242 + )
243 + );
244 + ?>
239 245 </div>
240 - <div class="wpsubs-p2-product-search__info">
241 - <p class="wpsubs-p2-product-search__name">
242 - <?php echo esc_html( $p->post_title ); ?>
243 - <?php if ( $is_variable_locked ) : ?>
244 - <span class="wpsubs-p2-pro-badge" title="<?php esc_attr_e( 'WPSubscription Pro required', 'subscription' ); ?>"><?php esc_html_e( 'Pro', 'subscription' ); ?></span>
245 - <?php endif; ?>
246 - </p>
247 - <p class="wpsubs-p2-product-search__meta"><?php echo esc_html( ( $sku ? 'SKU ' . $sku . ' · ' : '' ) . $type ); ?></p>
248 - </div>
249 - <?php if ( '' !== $price ) : ?>
250 - <span class="wpsubs-p2-product-search__price"><?php echo esc_html( get_woocommerce_currency_symbol() . number_format( (float) $price, 2 ) ); ?></span>
251 - <?php endif; ?>
252 246 </div>
253 - <?php endforeach; ?>
254 - <div class="wpsubs-p2-product-search__empty" style="display:none;"><?php esc_html_e( 'No products found.', 'subscription' ); ?></div>
247 + <div class="wpsubs-form-row" style="margin-bottom:0;">
248 + <label><?php esc_html_e( 'Name', 'subscription' ); ?></label>
249 + <input type="text" class="wpsubs-input" autocomplete="off" data-dur-name placeholder="<?php esc_attr_e( 'e.g. Every Month', 'subscription' ); ?>">
250 + </div>
255 251 </div>
256 252 </div>
257 - <input type="hidden" name="subscrpt_existing_product" id="subscrpt-existing-product-hidden" value="<?php echo $product_id > 0 ? esc_attr( $product_id ) : ''; ?>">
258 - </div>
259 - <div id="subscrpt-selected-product-chip" class="wpsubs-p2-selected-product" style="display:none;">
260 - <div class="wpsubs-p2-selected-product__avatar" id="p2-chip-avatar"></div>
261 - <div class="wpsubs-p2-selected-product__info">
262 - <p class="wpsubs-p2-selected-product__name" id="p2-chip-name"></p>
263 - <p class="wpsubs-p2-selected-product__meta" id="p2-chip-meta"></p>
264 - </div>
265 - <button type="button" class="wpsubs-p2-selected-product__clear" id="subscrpt-btn-clear-product" aria-label="<?php esc_attr_e( 'Clear selection', 'subscription' ); ?>">×</button>
266 - </div>
267 - <!-- Variation picker (shown when a variable product is selected) -->
268 - <div id="subscrpt-variation-picker-wrap" class="wpsubs-p2-variation-picker" style="display:none;">
269 - <div id="subscrpt-variation-picker-list"></div>
270 - </div>
271 - <input type="hidden" name="subscrpt_variation_id" id="subscrpt-variation-id-hidden" value="">
253 + </template>
272 254 </div>
273 - <?php endif; ?>
274 255 </div>
275 256
276 - <!-- 2. Subscription details -->
277 - <div class="wpsubs-p2-section-block" style="margin-bottom:0;">
278 - <p class="wpsubs-p2-section-label"><?php esc_html_e( '2. Subscription details', 'subscription' ); ?></p>
279 - <p class="wpsubs-p2-section-desc"><?php esc_html_e( 'How and how often customers are billed once they subscribe.', 'subscription' ); ?></p>
257 + <!-- PAGE 3: Connect to a Product -->
258 + <div class="wpsubs-wizard-section" data-page="3" id="subscrpt-section-3">
259 + <div class="wpsubs-wizard-card">
260 + <h1 class="wpsubs-p2-page-title"><?php esc_html_e( 'Connect the plan to a product', 'subscription' ); ?></h1>
261 + <p class="wpsubs-p2-page-subtitle"><?php esc_html_e( 'Connect this plan to a product to make it subscribable.', 'subscription' ); ?></p>
280 262
281 - <div class="wpsubs-p2-body">
282 - <!-- Left: form -->
283 - <div>
284 - <!-- Product name -->
285 - <div id="subscrpt-new-product-fields">
286 - <div class="wpsubs-form-row">
287 - <label for="subscrpt_product_name"><?php esc_html_e( 'Product name', 'subscription' ); ?></label>
288 - <input type="text" id="subscrpt_product_name" name="subscrpt_product_name" class="wpsubs-input" autocomplete="off" placeholder="<?php esc_attr_e( 'e.g. Monthly Subscription Box', 'subscription' ); ?>" value="<?php echo $product ? esc_attr( $product->get_name() ) : ( isset( $session_data['product_name'] ) ? esc_attr( $session_data['product_name'] ) : '' ); ?>">
289 - <p class="wpsubs-p2-field-hint"><?php esc_html_e( 'Shown on your store page and in subscription emails.', 'subscription' ); ?></p>
263 + <div class="wpsubs-p2-section-block">
264 + <?php if ( $has_products ) : ?>
265 + <p class="wpsubs-p2-section-label"><?php esc_html_e( '1. Select a product', 'subscription' ); ?></p>
266 + <div class="wpsubs-p2-option-cards wpsubs-p2-option-cards--compact">
267 + <button type="button" class="wpsubs-p2-option-card wpsubs-connect-mode-card active" data-mode="existing">
268 + <div class="wpsubs-p2-option-card__icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg></div>
269 + <p class="wpsubs-p2-option-card__title"><?php esc_html_e( 'Use an existing product', 'subscription' ); ?></p>
270 + </button>
271 + <button type="button" class="wpsubs-p2-option-card wpsubs-connect-mode-card" data-mode="new">
272 + <div class="wpsubs-p2-option-card__icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></div>
273 + <p class="wpsubs-p2-option-card__title"><?php esc_html_e( 'Create a new product', 'subscription' ); ?></p>
274 + </button>
290 275 </div>
291 - </div>
292 276
293 - <?php
294 - $billing_period = isset( $session_data['billing_period'] ) ? $session_data['billing_period'] : 'months';
295 - $trial_period = isset( $session_data['trial_timing_option'] ) ? $session_data['trial_timing_option'] : 'days';
296 - $trial_period_options = array(
297 - array(
298 - 'value' => 'days',
299 - 'label' => __( 'Day', 'subscription' ),
300 - ),
301 - array(
302 - 'value' => 'weeks',
303 - 'label' => __( 'Week', 'subscription' ),
304 - ),
305 - array(
306 - 'value' => 'months',
307 - 'label' => __( 'Month', 'subscription' ),
308 - ),
309 - array(
310 - 'value' => 'years',
311 - 'label' => __( 'Year', 'subscription' ),
312 - ),
313 - );
314 - $period_options = array(
315 - array(
316 - 'value' => 'days',
317 - 'label' => __( 'Day', 'subscription' ),
318 - ),
319 - array(
320 - 'value' => 'weeks',
321 - 'label' => __( 'Week', 'subscription' ),
322 - ),
323 - array(
324 - 'value' => 'months',
325 - 'label' => __( 'Month', 'subscription' ),
326 - ),
327 - array(
328 - 'value' => 'years',
329 - 'label' => __( 'Year', 'subscription' ),
330 - ),
331 - );
332 - ?>
333 - <input type="hidden" id="subscrpt_timing_option" name="subscrpt_timing_option" value="never">
334 - <input type="hidden" id="subscrpt_billing_per" name="subscrpt_billing_per" value="<?php echo $is_pro && isset( $session_data['billing_per'] ) ? esc_attr( $session_data['billing_per'] ) : '1'; ?>">
277 + <div id="subscrpt-connect-existing">
278 + <p class="wpsubs-p2-section-desc"><?php esc_html_e( 'Pick a product to attach this plan to.', 'subscription' ); ?></p>
335 279
336 - <!-- Row: Price | Billing every (group component) -->
337 - <div class="wpsubs-p2-form-grid">
338 - <div class="wpsubs-form-row">
339 - <label for="subscrpt_product_price"><?php esc_html_e( 'Price', 'subscription' ); ?></label>
340 - <div class="wpsubs-p2-input-wrap">
341 - <span class="wpsubs-p2-input-prefix"><?php echo esc_html( get_woocommerce_currency_symbol() ); ?></span>
342 - <input type="text" id="subscrpt_product_price" name="subscrpt_product_price" class="wpsubs-input" autocomplete="off" style="padding-left:24px!important;" placeholder="0.00" value="<?php echo $product ? esc_attr( $product->get_price() ) : ( isset( $session_data['product_price'] ) ? esc_attr( $session_data['product_price'] ) : '' ); ?>">
280 + <div id="subscrpt-product-select-wrap">
281 + <div class="wpsubs-p2-product-search">
282 + <div class="wpsubs-p2-product-search__input-wrap">
283 + <svg class="wpsubs-p2-product-search__icon" width="15" height="15" 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>
284 + <input type="text" class="wpsubs-p2-product-search__input wpsubs-input" id="subscrpt-product-search-input"
285 + placeholder="<?php esc_attr_e( 'Search products by name or SKU...', 'subscription' ); ?>" autocomplete="off">
286 + </div>
287 + <div class="wpsubs-p2-product-search__dropdown" id="subscrpt-product-search-dropdown" style="display:none;">
288 + <?php
289 + $subscrpt_products = wc_get_products(
290 + array(
291 + 'status' => 'publish',
292 + 'limit' => 100,
293 + 'orderby' => 'title',
294 + 'order' => 'ASC',
295 + 'type' => $is_pro ? array( 'simple', 'variable' ) : array( 'simple' ),
296 + )
297 + );
298 + foreach ( $subscrpt_products as $subscrpt_i => $subscrpt_wc_p ) :
299 + $subscrpt_price = $subscrpt_wc_p->get_price();
300 + $subscrpt_sku = $subscrpt_wc_p->get_sku();
301 + $subscrpt_type = ucfirst( $subscrpt_wc_p->get_type() ) . ' ' . __( 'product', 'subscription' );
302 + $subscrpt_name = $subscrpt_wc_p->get_name();
303 + $subscrpt_words = array_filter( explode( ' ', $subscrpt_name ) );
304 + $subscrpt_initials = implode(
305 + '',
306 + array_slice(
307 + array_map(
308 + function ( $w ) {
309 + return mb_strtoupper( mb_substr( $w, 0, 1 ) );
310 + },
311 + $subscrpt_words
312 + ),
313 + 0,
314 + 2
315 + )
316 + );
317 + $subscrpt_color = $avatar_palette[ $subscrpt_i % count( $avatar_palette ) ];
318 + // A product already attached to a plan can't be connected again —
319 + // same rule as the Plans page product tab.
320 + $subscrpt_conns = \SpringDevs\Subscription\Illuminate\Plans\PlanRepository::get_product_connections( $subscrpt_wc_p->get_id() );
321 + $subscrpt_connected = ! empty( $subscrpt_conns );
322 + ?>
323 + <div class="wpsubs-p2-product-search__item<?php echo $subscrpt_connected ? ' wpsubs-p2-product-search__item--disabled' : ''; ?>"
324 + data-id="<?php echo esc_attr( $subscrpt_wc_p->get_id() ); ?>"
325 + data-price="<?php echo esc_attr( $subscrpt_price ); ?>"
326 + data-type="<?php echo esc_attr( $subscrpt_type ); ?>"
327 + data-sku="<?php echo esc_attr( $subscrpt_sku ); ?>"
328 + data-name="<?php echo esc_attr( $subscrpt_name ); ?>"
329 + <?php echo $subscrpt_connected ? 'data-connected="1"' : ''; ?>>
330 + <div class="wpsubs-p2-product-search__avatar" style="background:<?php echo esc_attr( $subscrpt_color['bg'] ); ?>;color:<?php echo esc_attr( $subscrpt_color['fg'] ); ?>">
331 + <?php echo esc_html( $subscrpt_initials ? $subscrpt_initials : '?' ); ?>
332 + </div>
333 + <div class="wpsubs-p2-product-search__info">
334 + <p class="wpsubs-p2-product-search__name">
335 + <?php echo esc_html( $subscrpt_name ); ?>
336 + <?php if ( $subscrpt_connected ) : ?>
337 + <span class="wpsubs-p2-product-search__connected"><?php esc_html_e( 'Added to another plan', 'subscription' ); ?></span>
338 + <?php endif; ?>
339 + </p>
340 + <p class="wpsubs-p2-product-search__meta"><?php echo esc_html( ( $subscrpt_sku ? 'SKU ' . $subscrpt_sku . ' · ' : '' ) . $subscrpt_type ); ?></p>
341 + </div>
342 + <?php if ( '' !== $subscrpt_price ) : ?>
343 + <span class="wpsubs-p2-product-search__price"><?php echo esc_html( $currency_symbol . number_format( (float) $subscrpt_price, 2 ) ); ?></span>
344 + <?php endif; ?>
345 + </div>
346 + <?php endforeach; ?>
347 + <div class="wpsubs-p2-product-search__empty" style="display:none;"><?php esc_html_e( 'No products found.', 'subscription' ); ?></div>
348 + </div>
349 + </div>
350 + <input type="hidden" id="subscrpt-existing-product-hidden" value="">
343 351 </div>
344 - </div>
345 - <div class="wpsubs-form-row">
346 - <label><?php esc_html_e( 'Billing every', 'subscription' ); ?></label>
347 - <div class="wpsubs-input-group wpsubs-p2-billing-group">
348 - <?php if ( $is_pro ) : ?>
349 - <input type="number" id="subscrpt_billing_per_visible" class="wpsubs-input wpsubs-p2-billing-per-input" autocomplete="off" min="1"
350 - value="<?php echo isset( $session_data['billing_per'] ) ? esc_attr( $session_data['billing_per'] ) : '1'; ?>"
351 - oninput="document.getElementById('subscrpt_billing_per').value=this.value">
352 - <?php endif; ?>
353 - <?php
354 - wpsubs_render_adv_select(
355 - array(
356 - 'name' => 'subscrpt_billing_period',
357 - 'id' => 'subscrpt-billing-period-select',
358 - 'value' => $billing_period,
359 - 'options' => $period_options,
360 - )
361 - );
362 - ?>
352 +
353 + <div id="subscrpt-selected-product-chip" class="wpsubs-p2-selected-product" style="display:none;">
354 + <div class="wpsubs-p2-selected-product__avatar" id="p3-chip-avatar"></div>
355 + <div class="wpsubs-p2-selected-product__info">
356 + <p class="wpsubs-p2-selected-product__name" id="p3-chip-name"></p>
357 + <p class="wpsubs-p2-selected-product__meta" id="p3-chip-meta"></p>
358 + </div>
359 + <button type="button" class="wpsubs-p2-selected-product__clear" id="subscrpt-btn-clear-product" aria-label="<?php esc_attr_e( 'Clear selection', 'subscription' ); ?>">×</button>
363 360 </div>
364 - </div>
365 - </div>
361 + </div><!-- /#subscrpt-connect-existing -->
362 + <?php endif; ?>
366 363
367 - <!-- Free trial (free) + Sign-up fee (Pro only) -->
368 - <div class="wpsubs-p2-form-grid">
364 + <div id="subscrpt-connect-new" <?php echo $has_products ? 'style="display:none;"' : ''; ?>>
365 + <?php if ( ! $has_products ) : ?>
366 + <p class="wpsubs-p2-section-label"><?php esc_html_e( '1. Create a product', 'subscription' ); ?></p>
367 + <p class="wpsubs-p2-section-desc"><?php esc_html_e( "You don't have any products yet. Create one to connect this plan.", 'subscription' ); ?></p>
368 + <?php endif; ?>
369 369 <div class="wpsubs-form-row">
370 - <label for="subscrpt_trial_timing_per"><?php esc_html_e( 'Free trial', 'subscription' ); ?> <span class="wpsubs-p2-label-optional"><?php esc_html_e( 'Optional', 'subscription' ); ?></span></label>
371 - <div class="wpsubs-input-group wpsubs-p2-billing-group">
372 - <input type="number" id="subscrpt_trial_timing_per" name="subscrpt_trial_timing_per" class="wpsubs-input wpsubs-p2-billing-per-input" autocomplete="off" min="0" value="<?php echo isset( $session_data['trial_timing_per'] ) ? esc_attr( $session_data['trial_timing_per'] ) : '0'; ?>">
373 - <?php
374 - wpsubs_render_adv_select(
375 - array(
376 - 'name' => 'subscrpt_trial_timing_option',
377 - 'id' => 'subscrpt-trial-period-select',
378 - 'value' => $trial_period,
379 - 'options' => $trial_period_options,
380 - )
381 - );
382 - ?>
383 - </div>
384 - <p class="wpsubs-p2-field-hint"><?php esc_html_e( 'Free period before the first charge. Leave 0 for none.', 'subscription' ); ?></p>
370 + <label for="subscrpt_new_product_name"><?php esc_html_e( 'Product name', 'subscription' ); ?></label>
371 + <input type="text" id="subscrpt_new_product_name" class="wpsubs-input" autocomplete="off" placeholder="<?php esc_attr_e( 'e.g. Monthly Subscription Box', 'subscription' ); ?>">
372 + <p class="wpsubs-p2-field-hint"><?php esc_html_e( 'Shown on your store and in emails.', 'subscription' ); ?></p>
385 373 </div>
386 - <div class="wpsubs-form-row <?php echo $is_pro ? '' : 'wpsubs-p2-field-pro-locked'; ?>">
387 - <label for="subscrpt_signup_fee">
388 - <?php esc_html_e( 'Sign-up fee', 'subscription' ); ?>
389 - <?php if ( ! $is_pro ) : ?>
390 - <span class="wpsubs-p2-pro-badge" title="<?php esc_attr_e( 'WPSubscription Pro required', 'subscription' ); ?>"><?php esc_html_e( 'Pro', 'subscription' ); ?></span>
391 - <?php else : ?>
392 - <span class="wpsubs-p2-label-optional"><?php esc_html_e( 'Optional', 'subscription' ); ?></span>
393 - <?php endif; ?>
394 - </label>
395 - <div class="wpsubs-p2-input-wrap">
396 - <span class="wpsubs-p2-input-prefix"><?php echo esc_html( get_woocommerce_currency_symbol() ); ?></span>
397 - <input type="text" id="subscrpt_signup_fee" name="subscrpt_signup_fee" class="wpsubs-input" autocomplete="off" style="padding-left:24px!important;" placeholder="0.00"
398 - value="<?php echo $is_pro && isset( $session_data['signup_fee'] ) ? esc_attr( $session_data['signup_fee'] ) : ''; ?>"
399 - <?php echo $is_pro ? '' : 'disabled'; ?>>
400 - </div>
401 - <?php if ( ! $is_pro ) : ?>
402 - <p class="wpsubs-p2-field-hint"><?php esc_html_e( 'One-time charge at checkout. Upgrade to Pro to enable.', 'subscription' ); ?></p>
403 - <?php else : ?>
404 - <p class="wpsubs-p2-field-hint"><?php esc_html_e( 'One-time charge at checkout.', 'subscription' ); ?></p>
405 - <?php endif; ?>
406 - </div>
407 374 </div>
408 375
409 - <!-- Hidden compat fields -->
410 - <input type="hidden" id="subscrpt_trial_enabled" name="subscrpt_trial_enabled" value="0">
411 - <input type="hidden" id="subscrpt_length_enabled" name="subscrpt_length_enabled" value="0">
412 - <input type="hidden" id="subscrpt_length_per" name="subscrpt_length_per" value="">
413 - <input type="hidden" id="subscrpt_length_option" name="subscrpt_length_option" value="months">
376 + </div><!-- /product section-block -->
377 +
378 + <!-- Per-duration pricing: each duration from step 2 gets a price and an
379 + on/off toggle. Rows are built from JS (renderConnectDurations). -->
380 + <div class="wpsubs-p2-section-block wpsubs-connect-pricing" style="margin-bottom:0;">
381 + <p class="wpsubs-p2-section-label"><?php esc_html_e( '2. Set pricing', 'subscription' ); ?></p>
382 + <p class="wpsubs-p2-section-desc"><?php esc_html_e( "Set a price for each duration. Turn off any you don't want.", 'subscription' ); ?></p>
383 + <div id="subscrpt-connect-durations"></div>
414 384 </div>
415 385
416 - <!-- Right: shop preview -->
417 - <div class="wpsubs-p2-preview-col">
418 - <p class="wpsubs-p2-preview-col-label"><?php esc_html_e( 'Shop Preview', 'subscription' ); ?></p>
419 - <div class="wpsubs-p1-preview-card">
420 - <div class="wpsubs-p1-preview-img">
421 - <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
422 - <path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path>
423 - <line x1="3" y1="6" x2="21" y2="6"></line>
424 - <path d="M16 10a4 4 0 0 1-8 0"></path>
425 - </svg>
426 - <div class="wpsubs-p1-preview-img__dots"><span></span><span></span><span></span></div>
386 + <template id="subscrpt-connect-dur-tpl">
387 + <div class="wpsubs-connect-dur" data-connect-row>
388 + <span class="wpsubs-connect-dur__icon"><?php echo $subscrpt_icon_cal; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
389 + <div class="wpsubs-connect-dur__text">
390 + <p class="wpsubs-connect-dur__name" data-connect-name></p>
391 + <p class="wpsubs-connect-dur__billing" data-connect-billing></p>
427 392 </div>
428 - <div class="wpsubs-p1-preview-body">
429 - <p class="wpsubs-p1-preview-name" id="p2-preview-name"><?php echo $product ? esc_html( $product->get_name() ) : esc_html__( 'Your product', 'subscription' ); ?></p>
430 - <p class="wpsubs-p1-preview-price"><span id="p2-preview-price"><?php echo $product ? esc_html( $product->get_price() ) : '0.00'; ?></span>$ <span>/ <span id="p2-preview-period"><?php echo isset( $session_data['billing_period'] ) ? esc_html( $session_data['billing_period'] ) : esc_html__( 'month', 'subscription' ); ?></span></span></p>
431 - <div class="wpsubs-p1-preview-btn"><?php esc_html_e( 'Sign up', 'subscription' ); ?></div>
393 + <div class="wpsubs-p2-input-wrap wpsubs-connect-dur__price">
394 + <span class="wpsubs-p2-input-prefix"><?php echo esc_html( $currency_symbol ); ?></span>
395 + <input type="text" class="wpsubs-input" data-connect-price autocomplete="off" placeholder="0.00" style="padding-left:24px!important;">
432 396 </div>
397 + <label class="wpsubs-connect-dur__switch">
398 + <input type="checkbox" class="wpsubs-toggle" data-connect-enabled checked>
399 + <span class="wpsubs-toggle-ui" aria-hidden="true"></span>
400 + </label>
433 401 </div>
434 - <p class="wpsubs-p2-preview-col-desc"><?php esc_html_e( 'This is how the product will appear on your shop page. Each purchase creates a subscription you\'ll manage from the Subscriptions list.', 'subscription' ); ?></p>
435 - </div>
402 + </template>
436 403 </div>
437 404 </div>
438 - </div>
439 405
440 - <!-- Nav outside card -->
441 - <div class="wpsubs-p2-nav">
442 - <button type="button" id="subscrpt-btn-back" class="wpsubs-p2-nav-back">
443 - &#8249; <?php esc_html_e( 'Back', 'subscription' ); ?>
444 - </button>
445 - <button type="button" id="subscrpt-btn-save" class="wpsubs-btn wpsubs-btn--primary">
446 - <?php esc_html_e( 'Create product', 'subscription' ); ?> &rsaquo;
447 - </button>
448 - </div>
449 - </div>
406 + <!-- PAGE 4: Finish — everything is created here, sequentially. -->
407 + <div class="wpsubs-wizard-section" data-page="4" id="subscrpt-section-4">
408 + <div class="wpsubs-wizard-card wpsubs-p3-card">
450 409
451 - <!-- =========================================== -->
452 - <!-- SECTION 3: Completion -->
453 - <!-- =========================================== -->
454 - <div class="wpsubs-wizard-section <?php echo 3 === $wizard_page ? 'active' : ''; ?>" id="subscrpt-section-3">
455 - <div class="wpsubs-wizard-card wpsubs-p3-card">
410 + <!-- Working state: shown while the plan, durations and product are created. -->
411 + <div id="subscrpt-finalize-progress" class="wpsubs-finalize-progress">
412 + <div class="wpsubs-finalize-spinner" aria-hidden="true"></div>
413 + <h1 class="wpsubs-p3-heading"><?php esc_html_e( 'Setting things up…', 'subscription' ); ?></h1>
414 + <p class="wpsubs-p3-subtext"><?php esc_html_e( 'Creating your plan, durations and product. This takes a moment.', 'subscription' ); ?></p>
415 + <ul class="wpsubs-finalize-steps">
416 + <li data-finalize-step="plan"><span class="wpsubs-finalize-steps__dot"></span><?php esc_html_e( 'Create the plan', 'subscription' ); ?></li>
417 + <li data-finalize-step="durations"><span class="wpsubs-finalize-steps__dot"></span><?php esc_html_e( 'Add billing durations', 'subscription' ); ?></li>
418 + <li data-finalize-step="product"><span class="wpsubs-finalize-steps__dot"></span><?php esc_html_e( 'Connect the product', 'subscription' ); ?></li>
419 + </ul>
420 + </div>
456 421
457 - <!-- Success icon -->
458 - <div class="wpsubs-p3-success-icon">
459 - <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
460 - <polyline points="20 6 9 17 4 12"></polyline>
461 - </svg>
462 - </div>
422 + <!-- Error state: shown if any step fails; the user can retry. -->
423 + <div id="subscrpt-finalize-error" class="wpsubs-finalize-error" hidden>
424 + <div class="wpsubs-finalize-error__icon" aria-hidden="true">
425 + <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
426 + </div>
427 + <h1 class="wpsubs-p3-heading"><?php esc_html_e( "Something didn't go through.", 'subscription' ); ?></h1>
428 + <p class="wpsubs-p3-subtext" id="subscrpt-finalize-error-msg"></p>
429 + <button type="button" id="subscrpt-btn-retry-finalize" class="wpsubs-btn wpsubs-btn--primary"><?php esc_html_e( 'Try again', 'subscription' ); ?></button>
430 + </div>
463 431
464 - <h1 class="wpsubs-p3-heading"><?php esc_html_e( 'Your product is live.', 'subscription' ); ?></h1>
465 - <p class="wpsubs-p3-subtext"><?php esc_html_e( "It's published to your shop now. When a customer buys it, a subscription is created automatically. You'll see those in the Subscriptions list.", 'subscription' ); ?></p>
432 + <!-- Success state: shown once everything is created. -->
433 + <div id="subscrpt-finalize-success" hidden>
434 + <div class="wpsubs-p3-success-icon">
435 + <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
436 + <polyline points="20 6 9 17 4 12"></polyline>
437 + </svg>
438 + </div>
466 439
467 - <?php
468 - if ( $product ) :
469 - $p3_price = $product->get_price();
470 - $p3_period_raw = isset( $session_data['billing_period'] ) ? $session_data['billing_period'] : 'months';
471 - $p3_billing_per = isset( $session_data['billing_per'] ) ? (int) $session_data['billing_per'] : 1;
472 - $p3_period_label = $p3_billing_per > 1
473 - ? $p3_billing_per . ' ' . strtolower( $p3_period_raw )
474 - : strtolower( subscrpt_get_typos( 1, $p3_period_raw ) );
475 - $p3_words = array_filter( explode( ' ', $product->get_name() ) );
476 - $p3_initials = implode(
477 - '',
478 - array_map(
479 - function ( $w ) {
480 - return strtoupper( mb_substr( $w, 0, 1 ) );
481 - },
482 - array_slice( $p3_words, 0, 2 )
483 - )
484 - );
485 - ?>
486 - <!-- Product card -->
487 - <div class="wpsubs-p3-product-card">
488 - <div class="wpsubs-p3-product-card__header">
489 - <span><?php esc_html_e( 'PRODUCT', 'subscription' ); ?></span>
490 - <span><?php esc_html_e( 'STATUS', 'subscription' ); ?></span>
491 - <span><?php esc_html_e( 'PRICE', 'subscription' ); ?></span>
492 - </div>
493 - <div class="wpsubs-p3-product-card__row">
494 - <div class="wpsubs-p3-product-card__product">
495 - <div class="wpsubs-p3-product-avatar"><?php echo esc_html( $p3_initials ); ?></div>
496 - <div>
497 - <p class="wpsubs-p3-product-name"><?php echo esc_html( $product->get_name() ); ?></p>
498 - <p class="wpsubs-p3-product-meta">
499 - <?php
500 - /* translators: %d: product ID */
501 - echo esc_html( sprintf( __( 'Product #%d', 'subscription' ), $product->get_id() ) );
502 - ?>
503 - &middot; <?php esc_html_e( 'Subscription', 'subscription' ); ?>
504 - </p>
440 + <h1 class="wpsubs-p3-heading"><?php esc_html_e( 'Your plan is live.', 'subscription' ); ?></h1>
441 + <p class="wpsubs-p3-subtext"><?php esc_html_e( 'Your product is now subscribable. When a customer buys it, a subscription is created automatically.', 'subscription' ); ?></p>
442 +
443 + <p class="wpsubs-p3-what-now-label"><?php esc_html_e( 'WHAT NOW?', 'subscription' ); ?></p>
444 +
445 + <div class="wpsubs-p3-action-rows">
446 + <button type="button" id="subscrpt-btn-add-another" class="wpsubs-p3-action-row">
447 + <div class="wpsubs-p3-action-row__icon">
448 + <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
449 + </div>
450 + <div class="wpsubs-p3-action-row__content">
451 + <p class="wpsubs-p3-action-row__title"><?php esc_html_e( 'Create another plan', 'subscription' ); ?></p>
452 + <p class="wpsubs-p3-action-row__desc"><?php esc_html_e( 'Set up another subscription plan now.', 'subscription' ); ?></p>
453 + </div>
454 + <svg class="wpsubs-p3-action-row__chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"></polyline></svg>
455 + </button>
505 456 </div>
457 +
458 + <p class="wpsubs-p3-help-text">
459 + <?php esc_html_e( 'Need help? Check the', 'subscription' ); ?>
460 + <a href="https://docs.wpsubscription.co/en?utm_source=plugin&utm_medium=admin&utm_campaign=docs" target="_blank" rel="noopener" class="wpsubs-p3-help-link"><?php esc_html_e( 'setup guide', 'subscription' ); ?></a>
461 + <?php esc_html_e( 'or', 'subscription' ); ?>
462 + <a href="https://wordpress.org/support/plugin/subscription/" target="_blank" rel="noopener" class="wpsubs-p3-help-link"><?php esc_html_e( 'contact support', 'subscription' ); ?></a>.
463 + </p>
506 464 </div>
507 - <div class="wpsubs-p3-product-card__status">
508 - <span class="wpsubs-p3-status-badge">
509 - <span class="wpsubs-p3-status-badge__dot"></span>
510 - <?php esc_html_e( 'Published', 'subscription' ); ?>
511 - </span>
512 - <p class="wpsubs-p3-status-sub"><?php esc_html_e( 'Live in your shop', 'subscription' ); ?></p>
513 - </div>
514 - <div class="wpsubs-p3-product-card__price">
515 - <span class="wpsubs-p3-price-amount"><?php echo wp_kses_post( wc_price( $p3_price ) ); ?></span>
516 - <span class="wpsubs-p3-price-period">/ <?php echo esc_html( $p3_period_label ); ?></span>
517 - </div>
518 465 </div>
519 466 </div>
520 - <?php endif; ?>
521 467
522 - <!-- What now -->
523 - <p class="wpsubs-p3-what-now-label"><?php esc_html_e( 'WHAT NOW?', 'subscription' ); ?></p>
468 + </div><!-- /.wpsubs-wizard-steps -->
524 469
525 - <div class="wpsubs-p3-action-rows">
526 - <?php if ( $product ) : ?>
527 - <a href="<?php echo esc_url( get_permalink( $product->get_id() ) ); ?>" target="_blank" rel="noopener" class="wpsubs-p3-action-row">
528 - <div class="wpsubs-p3-action-row__icon">
529 - <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path><line x1="3" y1="6" x2="21" y2="6"></line><path d="M16 10a4 4 0 0 1-8 0"></path></svg>
470 + <!-- ===================== Live preview (right) ===================== -->
471 + <aside class="wpsubs-wizard-aside">
472 + <div class="wpsubs-preview">
473 + <p class="wpsubs-preview__label"><?php esc_html_e( 'Live preview', 'subscription' ); ?></p>
474 + <div class="wpsubs-p1-graph" id="subscrpt-preview-graph" data-active="plan" aria-hidden="true">
475 + <svg class="wpsubs-p1-graph__lines" viewBox="0 0 300 420" preserveAspectRatio="none">
476 + <!-- Plan -> durations (left→right offsets +1.5, +3, +1: right highest,
477 + left slightly lower, middle lowest). data-line-dur maps each line
478 + to the duration it feeds, so it colours in when filled. -->
479 + <path class="wpsubs-p1-flow" data-line-dur="1" d="M150,50 C150,80 51,80 51,130" />
480 + <path class="wpsubs-p1-flow" data-line-dur="0" d="M150,50 L150,168" />
481 + <path class="wpsubs-p1-flow" data-line-dur="2" d="M150,50 C150,74 249,74 249,118" />
482 + <!-- Durations -> the single product (start at each card's bottom).
483 + data-line-to="prod" keeps these muted until a product is added, and
484 + each shows only while its duration's toggle is on. -->
485 + <path class="wpsubs-p1-flow" data-line-dur="1" data-line-to="prod" d="M51,168 C51,235 75,235 75,300" />
486 + <path class="wpsubs-p1-flow" data-line-dur="0" data-line-to="prod" d="M150,206 C150,255 75,255 75,300" />
487 + <path class="wpsubs-p1-flow" data-line-dur="2" data-line-to="prod" d="M249,156 C249,250 75,250 75,300" />
488 + <!-- Decorative lines to the second (muted) product. No data-line-*, so they never colour in -- they just keep the second card connected. -->
489 + <path class="wpsubs-p1-flow" d="M51,168 C51,240 225,240 225,330" />
490 + <path class="wpsubs-p1-flow" d="M150,206 C150,262 225,262 225,330" />
491 + <path class="wpsubs-p1-flow" d="M249,156 C249,250 225,250 225,330" />
492 + </svg>
493 +
494 + <div class="wpsubs-p1-node wpsubs-p1-node--plan" data-group="plan" style="left:21%;top:2.9%;">
495 + <span class="wpsubs-p1-node__icon"><?php echo $subscrpt_icon_plan; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
496 + <span class="wpsubs-p1-node__text">
497 + <span class="wpsubs-p1-node__title" id="subscrpt-preview-plan"><?php esc_html_e( 'Recurring Subscription', 'subscription' ); ?></span>
498 + <span class="wpsubs-p1-node__sub" id="subscrpt-preview-plan-type"><?php esc_html_e( 'Recurring', 'subscription' ); ?></span>
499 + </span>
530 500 </div>
531 - <div class="wpsubs-p3-action-row__content">
532 - <p class="wpsubs-p3-action-row__title"><?php esc_html_e( 'View product in shop', 'subscription' ); ?></p>
533 - <p class="wpsubs-p3-action-row__desc"><?php esc_html_e( 'See how customers will subscribe to it.', 'subscription' ); ?></p>
501 +
502 + <div class="wpsubs-p1-node wpsubs-p1-node--dur wpsubs-p1-node--ghost" data-group="dur" data-preview-dur="1" style="left:2%;top:31%;">
503 + <span class="wpsubs-p1-node__icon"><?php echo $subscrpt_icon_cal; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
504 + <span class="wpsubs-p1-node__text">
505 + <span class="wpsubs-p1-node__title"><?php esc_html_e( 'Duration', 'subscription' ); ?></span>
506 + <span class="wpsubs-p1-node__sub"><?php esc_html_e( 'Add more', 'subscription' ); ?></span>
507 + </span>
534 508 </div>
535 - <svg class="wpsubs-p3-action-row__chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"></polyline></svg>
536 - </a>
537 - <?php endif; ?>
509 + <div class="wpsubs-p1-node wpsubs-p1-node--dur wpsubs-p1-node--ghost" data-group="dur" data-preview-dur="0" style="left:35%;top:40%;">
510 + <span class="wpsubs-p1-node__icon"><?php echo $subscrpt_icon_cal; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
511 + <span class="wpsubs-p1-node__text">
512 + <span class="wpsubs-p1-node__title"><?php esc_html_e( 'Duration', 'subscription' ); ?></span>
513 + <span class="wpsubs-p1-node__sub"><?php esc_html_e( 'Add more', 'subscription' ); ?></span>
514 + </span>
515 + </div>
516 + <div class="wpsubs-p1-node wpsubs-p1-node--dur wpsubs-p1-node--ghost" data-group="dur" data-preview-dur="2" style="left:68%;top:28%;">
517 + <span class="wpsubs-p1-node__icon"><?php echo $subscrpt_icon_cal; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
518 + <span class="wpsubs-p1-node__text">
519 + <span class="wpsubs-p1-node__title"><?php esc_html_e( 'Duration', 'subscription' ); ?></span>
520 + <span class="wpsubs-p1-node__sub"><?php esc_html_e( 'Add more', 'subscription' ); ?></span>
521 + </span>
522 + </div>
538 523
539 - <button type="button" id="subscrpt-btn-add-another" class="wpsubs-p3-action-row">
540 - <div class="wpsubs-p3-action-row__icon">
541 - <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
524 + <div class="wpsubs-p1-node wpsubs-p1-node--prod" data-group="prod" style="left:3%;top:71.4%;">
525 + <span class="wpsubs-p1-node__icon"><?php echo $subscrpt_icon_box; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
526 + <span class="wpsubs-p1-node__text">
527 + <span class="wpsubs-p1-node__title" id="subscrpt-preview-prod"><?php esc_html_e( 'Product', 'subscription' ); ?></span>
528 + <span class="wpsubs-p1-node__sub" id="subscrpt-preview-prod-sub"><?php esc_html_e( 'Price', 'subscription' ); ?></span>
529 + </span>
542 530 </div>
543 - <div class="wpsubs-p3-action-row__content">
544 - <p class="wpsubs-p3-action-row__title"><?php esc_html_e( 'Add another product', 'subscription' ); ?></p>
545 - <p class="wpsubs-p3-action-row__desc"><?php esc_html_e( 'Create another subscription product now.', 'subscription' ); ?></p>
531 + <div class="wpsubs-p1-node wpsubs-p1-node--prod wpsubs-p1-node--ghost" data-group="prod" style="left:53%;top:78.6%;">
532 + <span class="wpsubs-p1-node__icon"><?php echo $subscrpt_icon_box; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted static SVG. ?></span>
533 + <span class="wpsubs-p1-node__text">
534 + <span class="wpsubs-p1-node__title"><?php esc_html_e( 'Product', 'subscription' ); ?></span>
535 + <span class="wpsubs-p1-node__sub"><?php esc_html_e( 'Add more', 'subscription' ); ?></span>
536 + </span>
546 537 </div>
547 - <svg class="wpsubs-p3-action-row__chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"></polyline></svg>
538 + </div>
539 + <p class="wpsubs-preview__caption"><?php esc_html_e( 'A plan holds billing durations and connects to a product.', 'subscription' ); ?></p>
540 + </div>
541 + </aside>
542 +
543 + <!-- ======================= Footer nav (under the left column) ======================= -->
544 + <div class="wpsubs-wizard-footer">
545 + <div class="wpsubs-wizard-nav" data-nav="1" hidden>
546 + <button type="button" id="subscrpt-btn-back-0" class="wpsubs-p2-nav-back">
547 + &#8249; <?php esc_html_e( 'Back', 'subscription' ); ?>
548 548 </button>
549 -
549 + <button type="button" id="subscrpt-btn-next-1" class="wpsubs-btn wpsubs-btn--primary">
550 + <?php esc_html_e( 'Continue', 'subscription' ); ?> &rsaquo;
551 + </button>
550 552 </div>
551 -
552 - <p class="wpsubs-p3-help-text">
553 - <?php esc_html_e( 'Need help? Check the', 'subscription' ); ?>
554 - <a href="https://docs.wpsubscription.co/en" target="_blank" rel="noopener" class="wpsubs-p3-help-link"><?php esc_html_e( 'setup guide', 'subscription' ); ?></a>
555 - <?php esc_html_e( 'or', 'subscription' ); ?>
556 - <a href="https://wordpress.org/support/plugin/subscription/" target="_blank" rel="noopener" class="wpsubs-p3-help-link"><?php esc_html_e( 'contact support', 'subscription' ); ?></a>.
557 - </p>
553 + <div class="wpsubs-wizard-nav" data-nav="2" hidden>
554 + <button type="button" id="subscrpt-btn-back-1" class="wpsubs-p2-nav-back">
555 + &#8249; <?php esc_html_e( 'Back', 'subscription' ); ?>
556 + </button>
557 + <button type="button" id="subscrpt-btn-next-2" class="wpsubs-btn wpsubs-btn--primary">
558 + <?php esc_html_e( 'Continue', 'subscription' ); ?> &rsaquo;
559 + </button>
560 + </div>
561 + <div class="wpsubs-wizard-nav" data-nav="3" hidden>
562 + <button type="button" id="subscrpt-btn-back-2" class="wpsubs-p2-nav-back">
563 + &#8249; <?php esc_html_e( 'Back', 'subscription' ); ?>
564 + </button>
565 + <button type="button" id="subscrpt-btn-next-3" class="wpsubs-btn wpsubs-btn--primary">
566 + <?php esc_html_e( 'Continue', 'subscription' ); ?> &rsaquo;
567 + </button>
568 + </div>
569 + <div class="wpsubs-wizard-nav" data-nav="4" hidden>
570 + <div class="wpsubs-wizard-nav__group">
571 + <a href="#" id="subscrpt-link-plans" class="wpsubs-btn wpsubs-btn--outline" hidden>
572 + <?php esc_html_e( 'Go to Plans', 'subscription' ); ?>
573 + </a>
574 + <a href="#" id="subscrpt-link-products" class="wpsubs-btn wpsubs-btn--outline" hidden>
575 + <?php esc_html_e( 'Go to products', 'subscription' ); ?>
576 + </a>
577 + </div>
578 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=wp-subscription' ) ); ?>" id="subscrpt-btn-finish" class="wpsubs-btn wpsubs-btn--primary" hidden>
579 + <?php esc_html_e( 'Finish', 'subscription' ); ?>
580 + </a>
581 + </div>
558 582 </div>
559 583
560 - <!-- Bottom nav -->
561 - <div class="wpsubs-p3-nav">
562 - <button type="button" id="subscrpt-btn-start-over" class="wpsubs-btn wpsubs-btn--outline">
563 - <?php esc_html_e( 'Start over', 'subscription' ); ?>
564 - </button>
565 - <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=product' ) ); ?>" class="wpsubs-btn wpsubs-btn--primary">
566 - <?php esc_html_e( 'Go to products', 'subscription' ); ?>
567 - </a>
568 - </div>
569 - </div>
584 + </div><!-- /.wpsubs-wizard-layout -->
570 585 </div>