PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.11.1
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.11.1
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / admin / modules / setup-wizard / components / Content / PreviewTemplate.vue

PreviewTemplate.vue in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 3.11.1, at admin/modules/setup-wizard/components/Content/PreviewTemplate.vue

204 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div class="wpfnl-mm-preview-modal-overlay" @click.self="closeModal">
3 <div class="wpfnl-mm-preview-modal">
4 <!-- Modal Header -->
5 <div class="wpfnl-mm-preview-modal-header">
6 <h3 class="wpfnl-mm-preview-modal-title">{{ template.title }}</h3>
7 <div class="wpfnl-mm-preview-device-switcher">
8 <button
9 class="wpfnl-mm-device-btn"
10 :class="{ 'active': activeView === 'desktop' }"
11 @click="activeView = 'desktop'"
12 title="Desktop View"
13 >
14 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">>
15 <path d="M14 2H2C1.44772 2 1 2.44772 1 3V11C1 11.5523 1.44772 12 2 12H14C14.5523 12 15 11.5523 15 11V3C15 2.44772 14.5523 2 14 2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
16 <path d="M5 14H11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
17 <path d="M8 12V14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
18 </svg>
19 </button>
20 <button
21 class="wpfnl-mm-device-btn"
22 :class="{ 'active': activeView === 'tablet' }"
23 @click="activeView = 'tablet'"
24 title="Tablet View"
25 >
26 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">>
27 <rect x="3" y="1" width="10" height="14" rx="1.5" stroke="currentColor" stroke-width="1.5"/>
28 <path d="M7 12H9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
29 </svg>
30 </button>
31 <button
32 class="wpfnl-mm-device-btn"
33 :class="{ 'active': activeView === 'mobile' }"
34 @click="activeView = 'mobile'"
35 title="Mobile View"
36 >
37 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">>
38 <rect x="4" y="1" width="8" height="14" rx="1.5" stroke="currentColor" stroke-width="1.5"/>
39 <path d="M7 12H9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
40 </svg>
41 </button>
42 </div>
43
44 <div class="wpfnl-mm-preview-modal-actions">
45 <button class="wpfnl-mm-btn wpfnl-mm-btn-primary wpfnl-mm-btn-import-modal" @click="importTemplate">
46 Import
47 <svg width="17" height="12" viewBox="0 0 17 12" fill="none" xmlns="http://www.w3.org/2000/svg">>
48 <path d="M1 6H16M16 6L11 1M16 6L11 11" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
49 </svg>
50 </button>
51
52 <!-- Close Button -->
53 <button class="wpfnl-mm-preview-close-btn" @click="closeModal" title="Close">
54 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">>
55 <path d="M12 4L4 12M4 4L12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
56 </svg>
57 </button>
58 </div>
59 </div>
60
61 <!-- Modal Body -->
62 <div class="wpfnl-mm-preview-modal-body">
63 <!-- Steps Navigation -->
64 <div class="wpfnl-mm-preview-steps">
65 <div
66 v-for="step in displaySteps"
67 :key="step.ID"
68 class="wpfnl-mm-preview-step-card"
69 :class="{ 'active': activeStep.ID === step.ID }"
70 @click="setActiveStep(step)"
71 >
72 <div class="wpfnl-mm-preview-step-thumbnail">
73 <img :src="step.featured_image" :alt="step.title">
74 </div>
75 <p class="wpfnl-mm-preview-step-type">{{ step.step_type }}</p>
76 </div>
77 </div>
78
79 <!-- Preview Content -->
80 <div class="wpfnl-mm-preview-content" :class="activeView">
81 <div :class="`wpfnl-mm-preview-device-frame ${shouldShowImagePreview(activeStep) ? 'image-preview' : ''}`">
82 <div class="wpfnl-mm-preview-iframe-wrapper">
83 <iframe
84 :src="activeStep?.link"
85 width="100%"
86 height="100%"
87 frameborder="0"
88 @load="iframeLoaded"
89 v-if="!shouldShowImagePreview(activeStep)"
90 ></iframe>
91 <div class="wpfnl-mm-preview-loader" v-if="isLoading && !shouldShowImagePreview(activeStep)">
92 <span class="wpfnl-mm-loader"></span>
93 </div>
94
95 <div v-if="shouldShowImagePreview(activeStep)" class="wpfnl-mm-preview-checkout-placeholder">
96 <img :src="getStepImageForView(activeStep)" :alt="activeStep?.title">
97 </div>
98 </div>
99 </div>
100 </div>
101 </div>
102 </div>
103 </div>
104 </template>
105
106 <script>
107 export default {
108 name: 'PreviewTemplate',
109 props: {
110 template: {
111 type: Object,
112 required: true,
113 default: () => ({
114 steps: [],
115 title: ''
116 })
117 },
118 isStoreCheckout: {
119 type: Boolean,
120 default: false
121 },
122 isSalesFunnel: {
123 type: Boolean,
124 default: false
125 }
126 },
127 data() {
128 return {
129 activeStep: {},
130 activeView: 'desktop',
131 isLoading: true
132 }
133 },
134 computed: {
135 displaySteps() {
136 if (!this.template.steps) return [];
137 if (this.isStoreCheckout) {
138 return this.template.steps.filter(s => s.step_type === 'checkout' || s.step_type === 'thankyou');
139 }
140 if (this.isSalesFunnel) {
141 return this.template.steps.filter(s =>
142 s.step_type === 'landing' ||
143 s.step_type === 'checkout' ||
144 s.step_type === 'thankyou'
145 );
146 }
147 return this.template.steps;
148 }
149 },
150 mounted() {
151 if (this.displaySteps.length > 0) {
152 this.activeStep = this.displaySteps[0];
153 }
154 // Prevent body scroll when modal is open
155 document.body.style.overflow = 'hidden';
156 },
157 beforeUnmount() {
158 // Restore body scroll when modal is closed
159 document.body.style.overflow = '';
160 },
161 methods: {
162 getStepImageForView(step) {
163 if (!step) {
164 return '';
165 }
166
167 if (this.activeView === 'desktop') {
168 return step.desktop_view_image || '';
169 }
170
171 if (this.activeView === 'tablet') {
172 return step.tablet_view_image || '';
173 }
174
175 if (this.activeView === 'mobile') {
176 return step.mobile_view_image || '';
177 }
178
179 return '';
180 },
181 shouldShowImagePreview(step) {
182 const stepType = step?.step_type;
183 if (stepType !== 'checkout' && stepType !== 'thankyou') {
184 return false;
185 }
186
187 return !!this.getStepImageForView(step);
188 },
189 setActiveStep(step) {
190 this.activeStep = step;
191 this.isLoading = true;
192 },
193 iframeLoaded() {
194 this.isLoading = false;
195 },
196 closeModal() {
197 this.$emit('close');
198 },
199 importTemplate() {
200 this.$emit('import', this.template);
201 }
202 }
203 }
204 </script>