PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.8
Yatra – Travel Booking & Tour Operator Software v3.0.2.8
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / templates / setup-wizard / theme.php

theme.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.8, at templates/setup-wizard/theme.php

307 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Setup Wizard - Theme Step
4 *
5 * @package Yatra
6 */
7
8 defined('ABSPATH') || exit;
9
10 $resa_theme = wp_get_theme('resa');
11 $is_resa_installed = $resa_theme->exists();
12 $current_theme = wp_get_theme();
13 $current_theme_slug = $current_theme->get_stylesheet();
14 $is_resa_active = ($current_theme_slug === 'resa') || ($current_theme->get('Name') === 'Resa') || (get_template() === 'resa') || (get_stylesheet() === 'resa');
15 ?>
16
17 <form method="post" class="wizard-step">
18 <?php wp_nonce_field('yatra-setup'); ?>
19 <input type="hidden" name="save_step" value="theme">
20
21 <div class="wizard-header wizard-header--task">
22 <p class="wizard-header-kicker"><?php echo esc_html($this->get_wizard_progress_label()); ?></p>
23 <h1><?php esc_html_e('Site appearance', 'yatra'); ?></h1>
24 <p class="wizard-header-lead"><?php esc_html_e('Optional: Resa is built for travel layouts and pairs well with Yatra trip pages.', 'yatra'); ?></p>
25 </div>
26
27 <div class="wizard-content">
28 <!-- Resa Theme Card -->
29 <div class="theme-card-full" style="max-width: 600px; margin: 0 auto; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
30 <div style="width: 100%; height: 300px; overflow: hidden;">
31 <img src="https://i0.wp.com/themes.svn.wordpress.org/resa/1.0.6/screenshot.png"
32 alt="<?php esc_attr_e('Resa Theme', 'yatra'); ?>"
33 style="width: 100%; height: 100%; object-fit: cover;"
34 onerror="this.src='<?php echo esc_url(YATRA_PLUGIN_URI . 'assets/images/resa-theme-preview.jpg'); ?>'">
35 </div>
36 <div style="padding: 24px; background: #fff;">
37 <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 16px;">
38 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#4f46e5" stroke-width="2">
39 <path d="M12 2L2 7l10 5 10-5-10-5z"></path>
40 <path d="M2 17l10 5 10-5M2 12l10 5 10-5"></path>
41 </svg>
42 <h3 style="margin: 0; font-size: 20px; font-weight: 600; color: #111827;"><?php esc_html_e('Resa Theme', 'yatra'); ?></h3>
43 <span style="margin-left: auto; padding: 4px 12px; background: #4f46e5; color: #fff; font-size: 11px; font-weight: 700; border-radius: 12px; text-transform: uppercase; letter-spacing: 0.05em;"><?php esc_html_e('Recommended', 'yatra'); ?></span>
44 <?php if ($is_resa_installed && $is_resa_active) : ?>
45 <span style="padding: 4px 12px; background: #10b981; color: #fff; font-size: 11px; font-weight: 700; border-radius: 12px; text-transform: uppercase; letter-spacing: 0.05em;"><?php esc_html_e('Activated', 'yatra'); ?></span>
46 <?php endif; ?>
47 </div>
48
49 <p style="color: #6b7280; margin-bottom: 20px; line-height: 1.5;">
50 <?php esc_html_e('The perfect theme for travel and trip booking websites. Designed specifically to work seamlessly with Yatra plugin.', 'yatra'); ?>
51 </p>
52
53 <?php if ($is_resa_installed && $is_resa_active) : ?>
54 <!-- Theme is active, show no action buttons -->
55 <?php elseif ($is_resa_installed && !$is_resa_active) : ?>
56 <div style="display: flex; align-items: center; justify-content: space-between; background: #fef3c7; border: 1px solid #f59e0b; border-radius: 8px; padding: 16px;">
57 <div style="display: flex; align-items: center;">
58 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" style="margin-right: 12px;">
59 <path d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
60 </svg>
61 <span style="font-weight: 600; color: #92400e;"><?php esc_html_e('Installed but not activated', 'yatra'); ?></span>
62 </div>
63 <button type="button" class="btn btn-warning" onclick="activateTheme('resa')" style="display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; background: #f59e0b; color: #fff; border: none; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.15s ease;" onmouseover="this.style.background='#d97706'; this.style.transform='translateY(-1px)';" onmouseout="this.style.background='#f59e0b'; this.style.transform='translateY(0)';">
64 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
65 <path d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
66 </svg>
67 <?php esc_html_e('Activate', 'yatra'); ?>
68 </button>
69 </div>
70 <?php else : ?>
71 <div style="display: flex; align-items: center; justify-content: space-between; background: #eff6ff; border: 1px solid #3b82f6; border-radius: 8px; padding: 16px;">
72 <div style="display: flex; align-items: center;">
73 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="2" style="margin-right: 12px;">
74 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
75 <polyline points="7 10 12 15 17 10"></polyline>
76 <line x1="12" y1="15" x2="12" y2="3"></line>
77 </svg>
78 <span style="font-weight: 600; color: #1e40af;"><?php esc_html_e('Not installed', 'yatra'); ?></span>
79 </div>
80 <button type="button" class="btn btn-primary" onclick="installAndActivateTheme('resa')" style="display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; background: #3b82f6; color: #fff; border: none; border-radius: 6px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.15s ease;" onmouseover="this.style.background='#2563eb'; this.style.transform='translateY(-1px)';" onmouseout="this.style.background='#3b82f6'; this.style.transform='translateY(0)';">
81 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
82 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
83 <polyline points="7 10 12 15 17 10"></polyline>
84 <line x1="12" y1="15" x2="12" y2="3"></line>
85 </svg>
86 <?php esc_html_e('Install & Activate', 'yatra'); ?>
87 </button>
88 </div>
89 <?php endif; ?>
90 </div>
91 </div>
92 </div>
93
94 <div class="wizard-footer">
95 <a href="<?php echo esc_url($this->get_step_url('currency')); ?>" class="btn btn-secondary wizard-footer-back">
96 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>
97 <?php esc_html_e('Back', 'yatra'); ?>
98 </a>
99 <div class="wizard-footer-actions">
100 <a href="<?php echo esc_url($this->get_next_step_link()); ?>" class="btn btn-secondary btn-skip"><?php esc_html_e('Skip', 'yatra'); ?></a>
101 <button type="submit" class="btn btn-primary">
102 <?php esc_html_e('Continue', 'yatra'); ?>
103 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
104 </button>
105 </div>
106 </div>
107 </form>
108
109 <script>
110 // Define ajaxurl if not available
111 if (typeof ajaxurl === 'undefined') {
112 ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
113 }
114
115 function installAndActivateTheme(themeSlug) {
116 const button = event.target;
117 const originalContent = button.innerHTML;
118
119 // Show loading state with spinner
120 button.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="animation: spin 1s linear infinite;"><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2"></circle><path d="M12 2v10l4 2" fill="none" stroke="currentColor" stroke-width="2"></path></svg> Installing...';
121 button.disabled = true;
122 button.style.cursor = 'not-allowed';
123 button.style.opacity = '0.7';
124
125 // Add CSS animation for spinner
126 if (!document.querySelector('#spinner-style')) {
127 const style = document.createElement('style');
128 style.id = 'spinner-style';
129 style.textContent = '@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }';
130 document.head.appendChild(style);
131 }
132
133 // Make AJAX request to install theme
134 jQuery.ajax({
135 url: ajaxurl,
136 type: 'POST',
137 data: {
138 action: 'yatra_install_theme',
139 theme_slug: themeSlug,
140 nonce: '<?php echo wp_create_nonce('yatra_theme_actions'); ?>'
141 },
142 success: function(response) {
143 console.log('Raw installation response:', response); // Debug log
144
145 // Handle case where HTML is mixed with JSON
146 let jsonResponse = response;
147 if (typeof response === 'string' && response.includes('{')) {
148 // Extract JSON from mixed HTML/JSON response
149 const jsonStart = response.lastIndexOf('{');
150 const jsonEnd = response.lastIndexOf('}') + 1;
151 const jsonString = response.substring(jsonStart, jsonEnd);
152
153 try {
154 jsonResponse = JSON.parse(jsonString);
155 } catch (e) {
156 console.error('Failed to parse JSON:', e);
157 resetButtonState(button, originalContent);
158 alert('Installation failed: Invalid response format');
159 return;
160 }
161 }
162
163 if (jsonResponse && jsonResponse.success) {
164 // Theme installed successfully, now activate it
165 button.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="animation: spin 1s linear infinite;"><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2"></circle><path d="M12 2v10l4 2" fill="none" stroke="currentColor" stroke-width="2"></path></svg> Activating...';
166
167 jQuery.ajax({
168 url: ajaxurl,
169 type: 'POST',
170 data: {
171 action: 'yatra_activate_theme',
172 theme_slug: themeSlug,
173 nonce: '<?php echo wp_create_nonce('yatra_theme_actions'); ?>'
174 },
175 success: function(activateResponse) {
176 console.log('Activation response:', activateResponse); // Debug log
177 if (activateResponse && activateResponse.success) {
178 // Update UI dynamically to show activated state
179 updateThemeCardToActivated();
180 } else {
181 resetButtonState(button, originalContent);
182 const errorMsg = activateResponse && activateResponse.data ? activateResponse.data : 'Unknown activation error';
183 alert('Activation failed: ' + errorMsg);
184 }
185 },
186 error: function(xhr, status, error) {
187 console.log('Activation AJAX error:', {xhr: xhr, status: status, error: error}); // Debug log
188 resetButtonState(button, originalContent);
189 alert('Activation request failed. Please try again.');
190 }
191 });
192 } else {
193 resetButtonState(button, originalContent);
194 const errorMsg = jsonResponse && jsonResponse.data ? jsonResponse.data : 'Unknown installation error';
195 alert('Installation failed: ' + errorMsg);
196 }
197 },
198 error: function() {
199 button.innerHTML = originalContent;
200 button.disabled = false;
201 alert('Installation request failed. Please try again.');
202 }
203 });
204 }
205
206 function activateTheme(themeSlug) {
207 const button = event.target;
208 const originalContent = button.innerHTML;
209
210 // Show loading state with spinner
211 button.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="animation: spin 1s linear infinite;"><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2"></circle><path d="M12 2v10l4 2" fill="none" stroke="currentColor" stroke-width="2"></path></svg> Activating...';
212 button.disabled = true;
213 button.style.cursor = 'not-allowed';
214 button.style.opacity = '0.7';
215
216 // Add CSS animation for spinner if not already added
217 if (!document.querySelector('#spinner-style')) {
218 const style = document.createElement('style');
219 style.id = 'spinner-style';
220 style.textContent = '@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }';
221 document.head.appendChild(style);
222 }
223
224 // Make AJAX request to activate theme
225 jQuery.ajax({
226 url: ajaxurl,
227 type: 'POST',
228 data: {
229 action: 'yatra_activate_theme',
230 theme_slug: themeSlug,
231 nonce: '<?php echo wp_create_nonce('yatra_theme_actions'); ?>'
232 },
233 success: function(response) {
234 console.log('Activation response:', response); // Debug log
235 if (response && response.success) {
236 // Update UI dynamically to show activated state
237 updateThemeCardToActivated();
238 } else {
239 resetButtonState(button, originalContent);
240 const errorMsg = response && response.data ? response.data : 'Unknown activation error';
241 alert('Activation failed: ' + errorMsg);
242 }
243 },
244 error: function(xhr, status, error) {
245 console.log('Activation AJAX error:', {xhr: xhr, status: status, error: error}); // Debug log
246 resetButtonState(button, originalContent);
247 alert('Activation request failed. Please try again.');
248 }
249 });
250 }
251
252 function resetButtonState(button, originalContent) {
253 button.innerHTML = originalContent;
254 button.disabled = false;
255 button.style.cursor = 'pointer';
256 button.style.opacity = '1';
257 }
258
259 function updateThemeCardToActivated() {
260 // Find the theme card and update it to show activated state
261 const themeCard = document.querySelector('.theme-card-full');
262 if (!themeCard) return;
263
264 // Remove any existing action blocks
265 const actionBlocks = themeCard.querySelectorAll('div[style*="background: #fef3c7"], div[style*="background: #eff6ff"]');
266 actionBlocks.forEach(block => block.remove());
267
268 // Add "Activated" badge if not already present
269 const header = themeCard.querySelector('div[style*="align-items: center; gap: 12px"]');
270 if (header) {
271 // Remove existing "Activated" badge if present
272 const existingBadge = header.querySelector('span[style*="background: #10b981"]');
273 if (existingBadge) existingBadge.remove();
274
275 // Add new "Activated" badge
276 const activatedBadge = document.createElement('span');
277 activatedBadge.style.cssText = 'padding: 4px 12px; background: #10b981; color: #fff; font-size: 11px; font-weight: 700; border-radius: 12px; text-transform: uppercase; letter-spacing: 0.05em;';
278 activatedBadge.textContent = '<?php esc_html_e('Activated', 'yatra'); ?>';
279 header.appendChild(activatedBadge);
280 }
281
282 // Show success message briefly
283 const successMsg = document.createElement('div');
284 successMsg.style.cssText = 'background: #d1fae5; border: 1px solid #10b981; border-radius: 8px; padding: 16px; margin-bottom: 20px; text-align: center; color: #065f46; font-weight: 600;';
285 successMsg.innerHTML = `
286 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.5" style="display: inline-block; vertical-align: middle; margin-right: 8px;">
287 <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
288 <polyline points="22 4 12 14.01 9 11.01"></polyline>
289 </svg>
290 <?php esc_html_e('Theme activated successfully!', 'yatra'); ?>
291 `;
292
293 // Insert success message after the description
294 const description = themeCard.querySelector('p[style*="color: #6b7280"]');
295 if (description && description.nextElementSibling) {
296 description.parentNode.insertBefore(successMsg, description.nextElementSibling);
297 }
298
299 // Remove success message after 3 seconds
300 setTimeout(() => {
301 if (successMsg.parentNode) {
302 successMsg.remove();
303 }
304 }, 3000);
305 }
306 </script>
307