@teamvortexsoftware/vortex-react-native 0.0.13 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +1227 -11
- package/dist/InviteFormCore-D4HkMMo0.d.mts +721 -0
- package/dist/InviteFormCore-D9oUCbu7.d.ts +721 -0
- package/dist/VortexClient.js +192 -0
- package/dist/VortexClient.js.map +1 -0
- package/dist/VortexDeferredLinks.js +127 -0
- package/dist/VortexDeferredLinks.js.map +1 -0
- package/dist/clientInfo.js +45 -0
- package/dist/clientInfo.js.map +1 -0
- package/dist/components/ContactsPickerModal.js +182 -0
- package/dist/components/ContactsPickerModal.js.map +1 -0
- package/dist/components/InviteFormCore.js +2141 -0
- package/dist/components/InviteFormCore.js.map +1 -0
- package/dist/components/InviteFormMobile.js +463 -0
- package/dist/components/InviteFormMobile.js.map +1 -0
- package/dist/components/InviteFormWeb.js +295 -0
- package/dist/components/InviteFormWeb.js.map +1 -0
- package/dist/components/PlacedItemToolbar.js +147 -0
- package/dist/components/PlacedItemToolbar.js.map +1 -0
- package/dist/components/ShareButtons.js +1 -0
- package/dist/components/ShareButtons.js.map +1 -0
- package/dist/components/VrtxContactsImport.js +234 -0
- package/dist/components/VrtxContactsImport.js.map +1 -0
- package/dist/components/VrtxEmailInvitations.js +341 -0
- package/dist/components/VrtxEmailInvitations.js.map +1 -0
- package/dist/components/VrtxFindFriends.js +400 -0
- package/dist/components/VrtxFindFriends.js.map +1 -0
- package/dist/components/VrtxHeading.js +58 -0
- package/dist/components/VrtxHeading.js.map +1 -0
- package/dist/components/VrtxIncomingInvitations.js +657 -0
- package/dist/components/VrtxIncomingInvitations.js.map +1 -0
- package/dist/components/VrtxInvitationSuggestions.js +506 -0
- package/dist/components/VrtxInvitationSuggestions.js.map +1 -0
- package/dist/components/VrtxInviteContacts.js +512 -0
- package/dist/components/VrtxInviteContacts.js.map +1 -0
- package/dist/components/VrtxOutgoingInvitations.js +572 -0
- package/dist/components/VrtxOutgoingInvitations.js.map +1 -0
- package/dist/components/VrtxSearchBox.js +487 -0
- package/dist/components/VrtxSearchBox.js.map +1 -0
- package/dist/components/VrtxSelect.js +27 -0
- package/dist/components/VrtxSelect.js.map +1 -0
- package/dist/components/VrtxShareOptions.js +435 -0
- package/dist/components/VrtxShareOptions.js.map +1 -0
- package/dist/components/VrtxSubmit.js +132 -0
- package/dist/components/VrtxSubmit.js.map +1 -0
- package/dist/components/VrtxText.js +146 -0
- package/dist/components/VrtxText.js.map +1 -0
- package/dist/constants/mockData.d.mts +7 -0
- package/dist/constants/mockData.d.ts +7 -0
- package/dist/constants/mockData.js +48 -0
- package/dist/constants/mockData.js.map +1 -0
- package/dist/constants/mockData.mjs +22 -0
- package/dist/constants/mockData.mjs.map +1 -0
- package/dist/context/VortexModulesContext.js +135 -0
- package/dist/context/VortexModulesContext.js.map +1 -0
- package/dist/hooks/useInvitationFormLogic.d.mts +2 -0
- package/dist/hooks/useInvitationFormLogic.d.ts +2 -0
- package/dist/hooks/useInvitationFormLogic.js +300 -0
- package/dist/hooks/useInvitationFormLogic.js.map +1 -0
- package/dist/hooks/useInvitationFormLogic.mjs +276 -0
- package/dist/hooks/useInvitationFormLogic.mjs.map +1 -0
- package/dist/hooks/usePrefetchWidgetConfiguration.js +117 -0
- package/dist/hooks/usePrefetchWidgetConfiguration.js.map +1 -0
- package/dist/hooks/useThemeStyles.js +2 -0
- package/dist/hooks/useThemeStyles.js.map +1 -0
- package/dist/hooks/useVortexInvite.js +467 -56
- package/dist/hooks/useVortexInvite.js.map +1 -0
- package/dist/index-web.d.mts +93 -0
- package/dist/index-web.d.ts +93 -0
- package/dist/index-web.js +7397 -0
- package/dist/index-web.js.map +1 -0
- package/dist/index-web.mjs +7445 -0
- package/dist/index-web.mjs.map +1 -0
- package/dist/index.d.mts +656 -0
- package/dist/index.d.ts +656 -0
- package/dist/index.js +10205 -4
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10244 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/VortexClient.d.ts +106 -0
- package/dist/types/VortexClient.d.ts.map +1 -0
- package/dist/types/VortexDeferredLinks.d.ts +73 -0
- package/dist/types/VortexDeferredLinks.d.ts.map +1 -0
- package/dist/types/clientInfo.d.ts +5 -0
- package/dist/types/clientInfo.d.ts.map +1 -0
- package/dist/types/components/ContactsPickerModal.d.ts +18 -0
- package/dist/types/components/ContactsPickerModal.d.ts.map +1 -0
- package/dist/types/components/InviteFormCore.d.ts +166 -0
- package/dist/types/components/InviteFormCore.d.ts.map +1 -0
- package/dist/types/components/InviteFormMobile.d.ts +42 -0
- package/dist/types/components/InviteFormMobile.d.ts.map +1 -0
- package/dist/types/components/InviteFormWeb.d.ts +87 -0
- package/dist/types/components/InviteFormWeb.d.ts.map +1 -0
- package/dist/types/components/PlacedItemToolbar.d.ts +16 -0
- package/dist/types/components/PlacedItemToolbar.d.ts.map +1 -0
- package/dist/types/components/VrtxContactsImport.d.ts +14 -0
- package/dist/types/components/VrtxContactsImport.d.ts.map +1 -0
- package/dist/types/components/VrtxEmailInvitations.d.ts +31 -0
- package/dist/types/components/VrtxEmailInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxFindFriends.d.ts +25 -0
- package/dist/types/components/VrtxFindFriends.d.ts.map +1 -0
- package/dist/types/components/VrtxHeading.d.ts +6 -0
- package/dist/types/components/VrtxHeading.d.ts.map +1 -0
- package/dist/types/components/VrtxIncomingInvitations.d.ts +27 -0
- package/dist/types/components/VrtxIncomingInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxInvitationSuggestions.d.ts +25 -0
- package/dist/types/components/VrtxInvitationSuggestions.d.ts.map +1 -0
- package/dist/types/components/VrtxInviteContacts.d.ts +24 -0
- package/dist/types/components/VrtxInviteContacts.d.ts.map +1 -0
- package/dist/types/components/VrtxOutgoingInvitations.d.ts +27 -0
- package/dist/types/components/VrtxOutgoingInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxSearchBox.d.ts +28 -0
- package/dist/types/components/VrtxSearchBox.d.ts.map +1 -0
- package/dist/types/components/VrtxSelect.d.ts +6 -0
- package/dist/types/components/VrtxSelect.d.ts.map +1 -0
- package/dist/types/components/VrtxShareOptions.d.ts +41 -0
- package/dist/types/components/VrtxShareOptions.d.ts.map +1 -0
- package/dist/types/components/VrtxSubmit.d.ts +18 -0
- package/dist/types/components/VrtxSubmit.d.ts.map +1 -0
- package/dist/types/components/VrtxText.d.ts +8 -0
- package/dist/types/components/VrtxText.d.ts.map +1 -0
- package/dist/types/constants/mockData.d.ts +4 -0
- package/dist/types/constants/mockData.d.ts.map +1 -0
- package/dist/types/context/VortexModulesContext.d.ts +238 -0
- package/dist/types/context/VortexModulesContext.d.ts.map +1 -0
- package/dist/types/findFriends.js +10 -0
- package/dist/types/findFriends.js.map +1 -0
- package/dist/types/hooks/useInvitationFormLogic.d.ts +55 -0
- package/dist/types/hooks/useInvitationFormLogic.d.ts.map +1 -0
- package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts +39 -0
- package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts.map +1 -0
- package/dist/types/hooks/useThemeStyles.d.ts +1 -0
- package/dist/types/hooks/useThemeStyles.d.ts.map +1 -1
- package/dist/types/hooks/useVortexInvite.d.ts +48 -6
- package/dist/types/hooks/useVortexInvite.d.ts.map +1 -1
- package/dist/types/index-web.d.ts +23 -0
- package/dist/types/index-web.d.ts.map +1 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/invitations.js +13 -0
- package/dist/types/invitations.js.map +1 -0
- package/dist/types/inviteContacts.js +14 -0
- package/dist/types/inviteContacts.js.map +1 -0
- package/dist/{shared/InvitationResult.js → types/platformOperations.js} +1 -0
- package/dist/types/platformOperations.js.map +1 -0
- package/dist/types/searchBox.js +11 -0
- package/dist/types/searchBox.js.map +1 -0
- package/dist/types/types/findFriends.d.ts +101 -0
- package/dist/types/types/findFriends.d.ts.map +1 -0
- package/dist/types/types/invitations.d.ts +301 -0
- package/dist/types/types/invitations.d.ts.map +1 -0
- package/dist/types/types/inviteContacts.d.ts +86 -0
- package/dist/types/types/inviteContacts.d.ts.map +1 -0
- package/dist/types/types/platformOperations.d.ts +185 -0
- package/dist/types/types/platformOperations.d.ts.map +1 -0
- package/dist/types/types/searchBox.d.ts +69 -0
- package/dist/types/types/searchBox.d.ts.map +1 -0
- package/dist/types/types/unfurlConfig.d.ts +34 -0
- package/dist/types/types/unfurlConfig.d.ts.map +1 -0
- package/dist/types/unfurlConfig.js +21 -0
- package/dist/types/unfurlConfig.js.map +1 -0
- package/dist/types/utils/analytics.d.ts +54 -0
- package/dist/types/utils/analytics.d.ts.map +1 -0
- package/dist/types/utils/configCache.d.ts +34 -0
- package/dist/types/utils/configCache.d.ts.map +1 -0
- package/dist/types/utils/contactUtils.d.ts +9 -0
- package/dist/types/utils/contactUtils.d.ts.map +1 -0
- package/dist/types/utils/featureWarnings.d.ts +56 -0
- package/dist/types/utils/featureWarnings.d.ts.map +1 -0
- package/dist/types/utils/formUtils.d.ts +11 -3
- package/dist/types/utils/formUtils.d.ts.map +1 -1
- package/dist/types/utils/gradientUtils.d.ts +67 -0
- package/dist/types/utils/gradientUtils.d.ts.map +1 -0
- package/dist/types/utils/invitationEvents.d.ts +21 -0
- package/dist/types/utils/invitationEvents.d.ts.map +1 -0
- package/dist/types/utils/moduleLoaders.d.ts +115 -0
- package/dist/types/utils/moduleLoaders.d.ts.map +1 -0
- package/dist/types/utils/moduleLoaders.web.d.ts +73 -0
- package/dist/types/utils/moduleLoaders.web.d.ts.map +1 -0
- package/dist/types/utils/nameUtils.d.ts +15 -0
- package/dist/types/utils/nameUtils.d.ts.map +1 -0
- package/dist/types/utils/themeUtils.d.ts +3 -1
- package/dist/types/utils/themeUtils.d.ts.map +1 -1
- package/dist/types/vortexInvite.d.ts +145 -5
- package/dist/types/vortexInvite.d.ts.map +1 -1
- package/dist/useInvitationFormLogic-Ct73M19B.d.mts +242 -0
- package/dist/useInvitationFormLogic-Ct73M19B.d.ts +242 -0
- package/dist/utils/analytics.js +92 -0
- package/dist/utils/analytics.js.map +1 -0
- package/dist/utils/configCache.js +68 -0
- package/dist/utils/configCache.js.map +1 -0
- package/dist/utils/contactUtils.d.mts +12 -0
- package/dist/utils/contactUtils.d.ts +12 -0
- package/dist/utils/contactUtils.js +37 -0
- package/dist/utils/contactUtils.js.map +1 -0
- package/dist/utils/contactUtils.mjs +12 -0
- package/dist/utils/contactUtils.mjs.map +1 -0
- package/dist/utils/featureWarnings.js +214 -0
- package/dist/utils/featureWarnings.js.map +1 -0
- package/dist/utils/formUtils.js +161 -51
- package/dist/utils/formUtils.js.map +1 -0
- package/dist/utils/gradientUtils.js +120 -0
- package/dist/utils/gradientUtils.js.map +1 -0
- package/dist/utils/invitationEvents.js +45 -0
- package/dist/utils/invitationEvents.js.map +1 -0
- package/dist/utils/moduleLoaders.js +275 -0
- package/dist/utils/moduleLoaders.js.map +1 -0
- package/dist/utils/moduleLoaders.web.js +72 -0
- package/dist/utils/moduleLoaders.web.js.map +1 -0
- package/dist/utils/nameUtils.js +51 -0
- package/dist/utils/nameUtils.js.map +1 -0
- package/dist/utils/themeUtils.js +117 -32
- package/dist/utils/themeUtils.js.map +1 -0
- package/dist/vortexInvite.js +78 -167
- package/dist/vortexInvite.js.map +1 -0
- package/package.json +69 -31
- package/dist/components/Clipboard.js +0 -64
- package/dist/shared/api.js +0 -90
- package/dist/tests/TestVortexInvite.js +0 -134
- package/dist/types/components/Clipboard.d.ts +0 -16
- package/dist/types/components/Clipboard.d.ts.map +0 -1
- package/dist/types/shared/InvitationResult.d.ts +0 -24
- package/dist/types/shared/InvitationResult.d.ts.map +0 -1
- package/dist/types/shared/api.d.ts +0 -14
- package/dist/types/shared/api.d.ts.map +0 -1
- package/dist/types/tests/TestVortexInvite.d.ts +0 -4
- package/dist/types/tests/TestVortexInvite.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/index.tsx","../src/clientInfo.ts","../src/vortexInvite.tsx","../src/components/InviteFormMobile.tsx","../src/components/InviteFormCore.tsx","../src/hooks/useInvitationFormLogic.ts","../src/utils/contactUtils.ts","../src/components/VrtxShareOptions.tsx","../src/context/VortexModulesContext.tsx","../src/components/VrtxContactsImport.tsx","../src/components/VrtxEmailInvitations.tsx","../src/components/VrtxFindFriends.tsx","../../analytics-client/src/core.ts","../../analytics-client/src/eventNames.ts","../src/utils/invitationEvents.ts","../src/components/VrtxIncomingInvitations.tsx","../src/VortexClient.ts","../src/components/VrtxOutgoingInvitations.tsx","../src/components/VrtxInvitationSuggestions.tsx","../src/components/VrtxInviteContacts.tsx","../src/components/VrtxHeading.tsx","../src/components/VrtxText.tsx","../src/components/VrtxSelect.tsx","../src/components/VrtxSubmit.tsx","../src/components/VrtxSearchBox.tsx","../src/components/PlacedItemToolbar.tsx","../src/hooks/useVortexInvite.ts","../src/utils/themeUtils.ts","../src/hooks/useThemeStyles.ts","../src/utils/formUtils.ts","../../../node_modules/.pnpm/openapi-fetch@0.12.5/node_modules/openapi-fetch/dist/index.js","../../vortex-shared-ui/src/api/urlcat.ts","../../vortex-shared-ui/src/api/VortexWidgetError.ts","../../vortex-shared-ui/src/api/VortexClient.ts","../../vortex-shared-ui/src/utils/clientInfo.ts","../src/utils/configCache.ts","../src/utils/analytics.ts","../src/utils/nameUtils.ts","../src/utils/featureWarnings.ts","../src/utils/moduleLoaders.ts","../src/utils/gradientUtils.ts","../src/hooks/usePrefetchWidgetConfiguration.ts","../src/types/unfurlConfig.ts","../src/VortexDeferredLinks.ts","../src/constants/mockData.ts"],"sourcesContent":["{\n \"name\": \"@teamvortexsoftware/vortex-react-native\",\n \"description\": \"Vortex React Native SDK\",\n \"author\": \"@teamvortexsoftware\",\n \"license\": \"Apache-2.0\",\n \"version\": \"1.0.1\",\n \"files\": [\n \"dist\"\n ],\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\",\n \"react-native\": \"./dist/index.js\",\n \"source\": \"./src/index.tsx\"\n },\n \"./web\": {\n \"types\": \"./dist/index-web.d.ts\",\n \"import\": \"./dist/index-web.mjs\",\n \"require\": \"./dist/index-web.js\",\n \"source\": \"./src/index-web.tsx\"\n },\n \"./hooks/useInvitationFormLogic\": {\n \"types\": \"./dist/hooks/useInvitationFormLogic.d.ts\",\n \"import\": \"./dist/hooks/useInvitationFormLogic.mjs\",\n \"require\": \"./dist/hooks/useInvitationFormLogic.js\",\n \"source\": \"./src/hooks/useInvitationFormLogic.ts\"\n },\n \"./constants/mockData\": {\n \"types\": \"./dist/constants/mockData.d.ts\",\n \"import\": \"./dist/constants/mockData.mjs\",\n \"require\": \"./dist/constants/mockData.js\",\n \"source\": \"./src/constants/mockData.ts\"\n },\n \"./utils/contactUtils\": {\n \"types\": \"./dist/utils/contactUtils.d.ts\",\n \"import\": \"./dist/utils/contactUtils.mjs\",\n \"require\": \"./dist/utils/contactUtils.js\",\n \"source\": \"./src/utils/contactUtils.ts\"\n }\n },\n \"types\": \"dist/index.d.ts\",\n \"react-native\": \"dist/index.js\",\n \"scripts\": {\n \"clean\": \"rimraf dist\",\n \"build\": \"pnpm run clean && tsup\",\n \"dev\": \"pnpm run clean && tsup --watch\",\n \"prepack\": \"echo 'This package should not be published directly. Use publish:prod' && exit 1\",\n \"prepublish\": \"pnpm run build\",\n \"build:prod\": \"pnpm run clean && tsup\",\n \"prepublish:prod\": \"mkdir -p dist.d/prod && cp -r dist dist.d/prod/ && cp ./LICENSE ./README.md dist.d/prod/ && jq 'del(.dependencies.\\\"@teamvortexsoftware/analytics-client\\\") | del(.dependencies.\\\"@teamvortexsoftware/vortex-shared-ui\\\") | del(.devDependencies) | del(.scripts)' ./package.json > ./dist.d/prod/package.json\",\n \"publish:prod\": \"pnpm run prepublish:prod && pnpm publish --access public ./dist.d/prod\",\n \"lint\": \"eslint src/\",\n \"type-check\": \"tsc --noEmit\",\n \"test\": \"vitest\",\n \"test:ci\": \"vitest run --coverage\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"catalog:\",\n \"@teamvortexsoftware/eslint-config\": \"workspace:*\",\n \"@teamvortexsoftware/typescript-config\": \"workspace:*\",\n \"@teamvortexsoftware/vortex-types\": \"workspace:*\",\n \"@testing-library/jest-dom\": \"6.9.1\",\n \"@testing-library/react\": \"16.3.1\",\n \"@types/react\": \"catalog:\",\n \"@types/react-native-vector-icons\": \"^6.4.18\",\n \"@vitest/coverage-v8\": \"catalog:\",\n \"eslint\": \"catalog:\",\n \"eslint-plugin-react-native\": \"^4.1.0\",\n \"expo-haptics\": \"^15.0.7\",\n \"jsdom\": \"^26.0.2\",\n \"react\": \"catalog:\",\n \"react-dom\": \"catalog:\",\n \"react-native-web\": \"^0.19.13\",\n \"rimraf\": \"catalog:\",\n \"tsup\": \"catalog:\",\n \"typescript-eslint\": \"catalog:\",\n \"vite\": \"catalog:\",\n \"vitest\": \"catalog:\"\n },\n \"dependencies\": {\n \"@teamvortexsoftware/analytics-client\": \"workspace:*\",\n \"@teamvortexsoftware/vortex-shared-ui\": \"workspace:*\",\n \"react-native-uuid\": \"^2.0.3\",\n \"react-native-vector-icons\": \"^10.2.0\"\n },\n \"peerDependencies\": {\n \"@react-native-clipboard/clipboard\": \">=1.16.2\",\n \"@react-native-google-signin/google-signin\": \">=16.0.0\",\n \"expo-clipboard\": \">=7.1.4\",\n \"expo-haptics\": \">=13.0.0\",\n \"expo-linear-gradient\": \">=12.0.0\",\n \"expo-sharing\": \">=13.0.0\",\n \"react\": \">=18.0.0\",\n \"react-native\": \">=0.75.0\",\n \"react-native-linear-gradient\": \">=2.6.0\",\n \"react-native-qrcode-svg\": \">=6.3.0\",\n \"react-native-svg\": \">=15.0.0\",\n \"react-qr-code\": \">=2.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"@react-native-clipboard/clipboard\": {\n \"optional\": true\n },\n \"@react-native-google-signin/google-signin\": {\n \"optional\": true\n },\n \"expo-clipboard\": {\n \"optional\": true\n },\n \"expo-haptics\": {\n \"optional\": true\n },\n \"expo-linear-gradient\": {\n \"optional\": true\n },\n \"expo-sharing\": {\n \"optional\": true\n },\n \"react-native-linear-gradient\": {\n \"optional\": true\n },\n \"react-native-qrcode-svg\": {\n \"optional\": true\n },\n \"react-native-svg\": {\n \"optional\": true\n },\n \"react-qr-code\": {\n \"optional\": true\n }\n }\n}\n","// Initialize client info on module load\nimport { getReactNativeClientInfo } from './clientInfo';\n\n// Call immediately to set globalThis values\ngetReactNativeClientInfo();\n\nexport { VortexInvite, type VortexInviteProps, type Attributes, type VortexActionResult, type VortexActionType } from './vortexInvite';\n\n// Optional module types - for typing the modules prop\nexport type {\n VortexModules,\n} from './context/VortexModulesContext';\nexport { InviteFormMobile, InviteFormMobile as InvitationForm } from './components/InviteFormMobile';\nexport { InviteFormCore, InviteFormCore as InvitationFormCore, type InvitationFormCoreProps, type IconRendererProps, type IconName } from './components/InviteFormCore';\nexport { useInvitationFormLogic, type ViewType, type Contact } from './hooks/useInvitationFormLogic';\nexport { usePrefetchWidgetConfiguration, type UsePrefetchWidgetConfigurationOptions } from './hooks/usePrefetchWidgetConfiguration';\nexport { configCache } from './utils/configCache';\nexport { type PlatformOperations } from './types/platformOperations';\nexport {\n type FindFriendsConfig,\n type FindFriendsContact,\n} from './types/findFriends';\nexport {\n type InvitationItem,\n type IncomingInvitationItem,\n type OutgoingInvitationItem,\n type IncomingInvitationsConfig,\n type OutgoingInvitationsConfig,\n type InvitationSuggestionsConfig,\n} from './types/invitations';\nexport {\n type InviteContactsConfig,\n type InviteContactsContact,\n} from './types/inviteContacts';\nexport {\n type UnfurlConfig,\n unfurlConfigToMetadata,\n} from './types/unfurlConfig';\nexport {\n VortexDeferredLinks,\n type DeviceFingerprint,\n type MatchFingerprintResponse,\n type RetrieveDeferredDeepLinkOptions,\n} from './VortexDeferredLinks';\nexport {\n VortexClient,\n type VortexClientOptions,\n type InvitationResponse,\n} from './VortexClient';\nexport {\n type SearchBoxConfig,\n} from './types/searchBox';\nexport { VrtxInviteContacts, type VrtxInviteContactsProps } from './components/VrtxInviteContacts';\nexport { VrtxSearchBox, type VrtxSearchBoxProps } from './components/VrtxSearchBox';\nexport { MOCK_CONTACTS, MOCK_GOOGLE_CONTACTS } from './constants/mockData';\nexport { filterContacts } from './utils/contactUtils';\nexport type { EmailGroupMembershipCheckFunction, EmailGroupMembershipCheckResult, UnsignedData } from '@teamvortexsoftware/vortex-types';\n\n// Analytics exports\nexport {\n type VortexAnalyticsEvent,\n type SimpleAnalyticsEvent,\n type GroupDTO,\n DEFAULT_ANALYTICS_URL,\n} from './utils/analytics';\nexport { EventNames, type EventName } from '@teamvortexsoftware/analytics-client';\n","// Static client info for React Native - imports package.json at runtime\n// This file is committed and doesn't need to be generated\n\nlet cachedClientInfo: { name: string; version: string } | null = null;\n\nexport function getReactNativeClientInfo(): { name: string; version: string } {\n // Return cached value if available\n if (cachedClientInfo) {\n return cachedClientInfo;\n }\n\n try {\n // Try to import package.json - this works in React Native Metro bundler\n const packageJson = require('../package.json');\n\n // Extract client name from the full package name\n const clientName = packageJson.name || 'vortex-react-native';\n const clientVersion = packageJson.version || 'unknown';\n\n cachedClientInfo = {\n name: clientName,\n version: clientVersion\n };\n\n // Set on globalThis for the shared-ui getClientInfo() function\n if (typeof globalThis !== 'undefined') {\n globalThis.__VORTEX_CLIENT_NAME__ = clientName;\n globalThis.__VORTEX_CLIENT_VERSION__ = clientVersion;\n }\n\n return cachedClientInfo;\n } catch (error) {\n console.warn('[Vortex] Could not load package.json for client info:', error);\n\n // Fallback values\n const fallback = {\n name: 'vortex-react-native',\n version: 'unknown'\n };\n\n cachedClientInfo = fallback;\n\n // Set fallback on globalThis\n if (typeof globalThis !== 'undefined') {\n globalThis.__VORTEX_CLIENT_NAME__ = fallback.name;\n globalThis.__VORTEX_CLIENT_VERSION__ = fallback.version;\n }\n\n return fallback;\n }\n}","import React, { useEffect, useMemo } from 'react';\nimport { UnsignedData } from '@teamvortexsoftware/vortex-types';\nimport { Platform } from 'react-native';\nimport { InviteFormMobile } from './components/InviteFormMobile';\nimport { VortexAnalyticsEvent, GroupDTO } from './utils/analytics';\nimport { FindFriendsConfig } from './types/findFriends';\nimport { IncomingInvitationsConfig, OutgoingInvitationsConfig, InvitationSuggestionsConfig } from './types/invitations';\nimport { InviteContactsConfig } from './types/inviteContacts';\nimport { UnfurlConfig } from './types/unfurlConfig';\nimport { SearchBoxConfig } from './types/searchBox';\nimport {\n VortexModulesProvider,\n type VortexModules,\n type ModuleLoaders,\n} from './context/VortexModulesContext';\nimport { detectRequiredFeatures, printFeatureWarnings } from './utils/featureWarnings';\n// Import native module loaders - these contain the actual require() statements\nimport * as nativeLoaders from './utils/moduleLoaders';\n\n// Keep the existing type exports for backward compatibility\nexport type VortexActionType = 'invite' | 'share';\n\nexport interface VortexActionResult {\n type: VortexActionType;\n data: string;\n}\n\nexport interface Attributes {\n [key: string]: { value: string | string[]; type: string; role?: string };\n}\n\nexport interface VortexInviteProps {\n vortexApiUrl?: string;\n componentId: string;\n jwt?: string;\n user?: string | UnsignedData | undefined;\n googleIosClientId?: string;\n googleWebClientId?: string; // Required for Google Contacts on Android\n onSuccess?: (result: VortexActionResult) => void;\n onError?: (error: Error, type: VortexActionType) => void;\n onClose?: () => void;\n contentTokens?: Attributes;\n widgetConfiguration?: any; // Prefetched widget configuration for instant rendering\n group?: {\n name: string;\n type: string;\n id?: string;\n groupId?: string;\n };\n groups?: GroupDTO[];\n scope?: string;\n scopeType?: string;\n // Analytics props\n analyticsBaseURL?: string; // Defaults to production collector (https://collector.vortexsoftware.com)\n onEvent?: (event: VortexAnalyticsEvent) => void; // Callback for analytics events\n analyticsSegmentation?: Record<string, any>; // Segmentation data for analytics\n /**\n * Configuration for the Find Friends feature.\n * When provided, enables the Find Friends component to display\n * contacts with Connect buttons. When Connect is tapped and onConnect\n * returns true, an invitation is created via the Vortex backend.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * findFriendsConfig={{\n * contacts: [\n * { userId: 'user-123', name: 'John Doe', subtitle: '@johndoe' },\n * { userId: 'user-456', name: 'Jane Smith', avatarUrl: 'https://...' },\n * ],\n * onConnect: async (contact) => {\n * // Perform any pre-connection validation\n * // Return true to create the invitation via Vortex backend\n * return true;\n * },\n * onInvitationCreated: (contact) => {\n * // Called after invitation is successfully created\n * },\n * }}\n * />\n * ```\n */\n findFriendsConfig?: FindFriendsConfig;\n /**\n * Configuration for the Incoming Invitations feature.\n * When provided, enables the Incoming Invitations component to display\n * invitations the user has received with Accept/Delete buttons.\n */\n incomingInvitationsConfig?: IncomingInvitationsConfig;\n /**\n * Configuration for the Outgoing Invitations feature.\n * When provided, enables the Outgoing Invitations component to display\n * invitations the user has sent with a Cancel button.\n */\n outgoingInvitationsConfig?: OutgoingInvitationsConfig;\n /**\n * Configuration for the Invite Contacts feature.\n * When provided, enables the Invite Contacts component to display\n * a list of contacts that can be invited via SMS.\n *\n * The component shows an \"Invite your contacts\" link that expands to\n * a searchable contact list. When the user taps \"Invite\", an SMS\n * invitation is created and the SMS app opens with a pre-filled message.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * inviteContactsConfig={{\n * contacts: [\n * { id: '1', name: 'John Doe', phoneNumber: '+1234567890' },\n * { id: '2', name: 'Jane Smith', phoneNumber: '+0987654321' },\n * ],\n * onInvite: (contact, shortLink) => {\n * console.log(`Invited ${contact.name} with link ${shortLink}`);\n * },\n * }}\n * />\n * ```\n */\n inviteContactsConfig?: InviteContactsConfig;\n /**\n * Configuration for the Search Box feature.\n * When provided, enables the Search Box component with a search input,\n * search button, and results list with Connect buttons.\n */\n searchBoxConfig?: SearchBoxConfig;\n /**\n * Locale code for internationalization (e.g., \"es\", \"fr\", \"zh-TW\").\n * If provided and i18n is enabled on the widget, returns localized content.\n */\n locale?: string;\n /**\n * Configuration for invitation suggestions (People You May Know).\n * When provided, enables the Invitation Suggestions component to display\n * suggested contacts with Invite/Dismiss buttons.\n */\n invitationSuggestionsConfig?: InvitationSuggestionsConfig;\n /**\n * Configuration for Open Graph unfurl metadata.\n * Used to customize link previews when sharing invitation links.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * unfurlConfig={{\n * title: \"Join our team!\",\n * description: \"You've been invited to collaborate\",\n * image: \"https://example.com/preview.png\",\n * }}\n * />\n * ```\n */\n unfurlConfig?: UnfurlConfig;\n\n // ============================================================================\n // Optional Feature Modules\n // ============================================================================\n\n /**\n * Configuration for optional native libraries.\n * Specify which libraries you have installed in a single object.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * modules={{\n * gradient: 'expo-linear-gradient',\n * haptics: 'expo-haptics',\n * qrCode: 'react-native-qrcode-svg',\n * }}\n * />\n * ```\n */\n modules?: VortexModules;\n}\n\nexport function VortexInvite({\n componentId,\n vortexApiUrl,\n jwt,\n user,\n googleIosClientId,\n googleWebClientId,\n onSuccess,\n onError,\n onClose,\n contentTokens,\n widgetConfiguration,\n group,\n groups,\n scope,\n scopeType,\n analyticsBaseURL,\n onEvent,\n analyticsSegmentation,\n findFriendsConfig,\n incomingInvitationsConfig,\n outgoingInvitationsConfig,\n inviteContactsConfig,\n searchBoxConfig,\n locale,\n invitationSuggestionsConfig,\n unfurlConfig,\n modules,\n}: VortexInviteProps) {\n // Create the modules configuration object with native loaders\n const modulesConfig = useMemo(\n () => ({\n modules,\n // Inject native loaders - these contain the actual require() statements\n loaders: {\n loadGradientComponent: nativeLoaders.loadGradientComponent,\n parseCSSLinearGradient: nativeLoaders.parseCSSLinearGradient,\n angleToGradientPoints: nativeLoaders.angleToGradientPoints,\n parseGradientFirstColor: nativeLoaders.parseGradientFirstColor,\n } as ModuleLoaders,\n }),\n [modules]\n );\n\n // Warn about unsupported props in development\n useEffect(() => {\n if (__DEV__) {\n if (contentTokens) {\n console.warn('[VortexInvite] contentTokens prop is not yet supported in the new implementation');\n }\n if (onSuccess) {\n console.warn('[VortexInvite] onSuccess callback is not yet supported in the new implementation');\n }\n if (onError) {\n console.warn('[VortexInvite] onError callback is not yet supported in the new implementation');\n }\n }\n }, [contentTokens, onSuccess, onError]);\n\n // Print feature warnings when widget configuration is available\n useEffect(() => {\n if (widgetConfiguration) {\n const requirements = detectRequiredFeatures(widgetConfiguration);\n printFeatureWarnings(requirements, modulesConfig);\n }\n }, [widgetConfiguration, modulesConfig]);\n\n // Map old prop names to new ones\n const platform = Platform.OS === 'ios' ? 'ios' : 'android';\n\n return (\n <VortexModulesProvider config={modulesConfig}>\n <InviteFormMobile\n componentId={componentId}\n vortexApiUrl={vortexApiUrl || \"https://client-api.vortexsoftware.com\"}\n jwt={jwt}\n user={user}\n googleIosClientId={googleIosClientId}\n googleWebClientId={googleWebClientId}\n widgetConfiguration={widgetConfiguration}\n group={group}\n groups={groups}\n scope={scope}\n scopeType={scopeType}\n platform={platform}\n onClose={onClose}\n analyticsBaseURL={analyticsBaseURL}\n onEvent={onEvent}\n analyticsSegmentation={analyticsSegmentation}\n findFriendsConfig={findFriendsConfig}\n incomingInvitationsConfig={incomingInvitationsConfig}\n outgoingInvitationsConfig={outgoingInvitationsConfig}\n inviteContactsConfig={inviteContactsConfig}\n searchBoxConfig={searchBoxConfig}\n locale={locale}\n invitationSuggestionsConfig={invitationSuggestionsConfig}\n unfurlConfig={unfurlConfig}\n />\n </VortexModulesProvider>\n );\n}\n","import React, { useMemo, useEffect } from 'react';\nimport { StyleSheet, View, Text, ActivityIndicator } from 'react-native';\nimport Icon from 'react-native-vector-icons/FontAwesome6';\nimport { InviteFormCore, type IconRendererProps } from './InviteFormCore';\nimport { PlatformOperations } from '../types/platformOperations';\nimport { FindFriendsConfig } from '../types/findFriends';\nimport { IncomingInvitationsConfig, OutgoingInvitationsConfig, InvitationSuggestionsConfig } from '../types/invitations';\nimport { InviteContactsConfig } from '../types/inviteContacts';\nimport { UnfurlConfig } from '../types/unfurlConfig';\nimport { SearchBoxConfig } from '../types/searchBox';\nimport { useVortexInvite } from '../hooks/useVortexInvite';\nimport { inferNameFromEmail } from '../utils/nameUtils';\nimport { UnsignedData } from '@teamvortexsoftware/vortex-types';\nimport { VortexAnalyticsEvent, GroupDTO } from '../utils/analytics';\n\ninterface InvitationFormProps {\n platform?: 'ios' | 'android';\n onClose?: () => void;\n widgetConfiguration?: any;\n // Props for fetching configuration from server\n componentId: string;\n jwt?: string;\n user?: string | UnsignedData | undefined;\n vortexApiUrl?: string;\n group?: {\n name: string;\n type: string;\n id?: string;\n groupId?: string;\n };\n groups?: GroupDTO[];\n scope?: string;\n scopeType?: string;\n googleIosClientId?: string;\n googleWebClientId?: string; // Required for Google Contacts on Android\n // Analytics props\n analyticsBaseURL?: string; // Defaults to production collector\n onEvent?: (event: VortexAnalyticsEvent) => void; // Callback for analytics events\n analyticsSegmentation?: Record<string, any>; // Segmentation data for analytics\n // Find Friends configuration\n findFriendsConfig?: FindFriendsConfig;\n // Incoming/Outgoing Invitations configuration\n incomingInvitationsConfig?: IncomingInvitationsConfig;\n outgoingInvitationsConfig?: OutgoingInvitationsConfig;\n // Invitation Suggestions configuration\n invitationSuggestionsConfig?: InvitationSuggestionsConfig;\n // Invite Contacts configuration\n inviteContactsConfig?: InviteContactsConfig;\n // Search Box configuration\n searchBoxConfig?: SearchBoxConfig;\n // Internationalization\n locale?: string;\n // Unfurl configuration for link previews\n unfurlConfig?: UnfurlConfig;\n}\n\n// Map from generic icon names to FontAwesome6 names\nconst iconMap: Record<string, string> = {\n close: 'xmark',\n 'arrow-back': 'arrow-left',\n link: 'link',\n share: 'share-nodes',\n 'import-contacts': 'address-book',\n email: 'envelope',\n google: 'google',\n 'x-twitter': 'x-twitter',\n instagram: 'instagram',\n sms: 'comment',\n whatsapp: 'whatsapp',\n line: 'line',\n 'qr-code': 'qrcode',\n telegram: 'telegram',\n discord: 'discord',\n 'facebook-messenger': 'facebook-messenger',\n search: 'magnifying-glass',\n};\n\nexport function InviteFormMobile({\n platform = 'ios',\n onClose,\n widgetConfiguration: propsWidgetConfiguration,\n componentId,\n jwt,\n user,\n vortexApiUrl,\n group,\n groups,\n scope,\n scopeType,\n googleIosClientId,\n googleWebClientId,\n analyticsBaseURL,\n onEvent,\n analyticsSegmentation,\n findFriendsConfig,\n incomingInvitationsConfig,\n outgoingInvitationsConfig,\n inviteContactsConfig,\n searchBoxConfig,\n locale,\n invitationSuggestionsConfig,\n unfurlConfig,\n}: InvitationFormProps) {\n\n const hookResult = useVortexInvite({\n componentId,\n jwt: jwt,\n user: user,\n vortexApiUrl: vortexApiUrl!,\n group,\n groups,\n scope,\n scopeType,\n widgetConfiguration: propsWidgetConfiguration, // Pass prefetched configuration to skip loading\n analyticsBaseURL,\n onEvent,\n analyticsSegmentation,\n locale,\n });\n\n // Use configuration from hook if available (fresh data), otherwise use prefetched configuration from props\n // This ensures background refetch updates are reflected (stale-while-revalidate pattern)\n const widgetConfiguration = hookResult.widgetConfiguration || propsWidgetConfiguration;\n const { loading, error } = hookResult;\n\n // Track widget render when configuration is loaded\n useEffect(() => {\n if (widgetConfiguration && !loading && !error) {\n hookResult.trackWidgetRender();\n }\n }, [widgetConfiguration, loading, error, hookResult.trackWidgetRender]);\n\n // Track widget error when error occurs\n useEffect(() => {\n if (error) {\n hookResult.trackWidgetError(error.message || 'Unknown error');\n }\n }, [error, hookResult.trackWidgetError]);\n\n // Platform-specific font families\n const fontFamily =\n platform === 'ios'\n ? '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"SF Pro Display\", \"Helvetica Neue\", sans-serif'\n : 'Roboto, \"Segoe UI\", \"Helvetica Neue\", sans-serif';\n\n const renderIcon = ({ name, size, color, opacity }: IconRendererProps) => {\n const iconName = iconMap[name] || name;\n return <Icon name={iconName} size={size} color={color} solid={true} style={opacity != null ? { opacity } : undefined} />;\n };\n\n const renderQRCode = ({ value, size }: { value: string; size: number }) => {\n try {\n // Dynamic import to avoid hard dependency\n const QRCode = require('react-native-qrcode-svg').default;\n return <QRCode value={value} size={size} color=\"#333\" backgroundColor=\"#fff\" />;\n } catch (error) {\n console.warn('[Vortex] react-native-qrcode-svg not available:', error);\n return (\n <View style={{ padding: 20, alignItems: 'center' }}>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>\n QR Code feature not available. Install react-native-qrcode-svg and react-native-svg to\n enable.\n </Text>\n </View>\n );\n }\n };\n\n // Native platform operations using the hook's methods for copy/share (handles API calls)\n // Wrapped in useMemo to prevent recreation on every render, which would cause infinite loops\n const platformOperations: PlatformOperations = useMemo(\n () => ({\n copyToClipboard: async () => {\n await hookResult.handleCopyLink();\n },\n share: async () => {\n await hookResult.handleShareLink();\n },\n close: async () => {\n // Sign out from Google to allow account switching on next open\n try {\n const module = await import('@react-native-google-signin/google-signin');\n const { GoogleSignin } = module;\n await GoogleSignin.signOut();\n console.info('[Vortex] Signed out from Google to allow account switching.');\n } catch (signOutErr) {\n // Ignore sign-out errors (user might not have been signed in, or library not available)\n console.debug('[Vortex] Google sign-out skipped:', signOutErr);\n }\n\n if (onClose) {\n onClose();\n } else {\n console.log('[Vortex] Close bottom sheet');\n }\n },\n triggerHaptic: async (style: 'light' | 'medium' | 'heavy') => {\n try {\n // Dynamic import to avoid hard dependency\n const Haptics = await import('expo-haptics');\n const feedbackStyle =\n style === 'light'\n ? Haptics.ImpactFeedbackStyle.Light\n : style === 'medium'\n ? Haptics.ImpactFeedbackStyle.Medium\n : Haptics.ImpactFeedbackStyle.Heavy;\n\n await Haptics.impactAsync(feedbackStyle);\n } catch (error) {\n // Silent fail if expo-haptics not installed - this is expected and acceptable\n console.debug('[Vortex] Haptic feedback not available:', error);\n }\n },\n fetchContacts: async () => {\n // Call the existing fetchContactsWithEmailsIOS from the hook\n if (!hookResult.fetchContactsWithEmailsIOS) {\n console.warn('[Vortex] fetchContactsWithEmailsIOS method not available');\n return [];\n }\n const contactsWithEmails = await hookResult.fetchContactsWithEmailsIOS();\n\n // Use a Map to deduplicate by unique key (contact.id + email)\n const contactMap = new Map<string, { id: string; name: string; email: string; imageUri?: string }>();\n\n for (const contact of contactsWithEmails) {\n for (const email of contact.emails) {\n const key = `${contact.id}-${email}`;\n // Only add if not already in the map (prevents duplicates)\n if (!contactMap.has(key)) {\n // Infer name from email if contact name is missing or empty\n const displayName =\n contact.name && contact.name.trim() ? contact.name : inferNameFromEmail(email);\n\n contactMap.set(key, {\n id: key,\n name: displayName,\n email,\n imageUri: contact.imageUri,\n });\n }\n }\n }\n\n // Sort alphabetically by name\n return Array.from(contactMap.values()).sort((a, b) => a.name.localeCompare(b.name));\n },\n invite: async (email: string, contactName?: string) => {\n // Build content tokens for the invitation\n const contentTokens: Record<string, { value: string; type: string }> = {\n invitee_email: { value: email, type: 'email' },\n };\n\n // Add inviter name if available (could be extracted from JWT or config)\n // For now, using a placeholder that the backend can override\n contentTokens.inviter_name = { value: 'Current User', type: 'string' };\n\n // Add contact name if provided\n if (contactName) {\n contentTokens.invitee_name = { value: contactName, type: 'string' };\n }\n\n // Add group information if available\n if (group) {\n contentTokens.group_name = { value: group.name, type: 'string' };\n }\n\n // Call the handleInviteClick from useVortexInvite hook\n await hookResult.handleInviteClick(contentTokens);\n },\n fetchGoogleContacts: async () => {\n try {\n const { Platform } = require('react-native');\n if (Platform?.OS === 'web') {\n console.info('[Vortex] Web preview: skipping Google auth, returning [] (mocks).');\n return [];\n }\n\n try {\n const module = require('@react-native-google-signin/google-signin');\n const {\n GoogleSignin,\n isSuccessResponse,\n isCancelledResponse,\n isNoSavedCredentialFoundResponse,\n } = module;\n\n const iosClientId = googleIosClientId || '';\n const webClientId = googleWebClientId || '';\n \n // Check for required client ID based on platform\n if (Platform?.OS === 'ios' && !iosClientId) {\n console.warn('[Vortex] googleIosClientId prop not provided (required for iOS).');\n throw new Error('missing-ios-client-id');\n }\n if (Platform?.OS === 'android' && !webClientId) {\n console.warn('[Vortex] googleWebClientId prop not provided (required for Android).');\n throw new Error('missing-web-client-id');\n }\n\n // IMPORTANT: Make sure Info.plist has the reversed client id URL scheme (iOS).\n // For Android, ensure google-services.json is configured properly.\n // If using Expo, add the plugin: [\"react-native-google-signin\"] and prebuild.\n GoogleSignin.configure({\n iosClientId,\n webClientId, // Required for Android\n offlineAccess: false,\n scopes: ['https://www.googleapis.com/auth/contacts.readonly', 'email', 'profile'],\n });\n\n // 1) Try silent sign-in first (uses cached credentials)\n const silent = await GoogleSignin.signInSilently();\n if (isSuccessResponse?.(silent) || silent?.type === 'success') {\n console.info('[Vortex] Google silent sign-in success.');\n } else if (\n isNoSavedCredentialFoundResponse?.(silent) ||\n silent?.type === 'noSavedCredentialFound'\n ) {\n console.info('[Vortex] No saved credential; prompting interactive sign-in...');\n const interactive = await GoogleSignin.signIn();\n if (!(isSuccessResponse?.(interactive) || interactive?.type === 'success')) {\n if (isCancelledResponse?.(interactive) || interactive?.type === 'cancelled') {\n console.warn('[Vortex] Google sign-in cancelled by user.');\n return [];\n }\n console.warn('[Vortex] Google sign-in did not succeed.');\n return [];\n }\n } else {\n // unexpected silent state; try interactive as a fallback\n const interactive = await GoogleSignin.signIn();\n if (!(isSuccessResponse?.(interactive) || interactive?.type === 'success')) {\n if (isCancelledResponse?.(interactive) || interactive?.type === 'cancelled') {\n console.warn('[Vortex] Google sign-in cancelled by user.');\n return [];\n }\n console.warn('[Vortex] Google sign-in did not succeed.');\n return [];\n }\n }\n\n // Only now are we guaranteed to be signed in\n const tokens = await GoogleSignin.getTokens();\n const accessToken: string | undefined = tokens?.accessToken;\n if (!accessToken) {\n console.warn('[Vortex] No access token after sign-in.');\n return [];\n }\n\n const response = await fetch(\n 'https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses,photos&pageSize=1000',\n { headers: { Authorization: `Bearer ${accessToken}` } }\n );\n if (!response.ok) throw new Error(`Google API error: ${response.status}`);\n\n const data = await response.json();\n const contactMap = new Map<string, { id: string; name: string; email: string; imageUri?: string }>();\n if (data.connections && Array.isArray(data.connections)) {\n for (const person of data.connections) {\n if (person.emailAddresses && Array.isArray(person.emailAddresses)) {\n for (const emailObj of person.emailAddresses) {\n const key = `${person.resourceName}-${emailObj.value}`;\n if (!contactMap.has(key)) {\n // Infer name from email if Google contact name is missing\n const displayName =\n person.names?.[0]?.displayName || inferNameFromEmail(emailObj.value);\n\n // Extract photo URL (skip default silhouette photos)\n const photoUrl = person.photos?.[0]?.url;\n const isDefaultPhoto = person.photos?.[0]?.default === true;\n if (__DEV__ && person.photos) {\n console.log('[Vortex] Google contact photo:', displayName, { photoUrl, isDefaultPhoto, photos: person.photos });\n }\n contactMap.set(key, {\n id: key,\n name: displayName,\n email: emailObj.value,\n ...(photoUrl && !isDefaultPhoto ? { imageUri: photoUrl } : {}),\n });\n }\n }\n }\n }\n }\n\n // Sort alphabetically by name\n return Array.from(contactMap.values()).sort((a, b) => a.name.localeCompare(b.name));\n } catch (gsErr) {\n console.warn('[Vortex] Google Sign-In unavailable or failed. Returning [].', gsErr);\n return [];\n }\n } catch (error) {\n console.error('[Vortex] Failed to fetch Google contacts:', error);\n return [];\n }\n },\n shareViaEmail: async () => {\n await hookResult.handleEmailShare();\n },\n shareViaSms: async () => {\n await hookResult.handleSmsShare();\n },\n shareViaTwitter: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const text = `Join our team: ${invitationLink}`;\n const twitterUrl = `twitter://messages/compose?text=${encodeURIComponent(text)}`;\n const { Linking } = require('react-native');\n await Linking.openURL(twitterUrl).catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL(`https://twitter.com/messages/compose?text=${encodeURIComponent(text)}`);\n });\n },\n shareViaInstagram: async () => {\n const { Linking } = require('react-native');\n await Linking.openURL('instagram://direct-inbox').catch(() => {\n console.warn('Instagram app not installed');\n });\n },\n shareViaWhatsApp: async () => {\n await hookResult.handleWhatsAppShare();\n },\n shareViaLine: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const { Linking } = require('react-native');\n const lineUrl = `https://line.me/R/msg/text/?${encodeURIComponent(invitationLink)}`;\n await Linking.openURL(lineUrl);\n },\n shareViaLineLiff: async () => {\n const { Linking } = require('react-native');\n const liffUrl = 'https://liff.line.me/2008909352-RwnncfLZ';\n await Linking.openURL(liffUrl);\n },\n shareViaFacebookMessenger: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const { Linking } = require('react-native');\n const messengerUrl = `fb-messenger://share?link=${encodeURIComponent(invitationLink)}`;\n await Linking.openURL(messengerUrl).catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL(`https://www.facebook.com/dialog/send?link=${encodeURIComponent(invitationLink)}&app_id=0&redirect_uri=${encodeURIComponent(invitationLink)}`);\n });\n },\n shareViaTelegram: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const { Linking } = require('react-native');\n const telegramUrl = `tg://msg?text=${encodeURIComponent(invitationLink)}`;\n await Linking.openURL(telegramUrl).catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL(`https://t.me/share/url?url=${encodeURIComponent(invitationLink)}`);\n });\n },\n shareViaDiscord: async () => {\n const { Linking } = require('react-native');\n await Linking.openURL('discord://').catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL('https://discord.com/channels/@me');\n });\n },\n showQrCode: async () => {\n // Navigation to QR code view is handled in InviteFormCore\n console.log('[Vortex] Navigating to QR Code view');\n },\n }),\n [hookResult, onClose, group, googleIosClientId, googleWebClientId]\n );\n\n // Container styles for bottom sheet appearance\n const containerStyle = StyleSheet.create({\n container: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '80%',\n backgroundColor: '#fff',\n borderTopLeftRadius: 20,\n borderTopRightRadius: 20,\n },\n }).container;\n\n // Show loading state while fetching configuration\n if (loading) {\n return (\n <View style={[containerStyle, { justifyContent: 'center', alignItems: 'center' }]}>\n <ActivityIndicator size=\"large\" color=\"#6291d5\" />\n <Text style={{ marginTop: 16, fontSize: 16, color: '#666', fontFamily }}>Loading...</Text>\n </View>\n );\n }\n\n // Show error state if configuration fetch failed\n if (error) {\n return (\n <View\n style={[containerStyle, { justifyContent: 'center', alignItems: 'center', padding: 20 }]}\n >\n <Text\n style={{\n fontSize: 18,\n fontWeight: 'bold',\n color: '#d9534f',\n marginBottom: 8,\n fontFamily,\n }}\n >\n Error\n </Text>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>\n {error.message || 'Failed to load widget configuration'}\n </Text>\n </View>\n );\n }\n\n return (\n <InviteFormCore\n renderIcon={renderIcon}\n renderQRCode={renderQRCode}\n platformOperations={platformOperations}\n fontFamily={fontFamily}\n containerStyle={containerStyle}\n widgetConfiguration={widgetConfiguration}\n getShareableInviteLink={hookResult.getShareableInviteLink}\n // Analytics callbacks\n onShareLinkClick={hookResult.trackShareLinkClick}\n onEmailFieldFocus={hookResult.trackEmailFieldFocus}\n onEmailFieldBlur={hookResult.trackEmailFieldBlur}\n onEmailValidation={hookResult.trackEmailValidation}\n onEmailInvitationsSubmitted={hookResult.trackEmailInvitationsSubmitted}\n onEmailValidationError={hookResult.trackEmailValidationError}\n onEmailSubmitError={hookResult.trackEmailSubmitError}\n // Find Friends configuration\n findFriendsConfig={findFriendsConfig}\n createUserIdInvitation={hookResult.createUserIdInvitation}\n // Incoming/Outgoing Invitations configuration\n incomingInvitationsConfig={incomingInvitationsConfig}\n outgoingInvitationsConfig={outgoingInvitationsConfig}\n // Invite Contacts configuration\n inviteContactsConfig={inviteContactsConfig}\n // Invitation Suggestions configuration\n invitationSuggestionsConfig={invitationSuggestionsConfig}\n // Search Box configuration\n searchBoxConfig={searchBoxConfig}\n // API configuration for outgoing invitations\n apiUrl={vortexApiUrl!}\n jwt={jwt!}\n />\n );\n}\n","import React, { ReactNode, useState, useEffect, useCallback } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n TextInput,\n TouchableOpacity,\n ScrollView,\n ActivityIndicator,\n Linking,\n Platform,\n ViewStyle,\n Image,\n} from 'react-native';\nimport { useInvitationFormLogic } from '../hooks/useInvitationFormLogic';\nimport { PlatformOperations } from '../types/platformOperations';\nimport { FindFriendsConfig } from '../types/findFriends';\nimport {\n IncomingInvitationsConfig,\n OutgoingInvitationsConfig,\n InvitationSuggestionsConfig,\n} from '../types/invitations';\nimport { InviteContactsConfig } from '../types/inviteContacts';\nimport { SearchBoxConfig } from '../types/searchBox';\nimport { MOCK_GOOGLE_CONTACTS } from '../constants/mockData';\nimport { filterContacts } from '../utils/contactUtils';\nimport type { Contact } from '../hooks/useInvitationFormLogic';\nimport { VrtxShareOptions } from './VrtxShareOptions';\nimport { VrtxContactsImport } from './VrtxContactsImport';\nimport { VrtxEmailInvitations } from './VrtxEmailInvitations';\nimport { VrtxFindFriends } from './VrtxFindFriends';\nimport { VrtxIncomingInvitations } from './VrtxIncomingInvitations';\nimport { VrtxOutgoingInvitations } from './VrtxOutgoingInvitations';\nimport { VrtxInvitationSuggestions } from './VrtxInvitationSuggestions';\nimport { VrtxInviteContacts } from './VrtxInviteContacts';\nimport { VrtxHeading } from './VrtxHeading';\nimport { VrtxText } from './VrtxText';\nimport { VrtxSelect } from './VrtxSelect';\nimport { VrtxSubmit } from './VrtxSubmit';\nimport { VrtxSearchBox } from './VrtxSearchBox';\nimport { usePlacedItemToolbar } from './PlacedItemToolbar';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\n// Button wrapper component that handles gradients on web, solid color fallback on native\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n wrapperStyle?: ViewStyle | ViewStyle[];\n}\n\nconst ButtonWrapper: React.FC<ButtonWrapperProps> = ({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n wrapperStyle,\n}) => {\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[wrapperStyle, ...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, use first color from gradient as solid background\n const fallbackColor = gradientString ? parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor\n ? [wrapperStyle, ...styleArray, { backgroundColor: fallbackColor }]\n : [wrapperStyle, ...styleArray];\n\n return (\n <TouchableOpacity style={finalStyle} onPress={onPress} disabled={disabled} activeOpacity={0.7}>\n {children}\n </TouchableOpacity>\n );\n};\n\nexport type IconName =\n | 'close'\n | 'arrow-back'\n | 'link'\n | 'share'\n | 'import-contacts'\n | 'email'\n | 'google'\n | 'x-twitter'\n | 'instagram'\n | 'sms'\n | 'whatsapp'\n | 'line'\n | 'qr-code'\n | 'telegram'\n | 'discord'\n | 'facebook-messenger'\n | 'search';\n\nexport interface IconRendererProps {\n name: IconName;\n size: number;\n color: string;\n opacity?: number;\n}\n\nexport interface ComponentInfo {\n id: string;\n type: string; // 'button', 'text', 'input', etc.\n element: HTMLElement | null;\n styles: React.CSSProperties;\n content?: string;\n droppedItem?: any; // Data about the dropped item, if applicable\n}\n\nexport interface InvitationFormCoreProps {\n /**\n * Function to render icons - allows different icon libraries to be used\n */\n renderIcon: (props: IconRendererProps) => ReactNode;\n\n /**\n * Function to render QR code - allows platform-specific QR libraries to be used\n * - Native: uses react-native-qrcode-svg\n * - Web: uses react-qr-code\n */\n renderQRCode?: (props: { value: string; size: number }) => ReactNode;\n\n /**\n * Platform-specific operations (clipboard, share, close)\n */\n platformOperations: PlatformOperations;\n\n /**\n * Font family to use for text\n */\n fontFamily?: string;\n\n /**\n * Container style overrides\n */\n containerStyle?: Record<string, any>;\n\n /**\n * Widget configuration containing component settings\n */\n widgetConfiguration?: any;\n\n /**\n * Whether edit mode is enabled (for hover highlighting and drag-drop)\n */\n isEditMode?: boolean;\n\n /**\n * Callback when a component is selected in edit mode\n */\n onComponentSelect?: (componentInfo: ComponentInfo) => void;\n\n /**\n * Callback when a palette item is dropped onto a component\n */\n onDrop?: (componentInfo: ComponentInfo, droppedItem: any) => void;\n\n /**\n * Callbacks for setting/clearing drop targets (for Redux integration)\n */\n onSetDropTarget?: (target: {\n elementId: string;\n elementType: string;\n position: string;\n rowId?: string;\n insertionIndex?: number;\n }) => void;\n onClearDropTarget?: () => void;\n\n /**\n * Function to fetch the shareable invitation link for QR code\n */\n getShareableInviteLink?: () => Promise<string | undefined>;\n\n /**\n * Whether a drag is currently active (to show drop zones)\n */\n isDragging?: boolean;\n\n /**\n * Callback when a component is deleted in edit mode\n */\n onComponentDelete?: (componentId: string, componentType: string) => void;\n\n // Analytics callbacks (optional - no-op for preview mode)\n /**\n * Track share link click events\n */\n onShareLinkClick?: (clickName: string) => void;\n\n /**\n * Track email field focus events\n */\n onEmailFieldFocus?: () => void;\n\n /**\n * Track email field blur events\n */\n onEmailFieldBlur?: () => void;\n\n /**\n * Track email validation events\n */\n onEmailValidation?: (email: string, isValid: boolean) => void;\n\n /**\n * Track email invitations submitted events\n */\n onEmailInvitationsSubmitted?: (formData: Record<string, any>) => void;\n\n /**\n * Track email validation error events\n */\n onEmailValidationError?: (formData: Record<string, any>) => void;\n\n /**\n * Track email submit error events\n */\n onEmailSubmitError?: (error: string) => void;\n\n /**\n * Configuration for the Find Friends feature.\n * When provided, enables the Find Friends component to display\n * contacts with Connect buttons.\n */\n findFriendsConfig?: FindFriendsConfig;\n\n /**\n * Function to create an invitation with internal ID target type.\n * Called when user taps Connect and the onConnect callback returns true.\n */\n createUserIdInvitation?: (userId: string, name?: string, avatarUrl?: string, metadata?: Record<string, unknown>) => Promise<void>;\n\n /**\n * Configuration for the Incoming Invitations feature.\n * When provided, enables the Incoming Invitations component to display\n * invitations the user has received with Accept/Delete buttons.\n */\n incomingInvitationsConfig?: IncomingInvitationsConfig;\n\n /**\n * Configuration for the Outgoing Invitations feature.\n * When provided, enables the Outgoing Invitations component to display\n * invitations the user has sent with a Cancel button.\n */\n outgoingInvitationsConfig?: OutgoingInvitationsConfig;\n\n /**\n * Configuration for the Invitation Suggestions feature.\n * When provided, enables the Invitation Suggestions component to display\n * \"People you may know\" with Invite and Dismiss buttons.\n */\n invitationSuggestionsConfig?: InvitationSuggestionsConfig;\n\n /**\n * Configuration for the Invite Contacts feature.\n * When provided, enables the Invite Contacts component to display\n * a list of contacts that can be invited via SMS.\n */\n inviteContactsConfig?: InviteContactsConfig;\n\n /**\n * Configuration for the Search Box feature.\n * When provided, enables the Search Box component with a search input,\n * search button, and results list with Connect buttons.\n */\n searchBoxConfig?: SearchBoxConfig;\n\n /**\n * API URL for server operations (e.g., fetching outgoing invitations)\n */\n apiUrl: string;\n\n /**\n * JWT token for authentication\n */\n jwt: string;\n\n}\n\nexport function InviteFormCore({\n renderIcon,\n renderQRCode,\n platformOperations,\n fontFamily = '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif',\n containerStyle = {},\n widgetConfiguration,\n isEditMode = false,\n isDragging = false,\n onComponentSelect,\n onDrop,\n onSetDropTarget,\n onClearDropTarget,\n onComponentDelete,\n getShareableInviteLink,\n // Analytics callbacks (optional - no-op for preview mode)\n onShareLinkClick,\n onEmailFieldFocus,\n onEmailFieldBlur,\n onEmailValidation,\n onEmailInvitationsSubmitted,\n onEmailValidationError,\n onEmailSubmitError,\n // Find Friends configuration\n findFriendsConfig,\n createUserIdInvitation,\n // Incoming/Outgoing Invitations configuration\n incomingInvitationsConfig,\n outgoingInvitationsConfig,\n // Invitation Suggestions configuration\n invitationSuggestionsConfig,\n // Invite Contacts configuration\n inviteContactsConfig,\n // Search Box configuration\n searchBoxConfig,\n // API configuration\n apiUrl,\n jwt,\n}: InvitationFormCoreProps) {\n // Get the form structure from widget configuration\n const getFormStructure = () => {\n try {\n const formData = widgetConfiguration?.configuration?.props?.['vortex.components.form']?.value;\n if (formData && typeof formData === 'object' && formData.root) {\n return formData.root;\n }\n } catch (err) {\n console.error('[InviteFormCore] Failed to parse form structure:', err);\n }\n return null;\n };\n\n const formStructure = getFormStructure();\n\n if (!formStructure) {\n console.error(\n '[InviteFormCore] No form structure found in widget configuration. ' +\n 'The widget may not have a form configured, or the configuration format is unexpected. ' +\n 'Expected path: configuration.props[\"vortex.components.form\"].value.root'\n );\n }\n\n // Extract form title from widget configuration (mobile-specific key takes priority)\n const resolvedTitle =\n formStructure?.settings?.customizations?.['mobile.formTitle']?.textContent ||\n formStructure?.settings?.customizations?.formTitle?.textContent ||\n null;\n\n // Extract title theme styles from root theme options\n const resolvedTitleStyle = (() => {\n const themeOptions = formStructure?.theme?.options;\n if (!Array.isArray(themeOptions)) return undefined;\n const getVal = (key: string) => themeOptions.find((o: any) => o.key === key)?.value || undefined;\n const color = getVal('--vrtx-form-title-color');\n const fontSize = getVal('--vrtx-form-title-font-size');\n const fontWeight = getVal('--vrtx-form-title-font-weight');\n const fontFamily = getVal('--vrtx-form-title-font-family');\n if (!color && !fontSize && !fontWeight && !fontFamily) return undefined;\n return {\n ...(color && { color }),\n ...(fontSize && { fontSize: parseFloat(fontSize) || undefined }),\n ...(fontWeight && { fontWeight }),\n ...(fontFamily && { fontFamily }),\n };\n })();\n\n // Helper function to find email invitations block in form structure\n const findEmailInvitationsBlock = (): any => {\n if (!formStructure) return null;\n\n const searchChildren = (children: any[]): any => {\n if (!Array.isArray(children)) return null;\n\n for (const child of children) {\n if (\n child.type === 'block' &&\n child.subtype === 'vrtx-email-invitations' &&\n child.hidden !== true\n ) {\n return child;\n }\n if (child.children) {\n const found = searchChildren(child.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n if (formStructure.children) {\n return searchChildren(formStructure.children);\n }\n return null;\n };\n\n const emailInvitationsBlock = findEmailInvitationsBlock();\n\n // Helper function to find submit button block in form structure\n const findSubmitButtonBlock = (): any => {\n if (!formStructure) return null;\n\n const searchChildren = (children: any[]): any => {\n if (!Array.isArray(children)) return null;\n\n for (const child of children) {\n if (child.type === 'block' && child.subtype === 'vrtx-submit') {\n return child;\n }\n if (child.children) {\n const found = searchChildren(child.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n if (formStructure.children) {\n return searchChildren(formStructure.children);\n }\n return null;\n };\n\n const submitButtonBlock = findSubmitButtonBlock();\n\n // Helper function to find contacts-import block in form structure\n const findContactsImportBlock = (): any => {\n if (!formStructure) return null;\n\n const searchChildren = (children: any[]): any => {\n if (!Array.isArray(children)) return null;\n\n for (const child of children) {\n if (child.type === 'block' && child.subtype === 'vrtx-contacts-import') {\n return child;\n }\n if (child.children) {\n const found = searchChildren(child.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n if (formStructure.children) {\n return searchChildren(formStructure.children);\n }\n return null;\n };\n\n const contactsImportBlock = findContactsImportBlock();\n\n // Helper to get customization text from contacts-import block\n const getContactsCustomization = (key: string, defaultValue: string): string => {\n const textContent = contactsImportBlock?.settings?.customizations?.[key]?.textContent;\n if (textContent === null || textContent === undefined) {\n return defaultValue;\n }\n return textContent;\n };\n\n // Extract styles from email invitations block for \"Add by Email\" button\n const emailInvitationsStyle = emailInvitationsBlock?.style || {};\n\n // Extract gradient string and fallback color\n // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'\n const rawEmailBackground = emailInvitationsStyle.background || null;\n const isEmailGradient = rawEmailBackground?.includes('gradient');\n const emailInvitationsGradientString = isEmailGradient ? rawEmailBackground : null;\n const emailInvitationsFallbackColor = isEmailGradient\n ? parseGradientFirstColor(rawEmailBackground)\n : rawEmailBackground || emailInvitationsStyle.backgroundColor;\n\n const emailInvitationsTextColor = emailInvitationsStyle.color || '#333';\n\n // Helper function to check if native Contacts import is enabled\n const isNativeContactsEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components']?.value) {\n return false;\n }\n\n const components = widgetConfiguration.configuration.props['vortex.components'].value;\n return (\n Array.isArray(components) &&\n components.includes('vortex.components.importcontacts.providers.importcontacts')\n );\n };\n\n // Helper function to check if Google Contacts import is enabled\n const isGoogleContactsEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components']?.value) {\n return false;\n }\n\n const components = widgetConfiguration.configuration.props['vortex.components'].value;\n return (\n Array.isArray(components) &&\n components.includes('vortex.components.importcontacts.providers.google')\n );\n };\n\n // Helper function to check if Copy Link is enabled\n const isCopyLinkEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('copyLink');\n };\n\n // Helper function to check if Share (native share sheet) is enabled\n const isShareEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('nativeShareSheet');\n };\n\n // Helper function to check if Email Invitations is enabled\n // Check if the form structure contains a vrtx-email-invitations block\n const isEmailInvitationsEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components']?.value) {\n return false;\n }\n\n const components = widgetConfiguration.configuration.props['vortex.components'].value;\n return Array.isArray(components) && components.includes('vortex.components.emailinvitations');\n };\n\n // Helper function to check if Email share is enabled\n const isEmailShareEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('email');\n };\n\n // Helper function to check if SMS is enabled\n const isSmsEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('sms');\n };\n\n // Helper function to check if X/Twitter DMs is enabled\n const isTwitterDmsEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('twitterDms');\n };\n\n // Helper function to check if Instagram DMs is enabled\n const isInstagramDmsEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('instagramDms');\n };\n\n // Helper function to check if WhatsApp is enabled\n const isWhatsAppEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('whatsApp');\n };\n\n // Helper function to check if Line is enabled\n const isLineEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('line');\n };\n\n // Helper function to check if Line LIFF is enabled\n const isLineLiffEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('lineLiff');\n };\n\n // Helper function to check if QR Code is enabled\n const isQrCodeEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('qrCode');\n };\n\n // Helper function to check if Facebook Messenger is enabled\n const isFacebookMessengerEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('facebookMessenger');\n };\n\n // Helper function to check if Telegram is enabled\n const isTelegramEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('telegram');\n };\n\n // Helper function to check if Discord is enabled\n const isDiscordEnabled = () => {\n if (!widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value) {\n return false;\n }\n const shareOptions =\n widgetConfiguration.configuration.props['vortex.components.share.options'].value;\n return Array.isArray(shareOptions) && shareOptions.includes('discord');\n };\n\n // Helper function to get share options order from configuration\n const getShareOptionsOrder = (): string[] => {\n const shareOptions =\n widgetConfiguration?.configuration?.props?.['vortex.components.share.options']?.value;\n return Array.isArray(shareOptions) ? shareOptions : [];\n };\n\n // State for fetched contacts\n const [contacts, setContacts] = useState<Contact[]>([]);\n const [loadingContacts, setLoadingContacts] = useState(false);\n const [contactsFetchAttempted, setContactsFetchAttempted] = useState(false);\n const [contactsError, setContactsError] = useState<Error | null>(null);\n\n // State for fetched Google contacts\n const [googleContacts, setGoogleContacts] = useState<Contact[]>([]);\n const [loadingGoogleContacts, setLoadingGoogleContacts] = useState(false);\n const [googleContactsFetchAttempted, setGoogleContactsFetchAttempted] = useState(false);\n const [googleContactsError, setGoogleContactsError] = useState<Error | null>(null);\n\n // State for hover tracking in edit mode\n const [hoveredComponentId, setHoveredComponentId] = useState<string | null>(null);\n const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null);\n\n const logic = useInvitationFormLogic(\n platformOperations,\n contacts,\n googleContacts,\n getShareableInviteLink\n );\n\n // Destructure for easier access\n const {\n view,\n emailInput,\n emails,\n copySuccess,\n shareSuccess,\n sendSuccess,\n searchQuery,\n invitedContactIds,\n invitedGoogleContactIds,\n googleSearchQuery,\n setEmailInput,\n setSearchQuery,\n setGoogleSearchQuery,\n loadingContactIds,\n loadingGoogleContactIds,\n loadingEmailInvite,\n loadingCopy,\n loadingShare,\n loadingInvitationLink,\n lastInvalidEmail,\n handleClose,\n handleSendInvitation,\n handleCopyLink,\n handleShare,\n handleEmailSubmit,\n handleRemoveEmail,\n handleSelectFromGoogle,\n handleSelectFromContacts,\n handleAddByEmail,\n handleShowQrCode,\n handleBackToMain,\n handleInviteContact,\n handleInviteGoogleContact,\n } = logic;\n\n // Fetch contacts on-demand when the contacts view is opened\n useEffect(() => {\n // Reset fetch attempt when view changes away from contacts\n if (view !== 'contacts' && contactsFetchAttempted) {\n setContactsFetchAttempted(false);\n setContactsError(null);\n }\n\n if (view === 'contacts' && !contactsFetchAttempted && !loadingContacts) {\n setLoadingContacts(true);\n setContactsFetchAttempted(true);\n setContactsError(null); // Clear previous errors\n platformOperations\n .fetchContacts()\n .then((fetchedContacts) => {\n setContacts(fetchedContacts);\n setContactsError(null);\n })\n .catch((err) => {\n console.error('[Vortex] Failed to fetch contacts:', err);\n setContactsError(err instanceof Error ? err : new Error(String(err)));\n setContacts([]); // Clear contacts on error\n })\n .finally(() => setLoadingContacts(false));\n }\n }, [view, contactsFetchAttempted, loadingContacts]);\n\n // Fetch Google contacts on-demand when the googleContacts view is opened\n useEffect(() => {\n // Reset fetch attempt when view changes away from googleContacts\n if (view !== 'googleContacts' && googleContactsFetchAttempted) {\n setGoogleContactsFetchAttempted(false);\n setGoogleContactsError(null);\n }\n\n if (view === 'googleContacts' && !googleContactsFetchAttempted && !loadingGoogleContacts) {\n setLoadingGoogleContacts(true);\n setGoogleContactsFetchAttempted(true);\n setGoogleContactsError(null); // Clear previous errors\n platformOperations\n .fetchGoogleContacts()\n .then((fetchedContacts) => {\n setGoogleContacts(fetchedContacts);\n setGoogleContactsError(null);\n })\n .catch((err) => {\n console.error('[Vortex] Failed to fetch Google contacts:', err);\n setGoogleContactsError(err instanceof Error ? err : new Error(String(err)));\n setGoogleContacts([]); // Clear contacts on error\n })\n .finally(() => setLoadingGoogleContacts(false));\n }\n }, [view, googleContactsFetchAttempted, loadingGoogleContacts]);\n\n // Filter contacts using shared utility\n const filteredContacts = filterContacts(contacts, searchQuery);\n const filteredGoogleContacts = filterContacts(googleContacts, googleSearchQuery);\n\n // Wrapper functions with haptic feedback and analytics tracking\n const handleCopyLinkWithHaptics = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('copyLink');\n await handleCopyLink();\n };\n\n const handleShareWithHaptics = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaNativeShare');\n await handleShare();\n };\n\n const handleSelectFromContactsWithHaptics = async () => {\n await platformOperations.triggerHaptic?.('light');\n handleSelectFromContacts();\n };\n\n const handleSelectFromGoogleWithHaptics = async () => {\n await platformOperations.triggerHaptic?.('light');\n handleSelectFromGoogle();\n };\n\n const handleAddByEmailWithHaptics = async () => {\n await platformOperations.triggerHaptic?.('light');\n handleAddByEmail();\n };\n\n const handleInviteContactWithHaptics = async (contactId: string) => {\n await platformOperations.triggerHaptic?.('light');\n await handleInviteContact(contactId);\n };\n\n const handleInviteGoogleContactWithHaptics = async (contactId: string) => {\n await platformOperations.triggerHaptic?.('light');\n await handleInviteGoogleContact(contactId);\n };\n\n const handleSendInvitationWithHaptics = async () => {\n await platformOperations.triggerHaptic?.('light');\n await handleSendInvitation();\n };\n\n const handleRetryContacts = async () => {\n await platformOperations.triggerHaptic?.('light');\n // Clear the error and reset fetch attempt to trigger a new fetch\n setContactsError(null);\n setContactsFetchAttempted(false);\n };\n\n const handleOpenSettings = async () => {\n await platformOperations.triggerHaptic?.('light');\n try {\n await Linking.openSettings();\n } catch (err) {\n console.warn('[Vortex] Failed to open settings:', err);\n }\n };\n\n const handleEmailShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaEmail');\n await platformOperations.shareViaEmail?.();\n };\n\n const handleSmsShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaSMS');\n await platformOperations.shareViaSms?.();\n };\n\n const handleTwitterShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaTwitter');\n await platformOperations.shareViaTwitter?.();\n };\n\n const handleInstagramShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaInstagram');\n await platformOperations.shareViaInstagram?.();\n };\n\n const handleWhatsAppShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaWhatsApp');\n await platformOperations.shareViaWhatsApp?.();\n };\n\n const handleLineShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaLine');\n await platformOperations.shareViaLine?.();\n };\n\n const handleLineLiffShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaLineLiff');\n await platformOperations.shareViaLineLiff?.();\n };\n\n const handleFacebookMessengerShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaFacebookMessenger');\n await platformOperations.shareViaFacebookMessenger?.();\n };\n\n const handleTelegramShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaTelegram');\n await platformOperations.shareViaTelegram?.();\n };\n\n const handleDiscordShare = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaDiscord');\n await platformOperations.shareViaDiscord?.();\n };\n\n const handleQrCode = async () => {\n await platformOperations.triggerHaptic?.('light');\n onShareLinkClick?.('shareViaQrCode');\n handleShowQrCode();\n };\n\n // Block renderer functions - render individual components based on block type\n const renderShareOptionsBlock = (block: any) => {\n return (\n <VrtxShareOptions\n block={block}\n renderIcon={renderIcon}\n isCopyLinkEnabled={isCopyLinkEnabled}\n isShareEnabled={isShareEnabled}\n isEmailShareEnabled={isEmailShareEnabled}\n isSmsEnabled={isSmsEnabled}\n isTwitterDmsEnabled={isTwitterDmsEnabled}\n isInstagramDmsEnabled={isInstagramDmsEnabled}\n isWhatsAppEnabled={isWhatsAppEnabled}\n isLineEnabled={isLineEnabled}\n isLineLiffEnabled={isLineLiffEnabled}\n isQrCodeEnabled={isQrCodeEnabled}\n isFacebookMessengerEnabled={isFacebookMessengerEnabled}\n isTelegramEnabled={isTelegramEnabled}\n isDiscordEnabled={isDiscordEnabled}\n handleCopyLink={handleCopyLink}\n handleShare={handleShare}\n handleEmailShare={handleEmailShare}\n handleSmsShare={handleSmsShare}\n handleTwitterShare={handleTwitterShare}\n handleInstagramShare={handleInstagramShare}\n handleWhatsAppShare={handleWhatsAppShare}\n handleLineShare={handleLineShare}\n handleLineLiffShare={handleLineLiffShare}\n handleQrCode={handleQrCode}\n handleFacebookMessengerShare={handleFacebookMessengerShare}\n handleTelegramShare={handleTelegramShare}\n handleDiscordShare={handleDiscordShare}\n triggerHaptic={platformOperations.triggerHaptic}\n loadingCopy={loadingCopy}\n loadingShare={loadingShare}\n copySuccess={copySuccess}\n shareSuccess={shareSuccess}\n isEditMode={isEditMode}\n shareOptionsOrder={getShareOptionsOrder()}\n />\n );\n };\n\n const renderContactsImportBlock = (block: any) => {\n return (\n <VrtxContactsImport\n block={block}\n renderIcon={renderIcon}\n isNativeContactsEnabled={isNativeContactsEnabled}\n isGoogleContactsEnabled={isGoogleContactsEnabled}\n handleSelectFromContacts={handleSelectFromContacts}\n handleSelectFromGoogle={handleSelectFromGoogle}\n triggerHaptic={platformOperations.triggerHaptic}\n isEditMode={isEditMode}\n />\n );\n };\n\n const renderEmailInvitationsBlock = (block: any) => {\n // Don't pass submitButtonBlock - we'll render it separately\n return (\n <VrtxEmailInvitations\n block={block}\n view={view}\n emails={emails}\n emailInput={emailInput}\n setEmailInput={setEmailInput}\n handleEmailSubmit={handleEmailSubmit}\n handleRemoveEmail={handleRemoveEmail}\n submitButtonBlock={undefined}\n handleSendInvitation={handleSendInvitation}\n triggerHaptic={platformOperations.triggerHaptic}\n loadingEmailInvite={loadingEmailInvite}\n sendSuccess={sendSuccess}\n lastInvalidEmail={lastInvalidEmail}\n EditableWrapper={EditableWrapper}\n onEmailFieldFocus={onEmailFieldFocus}\n onEmailFieldBlur={onEmailFieldBlur}\n handleAddByEmail={handleAddByEmail}\n renderIcon={renderIcon}\n isEditMode={isEditMode}\n />\n );\n };\n\n const renderHeadingBlock = (block: any) => {\n return <VrtxHeading block={block} />;\n };\n\n // Stable text update handler that doesn't depend on block\n const handleTextUpdate = useCallback((blockId: string, updates: any) => {\n // Dispatch a custom event that PageBuilderMobile can listen to\n const updateEvent = new CustomEvent('vortex-update-text', {\n detail: {\n blockId,\n textContent: updates.textContent,\n },\n bubbles: true,\n });\n\n // Dispatch from document if we're on web\n if (isWeb && document) {\n document.dispatchEvent(updateEvent);\n }\n }, []); // Empty deps - this handler never needs to change\n\n const renderTextBlock = (block: any) => {\n return <VrtxText block={block} isEditMode={isEditMode} onUpdate={handleTextUpdate} />;\n };\n\n const renderSelectBlock = (block: any) => {\n return <VrtxSelect block={block} />;\n };\n\n const renderSubmitBlock = (block: any) => {\n return (\n <VrtxSubmit\n block={block}\n view={view}\n handleSendInvitation={handleSendInvitation}\n triggerHaptic={platformOperations.triggerHaptic}\n loadingEmailInvite={loadingEmailInvite}\n sendSuccess={sendSuccess}\n emailCount={emails.length}\n emailBlockCustomizations={emailInvitationsBlock?.settings?.customizations}\n emailBlockStyle={emailInvitationsBlock?.style}\n />\n );\n };\n\n const renderFindFriendsBlock = (block: any) => {\n // Extract theme colors from widget configuration\n const themeOptions =\n widgetConfiguration?.configuration?.props?.['vortex.theme']?.value?.options;\n const getThemeValue = (key: string): string | undefined => {\n const option = themeOptions?.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n const extractBorderColor = (borderValue: string | undefined): string | undefined => {\n if (!borderValue) return undefined;\n const parts = borderValue.trim().split(/\\s+/);\n if (parts.length === 3) return parts[2];\n return undefined;\n };\n\n const theme = {\n primaryBackground:\n getThemeValue('--vrtx-submit-primary-background') ||\n getThemeValue('--vrtx-button-primary-background') ||\n getThemeValue('--color-primary-background'),\n primaryForeground:\n getThemeValue('--vrtx-submit-primary-color') || getThemeValue('--color-primary-foreground'),\n secondaryBackground:\n getThemeValue('--vrtx-submit-secondary-background') ||\n getThemeValue('--vrtx-button-secondary-background') ||\n getThemeValue('--color-secondary-background'),\n secondaryForeground:\n getThemeValue('--vrtx-submit-secondary-color') ||\n getThemeValue('--vrtx-button-secondary-color') ||\n getThemeValue('--color-secondary-foreground'),\n foreground: getThemeValue('--vrtx-root-color') || getThemeValue('--color-foreground'),\n border:\n extractBorderColor(getThemeValue('--vrtx-root-border')) ||\n extractBorderColor(getThemeValue('--vrtx-input-border')) ||\n getThemeValue('--color-border'),\n };\n\n return (\n <VrtxFindFriends\n block={block}\n findFriendsConfig={findFriendsConfig}\n createUserIdInvitation={createUserIdInvitation}\n triggerHaptic={platformOperations.triggerHaptic}\n theme={theme}\n />\n );\n };\n\n const renderIncomingInvitationsBlock = (block: any) => {\n // Extract theme colors from widget configuration\n const themeOptions =\n widgetConfiguration?.configuration?.props?.['vortex.theme']?.value?.options;\n const getThemeValue = (key: string): string | undefined => {\n const option = themeOptions?.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n const extractBorderColor = (borderValue: string | undefined): string | undefined => {\n if (!borderValue) return undefined;\n const parts = borderValue.trim().split(/\\s+/);\n if (parts.length === 3) return parts[2];\n return undefined;\n };\n\n const theme = {\n primaryBackground:\n getThemeValue('--vrtx-submit-primary-background') ||\n getThemeValue('--vrtx-button-primary-background') ||\n getThemeValue('--color-primary-background'),\n primaryForeground:\n getThemeValue('--vrtx-submit-primary-color') || getThemeValue('--color-primary-foreground'),\n secondaryBackground:\n getThemeValue('--vrtx-submit-secondary-background') ||\n getThemeValue('--vrtx-button-secondary-background') ||\n getThemeValue('--color-secondary-background'),\n secondaryForeground:\n getThemeValue('--vrtx-submit-secondary-color') ||\n getThemeValue('--vrtx-button-secondary-color') ||\n getThemeValue('--color-secondary-foreground'),\n foreground: getThemeValue('--vrtx-root-color') || getThemeValue('--color-foreground'),\n border:\n extractBorderColor(getThemeValue('--vrtx-root-border')) ||\n extractBorderColor(getThemeValue('--vrtx-input-border')) ||\n getThemeValue('--color-border'),\n };\n\n return (\n <VrtxIncomingInvitations\n block={block}\n incomingInvitationsConfig={incomingInvitationsConfig}\n apiUrl={apiUrl}\n jwt={jwt}\n triggerHaptic={platformOperations.triggerHaptic}\n theme={theme}\n />\n );\n };\n\n const renderOutgoingInvitationsBlock = (block: any) => {\n // Extract theme colors from widget configuration\n const themeOptions =\n widgetConfiguration?.configuration?.props?.['vortex.theme']?.value?.options;\n const getThemeValue = (key: string): string | undefined => {\n const option = themeOptions?.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n const extractBorderColor = (borderValue: string | undefined): string | undefined => {\n if (!borderValue) return undefined;\n const parts = borderValue.trim().split(/\\s+/);\n if (parts.length === 3) return parts[2];\n return undefined;\n };\n\n const theme = {\n primaryBackground:\n getThemeValue('--vrtx-submit-primary-background') ||\n getThemeValue('--vrtx-button-primary-background') ||\n getThemeValue('--color-primary-background'),\n primaryForeground:\n getThemeValue('--vrtx-submit-primary-color') || getThemeValue('--color-primary-foreground'),\n secondaryBackground:\n getThemeValue('--vrtx-submit-secondary-background') ||\n getThemeValue('--vrtx-button-secondary-background') ||\n getThemeValue('--color-secondary-background'),\n secondaryForeground:\n getThemeValue('--vrtx-submit-secondary-color') ||\n getThemeValue('--vrtx-button-secondary-color') ||\n getThemeValue('--color-secondary-foreground'),\n foreground: getThemeValue('--vrtx-root-color') || getThemeValue('--color-foreground'),\n border:\n extractBorderColor(getThemeValue('--vrtx-root-border')) ||\n extractBorderColor(getThemeValue('--vrtx-input-border')) ||\n getThemeValue('--color-border'),\n };\n\n return (\n <VrtxOutgoingInvitations\n block={block}\n outgoingInvitationsConfig={outgoingInvitationsConfig}\n apiUrl={apiUrl}\n jwt={jwt}\n triggerHaptic={platformOperations.triggerHaptic}\n theme={theme}\n />\n );\n };\n\n const renderSearchBoxBlock = (block: any) => {\n // Extract theme colors from widget configuration\n const themeOptions = widgetConfiguration?.configuration?.props?.['vortex.theme']?.value?.options;\n const getThemeValue = (key: string): string | undefined => {\n const option = themeOptions?.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n const theme = {\n primaryBackground: getThemeValue('--color-primary-background'),\n primaryForeground: getThemeValue('--color-primary-foreground'),\n secondaryBackground: getThemeValue('--color-secondary-background'),\n secondaryForeground: getThemeValue('--color-secondary-foreground'),\n foreground: getThemeValue('--color-foreground'),\n border: getThemeValue('--color-border'),\n };\n\n return (\n <VrtxSearchBox\n block={block}\n searchBoxConfig={searchBoxConfig}\n createUserIdInvitation={createUserIdInvitation}\n triggerHaptic={platformOperations.triggerHaptic}\n renderIcon={renderIcon}\n theme={theme}\n />\n );\n };\n\n const renderInvitationSuggestionsBlock = (block: any) => {\n // Extract theme colors from widget configuration\n const themeOptions =\n widgetConfiguration?.configuration?.props?.['vortex.theme']?.value?.options;\n const getThemeValue = (key: string): string | undefined => {\n const option = themeOptions?.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n const extractBorderColor = (borderValue: string | undefined): string | undefined => {\n if (!borderValue) return undefined;\n const parts = borderValue.trim().split(/\\s+/);\n if (parts.length === 3) return parts[2];\n return undefined;\n };\n\n const theme = {\n primaryBackground:\n getThemeValue('--vrtx-submit-primary-background') ||\n getThemeValue('--vrtx-button-primary-background') ||\n getThemeValue('--color-primary-background'),\n primaryForeground:\n getThemeValue('--vrtx-submit-primary-color') || getThemeValue('--color-primary-foreground'),\n secondaryBackground:\n getThemeValue('--vrtx-submit-secondary-background') ||\n getThemeValue('--vrtx-button-secondary-background') ||\n getThemeValue('--color-secondary-background'),\n secondaryForeground:\n getThemeValue('--vrtx-submit-secondary-color') ||\n getThemeValue('--vrtx-button-secondary-color') ||\n getThemeValue('--color-secondary-foreground'),\n foreground: getThemeValue('--vrtx-root-color') || getThemeValue('--color-foreground'),\n border:\n extractBorderColor(getThemeValue('--vrtx-root-border')) ||\n extractBorderColor(getThemeValue('--vrtx-input-border')) ||\n getThemeValue('--color-border'),\n };\n\n return (\n <VrtxInvitationSuggestions\n block={block}\n invitationSuggestionsConfig={invitationSuggestionsConfig}\n createUserIdInvitation={createUserIdInvitation}\n triggerHaptic={platformOperations.triggerHaptic}\n theme={theme}\n />\n );\n };\n\n const renderInviteContactsBlock = (block: any) => {\n // Extract theme colors from widget configuration\n const themeOptions =\n widgetConfiguration?.configuration?.props?.['vortex.theme']?.value?.options;\n const getThemeValue = (key: string): string | undefined => {\n const option = themeOptions?.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n const extractBorderColor = (borderValue: string | undefined): string | undefined => {\n if (!borderValue) return undefined;\n const parts = borderValue.trim().split(/\\s+/);\n if (parts.length === 3) return parts[2];\n return undefined;\n };\n\n const theme = {\n primaryBackground:\n getThemeValue('--vrtx-submit-primary-background') ||\n getThemeValue('--vrtx-button-primary-background') ||\n getThemeValue('--color-primary-background'),\n primaryForeground:\n getThemeValue('--vrtx-submit-primary-color') || getThemeValue('--color-primary-foreground'),\n secondaryBackground:\n getThemeValue('--vrtx-submit-secondary-background') ||\n getThemeValue('--vrtx-button-secondary-background') ||\n getThemeValue('--color-secondary-background'),\n secondaryForeground:\n getThemeValue('--vrtx-submit-secondary-color') ||\n getThemeValue('--vrtx-button-secondary-color') ||\n getThemeValue('--color-secondary-foreground'),\n foreground: getThemeValue('--vrtx-root-color') || getThemeValue('--color-foreground'),\n border:\n extractBorderColor(getThemeValue('--vrtx-root-border')) ||\n extractBorderColor(getThemeValue('--vrtx-input-border')) ||\n getThemeValue('--color-border'),\n };\n\n // Get SMS message template from block settings\n const smsMessageTemplate = block?.settings?.customizations?.smsMessage?.textContent;\n\n // Create SMS invitation function that calls the API\n const createSmsInvitation = async (\n phoneNumber: string,\n contactName?: string\n ): Promise<string | null> => {\n try {\n if (platformOperations.createSmsInvitation) {\n return await platformOperations.createSmsInvitation(phoneNumber, contactName);\n }\n console.warn('[VrtxInviteContacts] No createSmsInvitation function provided');\n return null;\n } catch (err) {\n console.error('[VrtxInviteContacts] Failed to create SMS invitation:', err);\n return null;\n }\n };\n\n return (\n <VrtxInviteContacts\n block={block}\n inviteContactsConfig={inviteContactsConfig}\n createSmsInvitation={createSmsInvitation}\n triggerHaptic={platformOperations.triggerHaptic}\n theme={theme}\n smsMessageTemplate={smsMessageTemplate}\n />\n );\n };\n\n const renderBlock = (block: any) => {\n if (!block) return null;\n\n // Skip rendering if block is hidden\n if (block.hidden === true) {\n return null;\n }\n\n const content = (() => {\n switch (block.subtype) {\n case 'vrtx-share-options':\n return renderShareOptionsBlock(block);\n case 'vrtx-contacts-import':\n return renderContactsImportBlock(block);\n case 'vrtx-email-invitations':\n return renderEmailInvitationsBlock(block);\n case 'vrtx-find-friends':\n return renderFindFriendsBlock(block);\n case 'vrtx-incoming-invitations':\n return renderIncomingInvitationsBlock(block);\n case 'vrtx-outgoing-invitations':\n return renderOutgoingInvitationsBlock(block);\n case 'vrtx-invitation-suggestions':\n return renderInvitationSuggestionsBlock(block);\n case 'vrtx-invite-contacts':\n return renderInviteContactsBlock(block);\n case 'vrtx-search-box':\n return renderSearchBoxBlock(block);\n case 'vrtx-heading':\n return renderHeadingBlock(block);\n case 'vrtx-text':\n return renderTextBlock(block);\n case 'vrtx-select':\n return null; //renderSelectBlock(block);\n case 'vrtx-submit':\n return renderSubmitBlock(block);\n default:\n console.warn(`here [InvitationFormCore] Unknown block type: ${block.subtype}`);\n return null;\n }\n })();\n\n if (!content) return null;\n\n // Wrap in EditableWrapper for edit mode\n return (\n <EditableWrapper\n key={block.id}\n componentId={block.id}\n componentType={block.type}\n node={block}\n >\n {content}\n </EditableWrapper>\n );\n };\n\n const renderColumn = (column: any, filterGroup?: string, excludeGroups?: string[]) => {\n if (!column || !column.children) return null;\n\n // If filtering by include group, check if this column has any matching blocks\n if (filterGroup) {\n const hasMatchingBlocks = column.children.some((child: any) => {\n if (child.type === 'block') {\n const blockGroup = child.meta?.source?.group?.name;\n return blockGroup === filterGroup;\n }\n return false;\n });\n\n // Skip rendering this column if it has no matching blocks\n if (!hasMatchingBlocks) {\n return null;\n }\n }\n\n // If excluding groups, check if this column has any blocks NOT in excluded groups\n if (excludeGroups && excludeGroups.length > 0) {\n const hasNonExcludedBlocks = column.children.some((child: any) => {\n if (child.type === 'block') {\n const blockGroup = child.meta?.source?.group?.name;\n return !excludeGroups.includes(blockGroup);\n }\n return false;\n });\n\n // Skip rendering this column if all its blocks are excluded\n if (!hasNonExcludedBlocks) {\n return null;\n }\n }\n\n return (\n <EditableWrapper\n key={column.id}\n componentId={column.id}\n componentType={column.type}\n node={column}\n >\n <View style={{ flex: 1 }}>\n {column.children.map((child: any) => {\n if (child.type === 'block') {\n // Skip submit button blocks - they're rendered after email invitations\n if (child.subtype === 'vrtx-submit') {\n return null;\n }\n\n // If filterGroup is provided, only render blocks from that group\n if (filterGroup) {\n const blockGroup = child.meta?.source?.group?.name;\n if (blockGroup !== filterGroup) {\n return null;\n }\n }\n\n // If excludeGroups is provided, skip blocks from those groups\n if (excludeGroups && excludeGroups.length > 0) {\n const blockGroup = child.meta?.source?.group?.name;\n if (excludeGroups.includes(blockGroup)) {\n return null;\n }\n }\n\n // Special handling for email invitations block - render submit button separately\n if (child.subtype === 'vrtx-email-invitations' && submitButtonBlock) {\n return (\n <React.Fragment key={child.id}>\n {renderBlock(child)}\n {renderBlock(submitButtonBlock)}\n </React.Fragment>\n );\n }\n\n return renderBlock(child);\n }\n return null;\n })}\n </View>\n </EditableWrapper>\n );\n };\n\n const renderRow = (\n row: any,\n index: number,\n totalRows: number,\n filterGroup?: string,\n excludeGroups?: string[]\n ) => {\n if (!row) return null;\n\n // Check if row has any visible content (columns with blocks)\n const hasVisibleContent = row.children?.some((child: any) => {\n if (child.type === 'column' && child.children) {\n return child.children.some((blockChild: any) => blockChild.type === 'block');\n }\n return false;\n });\n\n // In non-edit mode, skip rows without children entirely\n if (!row.children && !isEditMode) return null;\n\n // If filtering by include group, check if this row has any columns with matching blocks\n if (filterGroup) {\n const hasMatchingContent = row.children?.some((child: any) => {\n if (child.type === 'column' && child.children) {\n return child.children.some((blockChild: any) => {\n if (blockChild.type === 'block') {\n const blockGroup = blockChild.meta?.source?.group?.name;\n return blockGroup === filterGroup;\n }\n return false;\n });\n }\n return false;\n });\n\n // Skip rendering this row if it has no matching content\n if (!hasMatchingContent) {\n return null;\n }\n }\n\n // If excluding groups, check if this row has any columns with non-excluded blocks\n if (excludeGroups && excludeGroups.length > 0) {\n const hasNonExcludedContent = row.children?.some((child: any) => {\n if (child.type === 'column' && child.children) {\n return child.children.some((blockChild: any) => {\n if (blockChild.type === 'block') {\n const blockGroup = blockChild.meta?.source?.group?.name;\n return !excludeGroups.includes(blockGroup);\n }\n return false;\n });\n }\n return false;\n });\n\n // Skip rendering this row if all its blocks are excluded\n // BUT in edit mode, allow empty rows through so they can be selected\n if (!hasNonExcludedContent && !(isEditMode && !hasVisibleContent)) {\n return null;\n }\n }\n\n // Determine if this is an empty row (no visible content)\n const isEmptyRow = !hasVisibleContent;\n\n return (\n <React.Fragment key={row.id}>\n {/* Drop zone before this row */}\n {isEditMode && isDragging && (\n <View\n // @ts-ignore\n data-drop-zone=\"between-rows\"\n data-insertion-index={index}\n style={{\n height: 40,\n // borderWidth: 2,\n // borderColor: '#4CAF50',\n // borderStyle: 'dashed',\n // borderRadius: 4,\n // backgroundColor: 'rgba(76, 175, 80, 0.1)',\n marginVertical: 8,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Text style={{ color: '#4CAF50', fontSize: 12, fontWeight: '600' }}>\n {/* Drop here to insert at position {index} */}\n </Text>\n </View>\n )}\n\n {/* The actual row */}\n <EditableWrapper componentId={row.id} componentType={row.type} node={row}>\n <View\n style={[\n styles.section,\n // In edit mode, empty rows get a minimum height so they can be selected\n isEditMode && isEmptyRow && styles.emptyRowEditMode,\n ]}\n >\n {row.children?.map((child: any) => {\n if (child.type === 'column') {\n return renderColumn(child, filterGroup, excludeGroups);\n }\n return null;\n })}\n </View>\n </EditableWrapper>\n\n {/* Drop zone after last row */}\n {isEditMode && isDragging && index === totalRows - 1 && (\n <View\n // @ts-ignore\n data-drop-zone=\"between-rows\"\n data-insertion-index={totalRows}\n style={{\n height: 40,\n borderWidth: 2,\n borderColor: '#4CAF50',\n borderStyle: 'dashed',\n borderRadius: 4,\n backgroundColor: 'rgba(76, 175, 80, 0.1)',\n marginVertical: 8,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Text style={{ color: '#4CAF50', fontSize: 12, fontWeight: '600' }}>\n Drop here to insert at position {totalRows}\n </Text>\n </View>\n )}\n </React.Fragment>\n );\n };\n\n // Helper function to get component label\n const getComponentLabel = (type: string): string => {\n const labelMap: Record<string, string> = {\n 'vrtx-share-options': 'Share Options',\n 'vrtx-contacts-import': 'Contacts Import',\n 'vrtx-email-invitations': 'Email Invitations',\n 'vrtx-find-friends': 'Find Friends',\n 'vrtx-incoming-invitations': 'Incoming Invitations',\n 'vrtx-outgoing-invitations': 'Outgoing Invitations',\n 'vrtx-invitation-suggestions': 'Invitation Suggestions',\n 'vrtx-heading': 'Heading',\n 'vrtx-text': 'Text',\n 'vrtx-select': 'Select',\n 'vrtx-submit': 'Submit',\n 'vrtx-form-label': 'Label',\n 'vrtx-row': 'Row',\n row: 'Row',\n column: 'Column',\n block: 'Block',\n };\n return labelMap[type] || type;\n };\n\n // EditableWrapper component for hover highlighting and drag-drop in edit mode\n // IMPORTANT: Memoized via useMemo to maintain stable component identity across re-renders.\n // Without this, every parent state change (e.g., typing in email input) would create a new\n // component type, causing React to unmount/remount all children — which blurs TextInputs.\n const EditableWrapper = React.useMemo(() => {\n const Wrapper = ({\n children,\n componentId,\n componentType,\n node,\n flex,\n }: {\n children: React.ReactNode;\n componentId: string;\n componentType: string;\n node?: any; // The actual node object from vortex.components.form\n flex?: boolean;\n }) => {\n const wrapperRef = React.useRef<HTMLDivElement>(null);\n const labelRef = React.useRef<HTMLDivElement | null>(null);\n const leftMarginRef = React.useRef<HTMLDivElement | null>(null);\n const rightMarginRef = React.useRef<HTMLDivElement | null>(null);\n const outlineRef = React.useRef<HTMLDivElement | null>(null);\n\n // For rows on web, allow margin-based hover/selection\n const isRow = componentType === 'row';\n const isColumn = componentType === 'column';\n const isBlock = !isRow && !isColumn;\n\n // State for row margin hover\n const [isRowMarginHovered, setIsRowMarginHovered] = React.useState(false);\n\n // Determine hover and selection states\n const isHovered = isBlock\n ? hoveredComponentId === componentId\n : isRow && isWeb\n ? isRowMarginHovered\n : false;\n const isSelected = isBlock\n ? selectedComponentId === componentId\n : isRow && isWeb\n ? selectedComponentId === componentId\n : false;\n const showLabel = isEditMode && (isHovered || isSelected);\n\n // Create margin detection boxes for rows on web\n React.useEffect(() => {\n if (!isWeb || !isRow || !isEditMode) {\n // Clean up margin detectors if they exist\n if (leftMarginRef.current && leftMarginRef.current.parentNode) {\n leftMarginRef.current.parentNode.removeChild(leftMarginRef.current);\n leftMarginRef.current = null;\n }\n if (rightMarginRef.current && rightMarginRef.current.parentNode) {\n rightMarginRef.current.parentNode.removeChild(rightMarginRef.current);\n rightMarginRef.current = null;\n }\n if (outlineRef.current && outlineRef.current.parentNode) {\n outlineRef.current.parentNode.removeChild(outlineRef.current);\n outlineRef.current = null;\n }\n return;\n }\n\n if (!wrapperRef.current) return;\n\n // Find the outermost container with padding - this creates the margin areas\n // Walk up the DOM tree until we find a container that's significantly wider than the row\n let scrollContainer: HTMLElement | null = wrapperRef.current.parentElement;\n const rowWidth = wrapperRef.current.getBoundingClientRect().width;\n\n let attempts = 0;\n while (scrollContainer && attempts < 15) {\n const containerWidth = scrollContainer.getBoundingClientRect().width;\n // If this container is significantly wider than the row (has margins/padding)\n if (containerWidth > rowWidth + 20) {\n break;\n }\n scrollContainer = scrollContainer.parentElement;\n attempts++;\n }\n\n // Fallback: use the widest ancestor we can find\n if (!scrollContainer || scrollContainer.getBoundingClientRect().width <= rowWidth) {\n scrollContainer = wrapperRef.current.parentElement;\n while (scrollContainer?.parentElement) {\n const parent = scrollContainer.parentElement;\n if (\n parent.getBoundingClientRect().width > scrollContainer.getBoundingClientRect().width\n ) {\n scrollContainer = parent;\n } else {\n break;\n }\n }\n }\n\n if (!scrollContainer) return;\n\n // Create margin detectors and outline if they don't exist\n if (!leftMarginRef.current) {\n leftMarginRef.current = document.createElement('div');\n document.body.appendChild(leftMarginRef.current);\n }\n if (!rightMarginRef.current) {\n rightMarginRef.current = document.createElement('div');\n document.body.appendChild(rightMarginRef.current);\n }\n if (!outlineRef.current) {\n outlineRef.current = document.createElement('div');\n document.body.appendChild(outlineRef.current);\n }\n\n const updateMarginDetectors = () => {\n if (!wrapperRef.current || !scrollContainer) return;\n\n const rowRect = wrapperRef.current.getBoundingClientRect();\n const containerRect = scrollContainer.getBoundingClientRect();\n\n // Update outline box (full width)\n if (outlineRef.current) {\n Object.assign(outlineRef.current.style, {\n position: 'fixed',\n top: `${rowRect.top}px`,\n left: `${containerRect.left}px`,\n width: `${containerRect.width}px`,\n height: `${rowRect.height}px`,\n outline:\n isRowMarginHovered || isSelected\n ? `3px solid ${isSelected ? '#1166c2' : '#72b3f3'}`\n : 'none',\n outlineOffset: '0px',\n borderRadius: '8px',\n pointerEvents: 'none',\n zIndex: '1199',\n });\n }\n\n // Update left margin detector\n if (leftMarginRef.current) {\n const leftWidth = rowRect.left - containerRect.left;\n Object.assign(leftMarginRef.current.style, {\n position: 'fixed',\n top: `${rowRect.top}px`,\n left: `${containerRect.left}px`,\n width: `${leftWidth}px`,\n height: `${rowRect.height}px`,\n cursor: 'pointer',\n pointerEvents: 'auto',\n zIndex: '1199',\n });\n }\n\n // Update right margin detector\n if (rightMarginRef.current) {\n const rightWidth = containerRect.right - rowRect.right;\n Object.assign(rightMarginRef.current.style, {\n position: 'fixed',\n top: `${rowRect.top}px`,\n left: `${rowRect.right}px`,\n width: `${rightWidth}px`,\n height: `${rowRect.height}px`,\n cursor: 'pointer',\n pointerEvents: 'auto',\n zIndex: '1199',\n });\n }\n };\n\n // Set up event handlers for margin detectors\n const handleMarginEnter = () => {\n setIsRowMarginHovered(true);\n };\n\n const handleMarginLeave = () => {\n setIsRowMarginHovered(false);\n };\n\n const handleMarginClick = (e: MouseEvent) => {\n e.stopPropagation();\n setSelectedComponentId(componentId);\n if (onComponentSelect) {\n onComponentSelect({\n id: componentId,\n type: componentType,\n element: node || null,\n styles: {},\n });\n }\n };\n\n leftMarginRef.current.addEventListener('mouseenter', handleMarginEnter);\n leftMarginRef.current.addEventListener('mouseleave', handleMarginLeave);\n leftMarginRef.current.addEventListener('click', handleMarginClick);\n\n rightMarginRef.current.addEventListener('mouseenter', handleMarginEnter);\n rightMarginRef.current.addEventListener('mouseleave', handleMarginLeave);\n rightMarginRef.current.addEventListener('click', handleMarginClick);\n\n updateMarginDetectors();\n\n window.addEventListener('scroll', updateMarginDetectors, true);\n window.addEventListener('resize', updateMarginDetectors);\n\n return () => {\n window.removeEventListener('scroll', updateMarginDetectors, true);\n window.removeEventListener('resize', updateMarginDetectors);\n\n if (leftMarginRef.current) {\n leftMarginRef.current.removeEventListener('mouseenter', handleMarginEnter);\n leftMarginRef.current.removeEventListener('mouseleave', handleMarginLeave);\n leftMarginRef.current.removeEventListener('click', handleMarginClick);\n if (leftMarginRef.current.parentNode) {\n leftMarginRef.current.parentNode.removeChild(leftMarginRef.current);\n }\n leftMarginRef.current = null;\n }\n if (rightMarginRef.current) {\n rightMarginRef.current.removeEventListener('mouseenter', handleMarginEnter);\n rightMarginRef.current.removeEventListener('mouseleave', handleMarginLeave);\n rightMarginRef.current.removeEventListener('click', handleMarginClick);\n if (rightMarginRef.current.parentNode) {\n rightMarginRef.current.parentNode.removeChild(rightMarginRef.current);\n }\n rightMarginRef.current = null;\n }\n if (outlineRef.current && outlineRef.current.parentNode) {\n outlineRef.current.parentNode.removeChild(outlineRef.current);\n outlineRef.current = null;\n }\n };\n }, [\n isWeb,\n isRow,\n isEditMode,\n isRowMarginHovered,\n isSelected,\n componentId,\n componentType,\n node,\n onComponentSelect,\n ]);\n\n // Create and manage a portal-like label element\n React.useEffect(() => {\n if (!isWeb || !showLabel) {\n // Clean up label if it exists\n if (labelRef.current && labelRef.current.parentNode) {\n labelRef.current.parentNode.removeChild(labelRef.current);\n labelRef.current = null;\n }\n return;\n }\n\n if (!wrapperRef.current) return;\n\n // Find the container using the same logic as margin detectors\n let scrollContainer: HTMLElement | null = null;\n if (isRow) {\n // For rows, find the outermost container with padding\n scrollContainer = wrapperRef.current.parentElement;\n const rowWidth = wrapperRef.current.getBoundingClientRect().width;\n let attempts = 0;\n while (scrollContainer && attempts < 15) {\n const containerWidth = scrollContainer.getBoundingClientRect().width;\n if (containerWidth > rowWidth + 20) {\n break;\n }\n scrollContainer = scrollContainer.parentElement;\n attempts++;\n }\n if (!scrollContainer || scrollContainer.getBoundingClientRect().width <= rowWidth) {\n scrollContainer = wrapperRef.current.parentElement;\n while (scrollContainer?.parentElement) {\n const parent = scrollContainer.parentElement;\n if (\n parent.getBoundingClientRect().width > scrollContainer.getBoundingClientRect().width\n ) {\n scrollContainer = parent;\n } else {\n break;\n }\n }\n }\n }\n\n // Create label element if it doesn't exist\n if (!labelRef.current) {\n labelRef.current = document.createElement('div');\n document.body.appendChild(labelRef.current);\n }\n\n const updateLabelPosition = () => {\n if (!wrapperRef.current || !labelRef.current) return;\n\n const rect = wrapperRef.current.getBoundingClientRect();\n const label = labelRef.current;\n\n // For rows on web, position at extreme left of container\n let leftPos = rect.left + 5;\n if (isRow && scrollContainer) {\n const containerRect = scrollContainer.getBoundingClientRect();\n leftPos = containerRect.left;\n }\n\n // Update styles\n Object.assign(label.style, {\n position: 'fixed',\n left: `${leftPos}px`,\n top: `${rect.top - 25}px`,\n height: '25px',\n display: 'flex',\n alignItems: 'center',\n backgroundColor: isSelected ? '#1166c2' : '#72b3f3',\n color: 'white',\n padding: '0 12px',\n fontSize: '11px',\n fontWeight: '600',\n borderRadius: '2px 2px 0 0',\n whiteSpace: 'nowrap',\n zIndex: '1200',\n pointerEvents: 'none',\n userSelect: 'none',\n boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.3)',\n });\n\n label.textContent = getComponentLabel(node?.subtype || componentType);\n };\n\n updateLabelPosition();\n\n window.addEventListener('scroll', updateLabelPosition, true);\n window.addEventListener('resize', updateLabelPosition);\n\n return () => {\n window.removeEventListener('scroll', updateLabelPosition, true);\n window.removeEventListener('resize', updateLabelPosition);\n if (labelRef.current && labelRef.current.parentNode) {\n labelRef.current.parentNode.removeChild(labelRef.current);\n labelRef.current = null;\n }\n };\n }, [showLabel, isSelected, node, componentType, isWeb, isRow, isEditMode]);\n\n // Use the toolbar hook to manage the delete button\n usePlacedItemToolbar({\n wrapperRef,\n isSelected,\n componentId,\n componentType,\n isRow,\n nodeSubtype: node?.subtype,\n });\n\n if (!isEditMode) return <>{children}</>;\n\n // Helper function to check if element is inside a contentEditable element\n const isInsideContentEditable = (target: any): boolean => {\n if (!target) return false;\n let el = target;\n let depth = 0;\n while (el && depth < 20) {\n if (el.getAttribute?.('data-slate-editor') === 'true') {\n return true;\n }\n if (el.contentEditable === 'true' || el.getAttribute?.('contenteditable') === 'true') {\n return true;\n }\n el = el.parentElement;\n depth++;\n }\n return false;\n };\n\n const handleClick = (e: any) => {\n // Don't handle clicks on columns - let them pass through to child blocks\n // Rows are allowed so empty rows can be selected and deleted\n if (isColumn) {\n return;\n }\n\n const target = e?.target || e?.nativeEvent?.target;\n\n // Check if the click is inside a contentEditable element\n if (isInsideContentEditable(target)) {\n // If the component is already selected, allow the click to proceed for text editing\n if (isSelected) {\n console.log(\n '[EditableWrapper] Allowing click inside contentEditable element (already selected)'\n );\n e?.stopPropagation?.();\n return;\n }\n // If not selected, we'll select it first (don't return early)\n console.log('[EditableWrapper] Selecting component with contentEditable element');\n }\n\n if (target) {\n let el = target;\n let depth = 0;\n while (el && depth < 20) {\n // Check for circle button attribute\n if (el.getAttribute?.('data-circle-button') === 'true') {\n console.log('[EditableWrapper] Ignoring circle button click - found data attribute');\n return;\n }\n el = el.parentElement;\n depth++;\n }\n }\n\n // Ignore clicks from circle button (legacy flag check)\n if (e?._circleButtonClick || e?.nativeEvent?._circleButtonClick) {\n console.log('[EditableWrapper] Ignoring circle button click - found flag');\n return;\n }\n\n // Only handle once - prevent double firing from both capture and bubble\n if (e?._editable_handled) return;\n if (e) e._editable_handled = true;\n\n e?.stopPropagation?.();\n console.log(\n '[EditableWrapper] Clicked:',\n componentId,\n componentType,\n 'onComponentSelect exists:',\n !!onComponentSelect\n );\n setSelectedComponentId(componentId);\n if (onComponentSelect) {\n console.log('[EditableWrapper] Calling onComponentSelect with:', {\n id: componentId,\n type: componentType,\n element: node || null,\n });\n onComponentSelect({\n id: componentId,\n type: componentType,\n element: node || null,\n styles: {},\n });\n } else {\n console.warn('[EditableWrapper] onComponentSelect is not defined!');\n }\n };\n\n return (\n <div\n ref={wrapperRef}\n data-component-id={componentId}\n data-component-type={componentType}\n style={{\n position: 'relative',\n ...(flex && { flex: 1 }),\n }}\n onMouseEnter={\n isColumn\n ? undefined\n : isColumn\n ? undefined\n : (e) => {\n if (!isInsideContentEditable(e.target)) {\n setHoveredComponentId(componentId);\n }\n }\n }\n onMouseLeave={\n isColumn\n ? undefined\n : isColumn\n ? undefined\n : (e) => {\n if (!isInsideContentEditable(e.target)) {\n setHoveredComponentId(null);\n }\n }\n }\n onClick={handleClick}\n >\n {children}\n {/* Selection border - only for blocks, not rows (rows use full-width outline) */}\n {showLabel && !isRow && (\n <>\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n border: `3px solid ${isSelected ? '#1166c2' : '#72b3f3'}`,\n borderRadius: '8px',\n pointerEvents: 'none',\n zIndex: 1,\n }}\n />\n </>\n )}\n </div>\n );\n };\n return Wrapper;\n }, [isEditMode, hoveredComponentId, selectedComponentId, onComponentSelect, onComponentDelete]);\n\n const styles = createStyles(fontFamily);\n\n const handleHeaderButtonPress = () => {\n if (view === 'main') {\n handleClose();\n } else {\n handleBackToMain();\n }\n };\n\n // Deselect when clicking on empty space (web only)\n React.useEffect(() => {\n if (!isEditMode || !isWeb) return;\n\n const handleDocumentClick = (e: MouseEvent) => {\n let el = e.target as HTMLElement | null;\n while (el) {\n // If the click is inside an editable element, do nothing\n if (el.getAttribute) {\n if (\n el.getAttribute('data-component-id') ||\n el.getAttribute('data-circle-button') === 'true'\n ) {\n return;\n }\n }\n el = el.parentElement;\n }\n // Click was on empty space, deselect\n setSelectedComponentId(null);\n };\n\n document.addEventListener('click', handleDocumentClick, true);\n return () => {\n document.removeEventListener('click', handleDocumentClick, true);\n };\n }, [isEditMode]);\n\n // Handle component deletion (web only)\n React.useEffect(() => {\n if (!isWeb || !isEditMode) return;\n\n const handleDeleteEvent = (e: Event) => {\n const customEvent = e as CustomEvent;\n const { id, type } = customEvent.detail;\n\n if (onComponentDelete) {\n onComponentDelete(id, type);\n }\n\n // Also deselect the component\n setSelectedComponentId(null);\n };\n\n document.addEventListener('vortex-delete-component', handleDeleteEvent, true);\n\n return () => {\n document.removeEventListener('vortex-delete-component', handleDeleteEvent, true);\n };\n }, [isEditMode, onComponentDelete]);\n\n // Extract root form styles from formStructure\n // Transform CSS properties to React Native equivalents (e.g., 'background' -> 'backgroundColor')\n const rawRootStyle = formStructure?.style || {};\n const rootFormStyle: Record<string, any> = {};\n for (const [key, value] of Object.entries(rawRootStyle)) {\n if (key === 'background' && typeof value === 'string' && !value.includes('gradient')) {\n // Convert CSS 'background' to RN 'backgroundColor' for solid colors\n rootFormStyle.backgroundColor = value;\n } else if (key !== 'background') {\n // Pass through other properties (skip gradients which need special handling)\n rootFormStyle[key] = value;\n }\n }\n\n return (\n <View style={{ ...styles.container, ...containerStyle, ...rootFormStyle }}>\n {/* Header with Close or Back button */}\n <View style={{ ...styles.header, ...rootFormStyle }}>\n <View\n style={[styles.headerButton, { minWidth: 44, minHeight: 44, justifyContent: 'center' }]}\n onStartShouldSetResponder={() => {\n return true;\n }}\n onResponderGrant={() => {\n // Handle responder grant\n }}\n onResponderRelease={() => {\n handleHeaderButtonPress();\n }}\n >\n {renderIcon({\n name: view === 'main' ? 'close' : 'arrow-back',\n size: 24,\n color: resolvedTitleStyle?.color || '#666',\n opacity: 0.75,\n })}\n </View>\n {resolvedTitle && (\n <Text\n style={[\n styles.headerTitle,\n resolvedTitleStyle && {\n ...(resolvedTitleStyle.color && { color: resolvedTitleStyle.color }),\n ...(resolvedTitleStyle.fontSize && { fontSize: resolvedTitleStyle.fontSize }),\n ...(resolvedTitleStyle.fontWeight && { fontWeight: resolvedTitleStyle.fontWeight as any }),\n ...(resolvedTitleStyle.fontFamily && { fontFamily: resolvedTitleStyle.fontFamily }),\n },\n ]}\n >\n {resolvedTitle}\n </Text>\n )}\n {/* Empty spacer to balance the header when title is present */}\n {resolvedTitle && <View style={[styles.headerButton, { minWidth: 44, minHeight: 44 }]} />}\n </View>\n\n <ScrollView\n style={{ ...styles.scrollContent, ...rootFormStyle }}\n contentContainerStyle={rootFormStyle}\n showsVerticalScrollIndicator={false}\n >\n {view === 'main' && formStructure && (\n <>\n {/* <EditableWrapper componentId=\"title-text\" componentType=\"text\">\n <Text style={styles.title}>Invite people to join your team</Text>\n </EditableWrapper> */}\n\n {/* Dynamic rendering from formStructure */}\n {formStructure.children?.map((child: any, index: number) => {\n if (child.type === 'row') {\n return renderRow(child, index, formStructure.children.length);\n }\n return null;\n })}\n </>\n )}\n\n {view === 'main' && !formStructure && (\n <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}>\n <Text style={{ fontSize: 50, marginBottom: 16 }}>⚠️</Text>\n <Text style={{ fontSize: 18, fontWeight: 'bold', color: '#d9534f', marginBottom: 8, fontFamily }}>\n Configuration Error\n </Text>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>\n Unable to load form structure from widget configuration. Please check your widget configuration and try again.\n </Text>\n </View>\n )}\n\n {view === 'email' && formStructure && (\n <>\n <View style={styles.section}>\n {/* Dynamic rendering from formStructure - only email-related blocks */}\n {formStructure.children?.map((child: any, index: number) => {\n if (child.type === 'row') {\n // Render all rows, but filter blocks inside to only show grp-email-invitations\n return renderRow(\n child,\n index,\n formStructure.children.length,\n 'grp-email-invitations'\n );\n }\n return null;\n })}\n </View>\n </>\n )}\n\n {view === 'email' && !formStructure && (\n <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}>\n <Text style={{ fontSize: 50, marginBottom: 16 }}>⚠️</Text>\n <Text style={{ fontSize: 18, fontWeight: 'bold', color: '#d9534f', marginBottom: 8, fontFamily }}>\n Configuration Error\n </Text>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>\n Unable to load form structure from widget configuration. Please check your widget configuration and try again.\n </Text>\n </View>\n )}\n\n {view === 'contacts' && (\n <>\n <Text style={styles.title}>{getContactsCustomization('importContacts.title', 'Add from Contacts')}</Text>\n\n <View style={styles.section}>\n <TextInput\n style={styles.input}\n placeholder={getContactsCustomization('importContacts.searchPlaceholder', 'Search contacts...')}\n placeholderTextColor=\"#999\"\n value={searchQuery}\n onChangeText={setSearchQuery}\n autoCapitalize=\"none\"\n autoCorrect={false}\n returnKeyType=\"search\"\n />\n\n {loadingContacts ? (\n <View style={styles.loadingContainer}>\n <ActivityIndicator size=\"large\" color=\"#6291d5\" />\n <Text style={styles.loadingText}>{getContactsCustomization('importContacts.loadingText', 'Loading contacts...')}</Text>\n </View>\n ) : contactsError ? (\n <View style={styles.errorContainer}>\n <Text style={styles.errorTitle}>{getContactsCustomization('importContacts.errorTitle', 'Unable to Access Contacts')}</Text>\n <Text style={styles.errorMessage}>{contactsError.message}</Text>\n {contactsError.message.includes('Settings') && (\n <>\n <Text style={styles.errorHint}>\n To grant access: Open Settings → Privacy & Security → Contacts → Enable for\n this app\n </Text>\n <View style={styles.errorActions}>\n <TouchableOpacity\n style={[styles.button, styles.secondaryButton, styles.halfButton]}\n onPress={handleOpenSettings}\n >\n <Text style={styles.secondaryButtonText}>{getContactsCustomization('importContacts.openSettingsButton', 'Open Settings')}</Text>\n </TouchableOpacity>\n <TouchableOpacity\n style={[styles.button, styles.secondaryButton, styles.halfButton]}\n onPress={handleRetryContacts}\n >\n <Text style={styles.secondaryButtonText}>{getContactsCustomization('importContacts.retryButton', 'Retry')}</Text>\n </TouchableOpacity>\n </View>\n </>\n )}\n {!contactsError.message.includes('Settings') && (\n <TouchableOpacity\n style={[styles.button, styles.secondaryButton, { marginTop: 16 }]}\n onPress={handleRetryContacts}\n >\n <Text style={styles.secondaryButtonText}>{getContactsCustomization('importContacts.tryAgainButton', 'Try Again')}</Text>\n </TouchableOpacity>\n )}\n <Text style={styles.errorDetails}>\n {contactsError.message || 'Unknown error occurred'}\n </Text>\n </View>\n ) : (\n <View style={styles.contactsList}>\n {filteredContacts.length === 0 ? (\n <Text style={styles.emptyText}>\n {searchQuery\n ? getContactsCustomization('importContacts.emptySearchState', 'No contacts match your search')\n : getContactsCustomization('importContacts.emptyState', 'No contacts with email addresses found')}\n </Text>\n ) : (\n filteredContacts.map((contact) => {\n const isInvited = invitedContactIds.has(contact.id);\n const isLoading = loadingContactIds.has(contact.id);\n const initials = contact.name\n .split(' ')\n .map((part) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n return (\n <View key={contact.id} style={styles.contactItem}>\n {contact.imageUri ? (\n <Image source={{ uri: contact.imageUri }} style={styles.contactAvatar} />\n ) : (\n <View style={styles.contactAvatarPlaceholder}>\n <Text style={styles.contactAvatarInitials}>{initials}</Text>\n </View>\n )}\n <View style={styles.contactInfo}>\n <Text style={styles.contactName}>{contact.name}</Text>\n <Text style={styles.contactEmail}>{contact.email}</Text>\n </View>\n {isInvited ? (\n <Text style={styles.invitedText}>{getContactsCustomization('importContacts.invitedStatus', '✓ Invited!')}</Text>\n ) : (\n <TouchableOpacity\n style={styles.inviteButton}\n onPress={() => handleInviteContactWithHaptics(contact.id)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#333\" />\n ) : (\n <Text style={styles.inviteButtonText}>{getContactsCustomization('importContacts.inviteButton', 'Invite')}</Text>\n )}\n </TouchableOpacity>\n )}\n </View>\n );\n })\n )}\n </View>\n )}\n </View>\n </>\n )}\n\n {view === 'googleContacts' && (\n <>\n <Text style={styles.title}>{getContactsCustomization('google.title', 'Add from Google Contacts')}</Text>\n\n <View style={styles.section}>\n <TextInput\n style={styles.input}\n placeholder={getContactsCustomization('google.searchPlaceholder', 'Search contacts...')}\n placeholderTextColor=\"#999\"\n value={googleSearchQuery}\n onChangeText={setGoogleSearchQuery}\n autoCapitalize=\"none\"\n autoCorrect={false}\n returnKeyType=\"search\"\n />\n\n {loadingGoogleContacts ? (\n <View style={styles.loadingContainer}>\n <ActivityIndicator size=\"large\" color=\"#6291d5\" />\n <Text style={styles.loadingText}>{getContactsCustomization('google.loadingText', 'Loading Google contacts...')}</Text>\n </View>\n ) : googleContactsError ? (\n <View style={styles.errorContainer}>\n <Text style={styles.errorTitle}>{getContactsCustomization('google.errorTitle', 'Unable to Access Google Contacts')}</Text>\n <Text style={styles.errorMessage}>{googleContactsError.message}</Text>\n <TouchableOpacity\n style={[styles.button, styles.secondaryButton, { marginTop: 16 }]}\n onPress={handleRetryContacts}\n >\n <Text style={styles.secondaryButtonText}>{getContactsCustomization('google.tryAgainButton', 'Try Again')}</Text>\n </TouchableOpacity>\n <Text style={styles.errorDetails}>\n {googleContactsError.message || 'Unknown error occurred'}\n </Text>\n </View>\n ) : (\n <View style={styles.contactsList}>\n {filteredGoogleContacts.length === 0 ? (\n <Text style={styles.emptyText}>\n {googleSearchQuery\n ? getContactsCustomization('google.emptySearchState', 'No contacts match your search')\n : getContactsCustomization('google.emptyState', 'No Google contacts with email addresses found')}\n </Text>\n ) : (\n filteredGoogleContacts.map((contact) => {\n const isInvited = invitedGoogleContactIds.has(contact.id);\n const isLoading = loadingGoogleContactIds.has(contact.id);\n const initials = contact.name\n .split(' ')\n .map((part) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n return (\n <View key={contact.id} style={styles.contactItem}>\n {contact.imageUri ? (\n <Image source={{ uri: contact.imageUri }} style={styles.contactAvatar} />\n ) : (\n <View style={styles.contactAvatarPlaceholder}>\n <Text style={styles.contactAvatarInitials}>{initials}</Text>\n </View>\n )}\n <View style={styles.contactInfo}>\n <Text style={styles.contactName}>{contact.name}</Text>\n <Text style={styles.contactEmail}>{contact.email}</Text>\n </View>\n {isInvited ? (\n <Text style={styles.invitedText}>{getContactsCustomization('google.invitedStatus', '✓ Invited!')}</Text>\n ) : (\n <TouchableOpacity\n style={styles.inviteButton}\n onPress={() => handleInviteGoogleContactWithHaptics(contact.id)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#333\" />\n ) : (\n <Text style={styles.inviteButtonText}>{getContactsCustomization('google.inviteButton', 'Invite')}</Text>\n )}\n </TouchableOpacity>\n )}\n </View>\n );\n })\n )}\n </View>\n )}\n </View>\n </>\n )}\n\n {view === 'qrcode' && (\n <View style={styles.section}>\n <View style={styles.qrCodeViewContainer}>\n {Platform.OS === 'web' ? (\n // In web preview mode, show placeholder QR code immediately for demo\n renderQRCode ? (\n renderQRCode({\n value: logic.invitationLink,\n size: 250,\n })\n ) : (\n <Text style={styles.errorMessage}>QR Code rendering not available</Text>\n )\n ) : loadingInvitationLink ||\n logic.invitationLink === 'https://app.vortexsoftware.com/invite/abc123' ? (\n // In native mode, show loading while fetching real link\n <View style={styles.loadingContainer}>\n <ActivityIndicator size=\"large\" color=\"#6291d5\" />\n <Text style={styles.loadingText}>Generating QR Code...</Text>\n </View>\n ) : renderQRCode ? (\n renderQRCode({\n value: logic.invitationLink,\n size: 250,\n })\n ) : (\n <Text style={styles.errorMessage}>QR Code rendering not available</Text>\n )}\n </View>\n </View>\n )}\n </ScrollView>\n </View>\n );\n}\n\nconst createStyles = (fontFamily: string) =>\n StyleSheet.create({\n container: {\n flex: 1,\n paddingTop: 8,\n backgroundColor: '#fff',\n },\n handle: {\n width: 40,\n height: 4,\n backgroundColor: '#ddd',\n borderRadius: 2,\n alignSelf: 'center',\n marginBottom: 2,\n },\n header: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n paddingHorizontal: 16,\n paddingVertical: 4,\n zIndex: 10,\n backgroundColor: '#fff',\n },\n headerButton: {\n padding: 4,\n },\n headerTitle: {\n fontFamily,\n fontSize: 17,\n fontWeight: '600',\n color: '#1a1a1a',\n textAlign: 'center',\n flex: 1,\n },\n sendButton: {\n paddingHorizontal: 8,\n paddingVertical: 8,\n },\n sendButtonText: {\n fontFamily,\n color: '#2196F3',\n fontSize: 16,\n fontWeight: '600',\n },\n scrollContent: {\n flex: 1,\n paddingHorizontal: 20,\n // backgroundColor: 'none',\n },\n title: {\n fontFamily,\n fontSize: 18,\n fontWeight: '700',\n color: '#1a1a1a',\n marginTop: 16,\n marginBottom: 20,\n textAlign: 'center',\n },\n subtitle: {\n fontFamily,\n fontSize: 13,\n color: '#666',\n marginBottom: 20,\n lineHeight: 18,\n },\n // Sections\n section: {\n marginBottom: 10,\n },\n emptyRowEditMode: {\n minHeight: 40,\n backgroundColor: 'rgba(200, 200, 200, 0.2)',\n borderWidth: 1,\n borderColor: 'rgba(150, 150, 150, 0.3)',\n borderStyle: 'dashed',\n borderRadius: 4,\n },\n sectionTitle: {\n fontFamily,\n fontSize: 16,\n fontWeight: '700',\n color: '#1a1a1a',\n marginBottom: 12,\n },\n // Email chips\n emailChipsContainer: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 8,\n marginBottom: 12,\n },\n emailChip: {\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: '#e3f2fd',\n borderRadius: 16,\n paddingVertical: 6,\n paddingLeft: 12,\n paddingRight: 8,\n borderWidth: 1,\n borderColor: '#90caf9',\n },\n emailChipText: {\n fontFamily,\n fontSize: 13,\n color: '#1565c0',\n marginRight: 6,\n },\n emailChipRemove: {\n fontFamily,\n fontSize: 20,\n color: '#1565c0',\n fontWeight: '600',\n lineHeight: 20,\n },\n // Input\n input: {\n fontFamily,\n borderWidth: 1,\n borderColor: '#ddd',\n borderRadius: 8,\n paddingHorizontal: 14,\n paddingVertical: 10,\n fontSize: 15,\n color: '#1a1a1a',\n backgroundColor: '#fafafa',\n marginBottom: 12,\n },\n // Buttons\n button: {\n borderRadius: 8,\n paddingVertical: 12,\n paddingHorizontal: 16,\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'row',\n },\n secondaryButton: {\n backgroundColor: '#f5f5f5',\n borderWidth: 1,\n borderColor: '#e0e0e0',\n },\n secondaryButtonText: {\n fontFamily,\n color: '#333',\n fontSize: 14,\n fontWeight: '600',\n },\n tertiaryButton: {\n backgroundColor: '#f5f5f5',\n borderWidth: 1,\n borderColor: '#e0e0e0',\n },\n tertiaryButtonText: {\n fontFamily,\n color: '#333',\n fontSize: 11,\n fontWeight: '600',\n },\n actionButtons: {\n flexDirection: 'row',\n gap: 10,\n },\n halfButton: {\n flex: 1,\n },\n shareButtonsContainer: {\n flexDirection: 'column',\n gap: 10,\n },\n contactButtonsContainer: {\n flexDirection: 'column',\n gap: 10,\n },\n fullButton: {\n width: '100%',\n },\n buttonIconContainer: {\n marginRight: 8,\n },\n // Contacts list\n contactsList: {\n gap: 0,\n },\n contactItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n contactAvatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n contactAvatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n backgroundColor: '#6291d5',\n alignItems: 'center',\n justifyContent: 'center',\n },\n contactAvatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n color: '#ffffff',\n },\n contactInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n contactName: {\n fontFamily,\n fontSize: 15,\n fontWeight: '600',\n color: '#1a1a1a',\n marginBottom: 4,\n },\n contactEmail: {\n fontFamily,\n fontSize: 13,\n color: '#666',\n },\n inviteButton: {\n paddingVertical: 8,\n paddingHorizontal: 16,\n backgroundColor: '#f5f5f5',\n borderWidth: 1,\n borderColor: '#e0e0e0',\n borderRadius: 6,\n minWidth: 80,\n alignItems: 'center',\n },\n inviteButtonText: {\n fontFamily,\n fontSize: 13,\n fontWeight: '600',\n color: '#333',\n },\n invitedText: {\n fontFamily,\n fontSize: 13,\n fontWeight: '600',\n color: '#666',\n },\n successMessageContainer: {\n paddingVertical: 12,\n alignItems: 'center',\n },\n // Loading state\n loadingContainer: {\n paddingVertical: 40,\n alignItems: 'center',\n justifyContent: 'center',\n },\n loadingText: {\n fontFamily,\n fontSize: 14,\n color: '#666',\n marginTop: 12,\n },\n emptyText: {\n fontFamily,\n fontSize: 14,\n color: '#999',\n textAlign: 'center',\n paddingVertical: 20,\n },\n // Error state\n errorContainer: {\n paddingVertical: 40,\n paddingHorizontal: 20,\n alignItems: 'center',\n justifyContent: 'center',\n },\n errorTitle: {\n fontFamily,\n fontSize: 16,\n fontWeight: '600',\n color: '#d9534f',\n marginBottom: 12,\n textAlign: 'center',\n },\n errorMessage: {\n fontFamily,\n fontSize: 14,\n color: '#666',\n marginBottom: 16,\n textAlign: 'center',\n lineHeight: 20,\n },\n errorHint: {\n fontFamily,\n fontSize: 13,\n color: '#666',\n marginTop: 12,\n marginBottom: 8,\n textAlign: 'center',\n lineHeight: 18,\n backgroundColor: '#f0f8ff',\n padding: 12,\n borderRadius: 6,\n borderWidth: 1,\n borderColor: '#b3d9ff',\n },\n errorActions: {\n flexDirection: 'row',\n gap: 10,\n marginTop: 16,\n marginBottom: 8,\n width: '100%',\n },\n errorDetails: {\n fontFamily,\n fontSize: 12,\n color: '#999',\n textAlign: 'center',\n fontStyle: 'italic',\n },\n // QR Code view\n qrCodeViewContainer: {\n alignItems: 'center',\n justifyContent: 'center',\n padding: 20,\n backgroundColor: '#fff',\n borderRadius: 10,\n marginVertical: 10,\n },\n // Edit mode circle button\n editModeCircleButton: {\n position: 'absolute',\n right: 8,\n top: '50%',\n transform: [{ translateY: -15 }],\n width: 30,\n height: 30,\n borderRadius: 15,\n backgroundColor: '#2196F3',\n justifyContent: 'center',\n alignItems: 'center',\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.25,\n shadowRadius: 3.84,\n elevation: 5,\n },\n editModeCircleButtonText: {\n color: '#fff',\n fontSize: 16,\n fontWeight: 'bold',\n },\n });\n","import { useState, useEffect, useRef } from 'react';\nimport { Platform } from 'react-native';\nimport { PlatformOperations } from '../types/platformOperations';\n\nexport type ViewType = 'main' | 'email' | 'contacts' | 'googleContacts' | 'qrcode';\n\nexport interface Contact {\n id: string;\n name: string;\n email: string;\n imageUri?: string;\n}\n\nexport function useInvitationFormLogic(\n platformOps: PlatformOperations,\n contacts?: Contact[],\n googleContacts?: Contact[],\n getShareableInviteLink?: () => Promise<string | undefined>\n) {\n const [view, setView] = useState<ViewType>('main');\n const [emailInput, setEmailInput] = useState('');\n const [emails, setEmails] = useState<string[]>([]);\n const [role, setRole] = useState<'member' | 'admin'>('member');\n const [copySuccess, setCopySuccess] = useState(false);\n const [shareSuccess, setShareSuccess] = useState(false);\n const [sendSuccess, setSendSuccess] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n const [invitedContactIds, setInvitedContactIds] = useState<Set<string>>(new Set());\n const [invitedGoogleContactIds, setInvitedGoogleContactIds] = useState<Set<string>>(new Set());\n const [googleSearchQuery, setGoogleSearchQuery] = useState('');\n const [loadingContactIds, setLoadingContactIds] = useState<Set<string>>(new Set());\n const [loadingGoogleContactIds, setLoadingGoogleContactIds] = useState<Set<string>>(new Set());\n const [loadingEmailInvite, setLoadingEmailInvite] = useState(false);\n const [loadingCopy, setLoadingCopy] = useState(false);\n const [loadingShare, setLoadingShare] = useState(false);\n const [invitationLink, setInvitationLink] = useState<string>('https://app.vortexsoftware.com/invite/abc123');\n const [loadingInvitationLink, setLoadingInvitationLink] = useState(false);\n const fetchedRef = useRef(false);\n\n // Fetch the actual invitation link when QR code view is shown\n // In web/preview mode, skip fetching and use the placeholder for demo purposes\n useEffect(() => {\n // If we're in web mode, don't fetch - just show the placeholder immediately\n if (Platform.OS === 'web') {\n console.log('[Vortex] Web preview mode: using placeholder QR code for demo');\n return;\n }\n\n if (view === 'qrcode' && getShareableInviteLink && !fetchedRef.current) {\n fetchedRef.current = true;\n setLoadingInvitationLink(true);\n getShareableInviteLink()\n .then((link) => {\n if (link) {\n setInvitationLink(link);\n console.log('[Vortex] QR code invitation link fetched:', link);\n } else {\n console.warn('[Vortex] No invitation link available for QR code');\n }\n })\n .catch((error) => {\n console.error('[Vortex] Failed to fetch invitation link for QR code:', error);\n fetchedRef.current = false; // Allow retry on error\n })\n .finally(() => {\n setLoadingInvitationLink(false);\n });\n }\n \n // Reset when leaving QR code view\n if (view !== 'qrcode') {\n fetchedRef.current = false;\n }\n }, [view, getShareableInviteLink]);\n\n const handleClose = () => {\n platformOps.close();\n };\n\n const handleSendInvitation = async () => {\n // First, process any pending email in the input field\n const trimmedEmail = emailInput.trim();\n let emailsToSend = [...emails];\n \n if (trimmedEmail && isValidEmail(trimmedEmail)) {\n // Add the pending email to the list\n emailsToSend = [...emails, trimmedEmail];\n setEmails(emailsToSend);\n }\n\n // If pending text exists but is invalid, show feedback instead of silently ignoring\n if (trimmedEmail && !isValidEmail(trimmedEmail)) {\n setLastInvalidEmail(trimmedEmail);\n setTimeout(() => setLastInvalidEmail(null), 1500);\n }\n\n // If there are no emails to send, don't proceed\n if (emailsToSend.length === 0) {\n return;\n }\n\n // De-duplicate before sending (user may have entered the same email twice)\n const uniqueEmails = [...new Set(emailsToSend)];\n\n setLoadingEmailInvite(true);\n try {\n // Send invites for all unique emails\n await Promise.all(uniqueEmails.map((email) => platformOps.invite(email)));\n\n console.log('[Vortex] Successfully sent invitations to:', emailsToSend);\n setSendSuccess(true);\n setEmails([]);\n setEmailInput('');\n setTimeout(() => setSendSuccess(false), 2000);\n } catch (error) {\n console.error('[Vortex] Failed to send invitations:', error);\n // Could add error state here if needed\n } finally {\n setLoadingEmailInvite(false);\n }\n };\n\n const handleCopyLink = async () => {\n setLoadingCopy(true);\n try {\n await platformOps.copyToClipboard();\n setCopySuccess(true);\n setTimeout(() => setCopySuccess(false), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n // On error, loading state is cleared but success is not set\n } finally {\n setLoadingCopy(false);\n }\n };\n\n const handleShare = async () => {\n setLoadingShare(true);\n try {\n await platformOps.share();\n setShareSuccess(true);\n setTimeout(() => setShareSuccess(false), 2000);\n } catch (err) {\n console.error('Failed to share:', err);\n // On error, loading state is cleared but success is not set\n } finally {\n setLoadingShare(false);\n }\n };\n\n const isValidEmail = (email: string): boolean => {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email.trim());\n };\n\n // Track the last invalid email attempt so the UI can show feedback\n const [lastInvalidEmail, setLastInvalidEmail] = useState<string | null>(null);\n\n const handleEmailSubmit = (overrideEmail?: string) => {\n const trimmedEmail = (overrideEmail ?? emailInput).trim();\n if (!trimmedEmail) return;\n\n if (isValidEmail(trimmedEmail)) {\n // Allow duplicate emails — they will be de-duplicated before sending\n setEmails([...emails, trimmedEmail]);\n setEmailInput('');\n setLastInvalidEmail(null);\n } else {\n // Signal invalid email so the UI can show brief feedback (red border flash)\n setLastInvalidEmail(trimmedEmail);\n // Auto-clear the invalid state after a short delay\n setTimeout(() => setLastInvalidEmail(null), 1500);\n }\n };\n\n const handleRemoveEmail = (emailToRemove: string) => {\n setEmails(emails.filter((email) => email !== emailToRemove));\n };\n\n const handleSelectFromGoogle = () => {\n setView('googleContacts');\n };\n\n const handleSelectFromContacts = () => {\n setView('contacts');\n };\n\n const handleAddByEmail = () => {\n setView('email');\n };\n\n const handleShowQrCode = () => {\n setView('qrcode');\n };\n\n const handleBackToMain = () => {\n console.log('[Vortex] handleBackToMain called, returning to main view');\n console.log('[Vortex] Current view before setView:', view);\n setView('main');\n console.log('[Vortex] setView(\"main\") called');\n setSearchQuery('');\n setGoogleSearchQuery('');\n };\n\n const handleInviteContact = async (contactId: string) => {\n const contact = contacts?.find((c) => c.id === contactId);\n if (!contact) {\n console.error('[Vortex] Contact not found:', contactId);\n return;\n }\n\n // Add to loading set\n setLoadingContactIds((prev) => {\n const newSet = new Set(prev);\n newSet.add(contactId);\n return newSet;\n });\n\n try {\n await platformOps.invite(contact.email, contact.name);\n\n setInvitedContactIds((prev) => {\n const newSet = new Set(prev);\n newSet.add(contactId);\n return newSet;\n });\n } catch (error) {\n console.error('[Vortex] Failed to invite contact:', error);\n // On error, we don't add to invited set, just remove from loading\n } finally {\n // Remove from loading set\n setLoadingContactIds((prev) => {\n const newSet = new Set(prev);\n newSet.delete(contactId);\n return newSet;\n });\n }\n };\n\n const handleInviteGoogleContact = async (contactId: string) => {\n const contact = googleContacts?.find((c) => c.id === contactId);\n if (!contact) {\n console.error('[Vortex] Google contact not found:', contactId);\n return;\n }\n\n // Add to loading set\n setLoadingGoogleContactIds((prev) => {\n const newSet = new Set(prev);\n newSet.add(contactId);\n return newSet;\n });\n\n try {\n await platformOps.invite(contact.email, contact.name);\n\n setInvitedGoogleContactIds((prev) => {\n const newSet = new Set(prev);\n newSet.add(contactId);\n return newSet;\n });\n } catch (error) {\n console.error('[Vortex] Failed to invite Google contact:', error);\n // On error, we don't add to invited set, just remove from loading\n } finally {\n // Remove from loading set\n setLoadingGoogleContactIds((prev) => {\n const newSet = new Set(prev);\n newSet.delete(contactId);\n return newSet;\n });\n }\n };\n\n return {\n // State\n view,\n emailInput,\n emails,\n role,\n copySuccess,\n shareSuccess,\n sendSuccess,\n searchQuery,\n invitedContactIds,\n invitedGoogleContactIds,\n googleSearchQuery,\n invitationLink,\n loadingContactIds,\n loadingGoogleContactIds,\n loadingEmailInvite,\n loadingCopy,\n loadingShare,\n loadingInvitationLink,\n lastInvalidEmail,\n // Setters\n setView,\n setEmailInput,\n setEmails,\n setRole,\n setCopySuccess,\n setShareSuccess,\n setSendSuccess,\n setSearchQuery,\n setInvitedContactIds,\n setInvitedGoogleContactIds,\n setGoogleSearchQuery,\n // Handlers\n handleClose,\n handleSendInvitation,\n handleCopyLink,\n handleShare,\n isValidEmail,\n handleEmailSubmit,\n handleRemoveEmail,\n handleSelectFromGoogle,\n handleSelectFromContacts,\n handleAddByEmail,\n handleShowQrCode,\n handleBackToMain,\n handleInviteContact,\n handleInviteGoogleContact,\n };\n}\n","import type { Contact } from '../hooks/useInvitationFormLogic';\n\n/**\n * Filters contacts based on a search query\n * @param contacts Array of contacts to filter\n * @param searchQuery Query string to filter by\n * @returns Filtered array of contacts\n */\nexport function filterContacts(contacts: Contact[], searchQuery: string): Contact[] {\n const query = searchQuery.toLowerCase().trim();\n if (!query) return contacts;\n \n return contacts.filter(contact =>\n contact.name.toLowerCase().includes(query) ||\n contact.email.toLowerCase().includes(query)\n );\n}\n","import React from 'react';\nimport {\n View,\n Text,\n TouchableOpacity,\n ActivityIndicator,\n StyleSheet,\n ViewStyle,\n Platform,\n} from 'react-native';\nimport { IconRendererProps, IconName } from './InviteFormCore';\nimport { useVortexModules } from '../context/VortexModulesContext';\n\nconst isWeb = Platform.OS === 'web';\n\nexport interface VrtxShareOptionsProps {\n block: any;\n renderIcon: (props: IconRendererProps) => React.ReactNode;\n isCopyLinkEnabled: () => boolean;\n isShareEnabled: () => boolean;\n isEmailShareEnabled: () => boolean;\n isSmsEnabled: () => boolean;\n isTwitterDmsEnabled: () => boolean;\n isInstagramDmsEnabled: () => boolean;\n isWhatsAppEnabled: () => boolean;\n isLineEnabled: () => boolean;\n isLineLiffEnabled: () => boolean;\n isQrCodeEnabled: () => boolean;\n isFacebookMessengerEnabled: () => boolean;\n isTelegramEnabled: () => boolean;\n isDiscordEnabled: () => boolean;\n handleCopyLink: () => Promise<void>;\n handleShare: () => Promise<void>;\n handleEmailShare: () => Promise<void>;\n handleSmsShare: () => Promise<void>;\n handleTwitterShare: () => Promise<void>;\n handleInstagramShare: () => Promise<void>;\n handleWhatsAppShare: () => Promise<void>;\n handleLineShare: () => Promise<void>;\n handleLineLiffShare: () => Promise<void>;\n handleQrCode: () => Promise<void>;\n handleFacebookMessengerShare: () => Promise<void>;\n handleTelegramShare: () => Promise<void>;\n handleDiscordShare: () => Promise<void>;\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n loadingCopy: boolean;\n loadingShare: boolean;\n copySuccess: boolean;\n shareSuccess: boolean;\n isEditMode?: boolean;\n shareOptionsOrder?: string[];\n}\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n wrapperStyle?: ViewStyle | ViewStyle[];\n}\n\nconst ButtonWrapper: React.FC<ButtonWrapperProps> = ({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n wrapperStyle,\n}) => {\n // Get the gradient module and loaders from context\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n const combinedStyle = wrapperStyle ? [wrapperStyle, ...styleArray] : styleArray;\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...combinedStyle, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n style={wrapperStyle}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor\n ? [...combinedStyle, { backgroundColor: fallbackColor }]\n : combinedStyle;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n};\n\nexport function VrtxShareOptions({\n block,\n renderIcon,\n isCopyLinkEnabled,\n isShareEnabled,\n isEmailShareEnabled,\n isSmsEnabled,\n isTwitterDmsEnabled,\n isInstagramDmsEnabled,\n isWhatsAppEnabled,\n isLineEnabled,\n isLineLiffEnabled,\n isQrCodeEnabled,\n isFacebookMessengerEnabled,\n isTelegramEnabled,\n isDiscordEnabled,\n handleCopyLink,\n handleShare,\n handleEmailShare,\n handleSmsShare,\n handleTwitterShare,\n handleInstagramShare,\n handleWhatsAppShare,\n handleLineShare,\n handleLineLiffShare,\n handleQrCode,\n handleFacebookMessengerShare,\n handleTelegramShare,\n handleDiscordShare,\n triggerHaptic,\n loadingCopy,\n loadingShare,\n copySuccess,\n shareSuccess,\n isEditMode = false,\n shareOptionsOrder = [],\n}: VrtxShareOptionsProps) {\n // Get loaders from context\n const { loaders } = useVortexModules();\n const handleCopyLinkWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleCopyLink();\n };\n\n const handleShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleShare();\n };\n\n const handleEmailShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleEmailShare();\n };\n\n const handleSmsShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleSmsShare();\n };\n\n const handleTwitterShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleTwitterShare();\n };\n\n const handleInstagramShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleInstagramShare();\n };\n\n const handleWhatsAppShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleWhatsAppShare();\n };\n\n const handleLineShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleLineShare();\n };\n\n const handleLineLiffShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleLineLiffShare();\n };\n\n const handleQrCodeWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleQrCode();\n };\n\n const handleFacebookMessengerShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleFacebookMessengerShare();\n };\n\n const handleTelegramShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleTelegramShare();\n };\n\n const handleDiscordShareWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleDiscordShare();\n };\n\n const showCopyLink = isCopyLinkEnabled();\n const showShare = isShareEnabled();\n const showEmail = isEmailShareEnabled();\n const showSms = isSmsEnabled();\n const showTwitter = isTwitterDmsEnabled();\n const showInstagram = isInstagramDmsEnabled();\n const showWhatsApp = isWhatsAppEnabled();\n const showLine = isLineEnabled();\n const showLineLiff = isLineLiffEnabled();\n const showQrCode = isQrCodeEnabled();\n const showFacebookMessenger = isFacebookMessengerEnabled();\n const showTelegram = isTelegramEnabled();\n const showDiscord = isDiscordEnabled();\n\n if (\n !showCopyLink &&\n !showShare &&\n !showEmail &&\n !showSms &&\n !showTwitter &&\n !showInstagram &&\n !showWhatsApp &&\n !showLine &&\n !showLineLiff &&\n !showQrCode &&\n !showFacebookMessenger &&\n !showTelegram &&\n !showDiscord\n )\n return null;\n\n // Convert theme options to inline styles\n const themeToStyle = (theme: any): Record<string, any> => {\n if (!theme?.options || !Array.isArray(theme.options)) return {};\n\n const style: Record<string, any> = {};\n\n theme.options.forEach((option: any) => {\n if (!option.value) return;\n\n const { key, value } = option;\n\n // Map CSS custom properties to React Native style properties\n // Example: --vrtx-icon-button-background -> background\n // Example: --vrtx-icon-button-color -> color\n\n // Handle padding and margin with shorthand expansion\n if (key === '--vrtx-icon-button-padding' && value) {\n const parts = value.trim().split(/\\s+/);\n if (parts.length === 1) {\n style.paddingTop = style.paddingRight = style.paddingBottom = style.paddingLeft = value;\n } else if (parts.length === 2) {\n style.paddingTop = style.paddingBottom = parts[0];\n style.paddingRight = style.paddingLeft = parts[1];\n } else if (parts.length === 3) {\n style.paddingTop = parts[0];\n style.paddingRight = style.paddingLeft = parts[1];\n style.paddingBottom = parts[2];\n } else if (parts.length === 4) {\n style.paddingTop = parts[0];\n style.paddingRight = parts[1];\n style.paddingBottom = parts[2];\n style.paddingLeft = parts[3];\n }\n return;\n }\n\n if (key === '--vrtx-icon-button-margin' && value) {\n const parts = value.trim().split(/\\s+/);\n if (parts.length === 1) {\n style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = value;\n } else if (parts.length === 2) {\n style.marginTop = style.marginBottom = parts[0];\n style.marginRight = style.marginLeft = parts[1];\n } else if (parts.length === 3) {\n style.marginTop = parts[0];\n style.marginRight = style.marginLeft = parts[1];\n style.marginBottom = parts[2];\n } else if (parts.length === 4) {\n style.marginTop = parts[0];\n style.marginRight = parts[1];\n style.marginBottom = parts[2];\n style.marginLeft = parts[3];\n }\n return;\n }\n\n const propertyMap: Record<string, string> = {\n '--vrtx-icon-button-color': 'color',\n '--vrtx-icon-button-background': 'background',\n '--vrtx-icon-button-background-color': 'backgroundColor',\n '--vrtx-icon-button-text-align': 'textAlign',\n '--vrtx-icon-button-font-family': 'fontFamily',\n '--vrtx-icon-button-font-size': 'fontSize',\n '--vrtx-icon-button-font-weight': 'fontWeight',\n '--vrtx-icon-button-text-decoration': 'textDecoration',\n '--vrtx-icon-button-text-transform': 'textTransform',\n '--vrtx-icon-button-border': 'border',\n '--vrtx-icon-button-border-radius': 'borderRadius',\n '--vrtx-icon-button-display': 'display',\n };\n\n const styleProperty = propertyMap[key];\n if (styleProperty) {\n style[styleProperty] = value;\n }\n });\n\n return style;\n };\n\n // Extract styles from both block.style and block.theme\n const blockStyle = block?.style || {};\n const themeStyle = themeToStyle(block?.theme);\n\n // Merge styles (theme styles take precedence)\n const mergedStyle = { ...blockStyle, ...themeStyle };\n\n // Extract gradient string and fallback color\n // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'\n const rawBackground = mergedStyle.background || null;\n const isGradient = rawBackground?.includes('gradient');\n const gradientString = isGradient ? rawBackground : null;\n const fallbackColor = isGradient\n ? loaders?.parseGradientFirstColor(rawBackground)\n : rawBackground || mergedStyle.backgroundColor;\n\n // Extract icon color (use text color from merged style, fallback to #333)\n const iconColor = mergedStyle.color || '#333';\n\n // Create text style that removes background\n const textStyle = { ...mergedStyle, backgroundColor: 'transparent', background: 'transparent' };\n\n // Map textAlign to flexbox justifyContent for button content alignment\n const getJustifyContent = (align: string | undefined): 'flex-start' | 'center' | 'flex-end' => {\n switch (align) {\n case 'left':\n case 'start':\n return 'flex-start';\n case 'right':\n case 'end':\n return 'flex-end';\n default:\n return 'center';\n }\n };\n const buttonJustifyContent = getJustifyContent(mergedStyle.textAlign);\n\n // Extract label from block attributes\n const label = block?.attributes?.label;\n\n // Extract customizations from block settings\n const customizations = block?.settings?.customizations || {};\n\n // Helper function to get button text from customizations with flat key resolution\n const getButtonText = (optionKey: string, defaultLabel: string): string => {\n if (!customizations) {\n return defaultLabel;\n }\n\n // Priority order (most specific to least specific):\n\n // 1. Flat key format with host (e.g., 'mobile.copyLink') - PREFERRED for new saves\n const flatKey = `mobile.${optionKey}`;\n if (customizations[flatKey]?.textContent !== undefined) {\n const textContent = customizations[flatKey]?.textContent;\n return textContent === null || textContent === undefined ? defaultLabel : textContent;\n }\n\n // 2. Legacy format: textContent directly on customization key (e.g., 'copyLink')\n // This is for data already in production without host prefix\n const legacyCustomization = customizations[optionKey];\n if (legacyCustomization?.textContent !== undefined) {\n const textContent = legacyCustomization.textContent;\n return textContent === null || textContent === undefined ? defaultLabel : textContent;\n }\n\n // 3. Nested object format (customizations.mobile.copyLink) - old legacy format\n if (customizations.mobile) {\n const textContent = customizations.mobile?.[optionKey]?.textContent;\n if (textContent !== undefined) {\n return textContent === null ? defaultLabel : textContent;\n }\n }\n\n return defaultLabel;\n };\n\n // Map of option keys to their button configurations\n const buttonConfigs: Record<string, {\n show: boolean;\n icon: IconName;\n label: string;\n onPress: () => void;\n isLoading?: boolean;\n successLabel?: string;\n showSuccess?: boolean;\n }> = {\n copyLink: {\n show: showCopyLink,\n icon: 'link',\n label: getButtonText('copyLink', 'Copy Link'),\n onPress: handleCopyLinkWithHaptics,\n isLoading: loadingCopy,\n successLabel: '✓ Copied!',\n showSuccess: copySuccess,\n },\n nativeShareSheet: {\n show: showShare,\n icon: 'share',\n label: getButtonText('nativeShareSheet', 'Share Link'),\n onPress: handleShareWithHaptics,\n isLoading: loadingShare,\n successLabel: '✓ Shared!',\n showSuccess: shareSuccess,\n },\n email: {\n show: showEmail,\n icon: 'email',\n label: getButtonText('email', 'Share via Email'),\n onPress: handleEmailShareWithHaptics,\n },\n sms: {\n show: showSms,\n icon: 'sms',\n label: getButtonText('sms', 'Share via SMS'),\n onPress: handleSmsShareWithHaptics,\n },\n twitterDms: {\n show: showTwitter,\n icon: 'x-twitter',\n label: getButtonText('twitterDms', 'Share via X'),\n onPress: handleTwitterShareWithHaptics,\n },\n instagramDms: {\n show: showInstagram,\n icon: 'instagram',\n label: getButtonText('instagramDms', 'Share via Instagram'),\n onPress: handleInstagramShareWithHaptics,\n },\n whatsApp: {\n show: showWhatsApp,\n icon: 'whatsapp',\n label: getButtonText('whatsApp', 'Share via WhatsApp'),\n onPress: handleWhatsAppShareWithHaptics,\n },\n line: {\n show: showLine,\n icon: 'line',\n label: getButtonText('line', 'Share via LINE'),\n onPress: handleLineShareWithHaptics,\n },\n lineLiff: {\n show: showLineLiff,\n icon: 'line',\n label: getButtonText('lineLiff', 'Share via LINE (LIFF)'),\n onPress: handleLineLiffShareWithHaptics,\n },\n qrCode: {\n show: showQrCode,\n icon: 'qr-code',\n label: getButtonText('qrCode', 'Show QR Code'),\n onPress: handleQrCodeWithHaptics,\n },\n facebookMessenger: {\n show: showFacebookMessenger,\n icon: 'facebook-messenger',\n label: getButtonText('facebookMessenger', 'Share via Messenger'),\n onPress: handleFacebookMessengerShareWithHaptics,\n },\n telegram: {\n show: showTelegram,\n icon: 'telegram',\n label: getButtonText('telegram', 'Share via Telegram'),\n onPress: handleTelegramShareWithHaptics,\n },\n discord: {\n show: showDiscord,\n icon: 'discord',\n label: getButtonText('discord', 'Share via Discord'),\n onPress: handleDiscordShareWithHaptics,\n },\n };\n\n // Render a single share button\n const renderShareButton = (option: string) => {\n const config = buttonConfigs[option];\n if (!config || !config.show) return null;\n\n const displayLabel = config.showSuccess && config.successLabel ? config.successLabel : config.label;\n\n return (\n <ButtonWrapper\n key={option}\n wrapperStyle={[styles.button, styles.fullButton]}\n style={[styles.tertiaryButton, mergedStyle, fallbackColor ? { backgroundColor: fallbackColor } : undefined]}\n gradientString={gradientString}\n onPress={isEditMode ? undefined : config.onPress}\n disabled={config.isLoading || isEditMode}\n >\n {config.isLoading ? (\n <View style={styles.buttonContent}>\n <ActivityIndicator size=\"small\" color=\"#333\" />\n </View>\n ) : (\n <View style={[styles.buttonContent, { justifyContent: buttonJustifyContent }]}>\n <View style={styles.buttonIconContainer}>\n {renderIcon({ name: config.icon, size: 18, color: iconColor })}\n </View>\n <Text style={[styles.tertiaryButtonText, textStyle]}>{displayLabel}</Text>\n </View>\n )}\n </ButtonWrapper>\n );\n };\n\n // Determine the order to render buttons\n // If shareOptionsOrder is provided and non-empty, use it; otherwise fall back to default order\n const defaultOrder = ['copyLink', 'nativeShareSheet', 'email', 'sms', 'twitterDms', 'instagramDms', 'whatsApp', 'facebookMessenger', 'telegram', 'discord', 'line', 'lineLiff', 'qrCode'];\n const orderToUse = shareOptionsOrder.length > 0 ? shareOptionsOrder : defaultOrder;\n\n return (\n <View key={block.id} style={styles.contactButtonsContainer}>\n {/* Section label from block attributes */}\n {label && (\n <Text style={styles.sectionLabel}>{label}</Text>\n )}\n {orderToUse.map(renderShareButton)}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n contactButtonsContainer: {\n gap: 12,\n marginBottom: 16,\n },\n sectionLabel: {\n fontSize: 14,\n fontWeight: '500',\n color: '#666',\n marginBottom: 4,\n },\n button: {\n borderRadius: 8,\n overflow: 'hidden', // Important for gradient clipping\n },\n tertiaryButton: {\n backgroundColor: '#f5f5f5',\n paddingVertical: 12,\n paddingHorizontal: 16,\n borderRadius: 8,\n },\n fullButton: {\n width: '100%',\n },\n buttonContent: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n },\n buttonIconContainer: {\n width: 24,\n height: 18,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'visible',\n },\n tertiaryButtonText: {\n color: '#333',\n fontSize: 16,\n fontWeight: '500',\n },\n});\n","/**\n * VortexModulesContext\n *\n * Internal context for passing optional module configuration AND loader functions\n * from entry points (VortexInvite/InviteFormWeb) down to child components\n * without prop drilling.\n *\n * This is completely internal to the SDK - end users only need to pass props\n * to <VortexInvite> and everything works automatically.\n *\n * The key insight is that entry points inject the appropriate loader functions:\n * - Native entry (index.tsx/InviteFormMobile) injects loaders from moduleLoaders.ts\n * - Web entry (preview.tsx/InviteFormWeb) injects loaders from moduleLoaders.web.ts\n *\n * This way, components don't import loaders directly, avoiding Metro/webpack bundler issues.\n *\n * Example usage (internal):\n * ```tsx\n * // In a child component\n * const { modules, loaders } = useVortexModules();\n * const GradientComponent = loaders.loadGradientComponent(modules?.gradient);\n * ```\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode, ComponentType } from 'react';\n\n/**\n * Supported gradient library module names.\n * Users specify which library they have installed.\n */\nexport type GradientModuleName = 'expo-linear-gradient' | 'react-native-linear-gradient';\n\n/**\n * Supported haptics library module names.\n */\nexport type HapticsModuleName = 'expo-haptics';\n\n/**\n * Supported QR code library module names.\n */\nexport type QRCodeModuleName = 'react-native-qrcode-svg' | 'react-qr-code';\n\n/**\n * Supported clipboard library module names.\n */\nexport type ClipboardModuleName = 'expo-clipboard' | '@react-native-clipboard/clipboard';\n\n/**\n * Supported sharing library module names.\n */\nexport type SharingModuleName = 'expo-sharing';\n\n/**\n * Unified modules configuration object.\n * Users specify which optional native libraries they have installed via a single prop.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * modules={{\n * gradient: 'expo-linear-gradient',\n * haptics: 'expo-haptics',\n * qrCode: 'react-native-qrcode-svg',\n * }}\n * />\n * ```\n */\nexport interface VortexModules {\n /**\n * Gradient library for button backgrounds.\n * For Expo: 'expo-linear-gradient'\n * For bare RN: 'react-native-linear-gradient'\n */\n gradient?: GradientModuleName;\n\n /**\n * Haptics library for touch feedback.\n * Currently only 'expo-haptics' is supported.\n */\n haptics?: HapticsModuleName;\n\n /**\n * QR code library for QR code display.\n * For native: 'react-native-qrcode-svg'\n * For web: 'react-qr-code'\n */\n qrCode?: QRCodeModuleName;\n\n /**\n * Clipboard library for copy functionality.\n * For Expo: 'expo-clipboard'\n * For bare RN: '@react-native-clipboard/clipboard'\n */\n clipboard?: ClipboardModuleName;\n\n /**\n * Sharing library for native share sheet.\n * Currently only 'expo-sharing' is supported.\n */\n sharing?: SharingModuleName;\n}\n\n/**\n * Props for gradient components (compatible with both expo and react-native-linear-gradient)\n */\nexport interface GradientProps {\n colors: string[];\n locations?: number[];\n start?: { x: number; y: number };\n end?: { x: number; y: number };\n style?: any;\n children?: React.ReactNode;\n}\n\n/**\n * Parsed gradient data structure\n */\nexport interface ParsedGradient {\n type: 'linear';\n angle: number;\n colors: string[];\n locations: number[];\n}\n\n/**\n * Gradient points for LinearGradient component\n */\nexport interface GradientPoints {\n start: { x: number; y: number };\n end: { x: number; y: number };\n}\n\n/**\n * Haptic feedback style\n */\nexport type HapticStyle = 'light' | 'medium' | 'heavy';\n\n/**\n * Module loader functions interface.\n * These are injected by entry points (native vs web) to avoid direct imports\n * that would cause bundler issues.\n */\nexport interface ModuleLoaders {\n /**\n * Loads the gradient component based on the specified module name.\n */\n loadGradientComponent: (moduleName: GradientModuleName | undefined) => ComponentType<GradientProps> | null;\n\n /**\n * Parses a CSS linear-gradient string into a structured format.\n */\n parseCSSLinearGradient: (css: string) => ParsedGradient | null;\n\n /**\n * Converts a CSS gradient angle to start/end points for LinearGradient component.\n */\n angleToGradientPoints: (angle: number) => GradientPoints;\n\n /**\n * Extracts the first color from a CSS gradient string.\n */\n parseGradientFirstColor: (gradientString: string) => string | null;\n}\n\n/**\n * Internal configuration for the modules context.\n * This combines the user-facing modules config with internal loader functions.\n */\nexport interface VortexModulesConfig {\n /**\n * Unified modules configuration object.\n * Users specify which optional native libraries they have installed.\n */\n modules?: VortexModules;\n\n /**\n * Module loader functions injected by entry points.\n * This allows native and web entry points to provide different implementations.\n * @internal\n */\n loaders?: ModuleLoaders;\n}\n\n// Default stub loaders that return null (used when no loaders are provided)\nconst defaultLoaders: ModuleLoaders = {\n loadGradientComponent: () => null,\n parseCSSLinearGradient: () => null,\n angleToGradientPoints: (angle: number) => ({\n start: { x: 0, y: 0 },\n end: { x: 1, y: 1 },\n }),\n parseGradientFirstColor: () => null,\n};\n\n// Default empty config\nconst defaultConfig: VortexModulesConfig = {\n loaders: defaultLoaders,\n};\n\n// Create the context with default empty config\nconst VortexModulesContext = createContext<VortexModulesConfig>(defaultConfig);\n\n/**\n * Hook to access the module configuration from any child component.\n *\n * @returns The current module configuration including loaders\n *\n * @example\n * ```tsx\n * function MyButton() {\n * const { modules, loaders } = useVortexModules();\n * const GradientComponent = loaders?.loadGradientComponent(modules?.gradient);\n * // Use GradientComponent if available\n * }\n * ```\n */\nexport function useVortexModules(): VortexModulesConfig & { \n // Computed properties for easy access\n gradientModule?: GradientModuleName;\n hapticsModule?: HapticsModuleName;\n qrCodeModule?: QRCodeModuleName;\n clipboardModule?: ClipboardModuleName;\n sharingModule?: SharingModuleName;\n} {\n const config = useContext(VortexModulesContext);\n \n return {\n ...config,\n loaders: config.loaders || defaultLoaders,\n // Provide computed accessors for easy access to individual module names\n gradientModule: config.modules?.gradient,\n hapticsModule: config.modules?.haptics,\n qrCodeModule: config.modules?.qrCode,\n clipboardModule: config.modules?.clipboard,\n sharingModule: config.modules?.sharing,\n };\n}\n\n/**\n * Props for the VortexModulesProvider component.\n */\nexport interface VortexModulesProviderProps {\n /**\n * Module configuration to provide to children.\n */\n config: VortexModulesConfig;\n\n /**\n * Child components that will have access to the module configuration.\n */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes module configuration available to all children.\n *\n * This is used internally by VortexInvite and InviteFormWeb.\n * End users don't need to use this directly.\n *\n * @example\n * ```tsx\n * // Internal usage in VortexInvite (native)\n * import * as nativeLoaders from '../utils/moduleLoaders';\n * \n * <VortexModulesProvider config={{ \n * modules: { gradient: 'expo-linear-gradient', haptics: 'expo-haptics' },\n * loaders: nativeLoaders \n * }}>\n * <InviteFormCore {...props} />\n * </VortexModulesProvider>\n * \n * // Internal usage in InviteFormWeb (web)\n * import * as webLoaders from '../utils/moduleLoaders.web';\n * \n * <VortexModulesProvider config={{ loaders: webLoaders }}>\n * <InviteFormCore {...props} />\n * </VortexModulesProvider>\n * ```\n */\nexport function VortexModulesProvider({ config, children }: VortexModulesProviderProps) {\n // Memoize the config to prevent unnecessary re-renders\n // Using the entire config object as dependency to ensure all properties are tracked\n const memoizedConfig = useMemo(\n () => ({\n ...config,\n loaders: config.loaders || defaultLoaders,\n }),\n [config]\n );\n\n return (\n <VortexModulesContext.Provider value={memoizedConfig}>\n {children}\n </VortexModulesContext.Provider>\n );\n}\n\n// Export the context for testing purposes\nexport { VortexModulesContext };\n","import React from 'react';\nimport { View, Text, TouchableOpacity, StyleSheet, ViewStyle, Platform } from 'react-native';\nimport { IconRendererProps } from './InviteFormCore';\nimport { useVortexModules } from '../context/VortexModulesContext';\n\nconst isWeb = Platform.OS === 'web';\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nconst ButtonWrapper: React.FC<ButtonWrapperProps> = ({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}) => {\n // Get the gradient module and loaders from context\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n};\n\nexport interface VrtxContactsImportProps {\n block: any;\n renderIcon: (props: IconRendererProps) => React.ReactNode;\n isNativeContactsEnabled: () => boolean;\n isGoogleContactsEnabled: () => boolean;\n handleSelectFromContacts: () => void;\n handleSelectFromGoogle: () => void;\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n isEditMode?: boolean;\n}\n\nexport function VrtxContactsImport({\n block,\n renderIcon,\n isNativeContactsEnabled,\n isGoogleContactsEnabled,\n handleSelectFromContacts,\n handleSelectFromGoogle,\n triggerHaptic,\n isEditMode = false,\n}: VrtxContactsImportProps) {\n // Get loaders from context\n const { loaders } = useVortexModules();\n\n // Helper to get customization label - null/undefined uses default, empty string shows nothing\n const getCustomLabel = (key: string, defaultLabel: string): string => {\n const textContent = block?.settings?.customizations?.[key]?.textContent;\n // If textContent is null or undefined, use default. Empty string is valid (shows no label).\n if (textContent === null || textContent === undefined) {\n return defaultLabel;\n }\n return textContent;\n };\n\n const handleSelectFromContactsWithHaptics = async () => {\n await triggerHaptic?.('light');\n handleSelectFromContacts();\n };\n\n const handleSelectFromGoogleWithHaptics = async () => {\n await triggerHaptic?.('light');\n handleSelectFromGoogle();\n };\n\n // Convert theme options to inline styles\n const themeToStyle = (theme: any): Record<string, any> => {\n if (!theme?.options || !Array.isArray(theme.options)) return {};\n\n const style: Record<string, any> = {};\n\n theme.options.forEach((option: any) => {\n if (!option.value) return;\n\n const { key, value } = option;\n\n // Handle padding and margin with shorthand expansion\n if (key === '--vrtx-icon-button-padding' && value) {\n const parts = value.trim().split(/\\s+/);\n if (parts.length === 1) {\n style.paddingTop = style.paddingRight = style.paddingBottom = style.paddingLeft = value;\n } else if (parts.length === 2) {\n style.paddingTop = style.paddingBottom = parts[0];\n style.paddingRight = style.paddingLeft = parts[1];\n } else if (parts.length === 3) {\n style.paddingTop = parts[0];\n style.paddingRight = style.paddingLeft = parts[1];\n style.paddingBottom = parts[2];\n } else if (parts.length === 4) {\n style.paddingTop = parts[0];\n style.paddingRight = parts[1];\n style.paddingBottom = parts[2];\n style.paddingLeft = parts[3];\n }\n return;\n }\n\n if (key === '--vrtx-icon-button-margin' && value) {\n const parts = value.trim().split(/\\s+/);\n if (parts.length === 1) {\n style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = value;\n } else if (parts.length === 2) {\n style.marginTop = style.marginBottom = parts[0];\n style.marginRight = style.marginLeft = parts[1];\n } else if (parts.length === 3) {\n style.marginTop = parts[0];\n style.marginRight = style.marginLeft = parts[1];\n style.marginBottom = parts[2];\n } else if (parts.length === 4) {\n style.marginTop = parts[0];\n style.marginRight = parts[1];\n style.marginBottom = parts[2];\n style.marginLeft = parts[3];\n }\n return;\n }\n\n // Map CSS custom properties to React Native style properties\n const propertyMap: Record<string, string> = {\n '--vrtx-icon-button-color': 'color',\n '--vrtx-icon-button-background': 'background',\n '--vrtx-icon-button-background-color': 'backgroundColor',\n '--vrtx-icon-button-border-radius': 'borderRadius',\n '--vrtx-icon-button-font-size': 'fontSize',\n '--vrtx-icon-button-font-weight': 'fontWeight',\n };\n\n const styleProperty = propertyMap[key];\n if (styleProperty) {\n style[styleProperty] = value;\n }\n });\n\n return style;\n };\n\n // Extract styles from the vrtx-contacts-import block itself (this block has the theme)\n const blockStyle = block?.style || {};\n const blockThemeStyle = themeToStyle(block?.theme);\n\n // Merge styles (theme styles take precedence over block.style)\n const mergedBlockStyle = { ...blockStyle, ...blockThemeStyle };\n\n // Extract gradient string and fallback color\n // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'\n const rawBlockBackground = mergedBlockStyle.background || null;\n const isBlockGradient = rawBlockBackground?.includes('gradient');\n const blockGradientString = isBlockGradient ? rawBlockBackground : null;\n const blockFallbackColor = isBlockGradient\n ? loaders?.parseGradientFirstColor(rawBlockBackground)\n : rawBlockBackground || mergedBlockStyle.backgroundColor;\n\n const blockTextColor = mergedBlockStyle.color || '#333';\n\n // Create a clean style object without background/backgroundColor (we'll handle those separately)\n const cleanBlockStyle = { ...mergedBlockStyle };\n delete cleanBlockStyle.background;\n delete cleanBlockStyle.backgroundColor;\n\n // Extract label from block attributes\n const label = block?.attributes?.label;\n\n return (\n <View key={block.id} style={styles.contactButtonsContainer}>\n {/* Section label from block attributes */}\n {label && (\n <Text style={styles.sectionLabel}>{label}</Text>\n )}\n {isNativeContactsEnabled() && (\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n styles.tertiaryButton,\n cleanBlockStyle,\n blockFallbackColor ? { backgroundColor: blockFallbackColor } : undefined,\n ]}\n gradientString={blockGradientString}\n onPress={handleSelectFromContactsWithHaptics}\n >\n <View style={styles.buttonIconContainer}>\n {renderIcon({ name: 'import-contacts', size: 18, color: blockTextColor })}\n </View>\n <Text style={[styles.tertiaryButtonText, { color: blockTextColor }]}>\n {getCustomLabel('importContacts', 'Add from Contacts')}\n </Text>\n </ButtonWrapper>\n )}\n\n {isGoogleContactsEnabled() && (\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n styles.tertiaryButton,\n cleanBlockStyle,\n blockFallbackColor ? { backgroundColor: blockFallbackColor } : undefined,\n ]}\n gradientString={blockGradientString}\n onPress={handleSelectFromGoogleWithHaptics}\n >\n <View style={styles.buttonIconContainer}>\n {renderIcon({ name: 'google', size: 18, color: blockTextColor })}\n </View>\n <Text style={[styles.tertiaryButtonText, { color: blockTextColor }]}>\n {getCustomLabel('google', 'Add from Google Contacts')}\n </Text>\n </ButtonWrapper>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n contactButtonsContainer: {\n gap: 12,\n },\n sectionLabel: {\n fontSize: 14,\n fontWeight: '500',\n color: '#666',\n marginBottom: 4,\n },\n button: {\n paddingVertical: 12,\n paddingHorizontal: 16,\n borderRadius: 8,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n },\n tertiaryButton: {\n backgroundColor: '#f5f5f5',\n },\n fullButton: {\n width: '100%',\n },\n buttonIconContainer: {\n width: 18,\n height: 18,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'visible',\n },\n tertiaryButtonText: {\n color: '#333',\n fontSize: 16,\n fontWeight: '500',\n },\n});\n","import React from 'react';\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ActivityIndicator,\n StyleSheet,\n ViewStyle,\n Platform,\n} from 'react-native';\nimport type { ViewType } from '../hooks/useInvitationFormLogic';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\nexport interface VrtxEmailInvitationsProps {\n block: any;\n view: ViewType;\n emails: string[];\n emailInput: string;\n setEmailInput: (value: string) => void;\n handleEmailSubmit: (overrideEmail?: string) => void;\n handleRemoveEmail: (email: string) => void;\n submitButtonBlock?: any;\n handleSendInvitation?: () => Promise<void>;\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n loadingEmailInvite?: boolean;\n sendSuccess?: boolean;\n /** When set, the input briefly shows a red border to indicate invalid email */\n lastInvalidEmail?: string | null;\n EditableWrapper?: React.ComponentType<{\n children: React.ReactNode;\n componentId: string;\n componentType: string;\n node?: any;\n }>;\n // Analytics callbacks (optional)\n onEmailFieldFocus?: () => void;\n onEmailFieldBlur?: () => void;\n // Handler to navigate to email view\n handleAddByEmail?: () => void;\n renderIcon?: (props: any) => React.ReactNode;\n isEditMode?: boolean;\n}\n\n// Button wrapper component that handles gradients on web, solid color fallback on native\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nconst ButtonWrapper: React.FC<ButtonWrapperProps> = ({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}) => {\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, use first color from gradient as solid background\n const fallbackColor = gradientString ? parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n};\n\n// Chip wrapper component that handles gradients on web, solid color fallback on native\ninterface ChipWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n}\n\nconst ChipWrapper: React.FC<ChipWrapperProps> = ({ children, style, gradientString }) => {\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return <View style={[...styleArray, { background: gradientString } as any]}>{children}</View>;\n }\n\n // On native, use first color from gradient as solid background\n const fallbackColor = gradientString ? parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return <View style={finalStyle}>{children}</View>;\n};\n\nexport function VrtxEmailInvitations({\n block,\n view,\n emails,\n emailInput,\n setEmailInput,\n handleEmailSubmit,\n handleRemoveEmail,\n submitButtonBlock,\n handleSendInvitation,\n triggerHaptic,\n loadingEmailInvite = false,\n sendSuccess = false,\n lastInvalidEmail = null,\n EditableWrapper,\n onEmailFieldFocus,\n onEmailFieldBlur,\n handleAddByEmail,\n renderIcon,\n isEditMode = false,\n}: VrtxEmailInvitationsProps) {\n const inputRef = React.useRef<any>(null);\n\n // Smart email input handler: detect delimiter characters (space, comma, semicolon)\n // and automatically convert valid emails into pills — best-practice multi-email UX.\n // Also handles paste of multiple emails separated by delimiters.\n const handleChangeText = React.useCallback((text: string) => {\n // Check if pasted text contains multiple emails (e.g. \"a@b.com, c@d.com\")\n const delimiterRegex = /[,;\\s]+/;\n if (delimiterRegex.test(text) && text.trim().includes('@')) {\n const parts = text.split(delimiterRegex).filter(Boolean);\n // If multiple parts, try to pill-ify all complete ones\n if (parts.length > 1) {\n for (const part of parts) {\n handleEmailSubmit(part.trim());\n }\n setEmailInput('');\n return;\n }\n }\n\n // Check if the last character typed is a delimiter\n const lastChar = text.slice(-1);\n const delimiters = [' ', ',', ';'];\n\n if (delimiters.includes(lastChar)) {\n const candidate = text.slice(0, -1).trim();\n if (candidate) {\n handleEmailSubmit(candidate);\n triggerHaptic?.('light');\n return;\n }\n // If nothing before the delimiter, ignore it\n return;\n }\n\n setEmailInput(text);\n }, [setEmailInput, handleEmailSubmit, triggerHaptic]);\n\n // Convert any pending text to a pill on blur\n const handleBlur = React.useCallback(() => {\n if (emailInput.trim()) {\n handleEmailSubmit(emailInput.trim());\n }\n onEmailFieldBlur?.();\n }, [emailInput, handleEmailSubmit, onEmailFieldBlur]);\n // Extract styles from block.style\n const blockStyle = block?.style || {};\n\n // Merge styles\n const mergedStyle = { ...blockStyle };\n\n // Extract gradient string and fallback color\n // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'\n const rawBackground = mergedStyle.background || null;\n const isGradient = rawBackground?.includes('gradient');\n const gradientString = isGradient ? rawBackground : null;\n const fallbackColor = isGradient\n ? parseGradientFirstColor(rawBackground)\n : rawBackground || mergedStyle.backgroundColor;\n\n // Extract text color\n const textColor = mergedStyle.color || '#333';\n\n // Create text style\n const textStyle = { ...mergedStyle, color: textColor };\n\n // Extract submit button styles and content if provided\n const submitButtonStyle = submitButtonBlock?.style || {};\n const submitButtonGradientString = submitButtonStyle.background || null;\n const submitButtonFallbackColor = submitButtonGradientString\n ? parseGradientFirstColor(submitButtonGradientString)\n : submitButtonStyle.backgroundColor;\n const submitButtonTextColor = submitButtonStyle.color || '#fff';\n\n const submitButtonText =\n submitButtonBlock?.textContent || submitButtonBlock?.attributes?.label || 'Invite';\n\n const handleSendInvitationWithHaptics = async () => {\n if (handleSendInvitation) {\n await triggerHaptic?.('light');\n await handleSendInvitation();\n }\n };\n\n const handleAddByEmailWithHaptics = async () => {\n if (handleAddByEmail) {\n await triggerHaptic?.('light');\n handleAddByEmail();\n }\n };\n\n // On main view, render as a button\n if (view === 'main') {\n return (\n <View\n key={block.id}\n style={{\n position: 'relative',\n }}\n >\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n {\n borderWidth: 1,\n borderColor: '#e0e0e0',\n },\n mergedStyle,\n fallbackColor ? { backgroundColor: fallbackColor } : undefined,\n ]}\n gradientString={gradientString}\n onPress={isEditMode ? undefined : handleAddByEmailWithHaptics}\n disabled={isEditMode}\n >\n {renderIcon && (\n <View style={styles.buttonIconContainer}>\n {renderIcon({ name: 'email', size: 18, color: textColor })}\n </View>\n )}\n <Text style={[styles.buttonText, { color: textColor }]}>\n {block.settings?.customizations?.['mobile.addByEmailButton']?.textContent || block.attributes?.label || 'Add by Email'}\n </Text>\n </ButtonWrapper>\n {/* Circle button for edit mode to preview the email form */}\n {isEditMode && (\n <TouchableOpacity\n {...({\n 'data-circle-button': 'true',\n onMouseDown: async (e: React.MouseEvent) => {\n console.log('[VrtxEmailInvitations] Circle button onMouseDown - switching to email view');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (e as any)._circleButtonClick = true;\n if (e.nativeEvent) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (e.nativeEvent as any)._circleButtonClick = true;\n }\n e.stopPropagation();\n e.preventDefault();\n await triggerHaptic?.('light');\n if (handleAddByEmail) {\n console.log('[VrtxEmailInvitations] Calling handleAddByEmail');\n handleAddByEmail();\n }\n },\n onClick: (e: React.MouseEvent) => {\n console.log('[VrtxEmailInvitations] Circle button onClick - preventing default');\n e.stopPropagation();\n e.preventDefault();\n },\n onClickCapture: (e: React.MouseEvent) => {\n console.log('[VrtxEmailInvitations] Circle button onClickCapture - preventing default');\n e.stopPropagation();\n e.preventDefault();\n },\n } as any)}\n style={{\n position: 'absolute',\n right: 8,\n bottom: '8%',\n transform: [{ translateY: -12 }],\n width: 24,\n height: 24,\n borderRadius: 12,\n backgroundColor: '#606971ff',\n justifyContent: 'center',\n alignItems: 'center',\n shadowColor: '#2196F3',\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: 0.8,\n shadowRadius: 8,\n elevation: 99999,\n zIndex: 99999,\n ...(isWeb && {\n boxShadow: '0 0 12px 3px rgba(118, 122, 125, 0.6)',\n }),\n }}\n activeOpacity={0.7}\n onPress={async (e: any) => {\n console.log('[VrtxEmailInvitations] Circle button pressed - switching to email view');\n // Mark the event so EditableWrapper ignores it\n if (e) {\n e._circleButtonClick = true;\n if (e.nativeEvent) {\n e.nativeEvent._circleButtonClick = true;\n }\n }\n await triggerHaptic?.('light');\n if (handleAddByEmail) {\n handleAddByEmail();\n }\n }}\n >\n <Text style={{ color: '#fff', fontSize: 14, fontWeight: 'bold' }}></Text>\n </TouchableOpacity>\n )}\n {/* Invisible spacer to ensure outline includes the circle button */}\n {isEditMode && (\n <View\n style={{\n position: 'absolute',\n right: 0,\n top: 0,\n bottom: 0,\n width: 40,\n pointerEvents: 'none',\n }}\n />\n )}\n </View>\n );\n }\n\n // On email view, render the full form\n if (view !== 'email') {\n return null;\n }\n\n return (\n <View key={block.id}>\n {emails.length > 0 && (\n <View style={styles.emailChipsContainer}>\n {emails.map((email, index) => (\n <ChipWrapper\n key={index}\n style={[styles.emailChip, mergedStyle, fallbackColor ? { backgroundColor: fallbackColor } : undefined]}\n gradientString={gradientString}\n >\n <Text style={[styles.emailChipText, textStyle]}>{email}</Text>\n <TouchableOpacity\n onPress={() => handleRemoveEmail(email)}\n hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}\n style={{ padding: 4 }}\n >\n <Text style={[styles.emailChipRemove, { color: textColor }]}>×</Text>\n </TouchableOpacity>\n </ChipWrapper>\n ))}\n </View>\n )}\n\n <TextInput\n ref={inputRef}\n style={[styles.input, lastInvalidEmail ? styles.inputInvalid : undefined]}\n placeholder={emails.length > 0 ? (block.settings?.customizations?.['mobile.addAnotherPlaceholder']?.textContent || 'Add another email') : (block.settings?.customizations?.['mobile.placeholder']?.textContent || 'Enter email addresses')}\n placeholderTextColor=\"#999\"\n value={emailInput}\n onChangeText={handleChangeText}\n onSubmitEditing={() => {\n handleEmailSubmit();\n // Keep keyboard open for entering more emails\n inputRef.current?.focus();\n }}\n onFocus={onEmailFieldFocus}\n onBlur={handleBlur}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n autoCorrect={false}\n returnKeyType=\"done\"\n blurOnSubmit={false}\n autoFocus={true}\n />\n\n {/* Hint text below input */}\n {(() => {\n const hintText = block.settings?.customizations?.['mobile.hint']?.textContent || 'Separate emails with spaces or commas';\n return hintText ? (\n <Text style={styles.hintText}>{hintText}</Text>\n ) : null;\n })()}\n\n {/* Submit button is now rendered separately in InviteFormCore */}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n emailChipsContainer: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 8,\n marginBottom: 12,\n },\n emailChip: {\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: '#f0f0f0',\n borderRadius: 16,\n paddingHorizontal: 12,\n paddingVertical: 6,\n gap: 6,\n },\n emailChipText: {\n fontSize: 14,\n color: '#333',\n },\n emailChipRemove: {\n fontSize: 20,\n color: '#666',\n fontWeight: '300',\n },\n input: {\n borderWidth: 1,\n borderColor: '#ddd',\n borderRadius: 8,\n padding: 12,\n fontSize: 16,\n backgroundColor: '#fff',\n marginBottom: 4,\n },\n inputInvalid: {\n borderColor: '#d9534f',\n borderWidth: 1.5,\n },\n hintText: {\n fontSize: 12,\n color: '#999',\n marginBottom: 12,\n marginLeft: 4,\n },\n submitButtonContainer: {\n marginTop: 16,\n },\n successMessageContainer: {\n padding: 16,\n backgroundColor: '#e8f5e9',\n borderRadius: 8,\n alignItems: 'center',\n },\n invitedText: {\n color: '#2e7d32',\n fontSize: 16,\n fontWeight: '600',\n },\n button: {\n paddingVertical: 12,\n paddingHorizontal: 16,\n borderRadius: 8,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n backgroundColor: '#f5f5f5',\n },\n submitButton: {\n backgroundColor: '#007AFF',\n },\n fullButton: {\n width: '100%',\n },\n submitButtonText: {\n color: '#fff',\n fontSize: 16,\n fontWeight: '600',\n },\n buttonContainer: {\n marginBottom: 16,\n },\n buttonIconContainer: {\n width: 18,\n height: 18,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'visible',\n },\n buttonText: {\n color: '#333',\n fontSize: 16,\n fontWeight: '500',\n },\n});\n","import React, { useState, useCallback } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n TouchableOpacity,\n ActivityIndicator,\n Image,\n Platform,\n ViewStyle,\n} from 'react-native';\nimport { EventNames } from '@teamvortexsoftware/analytics-client';\nimport { FindFriendsConfig, FindFriendsContact } from '../types/findFriends';\nimport type { SimpleAnalyticsEvent } from '../utils/analytics';\nimport { useVortexModules } from '../context/VortexModulesContext';\nimport { emitInvitationEvent } from '../utils/invitationEvents';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback on native\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nfunction ButtonWrapper({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}: ButtonWrapperProps) {\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n}\n\n\nexport interface VrtxFindFriendsProps {\n block: any;\n /** Find Friends configuration with contacts and callbacks */\n findFriendsConfig?: FindFriendsConfig;\n /** Function to create an invitation with internal ID target type */\n createUserIdInvitation?: (userId: string, name?: string, avatarUrl?: string, metadata?: Record<string, unknown>) => Promise<void>;\n /** Trigger haptic feedback */\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n /** Callback to emit analytics events */\n onAnalyticsEvent?: (event: SimpleAnalyticsEvent) => void;\n /** Theme colors from widget configuration */\n theme?: {\n primaryBackground?: string;\n primaryForeground?: string;\n secondaryBackground?: string;\n secondaryForeground?: string;\n foreground?: string;\n border?: string;\n };\n}\n\nexport function VrtxFindFriends({\n block,\n findFriendsConfig,\n createUserIdInvitation,\n triggerHaptic,\n onAnalyticsEvent,\n theme,\n}: VrtxFindFriendsProps) {\n const [actionInProgress, setActionInProgress] = useState<string | null>(null);\n // Track contacts that have been successfully invited (to hide them from the list)\n const [invitedContactIds, setInvitedContactIds] = useState<Set<string>>(new Set());\n\n // Get title from block title attribute (configured in Styles tab)\n const title = block?.attributes?.title || '';\n\n // Extract customization from block settings (editor) or config props, with defaults\n const blockCustomizations = block?.settings?.customizations;\n const connectButtonText =\n blockCustomizations?.connectButton?.textContent ??\n findFriendsConfig?.connectButtonText ??\n 'Connect';\n const emptyStateMessage =\n blockCustomizations?.emptyStateMessage?.textContent ??\n findFriendsConfig?.emptyStateMessage ??\n 'No contacts found';\n\n // Helper to get theme option value from block.theme.options\n const getBlockThemeValue = (key: string): string | undefined => {\n const options = block?.theme?.options;\n if (!options || !Array.isArray(options)) return undefined;\n const option = options.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n // Theme colors with defaults\n const colors = {\n primaryBackground: theme?.primaryBackground ?? '#6291d5',\n primaryForeground: theme?.primaryForeground ?? '#ffffff',\n secondaryBackground: theme?.secondaryBackground ?? '#ffffff',\n secondaryForeground: theme?.secondaryForeground ?? '#353e5c',\n foreground: theme?.foreground ?? '#334153',\n border: theme?.border ?? '#cccccc',\n };\n\n // Button styles from block.theme.options (microTheme)\n const connectButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-find-friends-connect-button-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-find-friends-connect-button-color') ||\n colors.primaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-find-friends-connect-button-border-radius'),\n border: getBlockThemeValue('--vrtx-find-friends-connect-button-border'),\n padding: getBlockThemeValue('--vrtx-find-friends-connect-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-find-friends-connect-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-find-friends-connect-button-font-weight'),\n };\n\n // Avatar/initials styles from block.theme.options (microTheme)\n const avatarStyles = {\n background:\n getBlockThemeValue('--vrtx-find-friends-avatar-background') || colors.primaryBackground,\n color: getBlockThemeValue('--vrtx-find-friends-avatar-color') || colors.primaryForeground,\n };\n\n // Contact name styles from block.theme.options (microTheme)\n const contactNameStyles = {\n color: getBlockThemeValue('--vrtx-find-friends-contact-name-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-find-friends-contact-name-font-family'),\n fontSize: getBlockThemeValue('--vrtx-find-friends-contact-name-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-find-friends-contact-name-font-weight'),\n };\n\n // Contact subtitle styles from block.theme.options (microTheme)\n const contactSubtitleStyles = {\n color:\n getBlockThemeValue('--vrtx-find-friends-contact-subtitle-color') ||\n colors.secondaryForeground,\n fontFamily: getBlockThemeValue('--vrtx-find-friends-contact-subtitle-font-family'),\n fontSize: getBlockThemeValue('--vrtx-find-friends-contact-subtitle-font-size'),\n };\n\n // Title styles from block.theme.options (microTheme)\n const titleStyles = {\n color: getBlockThemeValue('--vrtx-find-friends-title-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-find-friends-title-font-family'),\n fontSize: getBlockThemeValue('--vrtx-find-friends-title-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-find-friends-title-font-weight'),\n };\n\n // Handle Connect button press\n const handleConnect = useCallback(\n async (contact: FindFriendsContact) => {\n if (!findFriendsConfig?.onConnect) return;\n\n setActionInProgress(contact.userId);\n await triggerHaptic?.('light');\n\n // Track find friends invite click (matches iOS SDK)\n onAnalyticsEvent?.({\n name: EventNames.FIND_FRIENDS_INVITE_CLICKED,\n payload: {\n contactId: contact.userId,\n contactName: contact.name,\n },\n });\n\n try {\n // Call customer's callback to determine if we should create the invitation\n const shouldCreateInvitation = await findFriendsConfig.onConnect(contact);\n\n if (shouldCreateInvitation && createUserIdInvitation) {\n // Create invitation via Vortex backend (pass full contact info like iOS SDK)\n await createUserIdInvitation(contact.userId, contact.name, contact.avatarUrl, contact.metadata);\n \n // Mark contact as invited (removes from list)\n setInvitedContactIds((prev) => new Set(prev).add(contact.userId));\n \n // Notify other components (e.g., VrtxOutgoingInvitations) to refresh\n emitInvitationEvent('invitationCreated');\n \n findFriendsConfig.onInvitationCreated?.(contact);\n }\n } catch (err) {\n console.error('[VrtxFindFriends] Connect failed:', err);\n findFriendsConfig.onInvitationError?.(\n contact,\n err instanceof Error ? err : new Error(String(err))\n );\n } finally {\n setActionInProgress(null);\n }\n },\n [findFriendsConfig, createUserIdInvitation, triggerHaptic, onAnalyticsEvent]\n );\n\n // Render avatar or initials\n const renderAvatar = (contact: FindFriendsContact) => {\n if (contact.avatarUrl) {\n return <Image source={{ uri: contact.avatarUrl }} style={styles.avatar} />;\n }\n\n // Generate initials from name\n const initials = contact.name\n .split(' ')\n .map((part) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n // Handle avatar background with gradient support\n const avatarBackground = avatarStyles.background;\n const isAvatarGradient = avatarBackground?.includes('linear-gradient');\n const avatarBgStyle: any = {};\n\n if (isWeb && avatarBackground) {\n avatarBgStyle.background = avatarBackground;\n } else if (isAvatarGradient && avatarBackground) {\n const fallbackColor = parseGradientFirstColor(avatarBackground);\n avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;\n }\n\n return (\n <View style={[styles.avatarPlaceholder, avatarBgStyle]}>\n <Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</Text>\n </View>\n );\n };\n\n // Helper to parse CSS padding string to React Native padding object\n const parsePadding = (paddingStr: string | undefined) => {\n if (!paddingStr) return {};\n const parts = paddingStr.trim().split(/\\s+/);\n if (parts.length === 1) {\n const val = parseInt(parts[0], 10);\n return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };\n }\n if (parts.length === 2) {\n const vertical = parseInt(parts[0], 10);\n const horizontal = parseInt(parts[1], 10);\n return {\n ...(isNaN(vertical) ? {} : { paddingVertical: vertical }),\n ...(isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }),\n };\n }\n return {};\n };\n\n // Helper to parse border string (e.g., \"1px solid #ccc\")\n const parseBorder = (borderStr: string | undefined) => {\n if (!borderStr) return {};\n const match = borderStr.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n return {\n borderWidth: parseInt(match[1], 10),\n borderColor: match[3],\n };\n }\n return {};\n };\n\n // Render a single contact item\n const renderContactItem = ({ item }: { item: FindFriendsContact }) => {\n const isLoading = actionInProgress === item.userId;\n\n // Build dynamic button style (without background - handled by ButtonWrapper)\n const dynamicButtonStyle: any = {\n ...(connectButtonStyles.borderRadius\n ? { borderRadius: parseInt(connectButtonStyles.borderRadius, 10) }\n : {}),\n ...parsePadding(connectButtonStyles.padding),\n ...parseBorder(connectButtonStyles.border),\n backgroundColor: colors.primaryBackground, // fallback\n };\n\n // Build dynamic text style\n const dynamicTextStyle: any = {\n color: connectButtonStyles.color,\n ...(connectButtonStyles.fontSize\n ? { fontSize: parseInt(connectButtonStyles.fontSize, 10) }\n : {}),\n ...(connectButtonStyles.fontWeight ? { fontWeight: connectButtonStyles.fontWeight } : {}),\n };\n\n // Build dynamic contact name style\n const dynamicNameStyle: any = {\n color: contactNameStyles.color,\n ...(contactNameStyles.fontFamily ? { fontFamily: contactNameStyles.fontFamily } : {}),\n ...(contactNameStyles.fontSize\n ? { fontSize: parseInt(contactNameStyles.fontSize, 10) }\n : {}),\n ...(contactNameStyles.fontWeight ? { fontWeight: contactNameStyles.fontWeight } : {}),\n };\n\n // Build dynamic contact subtitle style\n const dynamicSubtitleStyle: any = {\n color: contactSubtitleStyles.color,\n ...(contactSubtitleStyles.fontFamily\n ? { fontFamily: contactSubtitleStyles.fontFamily }\n : {}),\n ...(contactSubtitleStyles.fontSize\n ? { fontSize: parseInt(contactSubtitleStyles.fontSize, 10) }\n : {}),\n };\n\n return (\n <View style={styles.contactItem}>\n {renderAvatar(item)}\n <View style={styles.contactInfo}>\n <Text style={[styles.contactName, dynamicNameStyle]} numberOfLines={1}>\n {item.name}\n </Text>\n {item.subtitle && (\n <Text style={[styles.contactSubtitle, dynamicSubtitleStyle]} numberOfLines={1}>\n {item.subtitle}\n </Text>\n )}\n </View>\n <ButtonWrapper\n style={[styles.actionButton, dynamicButtonStyle]}\n gradientString={connectButtonStyles.background?.includes('gradient') ? connectButtonStyles.background : null}\n onPress={() => handleConnect(item)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={connectButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, dynamicTextStyle]}>{connectButtonText}</Text>\n )}\n </ButtonWrapper>\n </View>\n );\n };\n\n // Build dynamic title style\n const dynamicTitleStyle: any = {\n color: titleStyles.color,\n ...(titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {}),\n ...(titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {}),\n ...(titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}),\n };\n\n // Show placeholder if no config provided\n if (!findFriendsConfig) {\n return (\n <View style={styles.container}>\n {title ? (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n ) : null}\n <Text style={[styles.placeholderText, { color: colors.secondaryForeground }]}>\n Find Friends component - provide findFriendsConfig to enable\n </Text>\n </View>\n );\n }\n\n const allContacts = findFriendsConfig.contacts || [];\n \n // Filter out contacts that have already been invited\n const contacts = allContacts.filter((c) => !invitedContactIds.has(c.userId));\n\n // Empty state - no contacts to show (either none provided or all invited)\n if (contacts.length === 0) {\n return (\n <View style={styles.container}>\n {title ? (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n ) : null}\n <Text style={[styles.emptyText, { color: colors.secondaryForeground }]}>\n {emptyStateMessage}\n </Text>\n </View>\n );\n }\n\n // Main view: Contacts list with title\n // Note: Using View + map instead of FlatList to avoid \"VirtualizedLists should never be nested\" warning\n // when this component is rendered inside a ScrollView (which InviteFormCore uses)\n return (\n <View style={styles.listContainer}>\n {title ? (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n ) : null}\n <View style={styles.listContent}>\n {contacts.map((item) => (\n <View key={item.userId}>\n {renderContactItem({ item })}\n </View>\n ))}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 120,\n },\n listContainer: {\n flex: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: '600',\n marginBottom: 16,\n },\n placeholderText: {\n fontSize: 14,\n textAlign: 'center',\n },\n emptyText: {\n fontSize: 14,\n textAlign: 'center',\n },\n listContent: {\n paddingBottom: 16,\n },\n contactItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n avatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n avatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n },\n contactInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n contactName: {\n fontSize: 16,\n fontWeight: '500',\n },\n contactSubtitle: {\n fontSize: 13,\n marginTop: 2,\n },\n actionButton: {\n paddingHorizontal: 16,\n paddingVertical: 8,\n borderRadius: 8,\n minWidth: 80,\n alignItems: 'center',\n justifyContent: 'center',\n },\n actionButtonText: {\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","import type { EventName } from './eventNames';\n\nexport interface AnalyticsEvent {\n name: EventName;\n widgetConfigurationId: string;\n deploymentId: string;\n environmentId?: string; // Optional - backend can derive from JWT\n platform: string;\n segmentation?: Record<string, any>;\n payload?: Record<string, any>;\n groups?: Array<{\n type: string;\n id?: string;\n groupId?: string;\n name: string;\n }>;\n}\n\nexport interface IAnalyticsClient {\n track(event: AnalyticsEvent): Promise<void>;\n}\n\nexport class AnalyticsClient implements IAnalyticsClient {\n constructor(\n private endpoint: string,\n private jwt: string,\n private sessionId: string,\n private clientName?: string,\n private clientVersion?: string\n ) {}\n\n async track(event: AnalyticsEvent): Promise<void> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.jwt}`,\n 'x-session-id': this.sessionId,\n };\n\n // Add client library identification headers\n if (this.clientName) {\n headers['x-vortex-client-name'] = this.clientName;\n }\n if (this.clientVersion) {\n headers['x-vortex-client-version'] = this.clientVersion;\n }\n\n await fetch(`${this.endpoint}/api/v1/events`, {\n method: 'POST',\n headers,\n body: JSON.stringify(event),\n });\n }\n}\n\nexport class AnalyticsClientNoop implements IAnalyticsClient {\n constructor(\n private endpoint: string,\n private jwt: string,\n private sessionId: string,\n private clientName?: string,\n private clientVersion?: string\n ) {\n console.log('AnalyticsClientNoop initialized', { endpoint, hasJwt: !!jwt, sessionId, clientName, clientVersion });\n }\n\n async track(event: AnalyticsEvent): Promise<void> {\n console.log('AnalyticsClientNoop:AnalyticsEvent:', event);\n }\n}\n","/**\n * Centralized analytics event names for Vortex.\n * All event tracking should use these constants to ensure consistency.\n */\nexport const EventNames = {\n // Invite form events\n INVITE_FORM_RENDER_SUCCEEDED: 'invite_formRender_succeeded',\n INVITE_FORM_RENDER_FAILED: 'invite_formRender_failed',\n\n // Email field events\n EMAIL_FIELD_FOCUSSED: 'email_field_focussed',\n EMAIL_FIELD_BLURRED: 'email_field_blurred',\n EMAIL_SUBMISSION_VALIDATED: 'email_submission_validated',\n EMAIL_FIELD_SUBMISSION_SUCCEEDED: 'email_fieldSubmission_succeeded',\n EMAIL_FIELD_SUBMISSION_FAILED: 'email_fieldSubmission_failed',\n\n // Sharing events\n SHARING_DESTINATION_BUTTON_CLICKED: 'sharingDestination_button_clicked',\n\n // Invitation lifecycle events (backend)\n INVITATION_EMAIL_SEND_SUCCEEDED: 'invitation_emailSend_succeeded',\n INVITATION_EMAIL_SEND_FAILED: 'invitation_emailSend_failed',\n INVITATION_LINK_CLICKED: 'invitation_link_clicked',\n INVITATION_ACCEPTED: 'invitation_accepted',\n INVITATION_LINK_UNFURLED: 'invitation_link_unfurled',\n\n // Reminder/Nudge events (backend)\n REMINDER_EMAIL_SEND_SUCCEEDED: 'reminder_emailSend_succeeded',\n NUDGE_EMAIL_SEND_SUCCEEDED: 'nudge_emailSend_succeeded',\n\n // Email tracking events (backend)\n EMAIL_OPENED: 'email_opened',\n EMAIL_DELIVERED: 'email_delivered',\n ACCEPTANCE_EMAIL_SEND_SUCCEEDED: 'acceptance_emailSend_succeeded',\n ACCEPTANCE_EMAIL_SEND_FAILED: 'acceptance_emailSend_failed',\n EMAIL_BOUNCED: 'email_bounced',\n EMAIL_REPORTED: 'email_reported',\n\n // Events requested by Mixerbox [DEV-1147]\n INBOUND_INVITATION_ACCEPT_CLICKED: 'inboundInvitationAccept_button_clicked',\n INBOUND_INVITATION_DELETE_CLICKED: 'inboundInvitationDelete_button_clicked',\n OUTBOUND_INVITATION_DELETE_CLICKED: 'outboundInvitationDelete_button_clicked',\n PYMK_INVITE_CLICKED: 'pymkInvite_button_clicked',\n PYMK_DELETE_CLICKED: 'pymkDelete_button_clicked',\n FIND_FRIENDS_INVITE_CLICKED: 'findFriendsInvite_button_clicked',\n\n // PYMK invitation lifecycle events\n PYMK_INVITATION_INITIATED: 'pymk_invitation_initiated',\n PYMK_INVITATION_SUCCEEDED: 'pymk_invitation_succeeded',\n PYMK_INVITATION_FAILED: 'pymk_invitation_failed',\n\n // Autojoin events\n AUTOJOIN_ENABLED: 'autojoin_enabled',\n AUTOJOIN_CONFIGURED: 'autojoin_configured',\n AUTOJOIN_DISABLED: 'autojoin_disabled',\n\n // Deferred deep linking events\n INVITATION_FINGERPRINT_MATCHED: 'invitation_fingerprint_matched',\n\n // Widget lifecycle events (client-side)\n WIDGET_CONFIGURATION_LOADED: 'widget_configuration_loaded',\n\n // API events\n GET_INVITATION: 'get_invitation',\n API_CALL: 'api_call',\n} as const;\n\nexport type EventName = (typeof EventNames)[keyof typeof EventNames];\n","/**\n * Simple event emitter for invitation-related events.\n * Used to notify components (like VrtxOutgoingInvitations) when invitations are created\n * so they can refresh their data.\n */\n\ntype InvitationEventType = 'invitationCreated' | 'invitationRevoked' | 'invitationAccepted' | 'invitationDeleted';\n\ntype InvitationEventListener = () => void;\n\nconst listeners: Map<InvitationEventType, Set<InvitationEventListener>> = new Map();\n\n/**\n * Subscribe to an invitation event.\n * @param event The event type to listen for\n * @param listener The callback to invoke when the event is emitted\n * @returns A function to unsubscribe\n */\nexport function subscribeToInvitationEvent(\n event: InvitationEventType,\n listener: InvitationEventListener\n): () => void {\n if (!listeners.has(event)) {\n listeners.set(event, new Set());\n }\n listeners.get(event)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n listeners.get(event)?.delete(listener);\n };\n}\n\n/**\n * Emit an invitation event to notify all subscribers.\n * @param event The event type to emit\n */\nexport function emitInvitationEvent(event: InvitationEventType): void {\n const eventListeners = listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach((listener) => {\n try {\n listener();\n } catch (err) {\n console.warn(`[InvitationEvents] Error in listener for ${event}:`, err);\n }\n });\n }\n}\n","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n TouchableOpacity,\n ActivityIndicator,\n Image,\n Platform,\n Alert,\n Animated,\n ViewStyle,\n} from 'react-native';\nimport { IncomingInvitationsConfig, IncomingInvitationItem } from '../types/invitations';\nimport type { IncomingInvitation } from '../VortexClient';\nimport { EventNames } from '@teamvortexsoftware/analytics-client';\nimport type { SimpleAnalyticsEvent } from '../utils/analytics';\nimport { VortexClient } from '../VortexClient';\nimport { useVortexModules } from '../context/VortexModulesContext';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback on native\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nfunction ButtonWrapper({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}: ButtonWrapperProps) {\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n}\n\nexport interface VrtxIncomingInvitationsProps {\n block: any;\n /** Incoming Invitations configuration with callbacks */\n incomingInvitationsConfig?: IncomingInvitationsConfig;\n /** API URL for making invitation API calls (required for automatic API integration) */\n apiUrl?: string;\n /** JWT token for authentication (required for automatic API integration) */\n jwt?: string;\n /** Trigger haptic feedback */\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n /** Theme colors from widget configuration */\n theme?: {\n primaryBackground?: string;\n primaryForeground?: string;\n secondaryBackground?: string;\n secondaryForeground?: string;\n foreground?: string;\n border?: string;\n };\n /** Callback to emit analytics events */\n onAnalyticsEvent?: (event: SimpleAnalyticsEvent) => void;\n}\n\n// Animated item wrapper for fade-out effect\nfunction AnimatedInvitationItem({\n item,\n renderContent,\n onRemove,\n}: {\n item: IncomingInvitationItem;\n renderContent: (item: IncomingInvitationItem) => React.ReactNode;\n onRemove: (id: string) => void;\n}) {\n const fadeAnim = useRef(new Animated.Value(1)).current;\n const heightAnim = useRef(new Animated.Value(1)).current;\n\n const animateOut = useCallback(() => {\n Animated.parallel([\n Animated.timing(fadeAnim, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.timing(heightAnim, {\n toValue: 0,\n duration: 200,\n useNativeDriver: true,\n }),\n ]).start(() => {\n onRemove(item.id);\n });\n }, [fadeAnim, heightAnim, item.id, onRemove]);\n\n return (\n <Animated.View\n style={{\n opacity: fadeAnim,\n transform: [{ scaleY: heightAnim }],\n }}\n >\n {renderContent({ ...item, metadata: { ...item.metadata, animateOut } })}\n </Animated.View>\n );\n}\n\nexport function VrtxIncomingInvitations({\n block,\n incomingInvitationsConfig,\n apiUrl,\n jwt,\n triggerHaptic,\n theme,\n onAnalyticsEvent,\n}: VrtxIncomingInvitationsProps) {\n // Local state for managing the displayed invitations (for animate-out)\n const [displayedInvitations, setDisplayedInvitations] = useState<IncomingInvitationItem[]>(\n incomingInvitationsConfig?.invitations || []\n );\n const [actionInProgress, setActionInProgress] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n // Fetch invitations from API in the background.\n // Note: This component may remount multiple times due to parent re-renders\n // (EditableWrapper is defined inside InviteFormCore's render body).\n // To avoid flashing a loading spinner on each remount, we show config\n // invitations immediately and only show loading if there are none.\n useEffect(() => {\n if (!apiUrl || !jwt) return;\n\n let cancelled = false;\n const hasConfigInvitations = (incomingInvitationsConfig?.invitations?.length ?? 0) > 0;\n\n // Only show loading spinner if we have NO config invitations to display\n if (!hasConfigInvitations) {\n setIsLoading(true);\n }\n\n const loadInvitations = async () => {\n try {\n const client = new VortexClient({ jwt, baseURL: apiUrl });\n const apiInvitations = await client.getIncomingInvitations();\n\n // Filter out already accepted invitations (client-side filter)\n const pendingInvitations = apiInvitations.filter((inv: IncomingInvitation) => {\n const status = inv.status?.toLowerCase() ?? '';\n return status !== 'accepted' && status !== 'accepted_elsewhere';\n });\n\n // Map API invitations to InvitationItem format\n const mappedInvitations: IncomingInvitationItem[] = pendingInvitations.map((inv: IncomingInvitation) => ({\n id: inv.id,\n name: inv.creatorName || inv.senderIdentifier || 'Unknown',\n userId: inv.foreignCreatorId || undefined,\n avatarUrl: inv.creatorAvatarUrl || inv.avatarUrl,\n isVortexInvitation: true,\n metadata: inv.metadata || undefined,\n }));\n\n if (!cancelled) {\n // Merge config invitations with API invitations, deduplicating by userId.\n const configInvitations = incomingInvitationsConfig?.invitations || [];\n const apiUserIds = new Set(\n mappedInvitations\n .filter((inv) => inv.userId)\n .map((inv) => inv.userId)\n );\n const dedupedConfig = configInvitations.filter(\n (inv) => !inv.userId || !apiUserIds.has(inv.userId)\n );\n setDisplayedInvitations([...dedupedConfig, ...mappedInvitations]);\n }\n } catch (error) {\n // Silently fail - just show config invitations\n if (__DEV__) {\n console.warn('[VrtxIncomingInvitations] Failed to fetch incoming invitations:', error);\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n };\n\n loadInvitations();\n return () => { cancelled = true; };\n }, [apiUrl, jwt, incomingInvitationsConfig?.invitations]);\n\n // Extract customization from block settings or config props, with defaults\n const blockCustomizations = block?.settings?.customizations;\n const acceptButtonText =\n blockCustomizations?.acceptButton?.textContent ??\n incomingInvitationsConfig?.acceptButtonText ??\n 'Accept';\n const deleteButtonText =\n blockCustomizations?.deleteButton?.textContent ??\n incomingInvitationsConfig?.deleteButtonText ??\n 'Delete';\n const emptyStateMessage =\n blockCustomizations?.emptyStateMessage?.textContent ??\n incomingInvitationsConfig?.emptyStateMessage ??\n 'No incoming invitations';\n\n // Confirmation dialog texts\n const acceptConfirmTitle = incomingInvitationsConfig?.acceptConfirmTitle ?? 'Accept Invitation';\n const acceptConfirmMessage =\n incomingInvitationsConfig?.acceptConfirmMessage ?? 'Accept invitation from {name}?';\n const deleteConfirmTitle = incomingInvitationsConfig?.deleteConfirmTitle ?? 'Delete Invitation';\n const deleteConfirmMessage =\n incomingInvitationsConfig?.deleteConfirmMessage ?? 'Delete invitation from {name}?';\n const confirmButtonText = incomingInvitationsConfig?.confirmButtonText ?? 'Confirm';\n const cancelButtonText = incomingInvitationsConfig?.cancelButtonText ?? 'Cancel';\n\n // Helper to get theme option value from block.theme.options\n const getBlockThemeValue = (key: string): string | undefined => {\n const options = block?.theme?.options;\n if (!options || !Array.isArray(options)) return undefined;\n const option = options.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n // Theme colors with defaults\n const colors = {\n primaryBackground: theme?.primaryBackground ?? '#6291d5',\n primaryForeground: theme?.primaryForeground ?? '#ffffff',\n secondaryBackground: theme?.secondaryBackground ?? '#ffffff',\n secondaryForeground: theme?.secondaryForeground ?? '#353e5c',\n foreground: theme?.foreground ?? '#334153',\n border: theme?.border ?? '#cccccc',\n };\n\n // Button styles from block.theme.options (microTheme)\n const acceptButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-incoming-invitations-accept-button-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-incoming-invitations-accept-button-color') ||\n colors.primaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-border-radius'),\n border: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-border'),\n padding: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-font-weight'),\n };\n\n const deleteButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-incoming-invitations-delete-button-background') ||\n colors.secondaryBackground,\n color:\n getBlockThemeValue('--vrtx-incoming-invitations-delete-button-color') ||\n colors.secondaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-border-radius'),\n border: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-border'),\n padding: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-font-weight'),\n };\n\n // Avatar/initials styles from block.theme.options (microTheme)\n const avatarStyles = {\n background:\n getBlockThemeValue('--vrtx-incoming-invitations-avatar-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-incoming-invitations-avatar-color') || colors.primaryForeground,\n };\n\n // Contact name styles from block.theme.options (microTheme)\n const nameStyles = {\n color: getBlockThemeValue('--vrtx-incoming-invitations-name-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-incoming-invitations-name-font-family'),\n fontSize: getBlockThemeValue('--vrtx-incoming-invitations-name-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-name-font-weight'),\n };\n\n // Subtitle styles from block.theme.options (microTheme)\n const subtitleStyles = {\n color:\n getBlockThemeValue('--vrtx-incoming-invitations-subtitle-color') ||\n colors.secondaryForeground,\n fontFamily: getBlockThemeValue('--vrtx-incoming-invitations-subtitle-font-family'),\n fontSize: getBlockThemeValue('--vrtx-incoming-invitations-subtitle-font-size'),\n };\n\n // Title styles from block.theme.options (microTheme)\n const titleStyles = {\n color: getBlockThemeValue('--vrtx-incoming-invitations-title-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-incoming-invitations-title-font-family'),\n fontSize: getBlockThemeValue('--vrtx-incoming-invitations-title-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-title-font-weight'),\n };\n\n // Remove invitation from displayed list (after animation)\n const handleRemoveFromDisplay = useCallback((id: string) => {\n setDisplayedInvitations((prev) => prev.filter((inv) => inv.id !== id));\n }, []);\n\n // Show confirmation dialog\n const showConfirmation = useCallback(\n (\n title: string,\n message: string,\n onConfirm: () => void\n ) => {\n if (isWeb) {\n // Web: use window.confirm\n const confirmed = window.confirm(message);\n if (confirmed) {\n onConfirm();\n }\n } else {\n // Native: use Alert\n Alert.alert(title, message, [\n {\n text: cancelButtonText,\n style: 'cancel',\n },\n {\n text: confirmButtonText,\n onPress: onConfirm,\n },\n ]);\n }\n },\n [confirmButtonText, cancelButtonText]\n );\n\n // Handle Accept button press\n const handleAccept = useCallback(\n async (invitation: IncomingInvitationItem, animateOut?: () => void) => {\n const message = acceptConfirmMessage.replace('{name}', invitation.name);\n\n showConfirmation(acceptConfirmTitle, message, async () => {\n setActionInProgress(invitation.id);\n await triggerHaptic?.('light');\n\n // Emit analytics event for accept button click\n onAnalyticsEvent?.({\n name: EventNames.INBOUND_INVITATION_ACCEPT_CLICKED,\n payload: { invitationId: invitation.id, inviterName: invitation.name },\n });\n\n try {\n // Call the callback if provided and check return value\n let shouldProceed = true;\n if (incomingInvitationsConfig?.onAccept) {\n const result = await incomingInvitationsConfig.onAccept(invitation);\n // If callback returns false explicitly, don't proceed\n if (result === false) {\n shouldProceed = false;\n }\n }\n\n if (!shouldProceed) {\n setActionInProgress(null);\n return;\n }\n\n // Only call Vortex API for Vortex invitations\n if (invitation.isVortexInvitation && apiUrl && jwt) {\n const client = new VortexClient({ jwt, baseURL: apiUrl });\n const result = await client.acceptIncomingInvitation(invitation.id);\n if (!result.success) {\n console.error('[VrtxIncomingInvitations] API accept failed:', result.message);\n throw new Error(result.message || 'Failed to accept invitation');\n }\n }\n\n // Animate out after successful action\n if (animateOut) {\n animateOut();\n } else {\n handleRemoveFromDisplay(invitation.id);\n }\n } catch (err) {\n console.error('[VrtxIncomingInvitations] Accept failed:', err);\n } finally {\n setActionInProgress(null);\n }\n });\n },\n [\n incomingInvitationsConfig,\n apiUrl,\n jwt,\n triggerHaptic,\n acceptConfirmTitle,\n acceptConfirmMessage,\n showConfirmation,\n handleRemoveFromDisplay,\n onAnalyticsEvent,\n ]\n );\n\n // Handle Delete button press\n const handleDelete = useCallback(\n async (invitation: IncomingInvitationItem, animateOut?: () => void) => {\n const message = deleteConfirmMessage.replace('{name}', invitation.name);\n\n showConfirmation(deleteConfirmTitle, message, async () => {\n setActionInProgress(invitation.id);\n await triggerHaptic?.('light');\n\n // Emit analytics event for delete button click\n onAnalyticsEvent?.({\n name: EventNames.INBOUND_INVITATION_DELETE_CLICKED,\n payload: { invitationId: invitation.id, inviterName: invitation.name },\n });\n\n try {\n // Call the callback if provided and check return value\n let shouldProceed = true;\n if (incomingInvitationsConfig?.onDelete) {\n const result = await incomingInvitationsConfig.onDelete(invitation);\n // If callback returns false explicitly, don't proceed\n if (result === false) {\n shouldProceed = false;\n }\n }\n\n if (!shouldProceed) {\n setActionInProgress(null);\n return;\n }\n\n // Only call Vortex API for Vortex invitations\n if (invitation.isVortexInvitation && apiUrl && jwt) {\n const client = new VortexClient({ jwt, baseURL: apiUrl });\n const result = await client.deleteIncomingInvitation(invitation.id);\n if (!result.success) {\n console.error('[VrtxIncomingInvitations] API delete failed:', result.message);\n throw new Error(result.message || 'Failed to delete invitation');\n }\n }\n\n // Animate out after successful action\n if (animateOut) {\n animateOut();\n } else {\n handleRemoveFromDisplay(invitation.id);\n }\n } catch (err) {\n console.error('[VrtxIncomingInvitations] Delete failed:', err);\n } finally {\n setActionInProgress(null);\n }\n });\n },\n [\n incomingInvitationsConfig,\n apiUrl,\n jwt,\n triggerHaptic,\n deleteConfirmTitle,\n deleteConfirmMessage,\n showConfirmation,\n handleRemoveFromDisplay,\n onAnalyticsEvent,\n ]\n );\n\n // Helper to parse CSS padding string to React Native padding object\n const parsePadding = (paddingStr: string | undefined) => {\n if (!paddingStr) return {};\n const parts = paddingStr.trim().split(/\\s+/);\n if (parts.length === 1) {\n const val = parseInt(parts[0], 10);\n return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };\n }\n if (parts.length === 2) {\n const vertical = parseInt(parts[0], 10);\n const horizontal = parseInt(parts[1], 10);\n return {\n ...(isNaN(vertical) ? {} : { paddingVertical: vertical }),\n ...(isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }),\n };\n }\n return {};\n };\n\n // Helper to parse border string (e.g., \"1px solid #ccc\")\n const parseBorder = (borderStr: string | undefined) => {\n if (!borderStr) return {};\n const match = borderStr.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n return {\n borderWidth: parseInt(match[1], 10),\n borderColor: match[3],\n };\n }\n return {};\n };\n\n // Render avatar or initials\n const renderAvatar = (invitation: IncomingInvitationItem) => {\n if (invitation.avatarUrl) {\n return <Image source={{ uri: invitation.avatarUrl }} style={styles.avatar} />;\n }\n\n // Generate initials from name\n const initials = invitation.name\n .split(' ')\n .map((part: string) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n // Handle avatar background with gradient support\n const avatarBackground = avatarStyles.background;\n const isAvatarGradient = avatarBackground?.includes('linear-gradient');\n const avatarBgStyle: any = {};\n\n if (isWeb && avatarBackground) {\n avatarBgStyle.background = avatarBackground;\n } else if (isAvatarGradient && avatarBackground) {\n const fallbackColor = parseGradientFirstColor(avatarBackground);\n avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;\n }\n\n return (\n <View style={[styles.avatarPlaceholder, avatarBgStyle]}>\n <Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</Text>\n </View>\n );\n };\n\n // Build button style with gradient support\n const buildButtonStyle = (buttonStyles: any, fallbackBg: string) => {\n const backgroundValue = buttonStyles.background;\n const isGradient = backgroundValue?.includes('linear-gradient');\n\n const dynamicButtonStyle: any = {\n ...(buttonStyles.borderRadius\n ? { borderRadius: parseInt(buttonStyles.borderRadius, 10) }\n : {}),\n ...parsePadding(buttonStyles.padding),\n ...parseBorder(buttonStyles.border),\n };\n\n if (isWeb && backgroundValue) {\n dynamicButtonStyle.background = backgroundValue;\n } else if (isGradient && backgroundValue) {\n const fallbackColor = parseGradientFirstColor(backgroundValue);\n dynamicButtonStyle.backgroundColor = fallbackColor || fallbackBg;\n } else {\n dynamicButtonStyle.backgroundColor = backgroundValue || fallbackBg;\n }\n\n return dynamicButtonStyle;\n };\n\n // Render a single invitation item\n const renderInvitationContent = (item: IncomingInvitationItem) => {\n const isLoading = actionInProgress === item.id;\n const animateOut = item.metadata?.animateOut as (() => void) | undefined;\n\n // Build dynamic button styles\n const deleteButtonDynamicStyle = buildButtonStyle(deleteButtonStyles, colors.secondaryBackground);\n const acceptButtonDynamicStyle = buildButtonStyle(acceptButtonStyles, colors.primaryBackground);\n\n // Build dynamic text styles\n const deleteTextStyle: any = {\n color: deleteButtonStyles.color,\n ...(deleteButtonStyles.fontSize ? { fontSize: parseInt(deleteButtonStyles.fontSize, 10) } : {}),\n ...(deleteButtonStyles.fontWeight ? { fontWeight: deleteButtonStyles.fontWeight } : {}),\n };\n\n const acceptTextStyle: any = {\n color: acceptButtonStyles.color,\n ...(acceptButtonStyles.fontSize ? { fontSize: parseInt(acceptButtonStyles.fontSize, 10) } : {}),\n ...(acceptButtonStyles.fontWeight ? { fontWeight: acceptButtonStyles.fontWeight } : {}),\n };\n\n // Build dynamic name style\n const dynamicNameStyle: any = {\n color: nameStyles.color,\n ...(nameStyles.fontFamily ? { fontFamily: nameStyles.fontFamily } : {}),\n ...(nameStyles.fontSize ? { fontSize: parseInt(nameStyles.fontSize, 10) } : {}),\n ...(nameStyles.fontWeight ? { fontWeight: nameStyles.fontWeight } : {}),\n };\n\n // Build dynamic subtitle style\n const dynamicSubtitleStyle: any = {\n color: subtitleStyles.color,\n ...(subtitleStyles.fontFamily ? { fontFamily: subtitleStyles.fontFamily } : {}),\n ...(subtitleStyles.fontSize ? { fontSize: parseInt(subtitleStyles.fontSize, 10) } : {}),\n };\n\n return (\n <View style={styles.invitationItem}>\n {renderAvatar(item)}\n <View style={styles.invitationInfo}>\n <Text style={[styles.invitationName, dynamicNameStyle]} numberOfLines={1}>\n {item.name}\n </Text>\n {(() => {\n const displaySubtitle = incomingInvitationsConfig?.getSubtitle?.(item);\n return displaySubtitle ? (\n <Text style={[styles.invitationSubtitle, dynamicSubtitleStyle]} numberOfLines={1}>\n {displaySubtitle}\n </Text>\n ) : null;\n })()}\n </View>\n <View style={styles.buttonContainer}>\n {/* Delete button (left) */}\n <ButtonWrapper\n style={[styles.actionButton, deleteButtonDynamicStyle, styles.deleteButton]}\n gradientString={deleteButtonStyles.background?.includes('gradient') ? deleteButtonStyles.background : null}\n onPress={() => handleDelete(item, animateOut)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={deleteButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, deleteTextStyle]}>{deleteButtonText}</Text>\n )}\n </ButtonWrapper>\n {/* Accept button (right) */}\n <ButtonWrapper\n style={[styles.actionButton, acceptButtonDynamicStyle]}\n gradientString={acceptButtonStyles.background?.includes('gradient') ? acceptButtonStyles.background : null}\n onPress={() => handleAccept(item, animateOut)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={acceptButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, acceptTextStyle]}>{acceptButtonText}</Text>\n )}\n </ButtonWrapper>\n </View>\n </View>\n );\n };\n\n // Render item with animation wrapper\n const renderItem = ({ item }: { item: IncomingInvitationItem }) => {\n return (\n <AnimatedInvitationItem\n item={item}\n renderContent={renderInvitationContent}\n onRemove={handleRemoveFromDisplay}\n />\n );\n };\n\n // Show placeholder if no config provided and no API credentials\n if (!incomingInvitationsConfig && !(apiUrl && jwt)) {\n const label = block?.attributes?.label || '';\n return (\n <View style={styles.container}>\n {label ? <Text style={[styles.label, { color: colors.foreground }]}>{label}</Text> : null}\n <Text style={[styles.placeholderText, { color: colors.secondaryForeground }]}>\n Incoming Invitations component - provide incomingInvitationsConfig or apiUrl+jwt to enable\n </Text>\n </View>\n );\n }\n\n // Loading state — only shown when there are no config invitations to display\n if (isLoading) {\n return (\n <View style={styles.container}>\n <ActivityIndicator size=\"large\" color={colors.primaryBackground} />\n </View>\n );\n }\n\n // Empty state - render nothing (0 height) when no invitations, like iOS\n if (displayedInvitations.length === 0) {\n return null;\n }\n\n // Get title from block attributes (configured in editor as \"Title\")\n const title = block?.attributes?.title;\n\n // Build dynamic title style\n const dynamicTitleStyle: any = {\n color: titleStyles.color,\n ...(titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {}),\n ...(titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {}),\n ...(titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}),\n };\n\n // Main view: Invitations list\n // Note: Using View + map instead of FlatList to avoid \"VirtualizedLists should never be nested\" warning\n // when this component is rendered inside a ScrollView (which InviteFormCore uses)\n return (\n <View style={styles.listContainer}>\n {title && (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n )}\n <View style={styles.listContent}>\n {displayedInvitations.map((item) => (\n <View key={item.id}>\n {renderItem({ item })}\n </View>\n ))}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 120,\n },\n listContainer: {\n flex: 1,\n },\n title: {\n fontSize: 16,\n fontWeight: '600',\n marginBottom: 12,\n },\n label: {\n fontSize: 16,\n fontWeight: '500',\n marginBottom: 12,\n },\n placeholderText: {\n fontSize: 14,\n textAlign: 'center',\n },\n emptyText: {\n fontSize: 14,\n textAlign: 'center',\n },\n listContent: {\n paddingBottom: 16,\n },\n invitationItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n avatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n avatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n },\n invitationInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n invitationName: {\n fontSize: 16,\n fontWeight: '500',\n },\n invitationSubtitle: {\n fontSize: 13,\n marginTop: 2,\n },\n buttonContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n actionButton: {\n paddingHorizontal: 12,\n paddingVertical: 8,\n borderRadius: 8,\n minWidth: 70,\n alignItems: 'center',\n justifyContent: 'center',\n },\n deleteButton: {\n marginRight: 8,\n },\n actionButtonText: {\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","/**\n * VortexClient provides API methods for invitation management.\n * \n * @example\n * ```tsx\n * import { VortexClient } from '@teamvortexsoftware/vortex-react-native';\n * \n * const client = new VortexClient({\n * jwt: 'your-jwt-token',\n * baseURL: 'https://client-api.vortexsoftware.com', // optional\n * });\n * \n * // Revoke an outgoing invitation\n * await client.revokeInvitation('invitation-id');\n * \n * // Accept an incoming invitation\n * await client.acceptIncomingInvitation('invitation-id');\n * \n * // Delete an incoming invitation\n * await client.deleteIncomingInvitation('invitation-id');\n * ```\n */\n\nconst DEFAULT_BASE_URL = 'https://client-api.vortexsoftware.com';\n\nexport interface VortexClientOptions {\n /** JWT token for authentication */\n jwt: string;\n /** Optional base URL override (defaults to production) */\n baseURL?: string;\n}\n\nexport interface InvitationResponse {\n success: boolean;\n message?: string;\n data?: any;\n}\n\n/** Target of an invitation (e.g., email or SMS recipient) */\nexport interface InvitationTarget {\n targetType: string;\n targetValue: string;\n targetName?: string;\n targetAvatarUrl?: string;\n}\n\n/** Individual incoming invitation from the API */\nexport interface IncomingInvitation {\n id: string;\n targets?: InvitationTarget[];\n senderIdentifier?: string;\n senderIdentifierType?: string;\n avatarUrl?: string;\n status?: string;\n createdAt?: string;\n source?: string;\n deliveryType?: string;\n /** Name of the user who created this invitation */\n creatorName?: string | null;\n /** Avatar URL of the user who created this invitation */\n creatorAvatarUrl?: string | null;\n /** Internal ID of the user who created this invitation */\n foreignCreatorId?: string | null;\n /** Optional metadata attached to the invitation */\n metadata?: Record<string, unknown>;\n}\n\n/** Response from GET /api/v1/invitations endpoint */\nexport interface IncomingInvitationsResponse {\n data: {\n invitations: IncomingInvitation[];\n nextCursor?: string;\n hasMore?: boolean;\n count?: number;\n };\n}\n\nexport class VortexClient {\n private jwt: string;\n private baseURL: string;\n\n constructor(options: VortexClientOptions) {\n this.jwt = options.jwt;\n this.baseURL = options.baseURL || DEFAULT_BASE_URL;\n }\n\n /**\n * Updates the JWT token used for authentication.\n */\n setJwt(jwt: string): void {\n this.jwt = jwt;\n }\n\n /**\n * Revokes an outgoing invitation that the user has sent.\n * \n * @param invitationId - The ID of the invitation to revoke\n * @returns Promise resolving to the response\n */\n async revokeInvitation(invitationId: string): Promise<InvitationResponse> {\n try {\n const response = await fetch(`${this.baseURL}/api/v1/invitations/${invitationId}`, {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.jwt}`,\n },\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n message: errorData.message || `Failed to revoke invitation: ${response.status}`,\n };\n }\n\n const data = await response.json().catch(() => ({}));\n return {\n success: true,\n data,\n };\n } catch (error) {\n console.warn('[VortexClient] Error revoking invitation:', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Accepts an incoming invitation that the user has received.\n * \n * @param invitationId - The ID of the invitation to accept\n * @returns Promise resolving to the response\n */\n async acceptIncomingInvitation(invitationId: string): Promise<InvitationResponse> {\n try {\n const response = await fetch(`${this.baseURL}/api/v1/invitations/accept`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.jwt}`,\n },\n body: JSON.stringify({ invitationId }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n message: errorData.message || `Failed to accept invitation: ${response.status}`,\n };\n }\n\n const data = await response.json().catch(() => ({}));\n return {\n success: true,\n data,\n };\n } catch (error) {\n console.warn('[VortexClient] Error accepting invitation:', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Fetches incoming (open) invitations for the current user.\n * \n * @returns Promise resolving to the list of incoming invitations\n */\n async getIncomingInvitations(): Promise<IncomingInvitation[]> {\n try {\n const response = await fetch(`${this.baseURL}/api/v1/invitations`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.jwt}`,\n },\n });\n\n if (!response.ok) {\n console.warn('[VortexClient] Failed to fetch incoming invitations:', response.status);\n return [];\n }\n\n const data: IncomingInvitationsResponse = await response.json();\n return data.data.invitations;\n } catch (error) {\n console.warn('[VortexClient] Error fetching incoming invitations:', error);\n return [];\n }\n }\n\n /**\n * Deletes/declines an incoming invitation that the user has received.\n * \n * @param invitationId - The ID of the invitation to delete\n * @returns Promise resolving to the response\n */\n async deleteIncomingInvitation(invitationId: string): Promise<InvitationResponse> {\n try {\n const response = await fetch(`${this.baseURL}/api/v1/invitations/incoming/${invitationId}`, {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.jwt}`,\n },\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n return {\n success: false,\n message: errorData.message || `Failed to delete invitation: ${response.status}`,\n };\n }\n\n const data = await response.json().catch(() => ({}));\n return {\n success: true,\n data,\n };\n } catch (error) {\n console.warn('[VortexClient] Error deleting invitation:', error);\n return {\n success: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n}\n","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n TouchableOpacity,\n ActivityIndicator,\n Image,\n Platform,\n Alert,\n Animated,\n} from 'react-native';\nimport { OutgoingInvitationsConfig, OutgoingInvitationItem } from '../types/invitations';\nimport { EventNames } from '@teamvortexsoftware/analytics-client';\nimport type { SimpleAnalyticsEvent } from '../utils/analytics';\nimport { subscribeToInvitationEvent } from '../utils/invitationEvents';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback on native\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\nexport interface VrtxOutgoingInvitationsProps {\n block: any;\n /** Outgoing Invitations configuration with optional onCancel callback */\n outgoingInvitationsConfig?: OutgoingInvitationsConfig;\n /** API URL for fetching invitations (required - passed from parent InviteFormCore) */\n apiUrl: string;\n /** JWT token for authentication (required - passed from parent InviteFormCore) */\n jwt: string;\n /** Trigger haptic feedback */\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n /** Theme colors from widget configuration */\n theme?: {\n primaryBackground?: string;\n primaryForeground?: string;\n secondaryBackground?: string;\n secondaryForeground?: string;\n foreground?: string;\n border?: string;\n };\n /** Callback to emit analytics events */\n onAnalyticsEvent?: (event: SimpleAnalyticsEvent) => void;\n}\n\n// Animated item wrapper for fade-out effect\nfunction AnimatedInvitationItem({\n item,\n renderContent,\n onRemove,\n}: {\n item: OutgoingInvitationItem;\n renderContent: (item: OutgoingInvitationItem) => React.ReactNode;\n onRemove: (id: string) => void;\n}) {\n const fadeAnim = useRef(new Animated.Value(1)).current;\n const heightAnim = useRef(new Animated.Value(1)).current;\n\n const animateOut = useCallback(() => {\n // Use sequential animations to avoid mixing useNativeDriver: true and false\n Animated.timing(fadeAnim, {\n toValue: 0,\n duration: 150,\n useNativeDriver: true,\n }).start(() => {\n onRemove(item.id);\n });\n }, [fadeAnim, item.id, onRemove]);\n\n return (\n <Animated.View\n style={{\n opacity: fadeAnim,\n }}\n >\n {renderContent({ ...item, metadata: { ...item.metadata, animateOut } })}\n </Animated.View>\n );\n}\n\nexport function VrtxOutgoingInvitations({\n block,\n outgoingInvitationsConfig,\n apiUrl,\n jwt,\n triggerHaptic,\n theme,\n onAnalyticsEvent,\n}: VrtxOutgoingInvitationsProps) {\n // Extract mock invitations from config (internal preview use only)\n const _mockInvitations = outgoingInvitationsConfig?._mockInvitations;\n // Local state for managing the displayed invitations (for animate-out)\n const [displayedInvitations, setDisplayedInvitations] = useState<OutgoingInvitationItem[]>([]);\n const [actionInProgress, setActionInProgress] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Use mock mode if _mockInvitations provided (preview), otherwise API mode\n const isMockMode = !!_mockInvitations;\n\n // Fetch invitations from API\n const fetchInvitations = useCallback(async () => {\n if (!apiUrl || !jwt) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n const response = await fetch(`${apiUrl}/api/v1/invitations/sent`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${jwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch invitations: ${response.status}`);\n }\n\n const data = await response.json();\n // Filter out shareable link invitations (targetType \"share\") - matches iOS SDK\n const filtered = (data.data?.invitations || []).filter((inv: any) => {\n const targetType = inv.targets?.[0]?.targetType;\n return targetType !== 'share';\n });\n const mappedInvitations: OutgoingInvitationItem[] = filtered.map((inv: any) => {\n // Extract target (invitee) info from the targets array - matches iOS SDK\n const target = inv.targets?.[0];\n const targetName = target?.targetName;\n const targetValue = target?.targetValue;\n \n // Use targetName as display name if available, otherwise fall back to targetValue\n const name = targetName ?? targetValue ?? inv.senderIdentifier ?? 'Unknown';\n return {\n id: inv.id,\n name,\n userId: targetValue,\n avatarUrl: target?.targetAvatarUrl,\n isVortexInvitation: true,\n metadata: inv,\n };\n });\n\n // Merge config invitations with API invitations, deduplicating by userId.\n const configInvitations = outgoingInvitationsConfig?.invitations || [];\n const apiUserIds = new Set(\n mappedInvitations\n .filter((inv) => inv.userId)\n .map((inv) => inv.userId)\n );\n const dedupedConfig = configInvitations.filter(\n (inv) => !inv.userId || !apiUserIds.has(inv.userId)\n );\n setDisplayedInvitations([...dedupedConfig, ...mappedInvitations]);\n } catch (err) {\n console.error('[VrtxOutgoingInvitations] Fetch failed:', err);\n setError(err instanceof Error ? err.message : 'Failed to load invitations');\n } finally {\n setIsLoading(false);\n }\n }, [apiUrl, jwt, outgoingInvitationsConfig?.invitations]);\n\n // Revoke invitation via API\n const revokeInvitation = useCallback(\n async (invitationId: string): Promise<boolean> => {\n if (!apiUrl || !jwt) return false;\n\n try {\n const response = await fetch(`${apiUrl}/api/v1/invitations/${invitationId}`, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${jwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok && response.status !== 204) {\n throw new Error(`Failed to revoke invitation: ${response.status}`);\n }\n\n return true;\n } catch (err) {\n console.error('[VrtxOutgoingInvitations] Revoke failed:', err);\n return false;\n }\n },\n [apiUrl, jwt]\n );\n\n // Fetch invitations on mount - use mock data in preview mode, otherwise fetch from API\n useEffect(() => {\n if (isMockMode) {\n setDisplayedInvitations(_mockInvitations || []);\n } else {\n fetchInvitations();\n }\n }, [isMockMode, _mockInvitations, fetchInvitations]);\n\n // Subscribe to invitation events to refresh the list when new invitations are created\n useEffect(() => {\n if (isMockMode) return; // Don't subscribe in mock mode\n \n const unsubscribe = subscribeToInvitationEvent('invitationCreated', () => {\n console.log('[VrtxOutgoingInvitations] Invitation created event received, refreshing...');\n fetchInvitations();\n });\n \n return unsubscribe;\n }, [isMockMode, fetchInvitations]);\n\n // Extract customization from block settings (widget configuration), with defaults\n const blockCustomizations = block?.settings?.customizations;\n const cancelButtonText =\n blockCustomizations?.cancelButton?.textContent ?? 'Cancel';\n const emptyStateMessage =\n blockCustomizations?.emptyStateMessage?.textContent ?? 'No sent invitations';\n\n // Confirmation dialog texts from widget configuration\n const cancelConfirmTitle =\n blockCustomizations?.cancelConfirmTitle?.textContent ?? 'Cancel Invitation';\n const cancelConfirmMessage =\n blockCustomizations?.cancelConfirmMessage?.textContent ?? 'Cancel invitation to {name}?';\n const confirmButtonText =\n blockCustomizations?.confirmButtonText?.textContent ?? 'Confirm';\n const dismissButtonText =\n blockCustomizations?.dismissButtonText?.textContent ?? 'Keep';\n\n // Helper to get theme option value from block.theme.options\n const getBlockThemeValue = (key: string): string | undefined => {\n const options = block?.theme?.options;\n if (!options || !Array.isArray(options)) return undefined;\n const option = options.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n // Theme colors with defaults\n const colors = {\n primaryBackground: theme?.primaryBackground ?? '#6291d5',\n primaryForeground: theme?.primaryForeground ?? '#ffffff',\n secondaryBackground: theme?.secondaryBackground ?? '#ffffff',\n secondaryForeground: theme?.secondaryForeground ?? '#353e5c',\n foreground: theme?.foreground ?? '#334153',\n border: theme?.border ?? '#cccccc',\n };\n\n // Button styles from block.theme.options (microTheme)\n const cancelButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-background') ||\n colors.secondaryBackground,\n color:\n getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-color') ||\n colors.secondaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-border-radius'),\n border: getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-border'),\n padding: getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-outgoing-invitations-cancel-button-font-weight'),\n };\n\n // Avatar/initials styles from block.theme.options (microTheme)\n const avatarStyles = {\n background:\n getBlockThemeValue('--vrtx-outgoing-invitations-avatar-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-outgoing-invitations-avatar-color') || colors.primaryForeground,\n };\n\n // Contact name styles from block.theme.options (microTheme)\n const nameStyles = {\n color: getBlockThemeValue('--vrtx-outgoing-invitations-name-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-outgoing-invitations-name-font-family'),\n fontSize: getBlockThemeValue('--vrtx-outgoing-invitations-name-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-outgoing-invitations-name-font-weight'),\n };\n\n // Subtitle styles from block.theme.options (microTheme)\n const subtitleStyles = {\n color:\n getBlockThemeValue('--vrtx-outgoing-invitations-subtitle-color') ||\n colors.secondaryForeground,\n fontFamily: getBlockThemeValue('--vrtx-outgoing-invitations-subtitle-font-family'),\n fontSize: getBlockThemeValue('--vrtx-outgoing-invitations-subtitle-font-size'),\n };\n\n // Title styles from block.theme.options (microTheme)\n const titleStyles = {\n color: getBlockThemeValue('--vrtx-outgoing-invitations-title-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-outgoing-invitations-title-font-family'),\n fontSize: getBlockThemeValue('--vrtx-outgoing-invitations-title-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-outgoing-invitations-title-font-weight'),\n };\n\n // Remove invitation from displayed list (after animation)\n const handleRemoveFromDisplay = useCallback((id: string) => {\n setDisplayedInvitations((prev) => prev.filter((inv) => inv.id !== id));\n }, []);\n\n // Show confirmation dialog\n const showConfirmation = useCallback(\n (title: string, message: string, onConfirm: () => void) => {\n if (isWeb) {\n // Web: use window.confirm\n const confirmed = window.confirm(message);\n if (confirmed) {\n onConfirm();\n }\n } else {\n // Native: use Alert\n Alert.alert(title, message, [\n {\n text: dismissButtonText,\n style: 'cancel',\n },\n {\n text: confirmButtonText,\n onPress: onConfirm,\n },\n ]);\n }\n },\n [confirmButtonText, dismissButtonText]\n );\n\n // Handle Cancel button press\n const handleCancel = useCallback(\n async (invitation: OutgoingInvitationItem, animateOut?: () => void) => {\n const message = cancelConfirmMessage.replace('{name}', invitation.name);\n\n showConfirmation(cancelConfirmTitle, message, async () => {\n setActionInProgress(invitation.id);\n await triggerHaptic?.('light');\n\n // Emit analytics event for delete button click\n onAnalyticsEvent?.({\n name: EventNames.OUTBOUND_INVITATION_DELETE_CLICKED,\n payload: { invitationId: invitation.id, inviteeName: invitation.name },\n });\n\n try {\n // Call the callback if provided and check return value\n let shouldProceed = true;\n if (outgoingInvitationsConfig?.onCancel) {\n const result = await outgoingInvitationsConfig.onCancel(invitation);\n // If callback returns false explicitly, don't proceed\n if (result === false) {\n shouldProceed = false;\n }\n }\n\n if (!shouldProceed) {\n setActionInProgress(null);\n return;\n }\n\n // In mock mode (web), skip API call AND don't remove the invitation (no-op)\n if (isMockMode) {\n // No-op in mock mode\n } else {\n // Real mode: call DELETE endpoint and remove on success\n const success = await revokeInvitation(invitation.id);\n\n if (success) {\n // Animate out after successful action\n if (animateOut) {\n animateOut();\n } else {\n handleRemoveFromDisplay(invitation.id);\n }\n }\n }\n } catch (err) {\n console.error('[VrtxOutgoingInvitations] Cancel failed:', err);\n } finally {\n setActionInProgress(null);\n }\n });\n },\n [\n outgoingInvitationsConfig,\n revokeInvitation,\n triggerHaptic,\n cancelConfirmTitle,\n cancelConfirmMessage,\n showConfirmation,\n handleRemoveFromDisplay,\n onAnalyticsEvent,\n ]\n );\n\n // Helper to parse CSS padding string to React Native padding object\n const parsePadding = (paddingStr: string | undefined) => {\n if (!paddingStr) return {};\n const parts = paddingStr.trim().split(/\\s+/);\n if (parts.length === 1) {\n const val = parseInt(parts[0], 10);\n return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };\n }\n if (parts.length === 2) {\n const vertical = parseInt(parts[0], 10);\n const horizontal = parseInt(parts[1], 10);\n return {\n ...(isNaN(vertical) ? {} : { paddingVertical: vertical }),\n ...(isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }),\n };\n }\n return {};\n };\n\n // Helper to parse border string (e.g., \"1px solid #ccc\")\n const parseBorder = (borderStr: string | undefined) => {\n if (!borderStr) return {};\n const match = borderStr.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n return {\n borderWidth: parseInt(match[1], 10),\n borderColor: match[3],\n };\n }\n return {};\n };\n\n // Render avatar or initials\n const renderAvatar = (invitation: OutgoingInvitationItem) => {\n if (invitation.avatarUrl) {\n return <Image source={{ uri: invitation.avatarUrl }} style={styles.avatar} />;\n }\n\n // Generate initials from name\n const initials = invitation.name\n .split(' ')\n .map((part: string) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n // Handle avatar background with gradient support\n const avatarBackground = avatarStyles.background;\n const isAvatarGradient = avatarBackground?.includes('linear-gradient');\n const avatarBgStyle: any = {};\n\n if (isWeb && avatarBackground) {\n avatarBgStyle.background = avatarBackground;\n } else if (isAvatarGradient && avatarBackground) {\n const fallbackColor = parseGradientFirstColor(avatarBackground);\n avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;\n }\n\n return (\n <View style={[styles.avatarPlaceholder, avatarBgStyle]}>\n <Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</Text>\n </View>\n );\n };\n\n // Build button style with gradient support\n const buildButtonStyle = (buttonStyles: any, fallbackBg: string) => {\n const backgroundValue = buttonStyles.background;\n const isGradient = backgroundValue?.includes('linear-gradient');\n\n const dynamicButtonStyle: any = {\n ...(buttonStyles.borderRadius\n ? { borderRadius: parseInt(buttonStyles.borderRadius, 10) }\n : {}),\n ...parsePadding(buttonStyles.padding),\n ...parseBorder(buttonStyles.border),\n };\n\n if (isWeb && backgroundValue) {\n dynamicButtonStyle.background = backgroundValue;\n } else if (isGradient && backgroundValue) {\n const fallbackColor = parseGradientFirstColor(backgroundValue);\n dynamicButtonStyle.backgroundColor = fallbackColor || fallbackBg;\n } else {\n dynamicButtonStyle.backgroundColor = backgroundValue || fallbackBg;\n }\n\n return dynamicButtonStyle;\n };\n\n // Render a single invitation item\n const renderInvitationContent = (item: OutgoingInvitationItem) => {\n const isLoading = actionInProgress === item.id;\n const animateOut = item.metadata?.animateOut as (() => void) | undefined;\n\n // Build dynamic button style\n const cancelButtonDynamicStyle = buildButtonStyle(\n cancelButtonStyles,\n colors.secondaryBackground\n );\n\n // Build dynamic text style\n const cancelTextStyle: any = {\n color: cancelButtonStyles.color,\n ...(cancelButtonStyles.fontSize\n ? { fontSize: parseInt(cancelButtonStyles.fontSize, 10) }\n : {}),\n ...(cancelButtonStyles.fontWeight ? { fontWeight: cancelButtonStyles.fontWeight } : {}),\n };\n\n // Build dynamic name style\n const dynamicNameStyle: any = {\n color: nameStyles.color,\n ...(nameStyles.fontFamily ? { fontFamily: nameStyles.fontFamily } : {}),\n ...(nameStyles.fontSize ? { fontSize: parseInt(nameStyles.fontSize, 10) } : {}),\n ...(nameStyles.fontWeight ? { fontWeight: nameStyles.fontWeight } : {}),\n };\n\n // Build dynamic subtitle style\n const dynamicSubtitleStyle: any = {\n color: subtitleStyles.color,\n ...(subtitleStyles.fontFamily ? { fontFamily: subtitleStyles.fontFamily } : {}),\n ...(subtitleStyles.fontSize ? { fontSize: parseInt(subtitleStyles.fontSize, 10) } : {}),\n };\n\n return (\n <View style={styles.invitationItem}>\n {renderAvatar(item)}\n <View style={styles.invitationInfo}>\n <Text style={[styles.invitationName, dynamicNameStyle]} numberOfLines={1}>\n {item.name}\n </Text>\n {(() => {\n const displaySubtitle = outgoingInvitationsConfig?.getSubtitle?.(item);\n return displaySubtitle ? (\n <Text style={[styles.invitationSubtitle, dynamicSubtitleStyle]} numberOfLines={1}>\n {displaySubtitle}\n </Text>\n ) : null;\n })()}\n </View>\n {/* Cancel button */}\n <TouchableOpacity\n style={[styles.actionButton, cancelButtonDynamicStyle]}\n onPress={() => handleCancel(item, animateOut)}\n disabled={isLoading}\n activeOpacity={0.7}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={cancelButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, cancelTextStyle]}>{cancelButtonText}</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n };\n\n // Render item with animation wrapper\n const renderItem = ({ item }: { item: OutgoingInvitationItem }) => {\n return (\n <AnimatedInvitationItem\n item={item}\n renderContent={renderInvitationContent}\n onRemove={handleRemoveFromDisplay}\n />\n );\n };\n\n\n // Loading state (API mode)\n if (isLoading) {\n return (\n <View style={styles.container}>\n <ActivityIndicator size=\"large\" color={colors.primaryBackground} />\n </View>\n );\n }\n\n // Error state (API mode)\n if (error) {\n return (\n <View style={styles.container}>\n <Text style={[styles.errorText, { color: '#dc2626' }]}>{error}</Text>\n </View>\n );\n }\n\n // Empty state - render nothing (no-op component with no height)\n if (displayedInvitations.length === 0) {\n return null;\n }\n\n // Get title from block attributes (configured in editor as \"Title\")\n const title = block?.attributes?.title;\n\n // Build dynamic title style\n const dynamicTitleStyle: any = {\n color: titleStyles.color,\n ...(titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {}),\n ...(titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {}),\n ...(titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}),\n };\n\n // Main view: Invitations list\n // Note: Using View + map instead of FlatList to avoid \"VirtualizedLists should never be nested\" warning\n // when this component is rendered inside a ScrollView (which InviteFormCore uses)\n return (\n <View style={styles.listContainer}>\n {title && (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n )}\n <View style={styles.listContent}>\n {displayedInvitations.map((item) => (\n <View key={item.id}>\n {renderItem({ item })}\n </View>\n ))}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 120,\n },\n listContainer: {\n flex: 1,\n },\n title: {\n fontSize: 16,\n fontWeight: '600',\n marginBottom: 12,\n },\n placeholderText: {\n fontSize: 14,\n textAlign: 'center',\n },\n emptyText: {\n fontSize: 14,\n textAlign: 'center',\n },\n errorText: {\n fontSize: 14,\n textAlign: 'center',\n },\n listContent: {\n paddingBottom: 16,\n },\n invitationItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n avatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n avatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n },\n invitationInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n invitationName: {\n fontSize: 16,\n fontWeight: '500',\n },\n invitationSubtitle: {\n fontSize: 13,\n marginTop: 2,\n },\n actionButton: {\n paddingHorizontal: 16,\n paddingVertical: 8,\n borderRadius: 8,\n minWidth: 80,\n alignItems: 'center',\n justifyContent: 'center',\n },\n actionButtonText: {\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n TouchableOpacity,\n ActivityIndicator,\n Image,\n Platform,\n Animated,\n ViewStyle,\n} from 'react-native';\nimport { EventNames } from '@teamvortexsoftware/analytics-client';\nimport { InvitationSuggestionsConfig, InvitationItem } from '../types/invitations';\nimport type { SimpleAnalyticsEvent } from '../utils/analytics';\nimport { useVortexModules } from '../context/VortexModulesContext';\nimport { emitInvitationEvent } from '../utils/invitationEvents';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback on native\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nfunction ButtonWrapper({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}: ButtonWrapperProps) {\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n}\n\nexport interface VrtxInvitationSuggestionsProps {\n block: any;\n /** Invitation Suggestions configuration with callbacks */\n invitationSuggestionsConfig?: InvitationSuggestionsConfig;\n /** Create an invitation via the Vortex API */\n createUserIdInvitation?: (userId: string, name?: string, avatarUrl?: string, metadata?: Record<string, unknown>) => Promise<void>;\n /** Trigger haptic feedback */\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n /** Callback to emit analytics events */\n onAnalyticsEvent?: (event: SimpleAnalyticsEvent) => void;\n /** Theme colors from widget configuration */\n theme?: {\n primaryBackground?: string;\n primaryForeground?: string;\n secondaryBackground?: string;\n secondaryForeground?: string;\n foreground?: string;\n border?: string;\n };\n}\n\n// Animated item wrapper for fade-out effect\nfunction AnimatedSuggestionItem({\n item,\n renderContent,\n onRemove,\n}: {\n item: InvitationItem;\n renderContent: (item: InvitationItem) => React.ReactNode;\n onRemove: (id: string) => void;\n}) {\n const fadeAnim = useRef(new Animated.Value(1)).current;\n const heightAnim = useRef(new Animated.Value(1)).current;\n\n const animateOut = useCallback(() => {\n Animated.parallel([\n Animated.timing(fadeAnim, {\n toValue: 0,\n duration: 200,\n useNativeDriver: false,\n }),\n Animated.timing(heightAnim, {\n toValue: 0,\n duration: 200,\n useNativeDriver: false,\n }),\n ]).start(() => {\n onRemove(item.id);\n });\n }, [fadeAnim, heightAnim, item.id, onRemove]);\n\n return (\n <Animated.View\n style={{\n opacity: fadeAnim,\n transform: [{ scaleY: heightAnim }],\n }}\n >\n {renderContent({ ...item, metadata: { ...item.metadata, animateOut } })}\n </Animated.View>\n );\n}\n\nexport function VrtxInvitationSuggestions({\n block,\n invitationSuggestionsConfig,\n createUserIdInvitation,\n triggerHaptic,\n onAnalyticsEvent,\n theme,\n}: VrtxInvitationSuggestionsProps) {\n // Local state for managing the displayed suggestions (for animate-out)\n const [displayedSuggestions, setDisplayedSuggestions] = useState<InvitationItem[]>(\n invitationSuggestionsConfig?.suggestions || []\n );\n const [actionInProgress, setActionInProgress] = useState<string | null>(null);\n\n // Sync with props when suggestions change\n useEffect(() => {\n setDisplayedSuggestions(invitationSuggestionsConfig?.suggestions || []);\n }, [invitationSuggestionsConfig?.suggestions]);\n\n // Extract customization from block settings or config props, with defaults\n const blockCustomizations = block?.settings?.customizations;\n const inviteButtonText =\n blockCustomizations?.inviteButton?.textContent ??\n invitationSuggestionsConfig?.inviteButtonText ??\n 'Invite';\n const emptyStateMessage =\n blockCustomizations?.emptyStateMessage?.textContent ??\n invitationSuggestionsConfig?.emptyStateMessage ??\n 'No suggestions';\n\n // Helper to get theme option value from block.theme.options\n const getBlockThemeValue = (key: string): string | undefined => {\n const options = block?.theme?.options;\n if (!options || !Array.isArray(options)) return undefined;\n const option = options.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n // Theme colors with defaults\n const colors = {\n primaryBackground: theme?.primaryBackground ?? '#6291d5',\n primaryForeground: theme?.primaryForeground ?? '#ffffff',\n secondaryBackground: theme?.secondaryBackground ?? '#ffffff',\n secondaryForeground: theme?.secondaryForeground ?? '#353e5c',\n foreground: theme?.foreground ?? '#334153',\n border: theme?.border ?? '#cccccc',\n };\n\n // Button styles from block.theme.options (microTheme)\n const inviteButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-color') ||\n colors.primaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-border-radius'),\n border: getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-border'),\n padding: getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-invitation-suggestions-invite-button-font-weight'),\n };\n\n // Dismiss button styles from block.theme.options (microTheme)\n const dismissButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-invitation-suggestions-dismiss-button-background') ||\n 'transparent',\n color:\n getBlockThemeValue('--vrtx-invitation-suggestions-dismiss-button-color') ||\n colors.secondaryForeground,\n };\n\n // Avatar/initials styles from block.theme.options (microTheme)\n const avatarStyles = {\n background:\n getBlockThemeValue('--vrtx-invitation-suggestions-avatar-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-invitation-suggestions-avatar-color') || colors.primaryForeground,\n };\n\n // Name styles from block.theme.options (microTheme)\n const nameStyles = {\n color: getBlockThemeValue('--vrtx-invitation-suggestions-name-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-invitation-suggestions-name-font-family'),\n fontSize: getBlockThemeValue('--vrtx-invitation-suggestions-name-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-invitation-suggestions-name-font-weight'),\n };\n\n // Subtitle styles from block.theme.options (microTheme)\n const subtitleStyles = {\n color:\n getBlockThemeValue('--vrtx-invitation-suggestions-subtitle-color') ||\n colors.secondaryForeground,\n fontFamily: getBlockThemeValue('--vrtx-invitation-suggestions-subtitle-font-family'),\n fontSize: getBlockThemeValue('--vrtx-invitation-suggestions-subtitle-font-size'),\n };\n\n // Title styles from block.theme.options (microTheme)\n const titleStyles = {\n color: getBlockThemeValue('--vrtx-invitation-suggestions-title-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-invitation-suggestions-title-font-family'),\n fontSize: getBlockThemeValue('--vrtx-invitation-suggestions-title-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-invitation-suggestions-title-font-weight'),\n };\n\n // Get title from block attributes (configured in Styles tab)\n const title = block?.attributes?.title || '';\n\n // Remove suggestion from displayed list (after animation)\n const handleRemoveFromDisplay = useCallback((id: string) => {\n setDisplayedSuggestions((prev) => prev.filter((s) => s.id !== id));\n }, []);\n\n // Handle Invite button press (no confirmation)\n const handleInvite = useCallback(\n async (suggestion: InvitationItem, animateOut?: () => void) => {\n if (!invitationSuggestionsConfig?.onInvite) return;\n\n setActionInProgress(suggestion.id);\n await triggerHaptic?.('light');\n\n // Emit analytics event for PYMK invite click\n onAnalyticsEvent?.({\n name: EventNames.PYMK_INVITE_CLICKED,\n segmentation: {\n suggestionId: suggestion.id,\n suggestionName: suggestion.name,\n },\n });\n\n try {\n // Call customer's callback\n await invitationSuggestionsConfig.onInvite(suggestion);\n\n // Create the invitation via the Vortex API so it appears in Outgoing Invitations\n if (createUserIdInvitation) {\n await createUserIdInvitation(suggestion.id, suggestion.name, suggestion.avatarUrl, suggestion.metadata);\n // Notify other components (e.g., VrtxOutgoingInvitations) to refresh\n emitInvitationEvent('invitationCreated');\n }\n\n // Animate out after successful action\n if (animateOut) {\n animateOut();\n } else {\n handleRemoveFromDisplay(suggestion.id);\n }\n } catch (err) {\n console.error('[VrtxInvitationSuggestions] Invite failed:', err);\n } finally {\n setActionInProgress(null);\n }\n },\n [invitationSuggestionsConfig, createUserIdInvitation, triggerHaptic, onAnalyticsEvent, handleRemoveFromDisplay]\n );\n\n // Handle Dismiss (X) button press (no confirmation)\n const handleDismiss = useCallback(\n async (suggestion: InvitationItem, animateOut?: () => void) => {\n if (!invitationSuggestionsConfig?.onDismiss) return;\n\n setActionInProgress(suggestion.id);\n await triggerHaptic?.('light');\n\n // Emit analytics event for PYMK dismiss click\n onAnalyticsEvent?.({\n name: EventNames.PYMK_DELETE_CLICKED,\n segmentation: {\n suggestionId: suggestion.id,\n suggestionName: suggestion.name,\n },\n });\n\n try {\n await invitationSuggestionsConfig.onDismiss(suggestion);\n // Animate out after successful action\n if (animateOut) {\n animateOut();\n } else {\n handleRemoveFromDisplay(suggestion.id);\n }\n } catch (err) {\n console.error('[VrtxInvitationSuggestions] Dismiss failed:', err);\n } finally {\n setActionInProgress(null);\n }\n },\n [invitationSuggestionsConfig, triggerHaptic, onAnalyticsEvent, handleRemoveFromDisplay]\n );\n\n // Helper to parse CSS padding string to React Native padding object\n const parsePadding = (paddingStr: string | undefined) => {\n if (!paddingStr) return {};\n const parts = paddingStr.trim().split(/\\s+/);\n if (parts.length === 1) {\n const val = parseInt(parts[0], 10);\n return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };\n }\n if (parts.length === 2) {\n const vertical = parseInt(parts[0], 10);\n const horizontal = parseInt(parts[1], 10);\n return {\n ...(isNaN(vertical) ? {} : { paddingVertical: vertical }),\n ...(isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }),\n };\n }\n return {};\n };\n\n // Helper to parse border string (e.g., \"1px solid #ccc\")\n const parseBorder = (borderStr: string | undefined) => {\n if (!borderStr) return {};\n const match = borderStr.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n return {\n borderWidth: parseInt(match[1], 10),\n borderColor: match[3],\n };\n }\n return {};\n };\n\n // Render avatar or initials\n const renderAvatar = (suggestion: InvitationItem) => {\n if (suggestion.avatarUrl) {\n return <Image source={{ uri: suggestion.avatarUrl }} style={styles.avatar} />;\n }\n\n // Generate initials from name\n const initials = suggestion.name\n .split(' ')\n .map((part) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n // Handle avatar background with gradient support\n const avatarBackground = avatarStyles.background;\n const isAvatarGradient = avatarBackground?.includes('linear-gradient');\n const avatarBgStyle: any = {};\n\n if (isWeb && avatarBackground) {\n avatarBgStyle.background = avatarBackground;\n } else if (isAvatarGradient && avatarBackground) {\n const fallbackColor = parseGradientFirstColor(avatarBackground);\n avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;\n }\n\n return (\n <View style={[styles.avatarPlaceholder, avatarBgStyle]}>\n <Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</Text>\n </View>\n );\n };\n\n // Build button style with gradient support\n const buildButtonStyle = (buttonStyles: any, fallbackBg: string) => {\n const backgroundValue = buttonStyles.background;\n const isGradient = backgroundValue?.includes('linear-gradient');\n\n const dynamicButtonStyle: any = {\n ...(buttonStyles.borderRadius\n ? { borderRadius: parseInt(buttonStyles.borderRadius, 10) }\n : {}),\n ...parsePadding(buttonStyles.padding),\n ...parseBorder(buttonStyles.border),\n };\n\n if (isWeb && backgroundValue) {\n dynamicButtonStyle.background = backgroundValue;\n } else if (isGradient && backgroundValue) {\n const fallbackColor = parseGradientFirstColor(backgroundValue);\n dynamicButtonStyle.backgroundColor = fallbackColor || fallbackBg;\n } else {\n dynamicButtonStyle.backgroundColor = backgroundValue || fallbackBg;\n }\n\n return dynamicButtonStyle;\n };\n\n // Render a single suggestion item\n const renderSuggestionContent = (item: InvitationItem) => {\n const isLoading = actionInProgress === item.id;\n const animateOut = item.metadata?.animateOut as (() => void) | undefined;\n\n // Build dynamic button style\n const inviteButtonDynamicStyle = buildButtonStyle(inviteButtonStyles, colors.primaryBackground);\n\n // Build dynamic text style\n const inviteTextStyle: any = {\n color: inviteButtonStyles.color,\n ...(inviteButtonStyles.fontSize\n ? { fontSize: parseInt(inviteButtonStyles.fontSize, 10) }\n : {}),\n ...(inviteButtonStyles.fontWeight ? { fontWeight: inviteButtonStyles.fontWeight } : {}),\n };\n\n // Build dynamic name style\n const dynamicNameStyle: any = {\n color: nameStyles.color,\n ...(nameStyles.fontFamily ? { fontFamily: nameStyles.fontFamily } : {}),\n ...(nameStyles.fontSize ? { fontSize: parseInt(nameStyles.fontSize, 10) } : {}),\n ...(nameStyles.fontWeight ? { fontWeight: nameStyles.fontWeight } : {}),\n };\n\n // Build dynamic subtitle style\n const dynamicSubtitleStyle: any = {\n color: subtitleStyles.color,\n ...(subtitleStyles.fontFamily ? { fontFamily: subtitleStyles.fontFamily } : {}),\n ...(subtitleStyles.fontSize ? { fontSize: parseInt(subtitleStyles.fontSize, 10) } : {}),\n };\n\n return (\n <View style={styles.suggestionItem}>\n {renderAvatar(item)}\n <View style={styles.suggestionInfo}>\n <Text style={[styles.suggestionName, dynamicNameStyle]} numberOfLines={1}>\n {item.name}\n </Text>\n {item.subtitle && (\n <Text style={[styles.suggestionSubtitle, dynamicSubtitleStyle]} numberOfLines={1}>\n {item.subtitle}\n </Text>\n )}\n </View>\n {/* Invite button */}\n <ButtonWrapper\n style={[styles.actionButton, inviteButtonDynamicStyle]}\n gradientString={inviteButtonStyles.background?.includes('gradient') ? inviteButtonStyles.background : null}\n onPress={() => handleInvite(item, animateOut)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={inviteButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, inviteTextStyle]}>{inviteButtonText}</Text>\n )}\n </ButtonWrapper>\n {/* Dismiss (X) button */}\n <TouchableOpacity\n style={[styles.dismissButton, { backgroundColor: dismissButtonStyles.background }]}\n onPress={() => handleDismiss(item, animateOut)}\n disabled={isLoading}\n activeOpacity={0.7}\n >\n <Text style={[styles.dismissButtonText, { color: dismissButtonStyles.color }]}>✕</Text>\n </TouchableOpacity>\n </View>\n );\n };\n\n // Render item with animation wrapper\n const renderSuggestionItem = ({ item }: { item: InvitationItem }) => {\n return (\n <AnimatedSuggestionItem\n item={item}\n renderContent={renderSuggestionContent}\n onRemove={handleRemoveFromDisplay}\n />\n );\n };\n\n // Build dynamic title style\n const dynamicTitleStyle: any = {\n color: titleStyles.color,\n ...(titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {}),\n ...(titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {}),\n ...(titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}),\n };\n\n // Show placeholder if no config provided\n if (!invitationSuggestionsConfig) {\n return (\n <View style={styles.container}>\n {title ? <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text> : null}\n <Text style={[styles.placeholderText, { color: colors.secondaryForeground }]}>\n Invitation Suggestions component - provide invitationSuggestionsConfig to enable\n </Text>\n </View>\n );\n }\n\n // Empty state\n if (displayedSuggestions.length === 0) {\n return (\n <View style={styles.container}>\n {title ? <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text> : null}\n <Text style={[styles.emptyText, { color: colors.secondaryForeground }]}>\n {emptyStateMessage}\n </Text>\n </View>\n );\n }\n\n // Main list view\n // Note: Using View + map instead of FlatList to avoid \"VirtualizedLists should never be nested\" warning\n // when this component is rendered inside a ScrollView (which InviteFormCore uses)\n return (\n <View style={styles.listContainer}>\n {title ? <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text> : null}\n <View style={styles.listContent}>\n {displayedSuggestions.map((item) => (\n <View key={item.id}>\n {renderSuggestionItem({ item })}\n </View>\n ))}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 120,\n },\n listContainer: {\n flex: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: '600',\n marginBottom: 16,\n },\n placeholderText: {\n fontSize: 14,\n textAlign: 'center',\n },\n emptyText: {\n fontSize: 14,\n textAlign: 'center',\n },\n listContent: {\n paddingBottom: 16,\n },\n suggestionItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n avatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n avatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n },\n suggestionInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n suggestionName: {\n fontSize: 16,\n fontWeight: '500',\n },\n suggestionSubtitle: {\n fontSize: 13,\n marginTop: 2,\n },\n dismissButton: {\n width: 32,\n height: 32,\n borderRadius: 16,\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: 8,\n },\n dismissButtonText: {\n fontSize: 16,\n fontWeight: '500',\n },\n actionButton: {\n paddingHorizontal: 16,\n paddingVertical: 8,\n borderRadius: 8,\n minWidth: 70,\n alignItems: 'center',\n justifyContent: 'center',\n },\n actionButtonText: {\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","import React, { useState, useCallback, useMemo } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n TouchableOpacity,\n ActivityIndicator,\n Image,\n TextInput,\n Platform,\n Linking,\n ViewStyle,\n} from 'react-native';\nimport { InviteContactsConfig, InviteContactsContact } from '../types/inviteContacts';\nimport { useVortexModules } from '../context/VortexModulesContext';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback on native\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nfunction ButtonWrapper({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}: ButtonWrapperProps) {\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n}\n\nexport interface VrtxInviteContactsProps {\n block: any;\n /** Invite Contacts configuration with contacts list */\n inviteContactsConfig?: InviteContactsConfig;\n /** Function to create SMS invitation and get short link */\n createSmsInvitation?: (phoneNumber: string, contactName?: string) => Promise<string | null>;\n /** Trigger haptic feedback */\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n /** Theme colors from widget configuration */\n theme?: {\n primaryBackground?: string;\n primaryForeground?: string;\n secondaryBackground?: string;\n secondaryForeground?: string;\n foreground?: string;\n border?: string;\n };\n /** SMS message template with {{link}} placeholder */\n smsMessageTemplate?: string;\n}\n\n// Helper function to sort contacts alphabetically by name\nfunction sortContacts(contacts: InviteContactsContact[]): InviteContactsContact[] {\n return [...contacts].sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport function VrtxInviteContacts({\n block,\n inviteContactsConfig,\n createSmsInvitation,\n triggerHaptic,\n theme,\n smsMessageTemplate,\n}: VrtxInviteContactsProps) {\n const [showContactsList, setShowContactsList] = useState(false);\n const [actionInProgress, setActionInProgress] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState('');\n const [invitedContacts, setInvitedContacts] = useState<Set<string>>(new Set());\n\n // Get contacts from config\n const contacts = useMemo(() => {\n if (!inviteContactsConfig?.contacts || inviteContactsConfig.contacts.length === 0) {\n return [];\n }\n return sortContacts(inviteContactsConfig.contacts);\n }, [inviteContactsConfig?.contacts]);\n\n // Filter contacts based on search query\n const filteredContacts = useMemo(() => {\n if (!searchQuery.trim()) {\n return contacts;\n }\n const query = searchQuery.toLowerCase().trim();\n return contacts.filter(\n (contact) =>\n contact.name.toLowerCase().includes(query) ||\n contact.phoneNumber.includes(query)\n );\n }, [contacts, searchQuery]);\n\n // Extract customization from block settings (editor) or config props, with defaults\n const blockCustomizations = block?.settings?.customizations;\n const inviteYourContactsText =\n blockCustomizations?.inviteYourContactsText?.textContent ??\n inviteContactsConfig?.inviteYourContactsText ??\n 'Invite your contacts';\n const inviteButtonText =\n blockCustomizations?.inviteButton?.textContent ??\n inviteContactsConfig?.inviteButtonText ??\n 'Invite';\n const emptyStateMessage =\n blockCustomizations?.emptyStateMessage?.textContent ??\n inviteContactsConfig?.emptyStateMessage ??\n 'No contacts to invite';\n const smsMessage =\n blockCustomizations?.smsMessage?.textContent ??\n smsMessageTemplate ??\n 'Check this out! {{link}}';\n\n // Helper to get theme option value from block.theme.options\n const getBlockThemeValue = (key: string): string | undefined => {\n const options = block?.theme?.options;\n if (!options || !Array.isArray(options)) return undefined;\n const option = options.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n // Theme colors with defaults\n const colors = {\n primaryBackground: theme?.primaryBackground ?? '#6291d5',\n primaryForeground: theme?.primaryForeground ?? '#ffffff',\n secondaryBackground: theme?.secondaryBackground ?? '#ffffff',\n secondaryForeground: theme?.secondaryForeground ?? '#353e5c',\n foreground: theme?.foreground ?? '#334153',\n border: theme?.border ?? '#cccccc',\n };\n\n // Button styles from block.theme.options (microTheme)\n const inviteButtonStyles = {\n background: getBlockThemeValue('--vrtx-invite-contacts-invite-button-background') || colors.primaryBackground,\n color: getBlockThemeValue('--vrtx-invite-contacts-invite-button-color') || colors.primaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-invite-contacts-invite-button-border-radius'),\n border: getBlockThemeValue('--vrtx-invite-contacts-invite-button-border'),\n padding: getBlockThemeValue('--vrtx-invite-contacts-invite-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-invite-contacts-invite-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-invite-contacts-invite-button-font-weight'),\n };\n\n // Avatar/initials styles from block.theme.options (microTheme)\n const avatarStyles = {\n background: getBlockThemeValue('--vrtx-invite-contacts-avatar-background') || colors.primaryBackground,\n color: getBlockThemeValue('--vrtx-invite-contacts-avatar-color') || colors.primaryForeground,\n };\n\n // Contact name styles from block.theme.options (microTheme)\n const contactNameStyles = {\n color: getBlockThemeValue('--vrtx-invite-contacts-name-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-invite-contacts-name-font-family'),\n fontSize: getBlockThemeValue('--vrtx-invite-contacts-name-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-invite-contacts-name-font-weight'),\n };\n\n // Contact phone/subtitle styles from block.theme.options (microTheme)\n const contactPhoneStyles = {\n color: getBlockThemeValue('--vrtx-invite-contacts-subtitle-color') || colors.secondaryForeground,\n fontFamily: getBlockThemeValue('--vrtx-invite-contacts-subtitle-font-family'),\n fontSize: getBlockThemeValue('--vrtx-invite-contacts-subtitle-font-size'),\n };\n\n // Title styles from block.theme.options (microTheme) - for \"Invite your contacts\" text\n const titleStyles = {\n color: getBlockThemeValue('--vrtx-invite-contacts-title-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-invite-contacts-title-font-family'),\n fontSize: getBlockThemeValue('--vrtx-invite-contacts-title-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-invite-contacts-title-font-weight'),\n };\n\n // Handle navigation to contacts list\n const handleNavigateToContacts = useCallback(async () => {\n await triggerHaptic?.('light');\n setShowContactsList(true);\n inviteContactsConfig?.onNavigateToContacts?.();\n }, [triggerHaptic, inviteContactsConfig]);\n\n // Handle navigation back from contacts list\n const handleNavigateBack = useCallback(async () => {\n await triggerHaptic?.('light');\n setShowContactsList(false);\n setSearchQuery('');\n inviteContactsConfig?.onNavigateBack?.();\n }, [triggerHaptic, inviteContactsConfig]);\n\n // Handle Invite button press\n const handleInvite = useCallback(\n async (contact: InviteContactsContact) => {\n setActionInProgress(contact.id);\n await triggerHaptic?.('light');\n\n try {\n // Create SMS invitation and get short link\n let shortLink: string | null = null;\n if (createSmsInvitation) {\n shortLink = await createSmsInvitation(contact.phoneNumber, contact.name);\n }\n\n if (shortLink) {\n // Replace {{link}} placeholder with actual link\n const message = smsMessage.replace('{{link}}', shortLink);\n\n // Open SMS app with pre-filled message\n const smsUrl = Platform.select({\n ios: `sms:${contact.phoneNumber}&body=${encodeURIComponent(message)}`,\n android: `sms:${contact.phoneNumber}?body=${encodeURIComponent(message)}`,\n default: `sms:${contact.phoneNumber}?body=${encodeURIComponent(message)}`,\n });\n\n await Linking.openURL(smsUrl);\n\n // Mark contact as invited\n setInvitedContacts((prev) => new Set(prev).add(contact.id));\n\n // Call optional callback for custom handling\n await inviteContactsConfig?.onInvite?.(contact, shortLink);\n\n // Notify other components that an invitation was created (for refresh)\n inviteContactsConfig?.onInvitationCreated?.(contact, shortLink);\n } else {\n console.warn('[VrtxInviteContacts] Failed to create SMS invitation - no short link returned');\n }\n } catch (err) {\n console.error('[VrtxInviteContacts] Invite failed:', err);\n } finally {\n setActionInProgress(null);\n }\n },\n [createSmsInvitation, triggerHaptic, inviteContactsConfig, smsMessage]\n );\n\n // Render avatar or initials\n const renderAvatar = (contact: InviteContactsContact) => {\n if (contact.avatarUrl) {\n return <Image source={{ uri: contact.avatarUrl }} style={styles.avatar} />;\n }\n\n // Generate initials from name\n const initials = contact.name\n .split(' ')\n .map((part) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n // Handle avatar background with gradient support\n const avatarBackground = avatarStyles.background;\n const isAvatarGradient = avatarBackground?.includes('linear-gradient');\n const avatarBgStyle: any = {};\n\n if (isWeb && avatarBackground) {\n avatarBgStyle.background = avatarBackground;\n } else if (isAvatarGradient && avatarBackground) {\n const fallbackColor = parseGradientFirstColor(avatarBackground);\n avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;\n }\n\n return (\n <View style={[styles.avatarPlaceholder, avatarBgStyle]}>\n <Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</Text>\n </View>\n );\n };\n\n // Helper to parse CSS padding string to React Native padding object\n const parsePadding = (paddingStr: string | undefined) => {\n if (!paddingStr) return {};\n const parts = paddingStr.trim().split(/\\s+/);\n if (parts.length === 1) {\n const val = parseInt(parts[0], 10);\n return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };\n }\n if (parts.length === 2) {\n const vertical = parseInt(parts[0], 10);\n const horizontal = parseInt(parts[1], 10);\n return {\n ...(isNaN(vertical) ? {} : { paddingVertical: vertical }),\n ...(isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }),\n };\n }\n return {};\n };\n\n // Helper to parse border string (e.g., \"1px solid #ccc\")\n const parseBorder = (borderStr: string | undefined) => {\n if (!borderStr) return {};\n const match = borderStr.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n return {\n borderWidth: parseInt(match[1], 10),\n borderColor: match[3],\n };\n }\n return {};\n };\n\n // Render a single contact item\n const renderContactItem = ({ item }: { item: InviteContactsContact }) => {\n const isLoading = actionInProgress === item.id;\n const isInvited = invitedContacts.has(item.id);\n\n // Build dynamic button style\n const backgroundValue = inviteButtonStyles.background;\n const isGradient = backgroundValue?.includes('linear-gradient');\n\n const dynamicButtonStyle: any = {\n ...(inviteButtonStyles.borderRadius ? { borderRadius: parseInt(inviteButtonStyles.borderRadius, 10) } : {}),\n ...parsePadding(inviteButtonStyles.padding),\n ...parseBorder(inviteButtonStyles.border),\n };\n\n if (isWeb && backgroundValue) {\n dynamicButtonStyle.background = backgroundValue;\n } else if (isGradient && backgroundValue) {\n const fallbackColor = parseGradientFirstColor(backgroundValue);\n dynamicButtonStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n dynamicButtonStyle.backgroundColor = backgroundValue || colors.primaryBackground;\n }\n\n // Build dynamic text style\n const dynamicTextStyle: any = {\n color: inviteButtonStyles.color,\n ...(inviteButtonStyles.fontSize ? { fontSize: parseInt(inviteButtonStyles.fontSize, 10) } : {}),\n ...(inviteButtonStyles.fontWeight ? { fontWeight: inviteButtonStyles.fontWeight } : {}),\n };\n\n // Build dynamic contact name style\n const dynamicNameStyle: any = {\n color: contactNameStyles.color,\n ...(contactNameStyles.fontFamily ? { fontFamily: contactNameStyles.fontFamily } : {}),\n ...(contactNameStyles.fontSize ? { fontSize: parseInt(contactNameStyles.fontSize, 10) } : {}),\n ...(contactNameStyles.fontWeight ? { fontWeight: contactNameStyles.fontWeight } : {}),\n };\n\n // Build dynamic contact phone style\n const dynamicPhoneStyle: any = {\n color: contactPhoneStyles.color,\n ...(contactPhoneStyles.fontFamily ? { fontFamily: contactPhoneStyles.fontFamily } : {}),\n ...(contactPhoneStyles.fontSize ? { fontSize: parseInt(contactPhoneStyles.fontSize, 10) } : {}),\n };\n\n return (\n <View style={styles.contactItem}>\n {renderAvatar(item)}\n <View style={styles.contactInfo}>\n <Text style={[styles.contactName, dynamicNameStyle]} numberOfLines={1}>\n {item.name}\n </Text>\n <Text style={[styles.contactPhone, dynamicPhoneStyle]} numberOfLines={1}>\n {item.phoneNumber}\n </Text>\n </View>\n <ButtonWrapper\n style={[\n styles.actionButton,\n dynamicButtonStyle,\n isInvited && styles.actionButtonInvited,\n ]}\n gradientString={inviteButtonStyles.background?.includes('gradient') ? inviteButtonStyles.background : null}\n onPress={() => handleInvite(item)}\n disabled={isLoading}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={inviteButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, dynamicTextStyle]}>\n {isInvited ? '✓' : inviteButtonText}\n </Text>\n )}\n </ButtonWrapper>\n </View>\n );\n };\n\n // Render the \"Invite your contacts\" entry row\n const renderInviteContactsEntry = () => {\n // Build dynamic title style\n const dynamicTitleStyle: any = {\n color: titleStyles.color,\n ...(titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {}),\n ...(titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {}),\n ...(titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}),\n };\n\n return (\n <TouchableOpacity\n style={styles.inviteContactsEntry}\n onPress={handleNavigateToContacts}\n activeOpacity={0.7}\n >\n <View style={styles.inviteContactsEntryContent}>\n <Text style={[styles.inviteContactsEntryText, dynamicTitleStyle]}>\n {inviteYourContactsText}\n </Text>\n </View>\n <Text style={[styles.chevronIcon, dynamicTitleStyle]}>›</Text>\n </TouchableOpacity>\n );\n };\n\n // Render the back header for contacts list\n const renderContactsHeader = () => {\n return (\n <View>\n <TouchableOpacity\n style={styles.backHeader}\n onPress={handleNavigateBack}\n activeOpacity={0.7}\n >\n <Text style={[styles.backChevron, { color: colors.secondaryForeground }]}>‹</Text>\n <Text style={[styles.backText, { color: colors.foreground }]}>Back</Text>\n </TouchableOpacity>\n <View style={[styles.searchContainer, { borderColor: colors.border }]}>\n <TextInput\n style={[styles.searchInput, { color: colors.foreground }]}\n placeholder=\"Search contacts...\"\n placeholderTextColor={colors.secondaryForeground}\n value={searchQuery}\n onChangeText={setSearchQuery}\n autoCapitalize=\"none\"\n autoCorrect={false}\n />\n </View>\n </View>\n );\n };\n\n // If no contacts provided or empty list, render nothing (no height)\n if (!inviteContactsConfig || contacts.length === 0) {\n return null;\n }\n\n // Contacts list view\n // Note: Using View + map instead of FlatList to avoid \"VirtualizedLists should never be nested\" warning\n // when this component is rendered inside a ScrollView (which InviteFormCore uses)\n if (showContactsList) {\n return (\n <View style={styles.listContainer}>\n {renderContactsHeader()}\n <View style={styles.listContent}>\n {filteredContacts.length === 0 ? (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: colors.secondaryForeground }]}>\n {searchQuery ? 'No contacts match your search' : emptyStateMessage}\n </Text>\n </View>\n ) : (\n filteredContacts.map((item) => (\n <View key={item.id}>\n {renderContactItem({ item })}\n </View>\n ))\n )}\n </View>\n </View>\n );\n }\n\n // Main view: \"Invite your contacts\" entry\n return (\n <View style={styles.entryContainer}>\n {renderInviteContactsEntry()}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n entryContainer: {\n // No padding - let the entry take minimal space\n },\n listContainer: {\n flex: 1,\n },\n emptyContainer: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n },\n emptyText: {\n fontSize: 14,\n textAlign: 'center',\n },\n listContent: {\n paddingBottom: 16,\n },\n contactItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n avatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n avatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n },\n contactInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n contactName: {\n fontSize: 16,\n fontWeight: '500',\n },\n contactPhone: {\n fontSize: 13,\n marginTop: 2,\n },\n actionButton: {\n paddingHorizontal: 16,\n paddingVertical: 8,\n borderRadius: 8,\n minWidth: 80,\n alignItems: 'center',\n justifyContent: 'center',\n },\n actionButtonInvited: {\n opacity: 0.7,\n },\n actionButtonText: {\n fontSize: 14,\n fontWeight: '600',\n },\n // \"Invite your contacts\" entry styles\n inviteContactsEntry: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingVertical: 16,\n },\n inviteContactsEntryContent: {\n flexDirection: 'row',\n alignItems: 'center',\n flex: 1,\n },\n inviteContactsEntryText: {\n fontSize: 16,\n fontWeight: '500',\n },\n inviteContactsEntryCount: {\n fontSize: 14,\n marginLeft: 8,\n opacity: 0.7,\n },\n inviteContactsEntryCountSpacing: {\n marginLeft: 8,\n },\n chevronIcon: {\n fontSize: 24,\n fontWeight: '300',\n marginLeft: 8,\n opacity: 0.75,\n },\n // Back header styles\n backHeader: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n marginBottom: 8,\n },\n backChevron: {\n fontSize: 24,\n fontWeight: '300',\n marginRight: 4,\n },\n backText: {\n fontSize: 16,\n fontWeight: '500',\n },\n // Search box styles\n searchContainer: {\n borderWidth: 1,\n borderRadius: 8,\n marginBottom: 12,\n },\n searchInput: {\n paddingHorizontal: 12,\n paddingVertical: 10,\n fontSize: 16,\n },\n});\n","import React from 'react';\nimport { View, Text, StyleSheet, Platform } from 'react-native';\n\nconst isWeb = Platform.OS === 'web';\n\nexport interface VrtxHeadingProps {\n block: any;\n}\n\n/**\n * Process text gradients for headings\n * Converts gradient color values to background-clip: text style (web only)\n */\nfunction processTextGradient(style: any) {\n if (!style) return style;\n\n const processedStyle = { ...style };\n const colorValue = processedStyle.color as string | undefined;\n\n // Handle text gradients on web\n if (isWeb && colorValue && typeof colorValue === 'string' && colorValue.includes('linear-gradient')) {\n // Use backgroundImage instead of background to avoid resetting backgroundClip\n processedStyle.backgroundImage = colorValue;\n processedStyle.backgroundColor = 'transparent'; // Ensure solid background doesn't interfere\n processedStyle.WebkitBackgroundClip = 'text';\n processedStyle.backgroundClip = 'text';\n processedStyle.WebkitTextFillColor = 'transparent';\n processedStyle.color = 'transparent'; // Fallback\n // Always set display to inline-block for gradients to render properly\n processedStyle.display = 'inline-block';\n }\n\n return processedStyle;\n}\n\nexport function VrtxHeading({ block }: VrtxHeadingProps) {\n const overrideTagName = block.settings?.overrideTagName || 'h1';\n const textContent = block.textContent || '';\n\n // Map heading levels to font sizes and weights\n const headingStyles: Record<string, any> = {\n h1: { fontSize: 24, fontWeight: '700', marginBottom: 16 },\n h2: { fontSize: 20, fontWeight: '700', marginBottom: 14 },\n h3: { fontSize: 18, fontWeight: '600', marginBottom: 12 },\n h4: { fontSize: 16, fontWeight: '600', marginBottom: 10 },\n h5: { fontSize: 14, fontWeight: '600', marginBottom: 8 },\n h6: { fontSize: 12, fontWeight: '600', marginBottom: 8 },\n };\n\n const headingStyle = headingStyles[overrideTagName] || headingStyles.h1;\n\n // Process gradient styles\n const processedBlockStyle = processTextGradient(block.style);\n\n return (\n <View key={block.id}>\n <Text style={[headingStyle, processedBlockStyle || {}]}>{textContent}</Text>\n </View>\n );\n}\n\n// const styles = StyleSheet.create({\n// heading: {\n// color: '#000',\n// },\n// });\n","import React, { useRef, useEffect, useCallback } from 'react';\nimport { View, Text, StyleSheet, Platform } from 'react-native';\n\nconst isWeb = Platform.OS === 'web';\n\nexport interface VrtxTextProps {\n block: any;\n isEditMode?: boolean;\n onUpdate?: (blockId: string, updates: any) => void;\n}\n\nconst VrtxTextComponent = ({ block, isEditMode = false, onUpdate }: VrtxTextProps) => {\n // Strip HTML tags to get plain text\n const stripHtml = (html: string) => {\n if (!html) return '';\n const tmp = document.createElement('div');\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || '';\n };\n\n // Process styles for text gradients\n const processTextGradient = (style: any) => {\n if (!style) return style;\n\n const processedStyle = { ...style };\n const colorValue = processedStyle.color as string | undefined;\n\n // Handle text gradients on web\n if (isWeb && colorValue && typeof colorValue === 'string' && colorValue.includes('linear-gradient')) {\n // Use backgroundImage instead of background to avoid resetting backgroundClip\n processedStyle.backgroundImage = colorValue;\n processedStyle.backgroundColor = 'transparent'; // Ensure solid background doesn't interfere\n processedStyle.WebkitBackgroundClip = 'text';\n processedStyle.backgroundClip = 'text';\n processedStyle.WebkitTextFillColor = 'transparent';\n processedStyle.color = 'transparent'; // Fallback\n // Always set display to inline-block for gradients to render properly\n processedStyle.display = 'inline-block';\n }\n\n return processedStyle;\n };\n\n const textContent = isWeb ? stripHtml(block.textContent || '') : block.textContent || '';\n const divRef = useRef<HTMLDivElement | null>(null);\n const blockIdRef = useRef<string>(block.id);\n const updateTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const onUpdateRef = useRef(onUpdate);\n const initializedRef = useRef(false);\n\n // Keep onUpdateRef in sync with latest onUpdate\n useEffect(() => {\n onUpdateRef.current = onUpdate;\n }, [onUpdate]);\n\n // Initialize content ONCE using ref callback instead of useEffect\n const refCallback = useCallback(\n (element: HTMLDivElement | null) => {\n if (!element || !isWeb || !isEditMode) return;\n\n // Store ref\n divRef.current = element;\n\n // Only initialize once or when block ID changes\n if (!initializedRef.current || blockIdRef.current !== block.id) {\n console.log('🆕 Initializing contentEditable with:', block.textContent);\n element.innerHTML = block.textContent || '';\n blockIdRef.current = block.id;\n initializedRef.current = true;\n }\n },\n [block.id, block.textContent, isWeb, isEditMode]\n );\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (updateTimeoutRef.current) {\n clearTimeout(updateTimeoutRef.current);\n updateTimeoutRef.current = null;\n }\n };\n }, []);\n\n // On web + edit mode, use contentEditable div\n if (isWeb && isEditMode) {\n return (\n <View>\n <div\n key={`editable-${block.id}`}\n ref={refCallback}\n contentEditable\n suppressContentEditableWarning\n data-block-id={block.id}\n data-text-editable=\"true\"\n onInput={(e: any) => {\n // Debounced auto-save on input\n if (updateTimeoutRef.current) {\n clearTimeout(updateTimeoutRef.current);\n }\n\n const newHtml = e.currentTarget.innerHTML || '';\n console.log('⌨️ Input changed:', newHtml);\n\n // Save after 1 second of no typing\n updateTimeoutRef.current = setTimeout(() => {\n console.log('💾 Auto-saving:', newHtml);\n onUpdateRef.current?.(block.id, {\n textContent: newHtml,\n });\n }, 1000);\n }}\n style={{\n outline: 'none',\n cursor: 'text',\n minHeight: '1em',\n whiteSpace: 'pre-wrap',\n ...processTextGradient(block.style),\n }}\n />\n </View>\n );\n }\n\n // Native rendering or web non-edit mode\n return (\n <View>\n <Text style={[styles.text, block.style ? processTextGradient(block.style) : {}]}>{textContent}</Text>\n </View>\n );\n};\n\n// Memo with custom comparison to prevent re-renders when block reference changes but content is the same\nexport const VrtxText = React.memo(VrtxTextComponent, (prevProps, nextProps) => {\n const sameBlock = prevProps.block.id === nextProps.block.id;\n const sameEditMode = prevProps.isEditMode === nextProps.isEditMode;\n const sameOnUpdate = prevProps.onUpdate === nextProps.onUpdate;\n\n // In edit mode, IGNORE textContent changes in block prop\n // The DOM contentEditable is the source of truth, not the Redux state\n // We only care if the block ID changes (switching to a different block)\n const shouldNotRerender = sameBlock && sameEditMode && sameOnUpdate;\n\n return shouldNotRerender;\n});\n\nconst styles = StyleSheet.create({\n text: {\n fontSize: 14,\n lineHeight: 20,\n color: '#000',\n },\n});\n","import React from 'react';\nimport { View, Text, StyleSheet } from 'react-native';\n\nexport interface VrtxSelectProps {\n block: any;\n}\n\nexport function VrtxSelect({ block }: VrtxSelectProps) {\n // Simple select - would need proper state management for production\n return (\n <View key={block.id} style={styles.section}>\n <Text style={styles.subtitle}>{block.attributes?.label || 'Select an option'}</Text>\n {/* Placeholder - would render actual select component */}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n section: {\n marginBottom: 24,\n },\n subtitle: {\n fontSize: 16,\n color: '#666',\n marginBottom: 16,\n },\n});\n","import React from 'react';\nimport { View, Text, TouchableOpacity, ActivityIndicator, StyleSheet, ViewStyle, Platform } from 'react-native';\nimport type { ViewType } from '../hooks/useInvitationFormLogic';\nimport { useVortexModules } from '../context/VortexModulesContext';\n\nconst isWeb = Platform.OS === 'web';\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nconst ButtonWrapper: React.FC<ButtonWrapperProps> = ({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}) => {\n // Get the gradient module and loaders from context\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n};\n\nexport interface VrtxSubmitProps {\n block: any;\n view: ViewType;\n handleSendInvitation: () => Promise<void>;\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n loadingEmailInvite: boolean;\n sendSuccess: boolean;\n /** Number of emails currently in the pill list (for singular/plural button label) */\n emailCount?: number;\n /** Mobile-specific customizations from the vrtx-email-invitations block */\n emailBlockCustomizations?: Record<string, any>;\n /** Style from the email invitations block (to match \"Add by Email\" button appearance) */\n emailBlockStyle?: Record<string, any>;\n}\n\nexport function VrtxSubmit({\n block,\n view,\n handleSendInvitation,\n triggerHaptic,\n loadingEmailInvite,\n sendSuccess,\n emailCount = 0,\n emailBlockCustomizations,\n emailBlockStyle,\n}: VrtxSubmitProps) {\n // Get loaders from context\n const { loaders } = useVortexModules();\n\n if (view !== 'email') return null;\n\n const handleSendInvitationWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleSendInvitation();\n };\n\n // Use email block style to match the \"Add by Email\" button appearance\n // Fall back to submit block's own style if no email block style provided\n const effectiveStyle = emailBlockStyle && Object.keys(emailBlockStyle).length > 0\n ? emailBlockStyle\n : (block?.style || {});\n\n // Extract gradient string and fallback color\n // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'\n const rawBackground = effectiveStyle.background || null;\n const isGradient = rawBackground?.includes('gradient');\n const gradientString = isGradient ? rawBackground : null;\n const fallbackColor = isGradient\n ? loaders?.parseGradientFirstColor(rawBackground)\n : rawBackground || effectiveStyle.backgroundColor;\n\n // Extract text color — for email block style, default to dark text like \"Add by Email\" button\n const textColor = effectiveStyle.color || (emailBlockStyle ? '#333' : '#fff');\n\n return (\n <View key={block.id}>\n {sendSuccess ? (\n <View style={styles.successMessageContainer}>\n <Text style={styles.invitedText}>✓ {emailBlockCustomizations?.['mobile.successMessage']?.textContent || 'Invitation sent successfully!'}</Text>\n </View>\n ) : (\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n {\n borderWidth: 1,\n borderColor: '#e0e0e0',\n },\n effectiveStyle,\n fallbackColor ? { backgroundColor: fallbackColor } : undefined,\n ]}\n gradientString={gradientString}\n onPress={handleSendInvitationWithHaptics}\n disabled={loadingEmailInvite}\n >\n {loadingEmailInvite ? (\n <ActivityIndicator size=\"small\" color={textColor} />\n ) : (\n <Text style={[styles.buttonText, { color: textColor }]}>\n {(() => {\n // Mobile-specific labels from vrtx-email-invitations block customizations\n // Defaults match elementRegistry: 'Send Invitation' / 'Send Invitations'\n const singularLabel =\n emailBlockCustomizations?.['mobile.sendButton']?.textContent || 'Send Invitation';\n const pluralLabel =\n emailBlockCustomizations?.['mobile.sendButtonPlural']?.textContent || 'Send Invitations';\n return emailCount > 1 ? pluralLabel : singularLabel;\n })()}\n </Text>\n )}\n </ButtonWrapper>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n successMessageContainer: {\n padding: 16,\n backgroundColor: '#e8f5e9',\n borderRadius: 8,\n alignItems: 'center',\n },\n invitedText: {\n color: '#2e7d32',\n fontSize: 16,\n fontWeight: '600',\n },\n button: {\n paddingVertical: 12,\n paddingHorizontal: 16,\n borderRadius: 8,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n backgroundColor: '#f5f5f5',\n },\n fullButton: {\n width: '100%',\n },\n buttonText: {\n color: '#333',\n fontSize: 16,\n fontWeight: '500',\n },\n});\n","import React, { useState, useCallback } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n FlatList,\n TouchableOpacity,\n ActivityIndicator,\n Image,\n TextInput,\n Platform,\n} from 'react-native';\nimport { FindFriendsContact } from '../types/findFriends';\nimport { SearchBoxConfig } from '../types/searchBox';\nimport type { SimpleAnalyticsEvent } from '../utils/analytics';\nimport type { IconRendererProps } from './InviteFormCore';\n\nconst isWeb = Platform.OS === 'web';\n\n// Parse CSS linear-gradient to extract first color for fallback on native\nfunction parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,8}|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n return match[1].trim();\n }\n\n return null;\n}\n\nexport interface VrtxSearchBoxProps {\n block: any;\n /** Search Box configuration with callbacks */\n searchBoxConfig?: SearchBoxConfig;\n /** Function to create an invitation with internal ID target type */\n createUserIdInvitation?: (userId: string, name?: string, avatarUrl?: string, metadata?: Record<string, unknown>) => Promise<void>;\n /** Trigger haptic feedback */\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n /** Callback to emit analytics events */\n onAnalyticsEvent?: (event: SimpleAnalyticsEvent) => void;\n /** Function to render icons (from InviteFormCore) */\n renderIcon?: (props: IconRendererProps) => React.ReactNode;\n /** Theme colors from widget configuration */\n theme?: {\n primaryBackground?: string;\n primaryForeground?: string;\n secondaryBackground?: string;\n secondaryForeground?: string;\n foreground?: string;\n border?: string;\n };\n}\n\nexport function VrtxSearchBox({\n block,\n searchBoxConfig,\n createUserIdInvitation,\n triggerHaptic,\n onAnalyticsEvent,\n renderIcon,\n theme,\n}: VrtxSearchBoxProps) {\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<FindFriendsContact[] | null>(null);\n const [isSearching, setIsSearching] = useState(false);\n const [actionInProgress, setActionInProgress] = useState<string | null>(null);\n\n // Get title from block title attribute (configured in Styles tab)\n const title = block?.attributes?.title || '';\n\n // Extract customization from block settings (editor) or config props, with defaults\n const blockCustomizations = block?.settings?.customizations;\n const placeholder =\n blockCustomizations?.searchPlaceholder?.textContent ??\n 'Search...';\n const connectButtonText =\n blockCustomizations?.connectButton?.textContent ??\n searchBoxConfig?.connectButtonText ??\n 'Connect';\n const noResultsMessage =\n blockCustomizations?.noResultsMessage?.textContent ??\n searchBoxConfig?.noResultsMessage ??\n 'No results found';\n\n // Helper to get theme option value from block.theme.options\n const getBlockThemeValue = (key: string): string | undefined => {\n const options = block?.theme?.options;\n if (!options || !Array.isArray(options)) return undefined;\n const option = options.find((opt: any) => opt.key === key);\n return option?.value || undefined;\n };\n\n // Theme colors with defaults\n const colors = {\n primaryBackground: theme?.primaryBackground ?? '#6291d5',\n primaryForeground: theme?.primaryForeground ?? '#ffffff',\n secondaryBackground: theme?.secondaryBackground ?? '#ffffff',\n secondaryForeground: theme?.secondaryForeground ?? '#353e5c',\n foreground: theme?.foreground ?? '#334153',\n border: theme?.border ?? '#cccccc',\n };\n\n // Button styles from block.theme.options (microTheme)\n const connectButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-search-box-connect-button-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-search-box-connect-button-color') ||\n colors.primaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-search-box-connect-button-border-radius'),\n border: getBlockThemeValue('--vrtx-search-box-connect-button-border'),\n padding: getBlockThemeValue('--vrtx-search-box-connect-button-padding'),\n fontSize: getBlockThemeValue('--vrtx-search-box-connect-button-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-search-box-connect-button-font-weight'),\n };\n\n // Avatar/initials styles from block.theme.options (microTheme)\n const avatarStyles = {\n background:\n getBlockThemeValue('--vrtx-search-box-avatar-background') || colors.primaryBackground,\n color: getBlockThemeValue('--vrtx-search-box-avatar-color') || colors.primaryForeground,\n };\n\n // Contact name styles from block.theme.options (microTheme)\n const contactNameStyles = {\n color: getBlockThemeValue('--vrtx-search-box-contact-name-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-search-box-contact-name-font-family'),\n fontSize: getBlockThemeValue('--vrtx-search-box-contact-name-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-search-box-contact-name-font-weight'),\n };\n\n // Contact subtitle styles from block.theme.options (microTheme)\n const contactSubtitleStyles = {\n color:\n getBlockThemeValue('--vrtx-search-box-contact-subtitle-color') ||\n colors.secondaryForeground,\n fontFamily: getBlockThemeValue('--vrtx-search-box-contact-subtitle-font-family'),\n fontSize: getBlockThemeValue('--vrtx-search-box-contact-subtitle-font-size'),\n };\n\n // Title styles from block.theme.options (microTheme)\n const titleStyles = {\n color: getBlockThemeValue('--vrtx-search-box-title-color') || colors.foreground,\n fontFamily: getBlockThemeValue('--vrtx-search-box-title-font-family'),\n fontSize: getBlockThemeValue('--vrtx-search-box-title-font-size'),\n fontWeight: getBlockThemeValue('--vrtx-search-box-title-font-weight'),\n };\n\n // Search button styles from block.theme.options (microTheme)\n const searchButtonStyles = {\n background:\n getBlockThemeValue('--vrtx-search-box-search-button-background') ||\n colors.primaryBackground,\n color:\n getBlockThemeValue('--vrtx-search-box-search-button-color') ||\n colors.primaryForeground,\n borderRadius: getBlockThemeValue('--vrtx-search-box-search-button-border-radius'),\n border: getBlockThemeValue('--vrtx-search-box-search-button-border'),\n padding: getBlockThemeValue('--vrtx-search-box-search-button-padding'),\n };\n\n // Handle search button press\n const handleSearch = useCallback(async () => {\n if (!searchBoxConfig?.onSearch || !query.trim()) return;\n\n setIsSearching(true);\n try {\n const searchResults = await searchBoxConfig.onSearch(query.trim());\n setResults(searchResults);\n } catch (err) {\n console.error('[VrtxSearchBox] Search failed:', err);\n setResults([]);\n } finally {\n setIsSearching(false);\n }\n }, [searchBoxConfig, query]);\n\n // Handle Connect button press\n const handleConnect = useCallback(\n async (contact: FindFriendsContact) => {\n if (!searchBoxConfig?.onConnect) return;\n\n setActionInProgress(contact.userId);\n await triggerHaptic?.('light');\n\n try {\n const shouldCreateInvitation = await searchBoxConfig.onConnect(contact);\n\n if (shouldCreateInvitation && createUserIdInvitation) {\n await createUserIdInvitation(contact.userId, contact.name, contact.avatarUrl, contact.metadata);\n searchBoxConfig.onInvitationCreated?.(contact);\n }\n } catch (err) {\n console.error('[VrtxSearchBox] Connect failed:', err);\n searchBoxConfig.onInvitationError?.(\n contact,\n err instanceof Error ? err : new Error(String(err))\n );\n } finally {\n setActionInProgress(null);\n }\n },\n [searchBoxConfig, createUserIdInvitation, triggerHaptic]\n );\n\n // Render avatar or initials\n const renderAvatar = (contact: FindFriendsContact) => {\n if (contact.avatarUrl) {\n return <Image source={{ uri: contact.avatarUrl }} style={styles.avatar} />;\n }\n\n const initials = contact.name\n .split(' ')\n .map((part) => part[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n const avatarBackground = avatarStyles.background;\n const isAvatarGradient = avatarBackground?.includes('linear-gradient');\n const avatarBgStyle: any = {};\n\n if (isWeb && avatarBackground) {\n avatarBgStyle.background = avatarBackground;\n } else if (isAvatarGradient && avatarBackground) {\n const fallbackColor = parseGradientFirstColor(avatarBackground);\n avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;\n }\n\n return (\n <View style={[styles.avatarPlaceholder, avatarBgStyle]}>\n <Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</Text>\n </View>\n );\n };\n\n // Helper to parse CSS padding string to React Native padding object\n const parsePadding = (paddingStr: string | undefined) => {\n if (!paddingStr) return {};\n const parts = paddingStr.trim().split(/\\s+/);\n if (parts.length === 1) {\n const val = parseInt(parts[0], 10);\n return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };\n }\n if (parts.length === 2) {\n const vertical = parseInt(parts[0], 10);\n const horizontal = parseInt(parts[1], 10);\n return {\n ...(isNaN(vertical) ? {} : { paddingVertical: vertical }),\n ...(isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }),\n };\n }\n return {};\n };\n\n // Helper to parse border string (e.g., \"1px solid #ccc\")\n const parseBorder = (borderStr: string | undefined) => {\n if (!borderStr) return {};\n const match = borderStr.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n return {\n borderWidth: parseInt(match[1], 10),\n borderColor: match[3],\n };\n }\n return {};\n };\n\n // Render a single contact item\n const renderContactItem = ({ item }: { item: FindFriendsContact }) => {\n const isLoading = actionInProgress === item.userId;\n\n const backgroundValue = connectButtonStyles.background;\n const isGradient = backgroundValue?.includes('linear-gradient');\n\n const dynamicButtonStyle: any = {\n ...(connectButtonStyles.borderRadius\n ? { borderRadius: parseInt(connectButtonStyles.borderRadius, 10) }\n : {}),\n ...parsePadding(connectButtonStyles.padding),\n ...parseBorder(connectButtonStyles.border),\n };\n\n if (isWeb && backgroundValue) {\n dynamicButtonStyle.background = backgroundValue;\n } else if (isGradient && backgroundValue) {\n const fallbackColor = parseGradientFirstColor(backgroundValue);\n dynamicButtonStyle.backgroundColor = fallbackColor || colors.primaryBackground;\n } else {\n dynamicButtonStyle.backgroundColor = backgroundValue || colors.primaryBackground;\n }\n\n const dynamicTextStyle: any = {\n color: connectButtonStyles.color,\n ...(connectButtonStyles.fontSize\n ? { fontSize: parseInt(connectButtonStyles.fontSize, 10) }\n : {}),\n ...(connectButtonStyles.fontWeight ? { fontWeight: connectButtonStyles.fontWeight } : {}),\n };\n\n const dynamicNameStyle: any = {\n color: contactNameStyles.color,\n ...(contactNameStyles.fontFamily ? { fontFamily: contactNameStyles.fontFamily } : {}),\n ...(contactNameStyles.fontSize\n ? { fontSize: parseInt(contactNameStyles.fontSize, 10) }\n : {}),\n ...(contactNameStyles.fontWeight ? { fontWeight: contactNameStyles.fontWeight } : {}),\n };\n\n const dynamicSubtitleStyle: any = {\n color: contactSubtitleStyles.color,\n ...(contactSubtitleStyles.fontFamily\n ? { fontFamily: contactSubtitleStyles.fontFamily }\n : {}),\n ...(contactSubtitleStyles.fontSize\n ? { fontSize: parseInt(contactSubtitleStyles.fontSize, 10) }\n : {}),\n };\n\n return (\n <View style={styles.contactItem}>\n {renderAvatar(item)}\n <View style={styles.contactInfo}>\n <Text style={[styles.contactName, dynamicNameStyle]} numberOfLines={1}>\n {item.name}\n </Text>\n {item.subtitle && (\n <Text style={[styles.contactSubtitle, dynamicSubtitleStyle]} numberOfLines={1}>\n {item.subtitle}\n </Text>\n )}\n </View>\n <TouchableOpacity\n style={[styles.actionButton, dynamicButtonStyle]}\n onPress={() => handleConnect(item)}\n disabled={isLoading}\n activeOpacity={0.7}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color={connectButtonStyles.color} />\n ) : (\n <Text style={[styles.actionButtonText, dynamicTextStyle]}>{connectButtonText}</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n };\n\n // Build dynamic title style\n const dynamicTitleStyle: any = {\n color: titleStyles.color,\n ...(titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {}),\n ...(titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {}),\n ...(titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}),\n };\n\n // Show placeholder if no config provided\n if (!searchBoxConfig) {\n return (\n <View style={styles.container}>\n {title ? (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n ) : null}\n <Text style={[styles.placeholderText, { color: colors.secondaryForeground }]}>\n Search Box component - provide searchBoxConfig to enable\n </Text>\n </View>\n );\n }\n\n return (\n <View style={styles.listContainer}>\n {title ? (\n <Text style={[styles.title, dynamicTitleStyle]}>{title}</Text>\n ) : null}\n\n {/* Search input row */}\n <View style={styles.searchRow}>\n <View style={[styles.searchContainer, { borderColor: colors.border }]}>\n <TextInput\n style={[styles.searchInput, { color: colors.foreground }]}\n placeholder={placeholder}\n placeholderTextColor={colors.secondaryForeground}\n value={query}\n onChangeText={setQuery}\n onSubmitEditing={handleSearch}\n autoCapitalize=\"none\"\n autoCorrect={false}\n returnKeyType=\"search\"\n />\n </View>\n <TouchableOpacity\n style={[\n styles.searchButton,\n (() => {\n const btnStyle: any = {};\n const bg = searchButtonStyles.background;\n const isGradient = bg?.includes('linear-gradient');\n if (isWeb && bg) {\n btnStyle.background = bg;\n } else if (isGradient && bg) {\n const fallback = parseGradientFirstColor(bg);\n btnStyle.backgroundColor = fallback || colors.primaryBackground;\n } else {\n btnStyle.backgroundColor = bg || colors.primaryBackground;\n }\n if (searchButtonStyles.borderRadius) {\n btnStyle.borderRadius = parseInt(searchButtonStyles.borderRadius, 10);\n }\n if (searchButtonStyles.border) {\n const match = searchButtonStyles.border.match(/^(\\d+)px\\s+(\\w+)\\s+(.+)$/);\n if (match) {\n btnStyle.borderWidth = parseInt(match[1], 10);\n btnStyle.borderColor = match[3];\n }\n }\n if (searchButtonStyles.padding) {\n const val = parseInt(searchButtonStyles.padding, 10);\n if (!isNaN(val)) {\n btnStyle.padding = val;\n }\n }\n return btnStyle;\n })(),\n ]}\n onPress={handleSearch}\n disabled={isSearching || !query.trim()}\n activeOpacity={0.7}\n >\n {isSearching ? (\n <ActivityIndicator size=\"small\" color={searchButtonStyles.color} />\n ) : renderIcon ? (\n renderIcon({ name: 'search', size: 20, color: searchButtonStyles.color || '#ffffff' })\n ) : (\n <View style={styles.searchIconContainer}>\n <View\n style={[\n styles.searchIconCircle,\n {\n borderColor: searchButtonStyles.color || '#ffffff',\n },\n ]}\n />\n <View\n style={[\n styles.searchIconHandle,\n {\n backgroundColor: searchButtonStyles.color || '#ffffff',\n },\n ]}\n />\n </View>\n )}\n </TouchableOpacity>\n </View>\n\n {/* Results */}\n {results !== null && results.length === 0 && !isSearching && (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: colors.secondaryForeground }]}>\n {noResultsMessage}\n </Text>\n </View>\n )}\n\n {results !== null && results.length > 0 && (\n <FlatList\n data={results}\n keyExtractor={(item) => item.userId}\n renderItem={renderContactItem}\n showsVerticalScrollIndicator={false}\n contentContainerStyle={styles.listContent}\n />\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 120,\n },\n listContainer: {\n flex: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: '600',\n marginBottom: 16,\n },\n placeholderText: {\n fontSize: 14,\n textAlign: 'center',\n },\n searchRow: {\n flexDirection: 'row',\n alignItems: 'center',\n marginBottom: 12,\n },\n searchContainer: {\n flex: 1,\n borderWidth: 1,\n borderRadius: 8,\n paddingHorizontal: 12,\n height: 44,\n justifyContent: 'center',\n },\n searchInput: {\n fontSize: 16,\n height: 44,\n },\n searchButton: {\n width: 44,\n height: 44,\n borderRadius: 8,\n marginLeft: 8,\n alignItems: 'center',\n justifyContent: 'center',\n },\n searchIconContainer: {\n width: 20,\n height: 20,\n position: 'relative',\n },\n searchIconCircle: {\n width: 14,\n height: 14,\n borderRadius: 7,\n borderWidth: 2.5,\n position: 'absolute',\n top: 0,\n left: 0,\n },\n searchIconHandle: {\n width: 7,\n height: 2.5,\n borderRadius: 1.25,\n position: 'absolute',\n bottom: 2,\n right: 0,\n transform: [{ rotate: '45deg' }],\n },\n emptyContainer: {\n padding: 16,\n alignItems: 'center',\n justifyContent: 'center',\n },\n emptyText: {\n fontSize: 14,\n textAlign: 'center',\n },\n listContent: {\n paddingBottom: 16,\n },\n contactItem: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: 12,\n },\n avatar: {\n width: 44,\n height: 44,\n borderRadius: 22,\n },\n avatarPlaceholder: {\n width: 44,\n height: 44,\n borderRadius: 22,\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarInitials: {\n fontSize: 16,\n fontWeight: '600',\n },\n contactInfo: {\n flex: 1,\n marginLeft: 12,\n marginRight: 12,\n },\n contactName: {\n fontSize: 16,\n fontWeight: '500',\n },\n contactSubtitle: {\n fontSize: 13,\n marginTop: 2,\n },\n actionButton: {\n paddingHorizontal: 16,\n paddingVertical: 8,\n borderRadius: 8,\n minWidth: 80,\n alignItems: 'center',\n justifyContent: 'center',\n },\n actionButtonText: {\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","import React from 'react';\nimport { Platform } from 'react-native';\n\nconst isWeb = Platform.OS === 'web';\n\ninterface PlacedItemToolbarProps {\n wrapperRef: React.RefObject<HTMLDivElement | null>;\n isSelected: boolean;\n componentId: string;\n componentType: string;\n isRow: boolean;\n nodeSubtype?: string;\n}\n\n/**\n * PlacedItemToolbar - A portal-based toolbar that appears on the right side of selected elements\n * Displays a delete button for removing the element from the page builder\n */\nexport const usePlacedItemToolbar = ({\n wrapperRef,\n isSelected,\n componentId,\n componentType,\n isRow,\n nodeSubtype,\n}: PlacedItemToolbarProps) => {\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n\n React.useEffect(() => {\n if (!isWeb || !isSelected) {\n // Clean up toolbar if it exists\n if (toolbarRef.current && toolbarRef.current.parentNode) {\n toolbarRef.current.parentNode.removeChild(toolbarRef.current);\n toolbarRef.current = null;\n }\n return;\n }\n\n if (!wrapperRef.current) return;\n\n // Find the container using the same logic as margin detectors\n let scrollContainer: HTMLElement | null = null;\n if (isRow) {\n // For rows, find the outermost container with padding\n scrollContainer = wrapperRef.current.parentElement;\n const rowWidth = wrapperRef.current.getBoundingClientRect().width;\n let attempts = 0;\n while (scrollContainer && attempts < 15) {\n const containerWidth = scrollContainer.getBoundingClientRect().width;\n if (containerWidth > rowWidth + 20) {\n break;\n }\n scrollContainer = scrollContainer.parentElement;\n attempts++;\n }\n if (!scrollContainer || scrollContainer.getBoundingClientRect().width <= rowWidth) {\n scrollContainer = wrapperRef.current.parentElement;\n while (scrollContainer?.parentElement) {\n const parent = scrollContainer.parentElement;\n if (\n parent.getBoundingClientRect().width > scrollContainer.getBoundingClientRect().width\n ) {\n scrollContainer = parent;\n } else {\n break;\n }\n }\n }\n }\n\n // Create toolbar element if it doesn't exist\n if (!toolbarRef.current) {\n toolbarRef.current = document.createElement('div');\n document.body.appendChild(toolbarRef.current);\n }\n\n const handleDelete = (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n\n const deleteEvent = new CustomEvent('vortex-delete-component', {\n detail: { id: componentId, type: componentType, subtype: nodeSubtype },\n bubbles: true,\n });\n document.dispatchEvent(deleteEvent);\n };\n\n const updateToolbarPosition = () => {\n if (!wrapperRef.current || !toolbarRef.current) return;\n\n const rect = wrapperRef.current.getBoundingClientRect();\n const toolbar = toolbarRef.current;\n\n // For rows on web, position at extreme right of container\n let leftPos = rect.right + 3;\n if (isRow && scrollContainer) {\n const containerRect = scrollContainer.getBoundingClientRect();\n // Rows...\n leftPos = containerRect.right + 6;\n }\n\n // Update styles\n Object.assign(toolbar.style, {\n position: 'fixed',\n left: `${leftPos}px`,\n top: `${rect.top + rect.height / 2}px`,\n transform: 'translateY(-50%)',\n backgroundColor: '#fff',\n borderRadius: '4px',\n border: '1px solid #1166c2',\n boxShadow: '0px 3px 5px rgba(0, 0, 0, 0.2)',\n display: 'flex',\n flexDirection: 'column',\n zIndex: '1200',\n pointerEvents: 'auto',\n });\n\n // Create delete button if it doesn't exist\n if (toolbar.children.length === 0) {\n const button = document.createElement('button');\n button.title = 'Delete';\n button.innerHTML = `\n <svg focusable=\"false\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" style=\"width: 24px; height: 24px; fill: currentColor;\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6zM8 9h8v10H8zm7.5-5-1-1h-5l-1 1H5v2h14V4z\"></path>\n </svg>\n `;\n Object.assign(button.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#c20a0a',\n fontSize: '20px',\n transition: 'background-color 0.2s',\n });\n\n button.addEventListener('mouseenter', () => {\n button.style.backgroundColor = 'rgba(194, 10, 10, 0.1)';\n });\n button.addEventListener('mouseleave', () => {\n button.style.backgroundColor = 'transparent';\n });\n button.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n e.preventDefault();\n });\n button.addEventListener('click', handleDelete);\n\n toolbar.appendChild(button);\n }\n };\n\n updateToolbarPosition();\n\n window.addEventListener('scroll', updateToolbarPosition, true);\n window.addEventListener('resize', updateToolbarPosition);\n\n return () => {\n window.removeEventListener('scroll', updateToolbarPosition, true);\n window.removeEventListener('resize', updateToolbarPosition);\n if (toolbarRef.current && toolbarRef.current.parentNode) {\n toolbarRef.current.parentNode.removeChild(toolbarRef.current);\n toolbarRef.current = null;\n }\n };\n }, [isSelected, componentId, componentType, isRow, nodeSubtype, wrapperRef]);\n\n return null;\n};\n","import { WidgetConfiguration, UnsignedData } from '@teamvortexsoftware/vortex-types';\nimport { useEffect, useMemo, useState, useCallback, useRef } from 'react';\nimport { Animated, Share, Linking, Platform } from 'react-native';\nimport { extractFeatureFlags, extractThemeColors } from '../utils/themeUtils';\nimport { useThemeStyles } from './useThemeStyles';\nimport { Attributes, VortexActionResult, VortexActionType } from '../vortexInvite';\nimport uuid from 'react-native-uuid';\nimport {\n extractFormConfiguration,\n mergeThemeAndComponentStyles,\n getEmailPlaceholder,\n getSubmitButtonLabel,\n hasGridLayout,\n hasEmailAndShareInSeparateColumns,\n getRoleOptions,\n} from '../utils/formUtils';\nimport { VortexClient, getClientInfo, VortexWidgetError } from '@teamvortexsoftware/vortex-shared-ui';\nimport { configCache } from '../utils/configCache';\nimport { AnalyticsClient, IAnalyticsClient, EventNames, type EventName } from '@teamvortexsoftware/analytics-client';\nimport {\n VortexAnalyticsEvent,\n GroupDTO,\n DEFAULT_ANALYTICS_URL,\n getDeviceInfo,\n extractForeignUserId,\n} from '../utils/analytics';\n\nexport interface UseVortexInviteOptions {\n componentId?: string;\n vortexApiUrl: string;\n isLoading?: boolean;\n jwt?: string;\n user?: string | UnsignedData | undefined;\n onSuccess?: (result: VortexActionResult) => void;\n onError?: (error: Error, type: VortexActionType) => void;\n group?: {\n name: string;\n type: string;\n id?: string;\n groupId?: string;\n };\n groups?: GroupDTO[];\n scope?: string;\n scopeType?: string;\n widgetConfiguration?: WidgetConfiguration; // Accept prefetched configuration\n // Analytics options\n analyticsBaseURL?: string; // Defaults to production collector\n onEvent?: (event: VortexAnalyticsEvent) => void; // Callback for analytics events\n analyticsSegmentation?: Record<string, any>; // Segmentation data for analytics\n // Internationalization\n locale?: string; // Locale code for i18n (e.g., \"es\", \"fr\", \"zh-TW\")\n}\n\nexport function useVortexInvite({\n componentId,\n vortexApiUrl,\n isLoading = false,\n jwt,\n user,\n onSuccess,\n onError,\n group,\n groups,\n scope,\n scopeType,\n widgetConfiguration: initialWidgetConfiguration,\n analyticsBaseURL,\n onEvent,\n analyticsSegmentation,\n locale,\n}: UseVortexInviteOptions) {\n // Check FIRST, before any hooks are called\n if (!componentId) {\n throw Error('[Vortex Invite] componentId is required to fetch configuration');\n }\n\n // Create effective groups with fallback logic: group > scope+scopeType\n const effectiveGroup = useMemo(() => {\n if (group) return group;\n if (scope && scopeType) {\n return { type: scopeType, groupId: scope, name: scope };\n }\n return undefined;\n }, [group, scope, scopeType]);\n // If user is provided, construct the insecure JWT token\n const effectiveJwt = useMemo(() => {\n if (jwt) return jwt;\n if (user) {\n if (typeof user === 'string') {\n return user;\n }\n const payload = { ...user, componentId };\n const jsonString = JSON.stringify(payload);\n const base64Encoded = Buffer.from(jsonString).toString('base64');\n return `raw-data:${base64Encoded}`;\n }\n return undefined;\n }, [jwt, user, componentId]);\n const vortexClient = useMemo(() => {\n const clientInfo = getClientInfo();\n const sessionId = uuid.v4() as string;\n return new VortexClient(vortexApiUrl, clientInfo.name, clientInfo.version, sessionId);\n }, [vortexApiUrl]);\n\n // Initialize from cache first, then fall back to initialWidgetConfiguration prop\n const cachedConfig = configCache.get(componentId);\n const [widgetConfiguration, setWidgetConfiguration] = useState<WidgetConfiguration | undefined>(\n cachedConfig || initialWidgetConfiguration\n );\n const [error, setError] = useState<{ message: string; code?: string; userMessage?: string; developerMessage?: string } | null>(null);\n const [fetching, setFetching] = useState(isLoading);\n const [loading, setLoading] = useState(!cachedConfig && !initialWidgetConfiguration); // Start as false if we have cached or prefetched config\n const [email, setEmail] = useState('');\n const [shareableLink, setShareableLink] = useState<string>();\n const [role, setRole] = useState<string | undefined>(undefined);\n const [inviteLoading, setInviteLoading] = useState(false);\n const [showSuccessMessage, setShowSuccessMessage] = useState(false);\n const opacity = new Animated.Value(0.3);\n\n // Analytics state\n const [deploymentId, setDeploymentId] = useState<string | null>(null);\n const [sessionId] = useState(() => uuid.v4() as string);\n const [widgetRenderTracked, setWidgetRenderTracked] = useState(false);\n const [formRenderTime, setFormRenderTime] = useState<number | null>(null);\n // Track when config has been fetched through VortexClient (which sets sessionAttestation)\n const [configFetchedViaClient, setConfigFetchedViaClient] = useState(false);\n\n // Create analytics client (memoized to avoid recreation)\n const analyticsClient = useMemo<IAnalyticsClient | null>(() => {\n if (!effectiveJwt) return null;\n const analyticsUrl = analyticsBaseURL || DEFAULT_ANALYTICS_URL;\n const clientInfo = getClientInfo();\n return new AnalyticsClient(analyticsUrl, effectiveJwt, sessionId, clientInfo.name, clientInfo.version);\n }, [effectiveJwt, analyticsBaseURL, sessionId]);\n\n // Compute effective groups for analytics\n const effectiveGroups = useMemo<GroupDTO[] | undefined>(() => {\n if (groups && groups.length > 0) return groups;\n if (effectiveGroup) {\n return [{\n type: effectiveGroup.type,\n id: effectiveGroup.groupId || effectiveGroup.id || '',\n name: effectiveGroup.name,\n }];\n }\n return undefined;\n }, [groups, effectiveGroup]);\n\n // Core event tracking function\n const trackEvent = useCallback(\n async (name: EventName, payload?: Record<string, any>) => {\n const event: VortexAnalyticsEvent = {\n name,\n widgetConfigurationId: widgetConfiguration?.id || '',\n deploymentId: deploymentId || '',\n environmentId: '', // Not currently used (matches web SDK)\n platform: Platform.OS, // 'ios' or 'android'\n timestamp: Math.floor(Date.now() / 1000), // Unix seconds\n sessionId,\n useragent: getDeviceInfo(),\n foreignUserId: extractForeignUserId(effectiveJwt),\n segmentation: analyticsSegmentation,\n payload,\n groups: effectiveGroups,\n };\n\n // Call user's onEvent callback\n if (onEvent) {\n onEvent(event);\n }\n\n // Send to analytics backend (fire-and-forget, non-blocking)\n if (analyticsClient && deploymentId && widgetConfiguration) {\n analyticsClient.track(event).catch(() => {\n // Silently ignore errors - analytics should never impact user experience\n });\n }\n },\n [\n widgetConfiguration,\n deploymentId,\n sessionId,\n effectiveJwt,\n analyticsSegmentation,\n effectiveGroups,\n onEvent,\n analyticsClient,\n ]\n );\n\n // Track widget render once per hook instance (on initial render only)\n // The flag resets when component unmounts, so remounting fires a new event (expected behavior)\n const trackWidgetRender = useCallback(() => {\n if (widgetRenderTracked) return;\n \n setWidgetRenderTracked(true);\n setFormRenderTime(Date.now());\n trackEvent(EventNames.INVITE_FORM_RENDER_SUCCEEDED);\n }, [widgetRenderTracked, trackEvent]);\n\n // Track widget error\n const trackWidgetError = useCallback(\n (errorMessage: string) => {\n trackEvent(EventNames.INVITE_FORM_RENDER_FAILED, { error: errorMessage });\n },\n [trackEvent]\n );\n\n // Track share link clicks\n const trackShareLinkClick = useCallback(\n (clickName: string) => {\n trackEvent(EventNames.SHARING_DESTINATION_BUTTON_CLICKED, { clickName });\n },\n [trackEvent]\n );\n\n // Track email field focus\n const trackEmailFieldFocus = useCallback(() => {\n const timestamp = formRenderTime ? Date.now() - formRenderTime : 0;\n trackEvent(EventNames.EMAIL_FIELD_FOCUSSED, { timestamp });\n }, [formRenderTime, trackEvent]);\n\n // Track email field blur\n const trackEmailFieldBlur = useCallback(() => {\n const timestamp = formRenderTime ? Date.now() - formRenderTime : 0;\n trackEvent(EventNames.EMAIL_FIELD_BLURRED, { timestamp });\n }, [formRenderTime, trackEvent]);\n\n // Track email validation\n const trackEmailValidation = useCallback(\n (emailValue: string, isValid: boolean) => {\n trackEvent(EventNames.EMAIL_SUBMISSION_VALIDATED, { email: emailValue, isValid });\n },\n [trackEvent]\n );\n\n // Track form submission\n const trackEmailInvitationsSubmitted = useCallback(\n (formData: Record<string, any>) => {\n trackEvent(EventNames.EMAIL_FIELD_SUBMISSION_SUCCEEDED, { formData });\n },\n [trackEvent]\n );\n\n // Track email validation error (now uses WIDGET_EMAIL_VALIDATION with error payload)\n const trackEmailValidationError = useCallback(\n (formData: Record<string, any>) => {\n trackEvent(EventNames.EMAIL_SUBMISSION_VALIDATED, { formData, hasError: true });\n },\n [trackEvent]\n );\n\n // Track email submit error\n const trackEmailSubmitError = useCallback(\n (errorMessage: string) => {\n trackEvent(EventNames.EMAIL_FIELD_SUBMISSION_FAILED, { error: errorMessage });\n },\n [trackEvent]\n );\n\n // Extract theme colors and feature flags using utility functions\n const themeColors = useMemo(() => extractThemeColors(widgetConfiguration), [widgetConfiguration]);\n\n // Extract form configuration\n const formConfig = useMemo(\n () => extractFormConfiguration(widgetConfiguration),\n [widgetConfiguration]\n );\n\n // Get base theme styles\n const baseThemeStyles = useThemeStyles(themeColors);\n\n // Merge theme styles with component-specific styles from form configuration\n const themeStyles = useMemo(\n () => mergeThemeAndComponentStyles(baseThemeStyles, themeColors, formConfig),\n [baseThemeStyles, themeColors, formConfig]\n );\n\n const options = useMemo(() => {\n return widgetConfiguration?.configuration?.props || {};\n }, [widgetConfiguration]);\n\n // Extract form layout information\n const formLayout = useMemo(\n () => ({\n emailPlaceholder: getEmailPlaceholder(formConfig),\n submitButtonLabel: getSubmitButtonLabel(formConfig),\n isGridLayout: hasGridLayout(formConfig),\n hasSeparateColumns: hasEmailAndShareInSeparateColumns(formConfig),\n formConfig,\n }),\n [formConfig]\n );\n\n // Extract role options and initialize default role\n const roleOptions = useMemo(() => getRoleOptions(formConfig), [formConfig]);\n useEffect(() => {\n if (!role && roleOptions.length > 0) {\n setRole(roleOptions[0]?.value);\n }\n }, [role, roleOptions]);\n\n const has = useMemo(() => {\n const flags = extractFeatureFlags(widgetConfiguration);\n console.log('[Vortex] Invite has', flags);\n return flags;\n }, [widgetConfiguration]);\n\n // Log the host only once when the hook mounts\n useEffect(() => {\n if (vortexApiUrl.indexOf('localhost') > -1) {\n console.warn('[Vortex] Invite Using localhost as host');\n }\n }, [vortexApiUrl]);\n\n // Loading animation effect (skip if we have prefetched configuration)\n useEffect(() => {\n // If we already have configuration, no need for loading animation\n if (initialWidgetConfiguration) {\n return;\n }\n\n const animation = Animated.loop(\n Animated.sequence([\n Animated.timing(opacity, {\n toValue: 1,\n duration: 1000,\n useNativeDriver: false,\n }),\n Animated.timing(opacity, {\n toValue: 0.3,\n duration: 1000,\n useNativeDriver: false,\n }),\n ])\n );\n animation.start();\n\n setTimeout(() => {\n setLoading(false);\n animation.stop();\n }, 2000);\n }, [opacity, initialWidgetConfiguration]);\n\n // Fetch widget configuration (always fetch to get latest, but don't show loading if we have prefetched data)\n useEffect(() => {\n if (!effectiveJwt) {\n console.log('[Vortex] Invite JWT is required');\n return;\n }\n\n const fetchData = async () => {\n // Only show loading state if we don't have ANY configuration yet\n const shouldShowLoading = !widgetConfiguration;\n\n if (shouldShowLoading) {\n console.log('[Vortex] Invite Fetching Data (first load)...');\n setFetching(true);\n setLoading(true);\n } else {\n console.log('[Vortex] Invite Refreshing configuration in background...');\n }\n \n setError(null);\n\n try {\n const result = await vortexClient.getWidgetConfiguration(componentId, effectiveJwt, undefined, locale);\n\n if (result?.data?.widgetConfiguration) {\n const freshConfig = result.data.widgetConfiguration as unknown as WidgetConfiguration;\n setWidgetConfiguration(freshConfig);\n configCache.set(componentId, freshConfig); // Update shared cache\n \n // Mark that config was fetched via VortexClient (sessionAttestation is now set)\n setConfigFetchedViaClient(true);\n \n // Extract deploymentId from API response (CRITICAL for analytics)\n if (result.data.deploymentId) {\n setDeploymentId(result.data.deploymentId);\n console.log('[Vortex] Invite deploymentId:', result.data.deploymentId);\n }\n \n console.log(\n '[Vortex] Invite Successfully fetched widgetConfiguration',\n JSON.stringify(freshConfig)\n );\n } else {\n const error = 'No configuration data found.';\n console.error(`[Vortex] Invite ${error}`);\n throw new Error(error);\n }\n } catch (err) {\n // Check if this is a VortexWidgetError with structured error information\n if (VortexWidgetError.isVortexWidgetError(err)) {\n console.error('[Vortex] Invite Widget Error:', {\n code: err.code,\n userMessage: err.userMessage,\n developerMessage: err.developerMessage,\n context: err.context,\n statusCode: err.statusCode,\n });\n setError({\n message: err.userMessage || err.message,\n code: err.code,\n userMessage: err.userMessage,\n developerMessage: err.developerMessage,\n });\n } else if (err instanceof Error) {\n const fetchError = err as any;\n console.error('[Vortex] Invite Error Details:', {\n message: fetchError.message,\n status: (fetchError as Record<string, unknown>).status || 'unknown',\n statusText: (fetchError as Record<string, unknown>).statusText,\n body: (fetchError as Record<string, unknown>).body,\n stack: fetchError.stack,\n });\n setError({\n message: (err as Error).message || 'Something went wrong!',\n });\n } else {\n console.error('[Vortex] Invite Error', err);\n setError({\n message: 'Something went wrong!',\n });\n }\n } finally {\n if (shouldShowLoading) {\n setFetching(false);\n setLoading(false);\n }\n }\n };\n\n fetchData();\n }, [componentId, effectiveJwt, vortexClient, locale]); // Removed widgetConfiguration from deps to allow refetch\n\n // Prefetch the shareable invitation link to avoid UI delays when user taps Copy Link or QR Code\n // IMPORTANT: Only prefetch after config has been fetched via VortexClient, which sets sessionAttestation\n useEffect(() => {\n if (widgetConfiguration?.id && effectiveJwt && vortexClient && !shareableLink && configFetchedViaClient) {\n console.log('[Vortex] Prefetching shareable invitation link...');\n getShareableInviteLink().catch((error) => {\n console.warn('[Vortex] Failed to prefetch shareable link:', error);\n // Silent fail - user can still trigger it manually later\n });\n }\n }, [widgetConfiguration?.id, effectiveJwt, vortexClient, shareableLink, configFetchedViaClient]);\n\n const handleInviteClick = async (contentTokens?: Attributes): Promise<void> => {\n try {\n setInviteLoading(true);\n setShowSuccessMessage(false);\n if (!widgetConfiguration?.id) {\n console.log('[Vortex Invite] Widget configuration ID is required');\n return;\n }\n // const url = `${host}/api/v1/no-auth/components/widget-configuration/${widgetConfigurationId}/invite`; // TODO should we use options.widgetHost?.value ?\n console.log('[Vortex] Invite Sending invitation', {\n email,\n componentId,\n });\n if (!effectiveJwt) {\n throw new Error('[Vortex Invite] JWT is required');\n }\n const payload: any = {\n ...contentTokens,\n email: {\n value: email,\n type: 'email',\n },\n };\n if (role) {\n payload.role = {\n value: role,\n type: 'string',\n };\n }\n\n // Use groups parameter instead of adding group to payload\n const groups = effectiveGroup ? [{ type: effectiveGroup.type, id: effectiveGroup.groupId || effectiveGroup.id, name: effectiveGroup.name }] : undefined;\n\n const body = await vortexClient.createInvite(effectiveJwt, widgetConfiguration?.id, payload, 'email', groups);\n console.log('[Vortex] Invite Response', body);\n if (onSuccess) {\n onSuccess({\n type: 'invite',\n data: 'Email invite sent',\n });\n }\n setShowSuccessMessage(true);\n\n // Auto-hide success message after 5 seconds\n setTimeout(() => {\n setShowSuccessMessage(false);\n }, 5000);\n return;\n } catch (error) {\n console.error('[Vortex]', error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)), 'invite');\n }\n throw error; // Re-throw the error to be caught by the component\n } finally {\n setInviteLoading(false);\n }\n };\n\n const getShareableLink = () => {\n return vortexClient.getShareableLinkFormatted();\n };\n\n /**\n * Create an invitation with internal ID target type.\n * Used by Find Friends component when user taps Connect.\n * Matches iOS SDK payload structure: { type: 'internal', value: { value, name, avatarUrl? } }\n */\n const createUserIdInvitation = async (\n userId: string,\n name?: string,\n avatarUrl?: string,\n metadata?: Record<string, unknown>\n ): Promise<void> => {\n if (!effectiveJwt) {\n throw new Error('[Vortex Invite] JWT is required');\n }\n if (!widgetConfiguration?.id) {\n throw new Error('[Vortex Invite] Widget configuration is required');\n }\n\n console.log('[Vortex] Creating user ID invitation', { userId, name, avatarUrl });\n\n // Build the target value object matching iOS SDK structure\n const targetValue: Record<string, string> = {\n value: userId,\n };\n if (name) {\n targetValue.name = name;\n }\n if (avatarUrl) {\n targetValue.avatarUrl = avatarUrl;\n }\n\n const payload = {\n internalId: {\n type: 'internal',\n value: targetValue,\n },\n };\n\n const groups = effectiveGroup\n ? [{ type: effectiveGroup.type, id: effectiveGroup.groupId || effectiveGroup.id, name: effectiveGroup.name }]\n : undefined;\n\n await vortexClient.createInvite(effectiveJwt, widgetConfiguration.id, payload, 'other', groups, undefined, metadata || undefined);\n console.log('[Vortex] Internal ID invitation created successfully');\n };\n\n const handleSmsShare = async () => {\n try {\n const template =\n widgetConfiguration?.configuration?.props?.['vortex.components.share.template.body']?.value;\n if (!template) throw new Error('No template available');\n const shareableLink = await getShareableInviteLink();\n if (!shareableLink) throw new Error('No shareable link available');\n const body = encodeURIComponent(template.replace(/{{vortex_share_link}}/g, shareableLink));\n const smsUrl = `sms:?body=${body}`;\n await Linking.openURL(smsUrl);\n } catch (error) {\n console.error('[Vortex] Failed to open SMS app:', error);\n if (onError) onError(error instanceof Error ? error : new Error(String(error)), 'share');\n }\n };\n\n const handleEmailShare = async () => {\n try {\n const template =\n widgetConfiguration?.configuration?.props?.['vortex.components.share.template.body']?.value;\n if (!template) throw new Error('No template available');\n const subject =\n widgetConfiguration?.configuration?.props?.[\n 'vortex.components.share.template.subject'\n ]?.value?.trim() || \"You're Invited\";\n const shareableLink = await getShareableInviteLink();\n if (!shareableLink) throw new Error('No shareable link available');\n const body = encodeURIComponent(template.replace(/{{vortex_share_link}}/g, shareableLink));\n const mailtoUrl = `mailto:?subject=${encodeURIComponent(subject)}&body=${body}`;\n await Linking.openURL(mailtoUrl);\n } catch (error) {\n console.error('[Vortex] Failed to open Email app:', error);\n if (onError) onError(error instanceof Error ? error : new Error(String(error)), 'share');\n }\n };\n\n const handleWhatsAppShare = async () => {\n try {\n const template =\n widgetConfiguration?.configuration?.props?.['vortex.components.share.template.body']?.value;\n if (!template) throw new Error('No template available');\n const shareableLink = await getShareableInviteLink();\n if (!shareableLink) throw new Error('No shareable link available');\n const message = encodeURIComponent(template.replace(/{{vortex_share_link}}/g, shareableLink));\n const whatsappUrl = `whatsapp://send?text=${message}`;\n await Linking.openURL(whatsappUrl).catch(() => {\n console.warn('WhatsApp not installed');\n });\n } catch (error) {\n console.error('[Vortex] Failed to open WhatsApp:', error);\n if (onError) onError(error instanceof Error ? error : new Error(String(error)), 'share');\n }\n };\n\n const getShareableInviteLink = async (\n contentTokens?: Attributes\n ): Promise<string | undefined> => {\n // if (this.isLoading || !this.vortex) {\n // return;\n // }\n if (!effectiveJwt || !widgetConfiguration?.id || !vortexClient) {\n return;\n }\n if (shareableLink) {\n return shareableLink;\n }\n\n // Use groups parameter for shareable invite as well\n const groups = effectiveGroup ? [{ type: effectiveGroup.type, id: effectiveGroup.groupId || effectiveGroup.id, name: effectiveGroup.name }] : undefined;\n const invite = await vortexClient.createShareableInvite(effectiveJwt, widgetConfiguration.id, groups);\n\n if (\n !invite ||\n !invite.data ||\n !invite.data.invitation.id ||\n !invite.data.invitation.shortLink\n ) {\n console.error('No shareable link found');\n onError?.(new Error('No shareable link found'), 'share');\n // this.error = {\n // message: 'No sharable link found',\n // };\n // this.host.requestUpdate();\n return;\n }\n const link = invite.data.invitation.shortLink;\n setShareableLink(link);\n return link;\n };\n\n const handleShareLink = async () => {\n try {\n const link = await getShareableInviteLink();\n if (!link) {\n throw new Error('No shareable link available');\n }\n\n const template = widgetConfiguration?.configuration?.props?.[\n 'vortex.components.share.template.body'\n ]?.value as string | undefined;\n const subject = (\n widgetConfiguration?.configuration?.props?.['vortex.components.share.template.subject']?.value as\n | string\n | undefined\n )?.trim();\n\n // Compose message\n let message = '';\n if (typeof template === 'string' && template.length > 0) {\n if (template.includes('{{vortex_share_link}}')) {\n message = template.replace(/{{vortex_share_link}}/g, link);\n } else {\n message = `${template}${template.endsWith(' ') ? '' : ' '}${link}`;\n }\n } else {\n message = link;\n }\n\n // Informative log about iOS share sheet branding\n if (Platform.OS === 'ios') {\n console.log(\n '[Vortex] iOS share sheet branding note: The icon/name come from the host app bundle; link preview (if any) is pulled from the shared URL\\'s Open Graph/Twitter meta tags. Customizing the header/logo via RN Share is not supported.'\n );\n }\n\n const content: any = {\n message,\n url: link, // iOS will use this for rich link preview when available\n title: subject || 'Share Invite Link',\n // Some platforms read subject from content\n ...(subject ? { subject } : {}),\n };\n\n const options: any = Platform.select({\n android: {\n dialogTitle: subject || 'Share Invite Link',\n },\n ios: {\n // Older RN versions used options.subject; keep for compatibility\n ...(subject ? { subject } : {}),\n },\n default: {},\n });\n\n await Share.share(content, options);\n\n console.log('[Vortex] handleShareLink', 'The invite link has been shared.');\n onSuccess?.({ type: 'share', data: 'Sharable link used' });\n } catch (error) {\n console.error('[Vortex] Failed to share link:', error);\n onError?.(error instanceof Error ? error : new Error(String(error)), 'share');\n }\n };\n\n const handleCopyLink = async () => {\n try {\n const shareableLink = await getShareableInviteLink();\n if (!shareableLink) {\n throw new Error('No shareable link available');\n }\n \n // Try expo-clipboard first, then @react-native-clipboard/clipboard, then web clipboard\n let copied = false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const expoClipboard = require('expo-clipboard');\n await expoClipboard.setStringAsync(shareableLink);\n copied = true;\n } catch (e) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const rnClipboard = require('@react-native-clipboard/clipboard');\n rnClipboard.default.setString(shareableLink);\n copied = true;\n } catch (e2) {\n // Fall back to web clipboard API\n if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(shareableLink);\n copied = true;\n }\n }\n }\n \n if (!copied) {\n throw new Error('No clipboard implementation available');\n }\n \n console.log('[Vortex] handleCopyLink', 'The invite link has been copied.');\n if (onSuccess) {\n onSuccess({\n type: 'share',\n data: 'Sharable copied',\n });\n }\n } catch (error) {\n console.error('[Vortex] Failed to copy link:', error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)), 'share');\n }\n }\n };\n\n // Contacts import: dynamically use expo-contacts when available (iOS & Android)\n const fetchContactsWithEmailsIOS = async (): Promise<Array<{ id: string; name: string; emails: string[]; imageUri?: string }>> => {\n try {\n let Contacts: any = null;\n try {\n // Dynamic require so the library does not hard depend on expo-contacts\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n Contacts = require('expo-contacts');\n } catch (e) {\n throw new Error('Contacts feature is not available. Please ensure expo-contacts is installed.');\n }\n\n // First check current permission status\n let currentStatus: string | undefined;\n try {\n const currentPerm = await (Contacts.getPermissionsAsync\n ? Contacts.getPermissionsAsync()\n : Contacts.getPermissionAsync?.());\n currentStatus = currentPerm?.status;\n } catch (permErr) {\n console.warn('[Vortex] Failed to check contacts permission:', permErr);\n }\n\n // If already denied, inform user they need to go to Settings\n if (currentStatus === 'denied') {\n throw new Error('Contacts access was denied. Please enable Contacts access in your device Settings to import contacts.');\n }\n\n // Request permission (either undetermined or checking again)\n let status: string | undefined;\n try {\n const perm = await (Contacts.requestPermissionsAsync\n ? Contacts.requestPermissionsAsync()\n : Contacts.requestPermissionAsync?.());\n status = perm?.status;\n } catch (permErr) {\n console.warn('[Vortex] Contacts permission request failed:', permErr);\n throw new Error('Failed to request contacts permission. Please try again.');\n }\n\n if (status === 'denied') {\n throw new Error('Contacts access was denied. Please enable Contacts access in your device Settings to import contacts.');\n }\n\n if (status !== 'granted') {\n throw new Error('Contacts access is required to import contacts.');\n }\n\n // Fetch contacts with emails and images\n const fields = Contacts.Fields\n ? [Contacts.Fields.Emails, Contacts.Fields.Image]\n : ['emails', 'image'];\n const args: any = { fields, pageSize: 500 };\n if (Contacts.SortTypes?.FirstName) {\n args.sort = Contacts.SortTypes.FirstName;\n }\n const result = await Contacts.getContactsAsync(args);\n const data: any[] = result?.data || [];\n if (!Array.isArray(data) || data.length === 0) {\n return [];\n }\n\n const normalizeEmail = (e: any) => e?.email || e?.address || (typeof e === 'string' ? e : undefined);\n const items: Array<{ id: string; name: string; emails: string[]; imageUri?: string }> = [];\n for (const c of data) {\n const emailsSrc = (c?.emails || c?.emailAddresses || []) as any[];\n const emails = emailsSrc.map(normalizeEmail).filter(Boolean) as string[];\n if (emails.length > 0) {\n const name = (c?.name || `${c?.firstName || ''} ${c?.lastName || ''}`)?.trim() || 'Unknown';\n const imageUri = c?.image?.uri || c?.imageAvailable ? c?.image?.uri : undefined;\n items.push({ id: String(c?.id ?? Math.random()), name, emails, imageUri });\n }\n }\n return items;\n } catch (err) {\n // Re-throw errors with messages so UI can display them properly\n if (err instanceof Error) {\n throw err;\n }\n console.error('[Vortex] Failed to fetch contacts:', err);\n throw new Error('An unexpected error occurred while accessing contacts.');\n }\n };\n\n return {\n widgetConfiguration,\n error,\n fetching,\n loading,\n email,\n setEmail,\n role,\n setRole,\n roleOptions,\n opacity,\n themeColors,\n themeStyles,\n has,\n options,\n inviteLoading,\n showSuccessMessage,\n handleInviteClick,\n handleShareLink,\n handleCopyLink,\n handleSmsShare,\n handleEmailShare,\n handleWhatsAppShare,\n getShareableLink,\n getShareableInviteLink,\n createUserIdInvitation,\n formLayout,\n fetchContactsWithEmailsIOS,\n // Analytics tracking functions\n trackWidgetRender,\n trackWidgetError,\n trackShareLinkClick,\n trackEmailFieldFocus,\n trackEmailFieldBlur,\n trackEmailValidation,\n trackEmailInvitationsSubmitted,\n trackEmailValidationError,\n trackEmailSubmitError,\n };\n}\n","import { WidgetConfiguration } from '@teamvortexsoftware/vortex-types';\n\nexport interface ThemeColors {\n containerBackground: string;\n containerForeground: string;\n containerBorder: string;\n primaryButtonBackground: string;\n primaryButtonForeground: string;\n primaryButtonBorder: string;\n secondaryButtonBackground: string;\n secondaryButtonForeground: string;\n secondaryButtonBorder: string;\n}\n\n/**\n * Extracts the color from a CSS border shorthand value (e.g., \"1px solid #c4c4c4\" → \"#c4c4c4\")\n * Returns undefined if the value doesn't match the expected format\n */\nfunction extractBorderColor(borderValue: string | undefined): string | undefined {\n if (!borderValue) return undefined;\n\n const parts = borderValue.trim().split(/\\s+/);\n // Expect exactly 3 parts: width, style, color (e.g., \"1px solid #c4c4c4\")\n if (parts.length === 3) {\n return parts[2];\n }\n\n return undefined;\n}\n\nexport interface FeatureFlags {\n shareableLinks: boolean;\n emailInvitations: boolean;\n shareOptionsCopyLink: boolean;\n shareOptionsSms: boolean;\n shareOptionsEmail: boolean;\n shareOptionsFacebookMessenger: boolean;\n shareOptionsInstagramDms: boolean;\n shareOptionsLinkedInMessaging: boolean;\n shareOptionsTwitterDms: boolean;\n shareOptionsWhatsApp: boolean;\n shareOptionsNativeShareSheet: boolean;\n shareOptionsQrCode: boolean;\n shareOptionsLine: boolean;\n shareEnabled: boolean;\n shareOptionsOrder: string[];\n}\n\n/**\n * Extracts theme colors from widget configuration\n */\nexport function extractThemeColors(widgetConfiguration?: WidgetConfiguration): ThemeColors {\n const props = widgetConfiguration?.configuration?.props as any;\n const themeValue = props?.['vortex.theme']?.value;\n\n // Normalize theme entries to an array of { key, value }\n let entries: Array<{ key?: string; value?: string }> = [];\n if (Array.isArray(themeValue)) {\n entries = themeValue as Array<{ key?: string; value?: string }>;\n } else if (themeValue && Array.isArray(themeValue.options)) {\n entries = themeValue.options as Array<{ key?: string; value?: string }>;\n } else if (themeValue && typeof themeValue === 'object') {\n // Fallback: treat object map as entries if present\n entries = Object.keys(themeValue)\n .filter((k) => k.startsWith('--'))\n .map((k) => ({ key: k, value: String((themeValue as any)[k]) }));\n }\n\n const colorMap: Record<string, string> = {};\n entries.forEach((item: any) => {\n const k = item?.key;\n const v = item?.value;\n if (typeof k === 'string' && typeof v === 'string') {\n colorMap[k] = v;\n }\n });\n\n return {\n containerBackground:\n colorMap['--vrtx-root-background'] || colorMap['--color-background'] || '#ffffff',\n containerForeground:\n colorMap['--vrtx-root-color'] || colorMap['--color-foreground'] || '#666666',\n containerBorder:\n extractBorderColor(colorMap['--vrtx-root-border']) ||\n extractBorderColor(colorMap['--vrtx-input-border']) ||\n colorMap['--color-border'] ||\n '#c4c4c4',\n primaryButtonBackground:\n colorMap['--vrtx-submit-primary-background'] ||\n colorMap['--vrtx-button-primary-background'] ||\n colorMap['--color-primary-background'] ||\n '#197af3',\n primaryButtonForeground:\n colorMap['--vrtx-submit-primary-color'] ||\n colorMap['--color-primary-foreground'] ||\n '#ffffff',\n primaryButtonBorder:\n extractBorderColor(colorMap['--vrtx-submit-primary-border']) ||\n colorMap['--vrtx-submit-primary-border-color'] ||\n colorMap['--vrtx-button-primary-border-color'] ||\n colorMap['--color-primary-border'] ||\n '#000000',\n secondaryButtonBackground:\n colorMap['--vrtx-submit-secondary-background'] ||\n colorMap['--vrtx-button-secondary-background'] ||\n colorMap['--color-secondary-background'] ||\n '#dfdfdf',\n secondaryButtonForeground:\n colorMap['--vrtx-submit-secondary-color'] ||\n colorMap['--vrtx-button-secondary-color'] ||\n colorMap['--color-secondary-foreground'] ||\n '#000000',\n secondaryButtonBorder:\n extractBorderColor(colorMap['--vrtx-submit-secondary-border']) ||\n colorMap['--vrtx-submit-secondary-border-color'] ||\n colorMap['--vrtx-button-secondary-border-color'] ||\n colorMap['--color-secondary-border'] ||\n '#c4c4c4',\n };\n}\n\n/**\n * Extracts feature flags from widget configuration\n */\nexport function extractFeatureFlags(widgetConfiguration?: WidgetConfiguration): FeatureFlags {\n const props = widgetConfiguration?.configuration?.props as any;\n const features: string[] = Array.isArray(props?.['vortex.components']?.value)\n ? props['vortex.components'].value\n : [];\n\n const shareOptions: string[] = Array.isArray(props?.['vortex.components.share.options']?.value)\n ? props['vortex.components.share.options'].value\n : [];\n\n // Detect presence of blocks in the form tree (row/column/block with subtype)\n const formValue = props?.['vortex.components.form']?.value;\n let hasEmailBlock = false;\n let hasShareBlock = false;\n\n const traverse = (node: any) => {\n if (!node) return;\n if (Array.isArray(node)) {\n node.forEach(traverse);\n return;\n }\n if (node.type === 'block') {\n if (node.subtype === 'vrtx-email-invitations') hasEmailBlock = true;\n if (node.subtype === 'vrtx-share-options') hasShareBlock = true;\n }\n if (node.children && node.children.length) {\n node.children.forEach(traverse);\n }\n };\n\n if (formValue?.root) {\n traverse(formValue.root);\n } else if (Array.isArray(formValue)) {\n traverse(formValue);\n }\n\n return {\n // Email invites if feature enabled or email block present\n emailInvitations: features.includes('vortex.components.emailinvitations') || hasEmailBlock,\n // Share section enabled if share block present or explicit feature (if ever provided)\n shareEnabled: hasShareBlock || features.includes('vortex.components.share'),\n shareableLinks: hasShareBlock || features.includes('vortex.components.share'),\n shareOptionsCopyLink: shareOptions.includes('copyLink'),\n shareOptionsFacebookMessenger: shareOptions.includes('facebookMessenger'),\n shareOptionsInstagramDms: shareOptions.includes('instagramDms'),\n shareOptionsLinkedInMessaging: shareOptions.includes('linkedInMessaging'),\n shareOptionsNativeShareSheet: shareOptions.includes('nativeShareSheet'),\n shareOptionsQrCode: shareOptions.includes('qrCode'),\n shareOptionsSms: shareOptions.includes('sms'),\n shareOptionsTwitterDms: shareOptions.includes('twitterDms'),\n shareOptionsEmail: shareOptions.includes('email'),\n shareOptionsWhatsApp: shareOptions.includes('whatsApp'),\n shareOptionsLine: shareOptions.includes('line'),\n shareOptionsOrder: shareOptions,\n } as FeatureFlags;\n}\n","import { useMemo } from \"react\";\nimport { ThemeColors } from \"../utils/themeUtils\";\n\n/**\n * Hook to generate dynamic styles based on theme colors\n * @param themeColors The theme colors object\n * @returns Object containing styled components based on the theme\n */\nexport function useThemeStyles(themeColors: ThemeColors) {\n const themeStyles = useMemo(\n () => ({\n primaryButton: {\n backgroundColor: themeColors.primaryButtonBackground,\n borderColor: themeColors.primaryButtonBorder,\n },\n primaryButtonText: {\n color: themeColors.primaryButtonForeground,\n },\n secondaryButton: {\n backgroundColor: themeColors.secondaryButtonBackground,\n borderColor: themeColors.secondaryButtonBorder,\n },\n secondaryButtonText: {\n color: themeColors.secondaryButtonForeground,\n },\n containerStyles: {\n backgroundColor: themeColors.containerBackground,\n borderColor: themeColors.containerBorder,\n },\n textStyles: {\n color: themeColors.containerForeground,\n },\n inputStyles: {\n borderColor: themeColors.containerBorder,\n color: themeColors.containerForeground,\n backgroundColor: themeColors.containerBackground,\n },\n }),\n [themeColors],\n );\n\n return themeStyles;\n}\n","import { WidgetConfiguration } from '@teamvortexsoftware/vortex-types';\nimport { ThemeColors } from './themeUtils';\n\nexport interface FormComponentStyle {\n [key: string]: {\n label?: string;\n value?: string | number;\n computedValue?: string;\n unit?: string;\n };\n}\n\nexport interface FormComponentSettings {\n action?: {\n type: string;\n value: string;\n target?: string;\n };\n size?: number;\n}\n\nexport interface FormComponent {\n id: string;\n type: string;\n subtype?: string;\n label?: string;\n hint?: string;\n name?: string;\n required?: boolean;\n placeholder?: string;\n style?: FormComponentStyle;\n settings?: FormComponentSettings;\n vortex?: {\n role?: string;\n canRemove?: boolean;\n };\n children?: FormComponent[];\n multiValue?: boolean;\n validation?: Array<{\n type: string;\n value: string;\n operator: string;\n canRemove: boolean;\n errorMessage: string;\n }>;\n tagName?: string;\n textContent?: string;\n attributes?: {\n [key: string]: string;\n };\n}\n\nexport interface FormConfiguration {\n value: FormComponent[];\n valueType: string;\n}\n\n/**\n * Extracts the form configuration from the widget configuration\n */\nexport function extractFormConfiguration(\n widgetConfiguration?: WidgetConfiguration\n): FormComponent[] | null {\n const formValue = widgetConfiguration?.configuration?.props?.['vortex.components.form']\n ?.value as any;\n if (!formValue) {\n return null;\n }\n // Normalize: if the value contains a root node, start traversal from it\n if (formValue.root) {\n return [formValue.root] as unknown as FormComponent[];\n }\n // If it's already an array, return as-is\n if (Array.isArray(formValue)) {\n return formValue as FormComponent[];\n }\n return null;\n}\n\n/**\n * Converts form component style object to React Native styles\n */\nexport function convertFormStyleToRNStyle(\n style?: FormComponentStyle | Record<string, any>\n): Record<string, string | number> {\n if (!style) return {};\n\n const rnStyle: Record<string, string | number> = {};\n\n const toCamel = (s: string) => s.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const parseValue = (val: any): string | number => {\n if (typeof val === 'number') return val;\n if (typeof val !== 'string') return String(val);\n const pxMatch = val.match(/^(-?\\d+(?:\\.\\d+)?)px$/i);\n if (pxMatch) return Number(pxMatch[1]);\n const num = Number(val);\n if (!isNaN(num)) return num;\n return val;\n };\n\n Object.keys(style).forEach((key) => {\n const raw = (style as any)[key];\n const normalizedKey = toCamel(key);\n\n if (raw && typeof raw === 'object' && ('value' in raw || 'computedValue' in raw)) {\n const styleObj = raw as { value?: any; computedValue?: any };\n if (styleObj.computedValue !== undefined) {\n rnStyle[normalizedKey] = parseValue(styleObj.computedValue);\n } else if (styleObj.value !== undefined) {\n rnStyle[normalizedKey] = parseValue(styleObj.value);\n }\n } else {\n rnStyle[normalizedKey] = parseValue(raw);\n }\n });\n\n return rnStyle;\n}\n\n/**\n * Find a specific component by role in the form configuration\n */\nexport function findComponentByRole(\n formConfig: FormComponent[] | null,\n role: string\n): FormComponent | null {\n if (!formConfig) return null;\n\n const findComponent = (components: FormComponent[]): FormComponent | null => {\n for (const component of components) {\n if (component.vortex?.role === role) {\n return component;\n }\n\n if (component.children) {\n const found = findComponent(component.children);\n if (found) return found;\n }\n }\n\n return null;\n };\n\n return findComponent(formConfig);\n}\n\n/**\n * Merges theme styles with component-specific styles from form configuration\n */\nexport function mergeThemeAndComponentStyles(\n themeStyles: Record<string, Record<string, string | number>>,\n themeColors: ThemeColors,\n formConfig: FormComponent[] | null\n): Record<string, Record<string, string | number>> {\n // Start with the base theme styles\n const mergedStyles = { ...themeStyles };\n\n // Helper: find first node by predicate\n const findNode = (\n nodes: FormComponent[] | null | undefined,\n predicate: (n: any) => boolean\n ): any => {\n if (!nodes) return null;\n for (const node of nodes) {\n if (predicate(node)) return node;\n if (node.children?.length) {\n const found = findNode(node.children, predicate);\n if (found) return found;\n }\n }\n return null;\n };\n\n // 1) Merge root container style into containerStyles\n const rootNode = formConfig?.[0];\n if (rootNode?.style) {\n const rootStyle = convertFormStyleToRNStyle(rootNode.style as any);\n // Avoid applying absolute dimensions that can break responsiveness on mobile\n const { width, height, maxWidth, minWidth, maxHeight, minHeight, ...responsiveRoot } =\n rootStyle as any;\n mergedStyles.containerStyles = {\n ...mergedStyles.containerStyles,\n ...responsiveRoot,\n };\n }\n\n // Find submit button and email input components\n const submitButton = findComponentByRole(formConfig, 'submit');\n const emailInput = findComponentByRole(formConfig, 'email');\n\n // 2) Merge submit button styles\n if (submitButton?.style) {\n const submitButtonStyle = convertFormStyleToRNStyle(submitButton.style);\n mergedStyles.primaryButton = {\n ...mergedStyles.primaryButton,\n ...(submitButtonStyle['backgroundColor'] && {\n backgroundColor: submitButtonStyle['backgroundColor'],\n }),\n ...(submitButtonStyle['borderColor'] && { borderColor: submitButtonStyle['borderColor'] }),\n };\n\n // Update button text if there's a color specified\n if (submitButtonStyle['color']) {\n mergedStyles.primaryButtonText = {\n ...mergedStyles.primaryButtonText,\n color: submitButtonStyle['color'],\n };\n }\n }\n\n // 3) Merge email input styles\n if (emailInput?.style) {\n const emailInputStyle = convertFormStyleToRNStyle(emailInput.style);\n mergedStyles.inputStyles = {\n ...mergedStyles.inputStyles,\n ...emailInputStyle,\n };\n }\n\n // 4) Merge vrtx-share-options block theme into secondary buttons\n const shareOptionsBlock = findNode(\n formConfig,\n (n) =>\n n.type === 'block' &&\n (n.subtype === 'vrtx-share-options' || n.tagName === 'vrtx-share-options')\n ) as any;\n const optionEntries: Array<{ key?: string; value?: string }> | undefined =\n shareOptionsBlock?.theme?.options;\n if (Array.isArray(optionEntries)) {\n const map: Record<string, string> = {};\n optionEntries.forEach((it) => {\n if (it?.key && typeof it.value === 'string') map[it.key] = it.value;\n });\n const bg = map['--vrtx-icon-button-background'];\n const color = map['--vrtx-icon-button-color'];\n if (bg) {\n mergedStyles.secondaryButton = {\n ...mergedStyles.secondaryButton,\n backgroundColor: bg,\n };\n }\n if (color) {\n mergedStyles.secondaryButtonText = {\n ...mergedStyles.secondaryButtonText,\n color,\n };\n }\n }\n\n return mergedStyles;\n}\n\n/**\n * Get email input placeholder from form configuration\n */\nexport function getEmailPlaceholder(formConfig: FormComponent[] | null): string {\n const emailInput = findComponentByRole(formConfig, 'email');\n // Prefer attributes.placeholder as per current JSON shape\n const attrPlaceholder = (emailInput as any)?.attributes?.placeholder;\n return attrPlaceholder || emailInput?.placeholder || 'Enter email';\n}\n\n/**\n * Get submit button label from form configuration\n */\nexport function getSubmitButtonLabel(formConfig: FormComponent[] | null): string {\n const submitButton = findComponentByRole(formConfig, 'submit') as any;\n // Prefer textContent per current JSON; fallback to label\n return submitButton?.textContent || submitButton?.label || 'Invite';\n}\n\n/**\n * Determines if the form layout uses a grid structure\n */\nexport function hasGridLayout(formConfig: FormComponent[] | null): boolean {\n if (!formConfig) return false;\n\n const findGrid = (components: FormComponent[]): boolean => {\n for (const component of components) {\n if (component.type === 'grid') {\n return true;\n }\n\n if (component.children) {\n const found = findGrid(component.children);\n if (found) return true;\n }\n }\n\n return false;\n };\n\n return findGrid(formConfig);\n}\n\n/**\n * Determines if email and share components are in separate grid items\n */\nexport function hasEmailAndShareInSeparateColumns(formConfig: FormComponent[] | null): boolean {\n if (!formConfig) return false;\n\n // Adjusted to the current JSON tree (row/column/block)\n const checkTree = (components: FormComponent[]): boolean => {\n for (const node of components) {\n if (node.type === 'row' && Array.isArray(node.children)) {\n // Look for two columns where one column has an email block and another has a submit block\n const columns = node.children.filter((c) => c.type === 'column');\n if (columns.length >= 2) {\n let hasEmailCol = false;\n let hasSubmitCol = false;\n\n for (const col of columns) {\n const blocks = (col.children || []).filter((c) => c.type === 'block');\n const hasEmail = blocks.some(\n (b) => b.vortex?.role === 'email' || b.subtype === 'vrtx-email-invitations'\n );\n const hasSubmit = blocks.some(\n (b) => b.vortex?.role === 'submit' || b.subtype === 'vrtx-submit'\n );\n if (hasEmail) hasEmailCol = true;\n if (hasSubmit) hasSubmitCol = true;\n }\n\n if (hasEmailCol && hasSubmitCol) return true;\n }\n }\n\n if (node.children && checkTree(node.children)) return true;\n }\n return false;\n };\n\n return checkTree(formConfig);\n}\n\n/**\n * Extract role options from form configuration (e.g., vrtx-select with attributes.name === 'role')\n */\nexport function getRoleOptions(\n formConfig: FormComponent[] | null\n): Array<{ id?: string; label: string; value: string }> {\n if (!formConfig) return [];\n\n const findRoleSelect = (components: FormComponent[]): any | null => {\n for (const component of components) {\n const isSelect = component.subtype === 'vrtx-select' || component.tagName === 'vrtx-select';\n const isRole =\n (component as any)?.attributes?.name === 'role' || component.vortex?.role === 'role';\n if (isSelect && isRole) {\n return (component as any)?.settings?.options || null;\n }\n if (component.children?.length) {\n const found = findRoleSelect(component.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const options = findRoleSelect(formConfig);\n if (Array.isArray(options)) {\n // Normalize to label/value objects\n return options.map((opt: any) => ({\n id: opt.id,\n label: opt.label ?? String(opt.value),\n value: String(opt.value),\n }));\n }\n return [];\n}\n","// settings & const\nconst PATH_PARAM_RE = /\\{[^{}]+\\}/g;\n\n/**\n * Returns a cheap, non-cryptographically-secure random ID\n * Courtesy of @imranbarbhuiya (https://github.com/imranbarbhuiya)\n */\nexport function randomID() {\n return Math.random().toString(36).slice(2, 11);\n}\n\n/**\n * Create an openapi-fetch client.\n * @type {import(\"./index.js\").default}\n */\nexport default function createClient(clientOptions) {\n let {\n baseUrl = \"\",\n Request: CustomRequest = globalThis.Request,\n fetch: baseFetch = globalThis.fetch,\n querySerializer: globalQuerySerializer,\n bodySerializer: globalBodySerializer,\n headers: baseHeaders,\n ...baseOptions\n } = { ...clientOptions };\n baseUrl = removeTrailingSlash(baseUrl);\n const middlewares = [];\n\n /**\n * Per-request fetch (keeps settings created in createClient()\n * @param {T} url\n * @param {import('./index.js').FetchOptions<T>} fetchOptions\n */\n async function coreFetch(schemaPath, fetchOptions) {\n const {\n baseUrl: localBaseUrl,\n fetch = baseFetch,\n Request = CustomRequest,\n headers,\n params = {},\n parseAs = \"json\",\n querySerializer: requestQuerySerializer,\n bodySerializer = globalBodySerializer ?? defaultBodySerializer,\n body,\n ...init\n } = fetchOptions || {};\n if (localBaseUrl) {\n baseUrl = removeTrailingSlash(localBaseUrl);\n }\n\n let querySerializer =\n typeof globalQuerySerializer === \"function\"\n ? globalQuerySerializer\n : createQuerySerializer(globalQuerySerializer);\n if (requestQuerySerializer) {\n querySerializer =\n typeof requestQuerySerializer === \"function\"\n ? requestQuerySerializer\n : createQuerySerializer({\n ...(typeof globalQuerySerializer === \"object\" ? globalQuerySerializer : {}),\n ...requestQuerySerializer,\n });\n }\n\n const serializedBody = body === undefined ? undefined : bodySerializer(body);\n\n const defaultHeaders =\n // with no body, we should not to set Content-Type\n serializedBody === undefined ||\n // if serialized body is FormData; browser will correctly set Content-Type & boundary expression\n serializedBody instanceof FormData\n ? {}\n : {\n \"Content-Type\": \"application/json\",\n };\n\n const requestInit = {\n redirect: \"follow\",\n ...baseOptions,\n ...init,\n body: serializedBody,\n headers: mergeHeaders(defaultHeaders, baseHeaders, headers, params.header),\n };\n\n let id;\n let options;\n let request = new CustomRequest(createFinalURL(schemaPath, { baseUrl, params, querySerializer }), requestInit);\n\n /** Add custom parameters to Request object */\n for (const key in init) {\n if (!(key in request)) {\n request[key] = init[key];\n }\n }\n\n if (middlewares.length) {\n id = randomID();\n\n // middleware (request)\n options = Object.freeze({\n baseUrl,\n fetch,\n parseAs,\n querySerializer,\n bodySerializer,\n });\n for (const m of middlewares) {\n if (m && typeof m === \"object\" && typeof m.onRequest === \"function\") {\n const result = await m.onRequest({\n request,\n schemaPath,\n params,\n options,\n id,\n });\n if (result) {\n if (!(result instanceof CustomRequest)) {\n throw new Error(\"onRequest: must return new Request() when modifying the request\");\n }\n request = result;\n }\n }\n }\n }\n\n // fetch!\n let response = await fetch(request);\n\n // middleware (response)\n // execute in reverse-array order (first priority gets last transform)\n if (middlewares.length) {\n for (let i = middlewares.length - 1; i >= 0; i--) {\n const m = middlewares[i];\n if (m && typeof m === \"object\" && typeof m.onResponse === \"function\") {\n const result = await m.onResponse({\n request,\n response,\n schemaPath,\n params,\n options,\n id,\n });\n if (result) {\n if (!(result instanceof Response)) {\n throw new Error(\"onResponse: must return new Response() when modifying the response\");\n }\n response = result;\n }\n }\n }\n }\n\n // handle empty content\n // note: we return `{}` because we want user truthy checks for `.data` or `.error` to succeed\n if (response.status === 204 || response.headers.get(\"Content-Length\") === \"0\") {\n return response.ok ? { data: {}, response } : { error: {}, response };\n }\n\n // parse response (falling back to .text() when necessary)\n if (response.ok) {\n // if \"stream\", skip parsing entirely\n if (parseAs === \"stream\") {\n return { data: response.body, response };\n }\n return { data: await response[parseAs](), response };\n }\n\n // handle errors\n let error = await response.text();\n try {\n error = JSON.parse(error); // attempt to parse as JSON\n } catch {\n // noop\n }\n return { error, response };\n }\n\n return {\n /** Call a GET endpoint */\n GET(url, init) {\n return coreFetch(url, { ...init, method: \"GET\" });\n },\n /** Call a PUT endpoint */\n PUT(url, init) {\n return coreFetch(url, { ...init, method: \"PUT\" });\n },\n /** Call a POST endpoint */\n POST(url, init) {\n return coreFetch(url, { ...init, method: \"POST\" });\n },\n /** Call a DELETE endpoint */\n DELETE(url, init) {\n return coreFetch(url, { ...init, method: \"DELETE\" });\n },\n /** Call a OPTIONS endpoint */\n OPTIONS(url, init) {\n return coreFetch(url, { ...init, method: \"OPTIONS\" });\n },\n /** Call a HEAD endpoint */\n HEAD(url, init) {\n return coreFetch(url, { ...init, method: \"HEAD\" });\n },\n /** Call a PATCH endpoint */\n PATCH(url, init) {\n return coreFetch(url, { ...init, method: \"PATCH\" });\n },\n /** Call a TRACE endpoint */\n TRACE(url, init) {\n return coreFetch(url, { ...init, method: \"TRACE\" });\n },\n /** Register middleware */\n use(...middleware) {\n for (const m of middleware) {\n if (!m) {\n continue;\n }\n if (typeof m !== \"object\" || !(\"onRequest\" in m || \"onResponse\" in m)) {\n throw new Error(\"Middleware must be an object with one of `onRequest()` or `onResponse()`\");\n }\n middlewares.push(m);\n }\n },\n /** Unregister middleware */\n eject(...middleware) {\n for (const m of middleware) {\n const i = middlewares.indexOf(m);\n if (i !== -1) {\n middlewares.splice(i, 1);\n }\n }\n },\n };\n}\n\nclass PathCallForwarder {\n constructor(client, url) {\n this.client = client;\n this.url = url;\n }\n\n GET(init) {\n return this.client.GET(this.url, init);\n }\n PUT(init) {\n return this.client.PUT(this.url, init);\n }\n POST(init) {\n return this.client.POST(this.url, init);\n }\n DELETE(init) {\n return this.client.DELETE(this.url, init);\n }\n OPTIONS(init) {\n return this.client.OPTIONS(this.url, init);\n }\n HEAD(init) {\n return this.client.HEAD(this.url, init);\n }\n PATCH(init) {\n return this.client.PATCH(this.url, init);\n }\n TRACE(init) {\n return this.client.TRACE(this.url, init);\n }\n}\n\nclass PathClientProxyHandler {\n constructor() {\n this.client = null;\n }\n\n // Assume the property is an URL.\n get(coreClient, url) {\n const forwarder = new PathCallForwarder(coreClient, url);\n this.client[url] = forwarder;\n return forwarder;\n }\n}\n\n/**\n * Wrap openapi-fetch client to support a path based API.\n * @type {import(\"./index.js\").wrapAsPathBasedClient}\n */\nexport function wrapAsPathBasedClient(coreClient) {\n const handler = new PathClientProxyHandler();\n const proxy = new Proxy(coreClient, handler);\n\n // Put the proxy on the prototype chain of the actual client.\n // This means if we do not have a memoized PathCallForwarder,\n // we fall back to the proxy to synthesize it.\n // However, the proxy itself is not on the hot-path (if we fetch the same\n // endpoint multiple times, only the first call will hit the proxy).\n function Client() {}\n Client.prototype = proxy;\n\n const client = new Client();\n\n // Feed the client back to the proxy handler so it can store the generated\n // PathCallForwarder.\n handler.client = client;\n\n return client;\n}\n\n/**\n * Convenience method to an openapi-fetch path based client.\n * Strictly equivalent to `wrapAsPathBasedClient(createClient(...))`.\n * @type {import(\"./index.js\").createPathBasedClient}\n */\nexport function createPathBasedClient(clientOptions) {\n return wrapAsPathBasedClient(createClient(clientOptions));\n}\n\n// utils\n\n/**\n * Serialize primitive param values\n * @type {import(\"./index.js\").serializePrimitiveParam}\n */\nexport function serializePrimitiveParam(name, value, options) {\n if (value === undefined || value === null) {\n return \"\";\n }\n if (typeof value === \"object\") {\n throw new Error(\n \"Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.\",\n );\n }\n return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`;\n}\n\n/**\n * Serialize object param (shallow only)\n * @type {import(\"./index.js\").serializeObjectParam}\n */\nexport function serializeObjectParam(name, value, options) {\n if (!value || typeof value !== \"object\") {\n return \"\";\n }\n const values = [];\n const joiner =\n {\n simple: \",\",\n label: \".\",\n matrix: \";\",\n }[options.style] || \"&\";\n\n // explode: false\n if (options.style !== \"deepObject\" && options.explode === false) {\n for (const k in value) {\n values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k]));\n }\n const final = values.join(\",\"); // note: values are always joined by comma in explode: false (but joiner can prefix)\n switch (options.style) {\n case \"form\": {\n return `${name}=${final}`;\n }\n case \"label\": {\n return `.${final}`;\n }\n case \"matrix\": {\n return `;${name}=${final}`;\n }\n default: {\n return final;\n }\n }\n }\n\n // explode: true\n for (const k in value) {\n const finalName = options.style === \"deepObject\" ? `${name}[${k}]` : k;\n values.push(serializePrimitiveParam(finalName, value[k], options));\n }\n const final = values.join(joiner);\n return options.style === \"label\" || options.style === \"matrix\" ? `${joiner}${final}` : final;\n}\n\n/**\n * Serialize array param (shallow only)\n * @type {import(\"./index.js\").serializeArrayParam}\n */\nexport function serializeArrayParam(name, value, options) {\n if (!Array.isArray(value)) {\n return \"\";\n }\n\n // explode: false\n if (options.explode === false) {\n const joiner = { form: \",\", spaceDelimited: \"%20\", pipeDelimited: \"|\" }[options.style] || \",\"; // note: for arrays, joiners vary wildly based on style + explode behavior\n const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner);\n switch (options.style) {\n case \"simple\": {\n return final;\n }\n case \"label\": {\n return `.${final}`;\n }\n case \"matrix\": {\n return `;${name}=${final}`;\n }\n // case \"spaceDelimited\":\n // case \"pipeDelimited\":\n default: {\n return `${name}=${final}`;\n }\n }\n }\n\n // explode: true\n const joiner = { simple: \",\", label: \".\", matrix: \";\" }[options.style] || \"&\";\n const values = [];\n for (const v of value) {\n if (options.style === \"simple\" || options.style === \"label\") {\n values.push(options.allowReserved === true ? v : encodeURIComponent(v));\n } else {\n values.push(serializePrimitiveParam(name, v, options));\n }\n }\n return options.style === \"label\" || options.style === \"matrix\"\n ? `${joiner}${values.join(joiner)}`\n : values.join(joiner);\n}\n\n/**\n * Serialize query params to string\n * @type {import(\"./index.js\").createQuerySerializer}\n */\nexport function createQuerySerializer(options) {\n return function querySerializer(queryParams) {\n const search = [];\n if (queryParams && typeof queryParams === \"object\") {\n for (const name in queryParams) {\n const value = queryParams[name];\n if (value === undefined || value === null) {\n continue;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n continue;\n }\n search.push(\n serializeArrayParam(name, value, {\n style: \"form\",\n explode: true,\n ...options?.array,\n allowReserved: options?.allowReserved || false,\n }),\n );\n continue;\n }\n if (typeof value === \"object\") {\n search.push(\n serializeObjectParam(name, value, {\n style: \"deepObject\",\n explode: true,\n ...options?.object,\n allowReserved: options?.allowReserved || false,\n }),\n );\n continue;\n }\n search.push(serializePrimitiveParam(name, value, options));\n }\n }\n return search.join(\"&\");\n };\n}\n\n/**\n * Handle different OpenAPI 3.x serialization styles\n * @type {import(\"./index.js\").defaultPathSerializer}\n * @see https://swagger.io/docs/specification/serialization/#path\n */\nexport function defaultPathSerializer(pathname, pathParams) {\n let nextURL = pathname;\n for (const match of pathname.match(PATH_PARAM_RE) ?? []) {\n let name = match.substring(1, match.length - 1);\n let explode = false;\n let style = \"simple\";\n if (name.endsWith(\"*\")) {\n explode = true;\n name = name.substring(0, name.length - 1);\n }\n if (name.startsWith(\".\")) {\n style = \"label\";\n name = name.substring(1);\n } else if (name.startsWith(\";\")) {\n style = \"matrix\";\n name = name.substring(1);\n }\n if (!pathParams || pathParams[name] === undefined || pathParams[name] === null) {\n continue;\n }\n const value = pathParams[name];\n if (Array.isArray(value)) {\n nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode }));\n continue;\n }\n if (typeof value === \"object\") {\n nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode }));\n continue;\n }\n if (style === \"matrix\") {\n nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);\n continue;\n }\n nextURL = nextURL.replace(match, style === \"label\" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));\n }\n return nextURL;\n}\n\n/**\n * Serialize body object to string\n * @type {import(\"./index.js\").defaultBodySerializer}\n */\nexport function defaultBodySerializer(body) {\n if (body instanceof FormData) {\n return body;\n }\n return JSON.stringify(body);\n}\n\n/**\n * Construct URL string from baseUrl and handle path and query params\n * @type {import(\"./index.js\").createFinalURL}\n */\nexport function createFinalURL(pathname, options) {\n let finalURL = `${options.baseUrl}${pathname}`;\n if (options.params?.path) {\n finalURL = defaultPathSerializer(finalURL, options.params.path);\n }\n let search = options.querySerializer(options.params.query ?? {});\n if (search.startsWith(\"?\")) {\n search = search.substring(1);\n }\n if (search) {\n finalURL += `?${search}`;\n }\n return finalURL;\n}\n\n/**\n * Merge headers a and b, with b taking priority\n * @type {import(\"./index.js\").mergeHeaders}\n */\nexport function mergeHeaders(...allHeaders) {\n const finalHeaders = new Headers();\n for (const h of allHeaders) {\n if (!h || typeof h !== \"object\") {\n continue;\n }\n const iterator = h instanceof Headers ? h.entries() : Object.entries(h);\n for (const [k, v] of iterator) {\n if (v === null) {\n finalHeaders.delete(k);\n } else if (Array.isArray(v)) {\n for (const v2 of v) {\n finalHeaders.append(k, v2);\n }\n } else if (v !== undefined) {\n finalHeaders.set(k, v);\n }\n }\n }\n return finalHeaders;\n}\n\n/**\n * Remove trailing slash from url\n * @type {import(\"./index.js\").removeTrailingSlash}\n */\nexport function removeTrailingSlash(url) {\n if (url.endsWith(\"/\")) {\n return url.substring(0, url.length - 1);\n }\n return url;\n}\n","export type QueryPrimitive = string | number | boolean | null | undefined;\nexport type QueryArray = Array<string | number | boolean>;\nexport type QueryParams = Record<string, QueryPrimitive | QueryArray>;\n\nexport function urlcat(base: string, path: string, params: QueryParams = {}): string {\n const copy: QueryParams = { ...params };\n\n // Replace :params in path (strict encoding; spaces => %20)\n let url = path.replace(/:([A-Za-z0-9_]+)/g, (_, key: string) => {\n const val = copy[key];\n if (val == null) throw new Error(`Missing value for path parameter ${key}.`);\n delete copy[key];\n return encodeURIComponent(String(val));\n });\n\n // Build query string (encodeURIComponent, then normalize spaces to '+')\n const parts: string[] = [];\n for (const [k, v] of Object.entries(copy)) {\n if (v == null) continue;\n\n if (Array.isArray(v)) {\n v.forEach((item, idx) => {\n if (item == null) return;\n const key = `${k}[${idx}]`;\n const pair = `${encodeURIComponent(key)}=${encodeURIComponent(String(item))}`;\n parts.push(pair);\n });\n } else {\n parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n }\n }\n\n if (parts.length) {\n const qs = parts.join('&').replace(/%20/g, '+'); // <- match original: space as '+'\n url += `?${qs}`;\n }\n\n // Join with base, handling slashes\n return [base.replace(/\\/+$/, ''), url.replace(/^\\/+/, '')].join('/');\n}\n","/**\n * Enum of possible widget error codes\n * Must match the backend WidgetErrorCode enum\n */\nexport enum VortexWidgetErrorCode {\n WIDGET_NOT_FOUND = 'WIDGET_NOT_FOUND',\n WIDGET_NOT_DEPLOYED = 'WIDGET_NOT_DEPLOYED',\n INVALID_WIDGET_CONFIGURATION = 'INVALID_WIDGET_CONFIGURATION',\n AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED',\n INVALID_SESSION = 'INVALID_SESSION',\n SESSION_ATTESTATION_FAILED = 'SESSION_ATTESTATION_FAILED',\n INVALID_TEMPLATE_VARIABLES = 'INVALID_TEMPLATE_VARIABLES',\n INVALID_WIDGET_TYPE = 'INVALID_WIDGET_TYPE',\n ENVIRONMENT_NOT_CONFIGURED = 'ENVIRONMENT_NOT_CONFIGURED',\n INTERNAL_ERROR = 'INTERNAL_ERROR',\n}\n\n/**\n * Widget error details from the backend\n */\nexport interface VortexWidgetErrorDetails {\n /** Machine-readable error code */\n code: VortexWidgetErrorCode;\n /** User-friendly error message for end users (members' customers) */\n userMessage: string;\n /** Technical error message for developers implementing Vortex widgets */\n developerMessage: string;\n /** Additional context about the error */\n context?: Record<string, any>;\n}\n\n/**\n * Widget error response structure from the backend\n */\nexport interface VortexWidgetErrorResponse {\n /** HTTP status code */\n statusCode: number;\n /** Detailed error information */\n error: VortexWidgetErrorDetails;\n /** ISO 8601 timestamp of when the error occurred */\n timestamp: string;\n /** Request path that generated the error */\n path: string;\n}\n\n/**\n * Custom error class for Vortex widget errors\n * Preserves the structured error information from the backend\n */\nexport class VortexWidgetError extends Error {\n public readonly code: VortexWidgetErrorCode;\n public readonly userMessage: string;\n public readonly developerMessage: string;\n public readonly statusCode: number;\n public readonly context?: Record<string, any>;\n public readonly timestamp?: string;\n public readonly path?: string;\n\n constructor(errorResponse: VortexWidgetErrorResponse) {\n // Use developer message as the Error message for stack traces\n super(errorResponse.error.developerMessage);\n this.name = 'VortexWidgetError';\n\n this.code = errorResponse.error.code;\n this.userMessage = errorResponse.error.userMessage;\n this.developerMessage = errorResponse.error.developerMessage;\n this.statusCode = errorResponse.statusCode;\n this.context = errorResponse.error.context;\n this.timestamp = errorResponse.timestamp;\n this.path = errorResponse.path;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, VortexWidgetError);\n }\n }\n\n /**\n * Check if an error object is a VortexWidgetError\n */\n static isVortexWidgetError(error: any): error is VortexWidgetError {\n return error instanceof VortexWidgetError;\n }\n\n /**\n * Check if an error response matches the VortexWidgetErrorResponse structure\n */\n static isVortexWidgetErrorResponse(response: any): response is VortexWidgetErrorResponse {\n return (\n response &&\n typeof response === 'object' &&\n 'error' in response &&\n typeof response.error === 'object' &&\n 'code' in response.error &&\n 'userMessage' in response.error &&\n 'developerMessage' in response.error &&\n 'statusCode' in response\n );\n }\n\n /**\n * Get a display-friendly error message\n * Returns userMessage for UI display, developerMessage for console logs\n */\n getDisplayMessage(forDevelopers: boolean = false): string {\n return forDevelopers ? this.developerMessage : this.userMessage;\n }\n\n /**\n * Convert to a plain object for logging or serialization\n */\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n userMessage: this.userMessage,\n developerMessage: this.developerMessage,\n statusCode: this.statusCode,\n context: this.context,\n timestamp: this.timestamp,\n path: this.path,\n };\n }\n}\n","import createClient from 'openapi-fetch';\nimport type {\n CreateInvitationResponseDto,\n GroupDto,\n HasBeenInvitedResponseDto,\n IVortexClient,\n paths,\n ShareableLinkResponseDto,\n WidgetConfigurationForWidgetDto,\n AutojoinDomainsResponseDto,\n GetOpenInvitationsResponseDto,\n} from './generatedTypes';\nimport { urlcat } from './urlcat';\nimport { VortexWidgetError } from './VortexWidgetError';\n\n// The types are imported from generatedTypes.ts\n\nexport class VortexClient implements IVortexClient {\n private client: ReturnType<typeof createClient<paths>>;\n private sessionAttestation: string | null = null;\n\n constructor(\n private readonly baseUrl: string,\n private readonly clientName: string,\n private readonly clientVersion: string,\n private readonly sessionId: string\n ) {\n this.client = createClient<paths>({ baseUrl });\n }\n\n private getAuthHeaders(jwt: string) {\n return {\n Authorization: `Bearer ${jwt}`,\n };\n }\n\n async getWidgetConfiguration(\n widgetId: string,\n jwt: string,\n templateVariables?: string,\n locale?: string\n ): Promise<{ data: WidgetConfigurationForWidgetDto }> {\n console.debug('[VortexClient] getWidgetConfiguration', {\n widgetId,\n jwt,\n templateVariables,\n locale,\n });\n const { data, error, response } = await this.client.GET('/api/v1/widgets/{widgetId}', {\n params: {\n path: { widgetId },\n query: {\n ...(templateVariables ? { templateVariables } : {}),\n ...(locale ? { locale } : {}),\n },\n header: {\n 'Content-Type': 'application/json',\n 'x-session-id': this.sessionId,\n 'x-vortex-client-version': this.clientVersion,\n 'x-vortex-client-name': this.clientName,\n 'x-session-attestation': this.sessionAttestation || '',\n Authorization: `Bearer ${jwt}`,\n },\n },\n });\n\n // Store status before type narrowing causes issues\n const status = response.status;\n\n if (error) {\n // Check if this is a structured widget error response\n if (VortexWidgetError.isVortexWidgetErrorResponse(error)) {\n throw new VortexWidgetError(error);\n }\n // Fallback to generic error\n throw new Error(`HTTP error! status: ${status}, message: ${JSON.stringify(error)}`);\n }\n\n if (!data) {\n throw new Error(`No data returned from API`);\n }\n\n // Extract session attestation for future requests\n this.sessionAttestation = data.data.sessionAttestation || null;\n\n console.debug('[VortexClient] getWidgetConfiguration', { data: data.data });\n return { data: data.data as WidgetConfigurationForWidgetDto };\n }\n\n async createInvite(\n jwt: string,\n widgetConfigurationId: string,\n payload: Record<string, unknown>,\n source: string,\n groups?: GroupDto[],\n templateVariables?: Record<string, string>,\n metadata?: Record<string, any>\n ): Promise<CreateInvitationResponseDto> {\n console.debug('[VortexClient] createInvite', {\n widgetConfigurationId,\n jwt,\n templateVariables,\n metadata,\n });\n\n // Use fetch directly for this endpoint since openapi-fetch doesn't handle mixed auth correctly\n const url = urlcat(this.baseUrl, '/api/v1/invitations');\n const body = { payload, groups, widgetConfigurationId, templateVariables, source, metadata };\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-session-id': this.sessionId,\n 'x-vortex-client-version': this.clientVersion,\n 'x-vortex-client-name': this.clientName,\n 'x-session-attestation': this.sessionAttestation || '',\n ...this.getAuthHeaders(jwt),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);\n }\n\n const data = await response.json();\n\n console.log('[VortexClient] createInvite', data);\n return data as CreateInvitationResponseDto;\n }\n\n async checkIfUserHasBeenInvited(\n jwt: string,\n emails: string[],\n groups?: GroupDto[]\n ): Promise<HasBeenInvitedResponseDto> {\n console.debug('[VortexClient] checkIfUserHasBeenInvited', {\n jwt,\n emails,\n });\n // Use fetch directly for this endpoint since openapi-fetch doesn't handle mixed auth correctly\n const url = urlcat(this.baseUrl, '/api/v1/invitations/has-been-invited');\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-session-id': this.sessionId,\n 'x-vortex-client-version': this.clientVersion,\n 'x-vortex-client-name': this.clientName,\n 'x-session-attestation': this.sessionAttestation || '',\n ...this.getAuthHeaders(jwt),\n },\n body: JSON.stringify({\n emails,\n groups,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);\n }\n\n const data = await response.json();\n\n console.log('[VortexClient] checkIfUserHasBeenInvited', data);\n return data as HasBeenInvitedResponseDto;\n }\n\n getShareableLinkFormatted(): string {\n return `${this.baseUrl}/i/...`;\n }\n\n async createShareableInvite(\n jwt: string,\n widgetConfigurationId: string,\n groups?: GroupDto[],\n group?: GroupDto,\n templateVariables?: Record<string, string>,\n metadata?: Record<string, any>\n ): Promise<ShareableLinkResponseDto> {\n console.debug('[VortexClient] createShareableInvite', {\n jwt,\n widgetConfigurationId,\n groups,\n group,\n templateVariables,\n metadata,\n });\n\n const { data, error, response } = await this.client.POST(\n '/api/v1/invitations/generate-shareable-link-invite',\n {\n params: {\n header: {\n 'x-session-id': this.sessionId,\n 'x-session-attestation': this.sessionAttestation || '',\n authorization: `Bearer ${jwt}`,\n },\n },\n body: {\n widgetConfigurationId,\n groups,\n group,\n templateVariables: templateVariables as Record<string, string>,\n // Metadata is typed as Record<string, never> in the OpenAPI spec but we still pass it\n // The type assertion tells TS to trust us that this is correct\n ...(metadata && { metadata: metadata as any }),\n },\n bodySerializer: (body) => JSON.stringify(body),\n headers: {\n 'Content-Type': 'application/json',\n } as any,\n }\n );\n\n // Store status before type narrowing causes issues\n const status = response.status;\n\n if (error) {\n throw new Error(`HTTP error! status: ${status}, message: ${JSON.stringify(error)}`);\n }\n\n console.log('[VortexClient] createShareableInvite', data);\n return data as ShareableLinkResponseDto;\n }\n\n async configureAutojoin(\n jwt: string,\n widgetId: string,\n domains: string[],\n group: GroupDto,\n metadata?: Record<string, any>\n ): Promise<AutojoinDomainsResponseDto> {\n console.debug('[VortexClient] configureAutojoin', {\n jwt,\n widgetId,\n domains,\n group,\n metadata,\n });\n\n const url = urlcat(this.baseUrl, '/api/v1/invitations/autojoin');\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-session-id': this.sessionId,\n 'x-vortex-client-version': this.clientVersion,\n 'x-vortex-client-name': this.clientName,\n 'x-session-attestation': this.sessionAttestation || '',\n ...this.getAuthHeaders(jwt),\n },\n body: JSON.stringify({\n widgetId,\n domains,\n group,\n metadata,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);\n }\n\n const data = await response.json();\n\n console.log('[VortexClient] configureAutojoin', data);\n return data as AutojoinDomainsResponseDto;\n }\n\n async getAutojoinDomainsByGroup(\n jwt: string,\n scopeType: string,\n scope: string\n ): Promise<AutojoinDomainsResponseDto> {\n console.debug('[VortexClient] getAutojoinDomainsByGroup', {\n jwt,\n scopeType,\n scope,\n });\n\n // Use fetch directly for this endpoint since openapi-fetch doesn't handle mixed auth correctly\n const url = urlcat(this.baseUrl, `/api/v1/invitations/by-scope/${scopeType}/${scope}/autojoin`);\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-session-id': this.sessionId,\n 'x-vortex-client-version': this.clientVersion,\n 'x-vortex-client-name': this.clientName,\n 'x-session-attestation': this.sessionAttestation || '',\n ...this.getAuthHeaders(jwt),\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);\n }\n\n const data = await response.json();\n\n console.debug('[VortexClient] getAutojoinDomainsByGroup result', data);\n return data as AutojoinDomainsResponseDto;\n }\n\n async getOpenInvitations(jwt: string): Promise<GetOpenInvitationsResponseDto> {\n console.debug('[VortexClient] getOpenInvitations', {\n jwt,\n });\n\n const { data, error, response } = await this.client.GET('/api/v1/invitations', {\n params: {\n header: {\n 'Content-Type': 'application/json',\n 'x-session-id': this.sessionId,\n 'x-vortex-client-version': this.clientVersion,\n 'x-vortex-client-name': this.clientName,\n 'x-session-attestation': this.sessionAttestation || '',\n Authorization: `Bearer ${jwt}`,\n },\n },\n });\n\n // Store status before type narrowing causes issues\n const status = response.status;\n\n if (error) {\n throw new Error(`HTTP error! status: ${status}, message: ${JSON.stringify(error)}`);\n }\n\n console.log('[VortexClient] getOpenInvitations', data);\n return data as GetOpenInvitationsResponseDto;\n }\n}\n","// Global variables that will be injected at build time by each consuming package\ndeclare global {\n var __VORTEX_CLIENT_NAME__: string | undefined;\n var __VORTEX_CLIENT_VERSION__: string | undefined;\n}\n\nexport interface ClientInfo {\n name: string;\n version: string;\n}\n\n/**\n * Gets the client name and version that were injected at build time.\n * If not available (fallback), attempts to detect from common patterns.\n */\nexport function getClientInfo(): ClientInfo {\n // First, try to get the injected build-time values (using bare identifiers for Vite replacement)\n try {\n if (typeof __VORTEX_CLIENT_NAME__ !== 'undefined' && typeof __VORTEX_CLIENT_VERSION__ !== 'undefined') {\n return {\n name: __VORTEX_CLIENT_NAME__,\n version: __VORTEX_CLIENT_VERSION__\n };\n }\n } catch (e) {\n // Variables not defined, fall through to globalThis check\n }\n\n // Fallback: try globalThis (for React Native injection)\n if (typeof globalThis !== 'undefined' && globalThis.__VORTEX_CLIENT_NAME__ && globalThis.__VORTEX_CLIENT_VERSION__) {\n return {\n name: globalThis.__VORTEX_CLIENT_NAME__,\n version: globalThis.__VORTEX_CLIENT_VERSION__\n };\n }\n\n // Final fallback: try to detect from environment/context\n return {\n name: detectClientName(),\n version: detectClientVersion()\n };\n}\n\nfunction detectClientName(): string {\n // Try React Native detection\n if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {\n return 'vortex-react-native';\n }\n\n // Try browser detection (React)\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n return 'vortex-react';\n }\n\n // Default fallback\n return 'vortex-unknown';\n}\n\nfunction detectClientVersion(): string {\n // Without build-time injection, we can't reliably detect version\n return 'unknown';\n}","import { WidgetConfiguration } from '@teamvortexsoftware/vortex-types';\n\n/**\n * Module-level cache for widget configurations.\n * This cache is shared across all hooks and components to ensure\n * configuration updates persist between component mount/unmount cycles.\n * \n * Benefits:\n * - Single source of truth for widget configurations\n * - Persists between modal open/close cycles\n * - Automatic synchronization between prefetch and main hooks\n * - No React Context overhead\n */\nconst cache = new Map<string, WidgetConfiguration>();\n\nexport const configCache = {\n /**\n * Get a cached widget configuration by component ID.\n * @param componentId - The widget component ID\n * @returns The cached configuration, or undefined if not found\n */\n get: (componentId: string): WidgetConfiguration | undefined => {\n return cache.get(componentId);\n },\n\n /**\n * Store a widget configuration in the cache.\n * @param componentId - The widget component ID\n * @param config - The widget configuration to cache\n */\n set: (componentId: string, config: WidgetConfiguration): void => {\n cache.set(componentId, config);\n console.log('[Vortex] Configuration cached', {\n componentId,\n configId: config.id,\n cacheSize: cache.size,\n });\n },\n\n /**\n * Clear cached configuration(s).\n * @param componentId - Optional component ID to clear specific config. If omitted, clears all.\n */\n clear: (componentId?: string): void => {\n if (componentId) {\n cache.delete(componentId);\n console.log('[Vortex] Configuration cache cleared', { componentId });\n } else {\n cache.clear();\n console.log('[Vortex] All configuration cache cleared');\n }\n },\n\n /**\n * Check if a configuration exists in the cache.\n * @param componentId - The widget component ID\n * @returns True if configuration is cached, false otherwise\n */\n has: (componentId: string): boolean => {\n return cache.has(componentId);\n },\n\n /**\n * Get cache statistics for debugging.\n */\n stats: () => ({\n size: cache.size,\n keys: Array.from(cache.keys()),\n }),\n};\n","import { Platform } from 'react-native';\nimport type { EventName } from '@teamvortexsoftware/analytics-client';\n\n// SDK version - should match package.json version\nconst SDK_VERSION = '0.0.15';\n\n// Default production analytics URL\nexport const DEFAULT_ANALYTICS_URL = 'https://collector.vortexsoftware.com';\n\n/**\n * Analytics event interface for React Native SDK\n * Based on AnalyticsEvent from analytics-client with additional mobile-specific fields\n */\nexport interface VortexAnalyticsEvent {\n // Core fields from AnalyticsEvent\n name: EventName;\n widgetConfigurationId: string;\n deploymentId: string;\n environmentId: string;\n platform: string;\n segmentation?: Record<string, any>;\n payload?: Record<string, any>;\n groups?: Array<{\n type: string;\n id: string;\n name: string;\n }>;\n // Additional mobile-specific fields\n timestamp: number; // Unix timestamp in seconds\n sessionId?: string; // Generated UUID per session\n useragent?: string; // Device info string\n foreignUserId?: string; // Extracted from JWT\n}\n\n/**\n * Simplified analytics event for components that emit minimal events.\n * These components emit (name + segmentation) and the parent\n * is responsible for enriching with widgetConfigurationId, deploymentId, etc.\n */\nexport interface SimpleAnalyticsEvent {\n name: EventName;\n segmentation?: Record<string, any>;\n payload?: Record<string, any>;\n}\n\n/**\n * Group DTO for analytics events\n */\nexport interface GroupDTO {\n type: string;\n id: string;\n name: string;\n}\n\n/**\n * Generates a device info / user agent string for analytics\n * Format: VortexSDK-RN/{version} ({OS} {osVersion})\n */\nexport function getDeviceInfo(): string {\n const osName = Platform.OS === 'ios' ? 'iOS' : 'Android';\n const osVersion = Platform.Version;\n\n return `VortexSDK-RN/${SDK_VERSION} (${osName} ${osVersion})`;\n}\n\n/**\n * Extracts the foreign user ID from a JWT token\n * Checks claims in order: userId, sub, user_id\n * Handles both standard JWTs and raw-data format (insecure development JWTs)\n */\nexport function extractForeignUserId(jwt?: string): string | undefined {\n if (!jwt) return undefined;\n\n // Handle raw-data format (insecure JWT for development)\n if (jwt.startsWith('raw-data:')) {\n try {\n const base64Part = jwt.replace('raw-data:', '');\n // Use a cross-platform base64 decode\n const decoded = decodeBase64(base64Part);\n const json = JSON.parse(decoded);\n return json.userId || json.user_id;\n } catch {\n return undefined;\n }\n }\n\n // Standard JWT: header.payload.signature\n const parts = jwt.split('.');\n if (parts.length < 2) return undefined;\n\n try {\n // Base64 URL decode\n const base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n const decoded = decodeBase64(base64);\n const payload = JSON.parse(decoded);\n\n // Try common user ID claims in order:\n return payload.userId || payload.sub || payload.user_id;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Cross-platform base64 decode function\n * Works in both React Native and web environments\n */\nfunction decodeBase64(base64: string): string {\n // Add padding if needed\n const padded = base64 + '==='.slice(0, (4 - (base64.length % 4)) % 4);\n\n // Try using Buffer (Node.js / React Native with polyfill)\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(padded, 'base64').toString('utf-8');\n }\n\n // Fallback to atob (web)\n if (typeof atob !== 'undefined') {\n return atob(padded);\n }\n\n // Manual decode as last resort\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n let output = '';\n let i = 0;\n\n while (i < padded.length) {\n const enc1 = chars.indexOf(padded.charAt(i++));\n const enc2 = chars.indexOf(padded.charAt(i++));\n const enc3 = chars.indexOf(padded.charAt(i++));\n const enc4 = chars.indexOf(padded.charAt(i++));\n\n const chr1 = (enc1 << 2) | (enc2 >> 4);\n const chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n const chr3 = ((enc3 & 3) << 6) | enc4;\n\n output += String.fromCharCode(chr1);\n if (enc3 !== 64) output += String.fromCharCode(chr2);\n if (enc4 !== 64) output += String.fromCharCode(chr3);\n }\n\n return output;\n}\n\n\n","/**\n * Infers a human-readable name from an email address\n * Handles common separators like dots, dashes, underscores\n * \n * @param email - The email address to extract a name from\n * @returns A capitalized name or the email if extraction fails\n * \n * @example\n * inferNameFromEmail('john@foo.com') // 'John'\n * inferNameFromEmail('john.doe@example.com') // 'John Doe'\n * inferNameFromEmail('mary-jane@test.com') // 'Mary Jane'\n * inferNameFromEmail('bob_smith123@mail.com') // 'Bob Smith'\n */\nexport function inferNameFromEmail(email: string): string {\n if (!email || typeof email !== 'string') {\n return 'Unknown';\n }\n\n // Extract the local part (before @)\n const localPart = email.split('@')[0];\n if (!localPart) {\n return 'Unknown';\n }\n\n // Split by common separators: dot, dash, underscore\n const parts = localPart.split(/[._-]+/);\n\n // Filter out empty parts and numbers-only parts\n const nameParts = parts\n .filter(part => part.length > 0)\n .filter(part => !/^\\d+$/.test(part)); // Remove pure number parts\n\n if (nameParts.length === 0) {\n // If nothing left after filtering, just capitalize the whole local part\n return capitalizeWord(localPart);\n }\n\n // Capitalize each part and join with spaces\n return nameParts.map(capitalizeWord).join(' ');\n}\n\n/**\n * Capitalizes the first letter of a word and lowercases the rest\n * \n * @param word - The word to capitalize\n * @returns The capitalized word\n */\nfunction capitalizeWord(word: string): string {\n if (!word || word.length === 0) {\n return word;\n }\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n","/**\n * Feature Warnings\n *\n * This module provides feature detection and helpful warnings for missing module configurations.\n * It scans widget configuration to detect which features are required and prints actionable\n * warnings when the corresponding module props are not specified.\n *\n * Warnings are only printed in development mode (__DEV__) and on native platforms.\n */\n\nimport { Platform } from 'react-native';\nimport type { VortexModulesConfig } from '../context/VortexModulesContext';\n\n/**\n * Features that may be required based on widget configuration\n */\nexport interface FeatureRequirements {\n needsGradient: boolean;\n needsQRCode: boolean;\n needsHaptics: boolean;\n needsClipboard: boolean;\n}\n\n/**\n * Recursively scans a node tree for gradient backgrounds.\n */\nfunction scanForGradients(node: any): boolean {\n if (!node) return false;\n\n // Check style.background for linear-gradient\n if (node.style?.background?.includes?.('linear-gradient')) {\n return true;\n }\n\n // Check theme options for gradients\n if (node.theme?.options && Array.isArray(node.theme.options)) {\n for (const option of node.theme.options) {\n if (option.value?.includes?.('linear-gradient')) {\n return true;\n }\n }\n }\n\n // Recursively check children\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (scanForGradients(child)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Recursively scans a node tree for QR code elements.\n */\nfunction scanForQRCode(node: any): boolean {\n if (!node) return false;\n\n if (node.type === 'vrtx-qr-code' || node.tagName === 'vrtx-qr-code') {\n return true;\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (scanForQRCode(child)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Recursively scans a node tree for share options (which need clipboard).\n */\nfunction scanForShareOptions(node: any): boolean {\n if (!node) return false;\n\n if (node.type === 'vrtx-share-options' || node.tagName === 'vrtx-share-options') {\n return true;\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (scanForShareOptions(child)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detects which features are required based on widget configuration.\n *\n * @param widgetConfiguration - The widget configuration from the API\n * @returns Object indicating which features are needed\n */\nexport function detectRequiredFeatures(widgetConfiguration: any): FeatureRequirements {\n const requirements: FeatureRequirements = {\n needsGradient: false,\n needsQRCode: false,\n needsHaptics: true, // Always nice to have for buttons\n needsClipboard: false,\n };\n\n if (!widgetConfiguration) return requirements;\n\n const rootElement =\n widgetConfiguration.data?.rootElement || widgetConfiguration.rootElement;\n\n requirements.needsGradient = scanForGradients(rootElement);\n requirements.needsQRCode = scanForQRCode(rootElement);\n requirements.needsClipboard = scanForShareOptions(rootElement);\n\n return requirements;\n}\n\n/**\n * Prints helpful warnings for missing module configurations.\n * Only prints in development mode and on native platforms.\n * Uses deduplication helpers to prevent warnings from printing on every render.\n *\n * @param requirements - The detected feature requirements\n * @param moduleConfig - The current module configuration from props\n */\nexport function printFeatureWarnings(\n requirements: FeatureRequirements,\n moduleConfig: VortexModulesConfig\n): void {\n // Only warn in development and on native platforms\n if (!__DEV__ || Platform.OS === 'web') return;\n\n // Check for module configuration\n const hasGradientModule = moduleConfig.modules?.gradient;\n const hasQRCodeModule = moduleConfig.modules?.qrCode;\n const hasHapticsModule = moduleConfig.modules?.haptics;\n const hasClipboardModule = moduleConfig.modules?.clipboard;\n\n // Gradient warning\n if (requirements.needsGradient && !hasGradientModule) {\n printWarningOnce(\n 'vortex-gradient-module',\n `[Vortex] ⚠️ Gradient backgrounds detected in widget configuration, but no gradient module specified.\n\nTo enable gradients on native platforms, add the modules prop to <VortexInvite>:\n\n For Expo projects:\n <VortexInvite modules={{ gradient: 'expo-linear-gradient' }} ... />\n Then run: npx expo install expo-linear-gradient\n\n For bare React Native:\n <VortexInvite modules={{ gradient: 'react-native-linear-gradient' }} ... />\n Then run: npm install react-native-linear-gradient\n\nWithout a gradient module, gradient backgrounds will fall back to solid colors.\n`\n );\n }\n\n // QR Code warning\n if (requirements.needsQRCode && !hasQRCodeModule) {\n printWarningOnce(\n 'vortex-qrcode-module',\n `[Vortex] ⚠️ QR Code feature detected in widget configuration, but no QR code module specified.\n\nTo enable QR codes, add the modules prop to <VortexInvite>:\n\n For native apps:\n <VortexInvite modules={{ qrCode: 'react-native-qrcode-svg' }} ... />\n Then run: npm install react-native-qrcode-svg react-native-svg\n\n For web preview:\n <VortexInvite modules={{ qrCode: 'react-qr-code' }} ... />\n Then run: npm install react-qr-code\n\nWithout a QR code module, QR codes will show a placeholder message.\n`\n );\n }\n\n // Haptics info (less critical)\n if (requirements.needsHaptics && !hasHapticsModule) {\n printInfoOnce(\n 'vortex-haptics-module',\n `[Vortex] 💡 Tip: Add haptic feedback for better UX:\n\n <VortexInvite modules={{ haptics: 'expo-haptics' }} ... />\n Then run: npx expo install expo-haptics\n`\n );\n }\n\n // Clipboard info (only if share options are present)\n if (requirements.needsClipboard && !hasClipboardModule) {\n printInfoOnce(\n 'vortex-clipboard-module',\n `[Vortex] 💡 Tip: For clipboard support (Copy Link), add:\n\n For Expo projects:\n <VortexInvite modules={{ clipboard: 'expo-clipboard' }} ... />\n Then run: npx expo install expo-clipboard\n\n For bare React Native:\n <VortexInvite modules={{ clipboard: '@react-native-clipboard/clipboard' }} ... />\n Then run: npm install @react-native-clipboard/clipboard\n\nWithout a clipboard module, the SDK will use React Native's built-in Clipboard API.\n`\n );\n }\n}\n\n/**\n * Tracks which warnings have been printed to avoid duplicate warnings.\n */\nconst printedWarnings = new Set<string>();\n\n/**\n * Prints a warning only once per session.\n * Useful for warnings that shouldn't spam the console on every render.\n *\n * @param key - Unique key for this warning\n * @param message - The warning message to print\n */\nexport function printWarningOnce(key: string, message: string): void {\n if (!__DEV__ || printedWarnings.has(key)) return;\n\n printedWarnings.add(key);\n console.warn(message);\n}\n\n/**\n * Prints an info message only once per session.\n *\n * @param key - Unique key for this message\n * @param message - The info message to print\n */\nexport function printInfoOnce(key: string, message: string): void {\n if (!__DEV__ || printedWarnings.has(key)) return;\n\n printedWarnings.add(key);\n console.info(message);\n}\n\n/**\n * Clears the printed warnings cache.\n * Useful for testing or when you want warnings to be printed again.\n */\nexport function clearWarningsCache(): void {\n printedWarnings.clear();\n}\n","/**\n * Module Loaders\n *\n * This module provides explicit module loading for optional dependencies.\n * Instead of auto-detecting which libraries are installed (which causes Metro bundler issues),\n * users explicitly specify which module they want to use via props.\n *\n * This approach:\n * - Avoids Metro static analysis issues with optional dependencies\n * - Gives users explicit control over which libraries to use\n * - Provides clear error messages when a module is specified but not installed\n * - Only requires the module that the user explicitly specifies\n */\n\nimport { Platform } from 'react-native';\nimport type { ComponentType } from 'react';\nimport type {\n GradientModuleName,\n HapticsModuleName,\n QRCodeModuleName,\n ClipboardModuleName,\n} from '../context/VortexModulesContext';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Props for gradient components (compatible with both expo and react-native-linear-gradient)\n */\nexport interface GradientProps {\n colors: string[];\n locations?: number[];\n start?: { x: number; y: number };\n end?: { x: number; y: number };\n style?: any;\n children?: React.ReactNode;\n}\n\n/**\n * Props for QR code components\n */\nexport interface QRCodeProps {\n value: string;\n size?: number;\n color?: string;\n backgroundColor?: string;\n style?: any;\n}\n\n/**\n * Haptic feedback style\n */\nexport type HapticStyle = 'light' | 'medium' | 'heavy';\n\n// ============================================================================\n// Module Loading Helpers\n// ============================================================================\n\n/**\n * Cache for loaded modules to avoid repeated require calls\n */\nconst moduleCache = new Map<string, any>();\n\n/**\n * List of modules that are native-only and should not be loaded on web.\n * These modules contain native code that doesn't exist in web builds.\n */\nconst NATIVE_ONLY_MODULES = [\n 'expo-linear-gradient',\n 'react-native-linear-gradient',\n 'expo-haptics',\n 'react-native-qrcode-svg',\n '@react-native-clipboard/clipboard',\n];\n\n/**\n * Loads a module by name, with caching and error handling.\n * Uses explicit require statements to ensure Metro can resolve them.\n *\n * IMPORTANT: Native-only modules are skipped on web platform to prevent\n * build errors. The web platform uses CSS equivalents (gradients) or\n * browser APIs (clipboard) instead.\n *\n * @param moduleName - The name of the module to load\n * @returns The loaded module or null if not available\n */\nfunction loadModule<T>(moduleName: string): T | null {\n // Check cache first\n if (moduleCache.has(moduleName)) {\n return moduleCache.get(moduleName);\n }\n\n // Skip native-only modules on web platform\n // These modules contain native code that doesn't exist in web builds\n if (Platform.OS === 'web' && NATIVE_ONLY_MODULES.includes(moduleName)) {\n moduleCache.set(moduleName, null);\n return null;\n }\n\n try {\n let mod: any = null;\n\n // Use explicit require statements for each supported module\n // This ensures Metro can properly resolve and bundle them when installed\n switch (moduleName) {\n case 'expo-linear-gradient':\n mod = require('expo-linear-gradient');\n break;\n case 'react-native-linear-gradient':\n mod = require('react-native-linear-gradient');\n break;\n case 'expo-haptics':\n mod = require('expo-haptics');\n break;\n case 'react-native-qrcode-svg':\n mod = require('react-native-qrcode-svg');\n break;\n case 'react-qr-code':\n mod = require('react-qr-code');\n break;\n case 'expo-clipboard':\n mod = require('expo-clipboard');\n break;\n case '@react-native-clipboard/clipboard':\n mod = require('@react-native-clipboard/clipboard');\n break;\n default:\n console.warn(`[Vortex] Unknown module: ${moduleName}`);\n return null;\n }\n\n moduleCache.set(moduleName, mod);\n return mod;\n } catch (error) {\n // Module not installed - cache null to avoid repeated attempts\n moduleCache.set(moduleName, null);\n console.error(\n `[Vortex] Failed to load module \"${moduleName}\". ` +\n `Make sure it's installed: npm install ${moduleName}`\n );\n return null;\n }\n}\n\n// ============================================================================\n// Gradient Loading\n// ============================================================================\n\n/**\n * Loads the gradient component based on the specified module name.\n *\n * @param moduleName - The gradient module to load ('expo-linear-gradient' or 'react-native-linear-gradient')\n * @returns The gradient component or null if not available\n *\n * @example\n * ```tsx\n * const GradientComponent = loadGradientComponent('expo-linear-gradient');\n * if (GradientComponent) {\n * return <GradientComponent colors={['#ff0000', '#0000ff']} style={styles.button} />;\n * }\n * ```\n */\nexport function loadGradientComponent(\n moduleName: GradientModuleName | undefined\n): ComponentType<GradientProps> | null {\n if (!moduleName) {\n return null;\n }\n\n // On web, we use CSS gradients directly, no component needed\n if (Platform.OS === 'web') {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n // expo-linear-gradient exports { LinearGradient }\n // react-native-linear-gradient exports default\n if (moduleName === 'expo-linear-gradient') {\n return mod.LinearGradient || null;\n } else if (moduleName === 'react-native-linear-gradient') {\n return mod.default || null;\n }\n\n return null;\n}\n\n// ============================================================================\n// Haptics Loading\n// ============================================================================\n\n/**\n * Creates a haptic feedback trigger function based on the specified module.\n *\n * @param moduleName - The haptics module to use ('expo-haptics')\n * @returns A function to trigger haptic feedback, or null if not available\n *\n * @example\n * ```tsx\n * const triggerHaptic = loadHapticsTrigger('expo-haptics');\n * if (triggerHaptic) {\n * await triggerHaptic('light');\n * }\n * ```\n */\nexport function loadHapticsTrigger(\n moduleName: HapticsModuleName | undefined\n): ((style: HapticStyle) => Promise<void>) | null {\n if (!moduleName) {\n return null;\n }\n\n // Haptics don't make sense on web\n if (Platform.OS === 'web') {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n if (moduleName === 'expo-haptics') {\n return async (style: HapticStyle) => {\n const feedbackStyle =\n style === 'light'\n ? mod.ImpactFeedbackStyle.Light\n : style === 'medium'\n ? mod.ImpactFeedbackStyle.Medium\n : mod.ImpactFeedbackStyle.Heavy;\n\n await mod.impactAsync(feedbackStyle);\n };\n }\n\n return null;\n}\n\n// ============================================================================\n// QR Code Loading\n// ============================================================================\n\n/**\n * Loads the QR code component based on the specified module name.\n *\n * @param moduleName - The QR code module to load ('react-native-qrcode-svg' or 'react-qr-code')\n * @returns The QR code component or null if not available\n *\n * @example\n * ```tsx\n * const QRCodeComponent = loadQRCodeComponent('react-native-qrcode-svg');\n * if (QRCodeComponent) {\n * return <QRCodeComponent value=\"https://example.com\" size={200} />;\n * }\n * ```\n */\nexport function loadQRCodeComponent(\n moduleName: QRCodeModuleName | undefined\n): ComponentType<QRCodeProps> | null {\n if (!moduleName) {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n // react-native-qrcode-svg exports default\n // react-qr-code exports default\n return mod.default || null;\n}\n\n// ============================================================================\n// Clipboard Loading\n// ============================================================================\n\n/**\n * Clipboard operations interface\n */\nexport interface ClipboardOperations {\n setString: (text: string) => Promise<void>;\n getString: () => Promise<string>;\n}\n\n/**\n * Loads clipboard operations based on the specified module.\n *\n * @param moduleName - The clipboard module to use ('expo-clipboard' or '@react-native-clipboard/clipboard')\n * @returns Clipboard operations object or null if not available\n *\n * @example\n * ```tsx\n * const clipboard = loadClipboardOperations('expo-clipboard');\n * if (clipboard) {\n * await clipboard.setString('Hello, world!');\n * }\n * ```\n */\nexport function loadClipboardOperations(\n moduleName: ClipboardModuleName | undefined\n): ClipboardOperations | null {\n if (!moduleName) {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n if (moduleName === 'expo-clipboard') {\n return {\n setString: async (text: string) => {\n await mod.setStringAsync(text);\n },\n getString: async () => {\n return await mod.getStringAsync();\n },\n };\n } else if (moduleName === '@react-native-clipboard/clipboard') {\n const Clipboard = mod.default || mod;\n return {\n setString: async (text: string) => {\n Clipboard.setString(text);\n },\n getString: async () => {\n return await Clipboard.getString();\n },\n };\n }\n\n return null;\n}\n\n// ============================================================================\n// Gradient Parsing Utilities (re-exported from shared gradientUtils.ts)\n// ============================================================================\n\n// Re-export gradient utilities from the shared module to maintain backward compatibility\n// and provide a single source of truth for gradient parsing logic\nexport {\n parseCSSLinearGradient,\n angleToGradientPoints,\n parseGradientFirstColor,\n type ParsedGradient,\n type GradientPoints,\n} from './gradientUtils';\n","/**\n * Gradient Parsing Utilities\n *\n * Pure JavaScript utilities for parsing CSS gradients.\n * These are shared between native (moduleLoaders.ts) and web (moduleLoaders.web.ts)\n * implementations to avoid code duplication.\n *\n * These utilities have NO native dependencies and are safe to import from anywhere.\n */\n\n/**\n * Parsed gradient data structure\n */\nexport interface ParsedGradient {\n type: 'linear';\n angle: number;\n colors: string[];\n locations: number[];\n}\n\n/**\n * Gradient points for LinearGradient component\n */\nexport interface GradientPoints {\n start: { x: number; y: number };\n end: { x: number; y: number };\n}\n\n/**\n * Parses a CSS linear-gradient string into a structured format.\n *\n * Supports formats like:\n * - \"linear-gradient(90deg, #ff0000 0%, #0000ff 100%)\"\n * - \"linear-gradient(to right, #ff0000 0%, #0000ff 100%)\"\n * - \"linear-gradient(135deg, rgba(255,0,0,1) 0%, rgba(0,0,255,1) 100%)\"\n *\n * @param css - CSS linear-gradient string\n * @returns Parsed gradient data or null if parsing fails\n */\nexport function parseCSSLinearGradient(css: string): ParsedGradient | null {\n if (!css || !css.includes('linear-gradient')) {\n return null;\n }\n\n // Parse angle\n let angle = 180; // Default: top to bottom\n\n const angleMatch = css.match(/linear-gradient\\(\\s*(\\d+)deg/i);\n if (angleMatch) {\n angle = parseInt(angleMatch[1], 10);\n } else {\n // Handle directional keywords\n const directionMatch = css.match(/linear-gradient\\(\\s*to\\s+(\\w+)(?:\\s+(\\w+))?/i);\n if (directionMatch) {\n const direction = directionMatch[1].toLowerCase();\n const secondDirection = directionMatch[2]?.toLowerCase();\n\n const directionAngles: Record<string, number> = {\n 'right': 90,\n 'left': 270,\n 'bottom': 180,\n 'top': 0,\n 'right-bottom': 135,\n 'left-bottom': 225,\n 'right-top': 45,\n 'left-top': 315,\n };\n\n const key = secondDirection ? `${direction}-${secondDirection}` : direction;\n angle = directionAngles[key] ?? 180;\n }\n }\n\n // Parse color stops\n const stopsRegex = /(#[0-9a-fA-F]{3,8}|rgba?\\([^)]+\\)|[a-z]+)\\s+(\\d+)%/gi;\n const colors: string[] = [];\n const locations: number[] = [];\n\n let match;\n while ((match = stopsRegex.exec(css)) !== null) {\n const color = match[1].trim();\n const location = parseInt(match[2], 10) / 100;\n\n if (color !== 'to' && color !== 'from') {\n colors.push(color);\n locations.push(location);\n }\n }\n\n if (colors.length < 2) {\n return null;\n }\n\n return { type: 'linear', angle, colors, locations };\n}\n\n/**\n * Converts a CSS gradient angle to start/end points for LinearGradient component.\n *\n * CSS gradient angles:\n * - 0deg = bottom to top\n * - 90deg = left to right\n * - 180deg = top to bottom\n * - 270deg = right to left\n *\n * LinearGradient uses normalized coordinates (0-1) for start/end points.\n *\n * @param angle - CSS gradient angle in degrees\n * @returns Start and end points for LinearGradient\n */\nexport function angleToGradientPoints(angle: number): GradientPoints {\n const normalizedAngle = ((angle % 360) + 360) % 360;\n const rad = ((90 - normalizedAngle) * Math.PI) / 180;\n\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n\n return {\n start: { x: 0.5 - cos / 2, y: 0.5 + sin / 2 },\n end: { x: 0.5 + cos / 2, y: 0.5 - sin / 2 },\n };\n}\n\n/**\n * Extracts the first color from a CSS gradient string.\n * Used as a fallback when gradient libraries are not available.\n *\n * @param gradientString - CSS linear-gradient string\n * @returns First color from the gradient or null\n */\nexport function parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(#[0-9a-fA-F]{3,8}|rgba?\\([^)]+\\)|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n const color = match[1].trim();\n if (color !== 'to' && color !== 'from') {\n return color;\n }\n }\n\n return null;\n}\n","import { useState, useEffect, useMemo } from 'react';\nimport { VortexClient, getClientInfo, VortexWidgetError } from '@teamvortexsoftware/vortex-shared-ui';\nimport { WidgetConfiguration, UnsignedData } from '@teamvortexsoftware/vortex-types';\nimport uuid from 'react-native-uuid';\nimport { configCache } from '../utils/configCache';\n\nexport interface UsePrefetchWidgetConfigurationOptions {\n componentId: string;\n vortexApiUrl: string;\n jwt?: string;\n user?: string | UnsignedData;\n enabled?: boolean; // Allow conditional prefetching\n}\n\n/**\n * Hook to prefetch widget configuration for instant rendering.\n * This hook fetches the configuration early (e.g., when JWT becomes available)\n * so the VortexInvite component can render immediately without showing a loading spinner.\n * \n * The hook will still refetch in the background when VortexInvite mounts to ensure\n * the configuration is up-to-date (stale-while-revalidate pattern).\n * \n * @example\n * ```tsx\n * const { widgetConfiguration } = usePrefetchWidgetConfiguration({\n * componentId: 'your-component-id',\n * vortexApiUrl: 'https://client-api.vortexsoftware.com',\n * jwt,\n * enabled: !!jwt, // Only prefetch when JWT is ready\n * });\n * \n * <VortexInvite\n * componentId={componentId}\n * jwt={jwt}\n * widgetConfiguration={widgetConfiguration} // Pass prefetched config\n * // ... other props\n * />\n * ```\n */\nexport function usePrefetchWidgetConfiguration({\n componentId,\n vortexApiUrl,\n jwt,\n user,\n enabled = true,\n}: UsePrefetchWidgetConfigurationOptions) {\n // Read from module-level cache instead of local state\n const widgetConfiguration = configCache.get(componentId);\n const [error, setError] = useState<Error | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n // Generate effective JWT (same logic as useVortexInvite)\n const effectiveJwt = useMemo(() => {\n if (jwt) return jwt;\n if (user) {\n if (typeof user === 'string') return user;\n const payload = { ...user, componentId };\n const jsonString = JSON.stringify(payload);\n const base64Encoded = Buffer.from(jsonString).toString('base64');\n return `raw-data:${base64Encoded}`;\n }\n return undefined;\n }, [jwt, user, componentId]);\n\n const vortexClient = useMemo(() => {\n const clientInfo = getClientInfo();\n const sessionId = uuid.v4() as string;\n return new VortexClient(vortexApiUrl, clientInfo.name, clientInfo.version, sessionId);\n }, [vortexApiUrl]);\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n if (!effectiveJwt) {\n return;\n }\n\n if (widgetConfiguration) {\n return;\n }\n\n let cancelled = false;\n\n const fetchConfig = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n console.log('[Vortex] Prefetching widget configuration...');\n const result = await vortexClient.getWidgetConfiguration(componentId, effectiveJwt);\n\n if (!cancelled && result?.data?.widgetConfiguration) {\n const config = result.data.widgetConfiguration as unknown as WidgetConfiguration;\n configCache.set(componentId, config); // Write to shared cache\n console.log('[Vortex] Widget configuration prefetched successfully');\n }\n } catch (err) {\n if (!cancelled) {\n const error = err instanceof Error ? err : new Error('Failed to prefetch configuration');\n setError(error);\n console.error('[Vortex] Failed to prefetch widget configuration:', error);\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n };\n\n fetchConfig();\n\n return () => {\n cancelled = true;\n };\n }, [componentId, effectiveJwt, vortexClient, enabled, widgetConfiguration]);\n\n return {\n widgetConfiguration,\n error,\n isLoading,\n };\n}\n","/**\n * Configuration for Open Graph unfurl metadata.\n * Used to customize link previews when sharing invitation links.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * unfurlConfig={{\n * title: \"Join our team!\",\n * description: \"You've been invited to collaborate\",\n * image: \"https://example.com/preview.png\",\n * siteName: \"My App\",\n * }}\n * />\n * ```\n */\nexport interface UnfurlConfig {\n /** The title for the link preview (og:title) */\n title?: string;\n /** The description for the link preview (og:description) */\n description?: string;\n /** URL to an image for the link preview (og:image) */\n image?: string;\n /** The site name for the link preview (og:site_name) */\n siteName?: string;\n /** The type of content (og:type), defaults to \"website\" */\n type?: string;\n}\n\n/**\n * Converts UnfurlConfig to the metadata format expected by the API.\n */\nexport function unfurlConfigToMetadata(config: UnfurlConfig): Record<string, string> {\n const metadata: Record<string, string> = {};\n if (config.title) metadata['og:title'] = config.title;\n if (config.description) metadata['og:description'] = config.description;\n if (config.image) metadata['og:image'] = config.image;\n if (config.siteName) metadata['og:site_name'] = config.siteName;\n if (config.type) metadata['og:type'] = config.type;\n return metadata;\n}\n","import { Platform, Dimensions, NativeModules } from 'react-native';\n\n/**\n * Device fingerprint data collected for deferred deep linking.\n */\nexport interface DeviceFingerprint {\n platform: 'ios' | 'android';\n osVersion: string;\n deviceModel: string;\n deviceBrand: string;\n timezone: string;\n language: string;\n screenWidth: number;\n screenHeight: number;\n carrierName?: string;\n totalMemory?: number;\n}\n\n/**\n * Response from the match-fingerprint API endpoint.\n */\nexport interface MatchFingerprintResponse {\n matched: boolean;\n invitationId?: string;\n deepLink?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Options for retrieving deferred deep links.\n */\nexport interface RetrieveDeferredDeepLinkOptions {\n /** JWT token for authentication */\n jwt: string;\n /** Optional base URL override (defaults to production) */\n baseURL?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://client-api.vortexsoftware.com';\n\n/**\n * VortexDeferredLinks provides deferred deep linking functionality.\n * \n * Deferred deep linking allows you to track invitation attribution even when\n * the app wasn't installed at the time the invitation link was clicked.\n * \n * @example\n * ```tsx\n * import { VortexDeferredLinks } from '@teamvortexsoftware/vortex-react-native';\n * \n * // On app first launch after install\n * async function checkDeferredDeepLink(jwt: string) {\n * const result = await VortexDeferredLinks.retrieveDeferredDeepLink({ jwt });\n * if (result.matched && result.deepLink) {\n * // Handle the deferred deep link\n * console.log('User came from invitation:', result.invitationId);\n * // Navigate to appropriate screen\n * }\n * }\n * ```\n */\nexport class VortexDeferredLinks {\n /**\n * Collects device fingerprint data for matching.\n * This data is used to match the device against fingerprints collected\n * when invitation links were clicked.\n */\n static collectDeviceFingerprint(): DeviceFingerprint {\n const { width, height } = Dimensions.get('screen');\n const platformOS = Platform.OS === 'ios' ? 'ios' : 'android';\n \n // Get OS version\n const osVersion = Platform.Version?.toString() || 'unknown';\n \n // Get device model and brand\n let deviceModel = 'unknown';\n let deviceBrand = 'unknown';\n \n if (Platform.OS === 'ios') {\n // On iOS, we can get some info from Platform.constants\n const constants = Platform.constants as any;\n deviceModel = constants?.systemName || 'iPhone';\n deviceBrand = 'Apple';\n } else if (Platform.OS === 'android') {\n // On Android, we can access more device info\n const constants = Platform.constants as any;\n deviceModel = constants?.Model || 'unknown';\n deviceBrand = constants?.Brand || constants?.Manufacturer || 'unknown';\n }\n \n // Get timezone\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'unknown';\n \n // Get language\n const language = Platform.OS === 'ios'\n ? (NativeModules.SettingsManager?.settings?.AppleLocale ||\n NativeModules.SettingsManager?.settings?.AppleLanguages?.[0] ||\n 'en')\n : (NativeModules.I18nManager?.localeIdentifier || 'en');\n \n return {\n platform: platformOS,\n osVersion,\n deviceModel,\n deviceBrand,\n timezone,\n language,\n screenWidth: Math.round(width),\n screenHeight: Math.round(height),\n };\n }\n\n /**\n * Retrieves a deferred deep link by matching the device fingerprint.\n * \n * Call this method on first app launch after installation to check if\n * the user came from an invitation link.\n * \n * @param options - Configuration options including JWT and optional base URL\n * @returns Promise resolving to match result with optional deep link\n */\n static async retrieveDeferredDeepLink(\n options: RetrieveDeferredDeepLinkOptions\n ): Promise<MatchFingerprintResponse> {\n const { jwt, baseURL = DEFAULT_BASE_URL } = options;\n \n const fingerprint = VortexDeferredLinks.collectDeviceFingerprint();\n \n try {\n const response = await fetch(`${baseURL}/api/v1/invitations/match-fingerprint`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${jwt}`,\n },\n body: JSON.stringify(fingerprint),\n });\n \n if (!response.ok) {\n // Non-blocking: return no match on error\n console.warn('[VortexDeferredLinks] Failed to match fingerprint:', response.status);\n return { matched: false };\n }\n \n const data = await response.json();\n return {\n matched: data.matched ?? false,\n invitationId: data.invitationId,\n deepLink: data.deepLink,\n metadata: data.metadata,\n };\n } catch (error) {\n // Non-blocking: silently fail and return no match\n console.warn('[VortexDeferredLinks] Error matching fingerprint:', error);\n return { matched: false };\n }\n }\n}\n","import type { Contact } from '../hooks/useInvitationFormLogic';\n\n// Mock contact data for demonstration\nexport const MOCK_CONTACTS: Contact[] = [\n { id: '1', name: 'Alice Johnson', email: 'alice.johnson@example.com' },\n { id: '2', name: 'Bob Smith', email: 'bob.smith@example.com' },\n { id: '3', name: 'Charlie Brown', email: 'charlie.brown@example.com' },\n { id: '4', name: 'Diana Prince', email: 'diana.prince@example.com' },\n { id: '5', name: 'Ethan Hunt', email: 'ethan.hunt@example.com' },\n { id: '6', name: 'Fiona Green', email: 'fiona.green@example.com' },\n];\n\n// Mock Google contact data for demonstration\nexport const MOCK_GOOGLE_CONTACTS: Contact[] = [\n { id: 'g1', name: 'John Doe', email: 'john.doe@gmail.com' },\n { id: 'g2', name: 'Jane Smith', email: 'jane.smith@gmail.com' },\n { id: 'g3', name: 'Michael Johnson', email: 'michael.j@gmail.com' },\n { id: 'g4', name: 'Sarah Williams', email: 'sarah.w@gmail.com' },\n { id: 'g5', name: 'David Brown', email: 'david.brown@gmail.com' },\n { id: 'g6', name: 'Emma Davis', email: 'emma.davis@gmail.com' },\n];\n"],"mappings":"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","names":["exports","module","import_react","import_react_native","import_react","import_react_native","import_react","import_react_native","import_react_native","import_react","import_jsx_runtime","_a","_b","import_react_native","import_jsx_runtime","isWeb","ButtonWrapper","_a","styles","import_react","import_react_native","import_jsx_runtime","isWeb","ButtonWrapper","React","styles","_a","_b","_c","import_react","import_react_native","import_jsx_runtime","isWeb","parseGradientFirstColor","ButtonWrapper","_a","_b","styles","import_react","import_react_native","import_jsx_runtime","isWeb","parseGradientFirstColor","ButtonWrapper","_a","_b","title","styles","_c","isLoading","import_react","import_react_native","import_jsx_runtime","isWeb","parseGradientFirstColor","AnimatedInvitationItem","_a","_b","_c","title","styles","isLoading","import_react","import_react_native","import_jsx_runtime","isWeb","parseGradientFirstColor","ButtonWrapper","_a","styles","_b","import_react","import_react_native","import_jsx_runtime","isWeb","parseGradientFirstColor","ButtonWrapper","_a","_b","styles","import_react_native","import_jsx_runtime","isWeb","import_react","import_react_native","import_jsx_runtime","isWeb","processTextGradient","styles","React","import_react_native","import_jsx_runtime","styles","import_react_native","import_jsx_runtime","isWeb","ButtonWrapper","styles","_a","import_react","import_react_native","import_jsx_runtime","isWeb","parseGradientFirstColor","_a","_b","styles","import_react","import_react_native","isWeb","React","import_jsx_runtime","isWeb","parseGradientFirstColor","_a","_b","_c","fontFamily","parseGradientFirstColor","isWeb","_d","extractBorderColor","_e","_f","_g","React","styles","import_react","import_react_native","import_react","_a","_a","fetch","final","joiner","VortexWidgetErrorCode","VortexClient","import_react_native","sessionId","uuid","VortexClient","error","groups","shareableLink","options","import_jsx_runtime","Icon","error","module","Platform","Linking","import_react_native","import_react_native","parseGradientFirstColor","import_jsx_runtime","parseGradientFirstColor","import_react","import_react_native_uuid","uuid","VortexClient","error","import_react_native","DEFAULT_BASE_URL"]}
|