# ivyforms/1.1/frontend/src/composables/useIntegrations.ts

The Innovative Form Builder – IvyForms, version 1.1. 195 lines.

- Page: https://pluginprobe.com/plugins/ivyforms/1.1/code/frontend/src/composables/useIntegrations.ts
- Raw: https://pluginprobe.com/plugins/ivyforms/1.1/raw/frontend/src/composables/useIntegrations.ts
- Modified: 2026-05-06T08:31:02+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/ivyforms/1.1/code/frontend/src/composables/useIntegrations.ts#L10-L20`.

```typescript
import { computed, ref } from 'vue'
import { getIntegrations, type Integration, type integrationType } from '@/constants/integrations'
import { useProFeatures } from '@/composables/useProFeatures'
import { useProFeatureUpgrade } from '@/composables/useProFeatureUpgrade'
import { useSettingsStore } from '@/stores/useSettingsStore'

/**
 * Integrations Composable
 *
 * Manages integration status and dynamically updates types based on:
 * - Pro installation status
 * - Current license plan
 * - Connection/activation state
 */

interface IntegrationState {
  [key: string]: {
    enabled: boolean
    connected: boolean
  }
}

export function useIntegrations() {
  const pro = useProFeatures()
  const settingsStore = useSettingsStore()
  const { isProInstalled: checkProInstalled, isProLicenseActive: checkProLicenseActive } =
    useProFeatureUpgrade()
  const integrationState = ref<IntegrationState>({})

  /**
   * Load integration states from settings store
   */
  const loadIntegrationStates = async () => {
    // Load from the settings store's integrationsSettings
    const storeSettings = settingsStore.integrationsSettings || {}

    // Transform to match our IntegrationState interface
    const transformed: IntegrationState = {}
    for (const [key, value] of Object.entries(storeSettings)) {
      if (value && typeof value === 'object') {
        transformed[key] = {
          enabled: (value as { enabled?: boolean }).enabled || false,
          connected: (value as { connected?: boolean }).connected || false,
        }
      }
    }

    integrationState.value = transformed
  }

  /**
   * Check if Pro is installed and meets minimum plan requirement
   * Also checks if license is active
   */
  const meetsRequirement = (requiredPlan?: string): boolean => {
    if (!requiredPlan) return true

    // First check: Is Pro installed and license active?
    if (!checkProInstalled() || !checkProLicenseActive()) {
      return false
    }

    // Wait for Pro features to be loaded
    if (!pro.loaded.value) {
      return false
    }

    const currentPlan = pro.plan.value
    const isProInstalledCheck =
      currentPlan !== 'lite' && currentPlan !== 'error' && currentPlan !== 'unauthorized'

    if (!isProInstalledCheck) return false

    const planHierarchy = ['essentials', 'growth', 'agency']
    const currentIndex = planHierarchy.indexOf(currentPlan)
    const requiredIndex = planHierarchy.indexOf(requiredPlan)

    return currentIndex >= requiredIndex && currentIndex !== -1
  }

  /**
   * Determine integration type dynamically
   */
  const getIntegrationType = (integration: Integration): integrationType => {
    const state = integrationState.value[integration.value] || { enabled: false, connected: false }

    // Check if this is a Pro integration (plan is not 'lite')
    const isProIntegration = integration.searchCategory !== 'lite'

    if (isProIntegration) {
      const proInstalled = checkProInstalled()
      const licenseActive = checkProLicenseActive()

      // CASE 1: Pro not installed at all
      // All Pro features show upgrade badge
      if (!proInstalled) {
        return 'upgrade' // Show upgrade with plan badge, disable toggle
      }

      // CASE 2: Pro installed but license not active
      // Check if the user's stored plan tier covers the required plan.
      // If yes → show "Activate License" (proDisabled); they have the right plan, just need a key.
      // If no  → show "Upgrade" (upgrade); they need to purchase a higher tier.
      if (!licenseActive) {
        const planHierarchy = ['essentials', 'growth', 'agency']
        const storedPlanIndex = planHierarchy.indexOf(pro.installedPlan.value)
        const requiredPlanIndex = planHierarchy.indexOf(integration.requiredPlan || 'essentials')

        if (storedPlanIndex !== -1 && storedPlanIndex >= requiredPlanIndex) {
          return 'proDisabled' // Right plan tier — just needs an active license
        }
        return 'upgrade' // Needs a higher plan tier
      }

      // CASE 3: Pro installed and licensed - check plan hierarchy
      // Plan hierarchy: essentials < growth < agency
      if (!meetsRequirement(integration.requiredPlan)) {
        // Licensed but insufficient plan
        // Examples:
        // - Essentials user viewing Growth feature → show 'upgrade' with "GROWTH" badge
        // - Essentials user viewing Agency feature → show 'upgrade' with "AGENCY" badge
        // - Growth user viewing Agency feature → show 'upgrade' with "AGENCY" badge
        return 'upgrade' // Show upgrade with required plan badge, disable toggle
      }

      // CASE 4: Pro installed, licensed, and plan is sufficient
      // User has the required plan or higher - show normal functionality
      // Now check if integration is enabled/connected

      // If not enabled, return 'proDisabled'
      if (!state.enabled) {
        return 'proDisabled'
      }

      // If enabled but not connected, return 'proDisabled'
      if (!state.connected) {
        return 'proDisabled'
      }

      // Enabled and connected
      return 'proActive'
    }

    // Lite integrations
    // PRIORITY 1: Check if plugin is installed (connected)
    // If installed, ALWAYS show "Learn More" regardless of toggle state
    if (state.connected) {
      return 'active'
    }

    // PRIORITY 2: Plugin is NOT installed
    return 'disabled'
  }

  /**
   * Get all integrations with dynamic types
   * Now async - loads from backend registry
   */
  const integrations = ref<Integration[]>([])
  const integrationsLoaded = ref(false)

  const loadIntegrations = async () => {
    if (integrationsLoaded.value) {
      return integrations.value
    }

    // Call getIntegrations() to get filtered list from backend at runtime
    const loaded = await getIntegrations()
    integrations.value = loaded.map((integration) => ({
      ...integration,
      type: getIntegrationType(integration),
    }))

    integrationsLoaded.value = true
    return integrations.value
  }

  /**
   * Update integration state
   */
  const updateIntegrationState = (name: string, enabled: boolean, connected = false) => {
    integrationState.value[name] = { enabled, connected }
  }

  return {
    integrations: computed(() => integrations.value),
    integrationsLoaded: computed(() => integrationsLoaded.value),
    integrationState,
    loadIntegrations,
    loadIntegrationStates,
    updateIntegrationState,
    getIntegrationType,
  }
}

```
