PluginProbe
The Innovative Form Builder – IvyForms / 0.6.1.1
The Innovative Form Builder – IvyForms v0.6.1.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / composables / useProFeatureUpgrade.ts

useProFeatureUpgrade.ts in The Innovative Form Builder – IvyForms 0.6.1.1, at frontend/src/composables/useProFeatureUpgrade.ts

257 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Pro Feature Upgrade Dialog Composable
3 *
4 * Shows appropriate upgrade dialogs based on Pro plugin status:
5 * 1. Pro NOT installed/active -> Notification Pop-up (simple)
6 * 2. Pro installed but license not activated -> Activation Pop-up (detailed)
7 */
8
9 import { useProUpgradeDialogStore } from '@/stores/proUpgradeDialogStore'
10 import { useLabels } from '@/composables/useLabels'
11 import { useSettingsStore } from '@/stores/useSettingsStore'
12 import { IVYFORMS_WEBSITE_PRICING, IVYFORMS_WEBSITE } from '@/constants/links'
13
14 type ProFeatureType = string
15
16 export function useProFeatureUpgrade() {
17 const proUpgradeDialog = useProUpgradeDialogStore()
18 const { getLabel } = useLabels()
19 const settingsStore = useSettingsStore()
20
21 /**
22 * Get all available Pro field features from the plan
23 * These are loaded from the backend plan configuration
24 */
25 const getProFieldFeatures = (): Record<string, ProFeatureType> => {
26 const proFeatures = window.IvyForms?.pro?.features?.fields || {}
27 return proFeatures as Record<string, ProFeatureType>
28 }
29
30 /**
31 * Check if a field type is a Pro feature field
32 * Dynamically checks against available Pro features from the plan
33 */
34 const isProFieldFeature = (fieldType: string): boolean => {
35 const proFieldFeatures = getProFieldFeatures()
36 return Object.values(proFieldFeatures).includes(fieldType)
37 }
38
39 /**
40 * Get the feature slug for a given field type
41 * Maps field type to its corresponding feature slug from the plan
42 */
43 const getFeatureSlugForFieldType = (fieldType: string): ProFeatureType | null => {
44 const proFieldFeatures = getProFieldFeatures()
45 for (const [, featureSlug] of Object.entries(proFieldFeatures)) {
46 if (featureSlug === fieldType) {
47 return featureSlug
48 }
49 }
50 return null
51 }
52
53 /**
54 * Get all available Pro field option features from the plan
55 * These are loaded from the backend plan configuration
56 */
57 const getProFieldOptionFeatures = (): Record<string, ProFeatureType> => {
58 const proFeatures = window.IvyForms?.pro?.features?.field_options || {}
59 return proFeatures as Record<string, ProFeatureType>
60 }
61
62 /**
63 * Check if a field option slug is a Pro feature
64 * Dynamically checks against available Pro features from the plan
65 */
66 const isProFieldOption = (slug: string): boolean => {
67 const proFieldOptions = getProFieldOptionFeatures()
68 return Object.values(proFieldOptions).includes(slug)
69 }
70
71 /**
72 * Get all available Pro integration features from the plan
73 * These are loaded from the backend plan configuration
74 */
75 const getProIntegrationFeatures = (): Record<string, ProFeatureType> => {
76 const proFeatures = window.IvyForms?.pro?.features?.integrations || {}
77 return proFeatures as Record<string, ProFeatureType>
78 }
79
80 /**
81 * Check if an integration slug is a Pro feature
82 * Dynamically checks against available Pro features from the plan
83 */
84 const isProIntegration = (slug: string): boolean => {
85 const proIntegrations = getProIntegrationFeatures()
86 return Object.values(proIntegrations).includes(slug)
87 }
88
89 /**
90 * Check if Pro plugin is installed and activated
91 * Pro plugin must be both installed AND activated for this to return true
92 */
93 const isProInstalled = (): boolean => {
94 // First check: Pro scripts must be loaded by WordPress
95 // This is the most reliable indicator that Pro plugin is ACTIVE
96 const proScriptsLoaded =
97 (window as { ivyFormsProScripts?: Record<string, string> }).ivyFormsProScripts !== undefined
98
99 if (!proScriptsLoaded) {
100 return false
101 }
102
103 // Second check: Pro object must exist
104 if (!window.IvyForms?.pro) {
105 return false
106 }
107
108 // Third check: Pro must be loaded or have features
109 const isLoaded = window.IvyForms.pro.loaded === true
110 const hasFeatures =
111 window.IvyForms.pro.features !== undefined &&
112 window.IvyForms.pro.features !== null &&
113 Object.keys(window.IvyForms.pro.features).length > 0
114
115 return isLoaded || hasFeatures
116 }
117
118 /**
119 * Check if Pro license is active
120 * Checks if license settings exist and are valid in the settings store
121 */
122 const isProLicenseActive = (): boolean => {
123 if (!isProInstalled()) return false
124
125 // Check if allSettings has been loaded
126 const settings = settingsStore.allSettings
127 if (!settings) return false
128
129 // Check if Pro license settings exist
130 const proSettings = (settings as Record<string, unknown>).pro as
131 | Record<string, unknown>
132 | undefined
133 if (!proSettings || !proSettings.license) return false
134
135 const licenseInfo = proSettings.license as { status?: string; plan?: string }
136
137 // License is active if status is 'valid' and plan is not 'lite'
138 return licenseInfo.status === 'valid' && licenseInfo.plan !== 'lite'
139 }
140
141 /**
142 * Show upgrade dialog based on current Pro status
143 */
144 const showUpgradeDialog = () => {
145 const proInstalled = isProInstalled()
146 const licenseActive = isProLicenseActive()
147
148 // Scenario 1: Pro plugin NOT installed/active
149 // Show simple "Notification Pop-up" from Figma
150 if (!proInstalled) {
151 proUpgradeDialog.showDialog({
152 iconName: 'pro-lightning-alt',
153 title: getLabel('pro_feature_available'),
154 subtitle: '',
155 buttons: {
156 close: {
157 type: 'tertiary',
158 text: getLabel('learn_more'),
159 //TODO: Update URL to specific feature page if available
160 function: () => {
161 window.open(IVYFORMS_WEBSITE, '_blank')
162 },
163 },
164 confirm: {
165 type: 'primary',
166 text: getLabel('upgrade_to_pro'),
167 function: () => {
168 window.open(IVYFORMS_WEBSITE_PRICING, '_blank')
169 },
170 },
171 },
172 })
173 }
174 // Scenario 2: Pro installed but license NOT activated
175 // Show detailed "Pop-up" with activation message from Figma
176 else if (!licenseActive) {
177 proUpgradeDialog.showDialog({
178 iconName: 'pro-lightning',
179 title: getLabel('pro_feature_requires_activation'),
180 subtitle: getLabel('pro_feature_activation_subtitle'),
181 buttons: {
182 confirm: {
183 type: 'primary',
184 text: getLabel('activate_license'),
185 function: () => {
186 //TODO: Update URL to specific license activation page if available
187 const currentUrl = new URL(window.location.href)
188 currentUrl.searchParams.set('page', 'ivyforms-settings')
189 currentUrl.hash = '/license'
190 window.location.href = currentUrl.toString()
191 },
192 },
193 },
194 })
195 }
196 // Scenario 3: Pro active but feature not in current plan - Later for different plan tiers
197 else {
198 proUpgradeDialog.showDialog({
199 iconName: 'pro-lightning-alt',
200 title: getLabel('pro_feature_available'),
201 subtitle: '',
202 buttons: {
203 close: {
204 type: 'tertiary',
205 text: getLabel('learn_more'),
206 function: () => {
207 window.open(IVYFORMS_WEBSITE_PRICING, '_blank')
208 },
209 },
210 confirm: {
211 type: 'primary',
212 text: getLabel('upgrade_plan'),
213 function: () => {
214 window.open(IVYFORMS_WEBSITE_PRICING, '_blank')
215 },
216 },
217 },
218 })
219 }
220 }
221
222 /**
223 * Check if a feature is available and show upgrade dialog if not
224 * @returns true if feature is available, false if upgrade dialog was shown
225 */
226 const checkFeatureAccess = (featureType: ProFeatureType): boolean => {
227 // If Pro is not installed or license is not active, show upgrade dialog
228 if (!isProInstalled() || !isProLicenseActive()) {
229 showUpgradeDialog()
230 return false
231 }
232
233 // Check if specific feature is available (for different plan tiers)
234 const hasFeature = window.IvyForms?.pro?.features?.[featureType]
235 if (!hasFeature) {
236 showUpgradeDialog()
237 return false
238 }
239
240 return true
241 }
242
243 return {
244 isProInstalled,
245 isProLicenseActive,
246 showUpgradeDialog,
247 checkFeatureAccess,
248 getProFieldFeatures,
249 isProFieldFeature,
250 getFeatureSlugForFieldType,
251 getProFieldOptionFeatures,
252 isProFieldOption,
253 getProIntegrationFeatures,
254 isProIntegration,
255 }
256 }
257