@teamvortexsoftware/vortex-react-native 1.0.0 → 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.
Files changed (217) hide show
  1. package/dist/InviteFormCore-D4HkMMo0.d.mts +721 -0
  2. package/dist/InviteFormCore-D9oUCbu7.d.ts +721 -0
  3. package/dist/VortexClient.js +192 -0
  4. package/dist/VortexClient.js.map +1 -0
  5. package/dist/VortexDeferredLinks.js +127 -0
  6. package/dist/VortexDeferredLinks.js.map +1 -0
  7. package/dist/clientInfo.js +45 -0
  8. package/dist/clientInfo.js.map +1 -0
  9. package/dist/components/ContactsPickerModal.js +182 -0
  10. package/dist/components/ContactsPickerModal.js.map +1 -0
  11. package/dist/components/InviteFormCore.js +2141 -0
  12. package/dist/components/InviteFormCore.js.map +1 -0
  13. package/dist/components/InviteFormMobile.js +463 -0
  14. package/dist/components/InviteFormMobile.js.map +1 -0
  15. package/dist/components/InviteFormWeb.js +295 -0
  16. package/dist/components/InviteFormWeb.js.map +1 -0
  17. package/dist/components/PlacedItemToolbar.js +147 -0
  18. package/dist/components/PlacedItemToolbar.js.map +1 -0
  19. package/dist/components/ShareButtons.js +181 -0
  20. package/dist/components/ShareButtons.js.map +1 -0
  21. package/dist/components/VrtxContactsImport.js +234 -0
  22. package/dist/components/VrtxContactsImport.js.map +1 -0
  23. package/dist/components/VrtxEmailInvitations.js +341 -0
  24. package/dist/components/VrtxEmailInvitations.js.map +1 -0
  25. package/dist/components/VrtxFindFriends.js +400 -0
  26. package/dist/components/VrtxFindFriends.js.map +1 -0
  27. package/dist/components/VrtxHeading.js +58 -0
  28. package/dist/components/VrtxHeading.js.map +1 -0
  29. package/dist/components/VrtxIncomingInvitations.js +657 -0
  30. package/dist/components/VrtxIncomingInvitations.js.map +1 -0
  31. package/dist/components/VrtxInvitationSuggestions.js +506 -0
  32. package/dist/components/VrtxInvitationSuggestions.js.map +1 -0
  33. package/dist/components/VrtxInviteContacts.js +512 -0
  34. package/dist/components/VrtxInviteContacts.js.map +1 -0
  35. package/dist/components/VrtxOutgoingInvitations.js +572 -0
  36. package/dist/components/VrtxOutgoingInvitations.js.map +1 -0
  37. package/dist/components/VrtxSearchBox.js +487 -0
  38. package/dist/components/VrtxSearchBox.js.map +1 -0
  39. package/dist/components/VrtxSelect.js +27 -0
  40. package/dist/components/VrtxSelect.js.map +1 -0
  41. package/dist/components/VrtxShareOptions.js +435 -0
  42. package/dist/components/VrtxShareOptions.js.map +1 -0
  43. package/dist/components/VrtxSubmit.js +132 -0
  44. package/dist/components/VrtxSubmit.js.map +1 -0
  45. package/dist/components/VrtxText.js +146 -0
  46. package/dist/components/VrtxText.js.map +1 -0
  47. package/dist/constants/mockData.d.mts +7 -0
  48. package/dist/constants/mockData.d.ts +7 -0
  49. package/dist/constants/mockData.js +48 -0
  50. package/dist/constants/mockData.js.map +1 -0
  51. package/dist/constants/mockData.mjs +22 -0
  52. package/dist/constants/mockData.mjs.map +1 -0
  53. package/dist/context/VortexModulesContext.js +135 -0
  54. package/dist/context/VortexModulesContext.js.map +1 -0
  55. package/dist/hooks/useInvitationFormLogic.d.mts +2 -0
  56. package/dist/hooks/useInvitationFormLogic.d.ts +2 -0
  57. package/dist/hooks/useInvitationFormLogic.js +300 -0
  58. package/dist/hooks/useInvitationFormLogic.js.map +1 -0
  59. package/dist/hooks/useInvitationFormLogic.mjs +276 -0
  60. package/dist/hooks/useInvitationFormLogic.mjs.map +1 -0
  61. package/dist/hooks/usePrefetchWidgetConfiguration.js +117 -0
  62. package/dist/hooks/usePrefetchWidgetConfiguration.js.map +1 -0
  63. package/dist/hooks/useThemeStyles.js +41 -0
  64. package/dist/hooks/useThemeStyles.js.map +1 -0
  65. package/dist/hooks/useVortexInvite.js +732 -0
  66. package/dist/hooks/useVortexInvite.js.map +1 -0
  67. package/dist/index-web.d.mts +93 -0
  68. package/dist/index-web.d.ts +93 -0
  69. package/dist/index-web.js +7397 -0
  70. package/dist/index-web.js.map +1 -0
  71. package/dist/index-web.mjs +7445 -0
  72. package/dist/index-web.mjs.map +1 -0
  73. package/dist/index.d.mts +656 -0
  74. package/dist/index.d.ts +656 -0
  75. package/dist/index.js +10206 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/index.mjs +10244 -0
  78. package/dist/index.mjs.map +1 -0
  79. package/dist/types/VortexClient.d.ts +106 -0
  80. package/dist/types/VortexClient.d.ts.map +1 -0
  81. package/dist/types/VortexDeferredLinks.d.ts +73 -0
  82. package/dist/types/VortexDeferredLinks.d.ts.map +1 -0
  83. package/dist/types/clientInfo.d.ts +5 -0
  84. package/dist/types/clientInfo.d.ts.map +1 -0
  85. package/dist/types/components/ContactsPickerModal.d.ts +18 -0
  86. package/dist/types/components/ContactsPickerModal.d.ts.map +1 -0
  87. package/dist/types/components/InviteFormCore.d.ts +166 -0
  88. package/dist/types/components/InviteFormCore.d.ts.map +1 -0
  89. package/dist/types/components/InviteFormMobile.d.ts +42 -0
  90. package/dist/types/components/InviteFormMobile.d.ts.map +1 -0
  91. package/dist/types/components/InviteFormWeb.d.ts +87 -0
  92. package/dist/types/components/InviteFormWeb.d.ts.map +1 -0
  93. package/dist/types/components/PlacedItemToolbar.d.ts +16 -0
  94. package/dist/types/components/PlacedItemToolbar.d.ts.map +1 -0
  95. package/dist/types/components/ShareButtons.d.ts +29 -0
  96. package/dist/types/components/ShareButtons.d.ts.map +1 -0
  97. package/dist/types/components/VrtxContactsImport.d.ts +14 -0
  98. package/dist/types/components/VrtxContactsImport.d.ts.map +1 -0
  99. package/dist/types/components/VrtxEmailInvitations.d.ts +31 -0
  100. package/dist/types/components/VrtxEmailInvitations.d.ts.map +1 -0
  101. package/dist/types/components/VrtxFindFriends.d.ts +25 -0
  102. package/dist/types/components/VrtxFindFriends.d.ts.map +1 -0
  103. package/dist/types/components/VrtxHeading.d.ts +6 -0
  104. package/dist/types/components/VrtxHeading.d.ts.map +1 -0
  105. package/dist/types/components/VrtxIncomingInvitations.d.ts +27 -0
  106. package/dist/types/components/VrtxIncomingInvitations.d.ts.map +1 -0
  107. package/dist/types/components/VrtxInvitationSuggestions.d.ts +25 -0
  108. package/dist/types/components/VrtxInvitationSuggestions.d.ts.map +1 -0
  109. package/dist/types/components/VrtxInviteContacts.d.ts +24 -0
  110. package/dist/types/components/VrtxInviteContacts.d.ts.map +1 -0
  111. package/dist/types/components/VrtxOutgoingInvitations.d.ts +27 -0
  112. package/dist/types/components/VrtxOutgoingInvitations.d.ts.map +1 -0
  113. package/dist/types/components/VrtxSearchBox.d.ts +28 -0
  114. package/dist/types/components/VrtxSearchBox.d.ts.map +1 -0
  115. package/dist/types/components/VrtxSelect.d.ts +6 -0
  116. package/dist/types/components/VrtxSelect.d.ts.map +1 -0
  117. package/dist/types/components/VrtxShareOptions.d.ts +41 -0
  118. package/dist/types/components/VrtxShareOptions.d.ts.map +1 -0
  119. package/dist/types/components/VrtxSubmit.d.ts +18 -0
  120. package/dist/types/components/VrtxSubmit.d.ts.map +1 -0
  121. package/dist/types/components/VrtxText.d.ts +8 -0
  122. package/dist/types/components/VrtxText.d.ts.map +1 -0
  123. package/dist/types/constants/mockData.d.ts +4 -0
  124. package/dist/types/constants/mockData.d.ts.map +1 -0
  125. package/dist/types/context/VortexModulesContext.d.ts +238 -0
  126. package/dist/types/context/VortexModulesContext.d.ts.map +1 -0
  127. package/dist/types/findFriends.js +10 -0
  128. package/dist/types/findFriends.js.map +1 -0
  129. package/dist/types/hooks/useInvitationFormLogic.d.ts +55 -0
  130. package/dist/types/hooks/useInvitationFormLogic.d.ts.map +1 -0
  131. package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts +39 -0
  132. package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts.map +1 -0
  133. package/dist/types/hooks/useThemeStyles.d.ts +35 -0
  134. package/dist/types/hooks/useThemeStyles.d.ts.map +1 -0
  135. package/dist/types/hooks/useVortexInvite.d.ts +86 -0
  136. package/dist/types/hooks/useVortexInvite.d.ts.map +1 -0
  137. package/dist/types/index-web.d.ts +23 -0
  138. package/dist/types/index-web.d.ts.map +1 -0
  139. package/dist/types/index.d.ts +23 -0
  140. package/dist/types/index.d.ts.map +1 -0
  141. package/dist/types/invitations.js +13 -0
  142. package/dist/types/invitations.js.map +1 -0
  143. package/dist/types/inviteContacts.js +14 -0
  144. package/dist/types/inviteContacts.js.map +1 -0
  145. package/dist/types/platformOperations.js +3 -0
  146. package/dist/types/platformOperations.js.map +1 -0
  147. package/dist/types/searchBox.js +11 -0
  148. package/dist/types/searchBox.js.map +1 -0
  149. package/dist/types/types/findFriends.d.ts +101 -0
  150. package/dist/types/types/findFriends.d.ts.map +1 -0
  151. package/dist/types/types/invitations.d.ts +301 -0
  152. package/dist/types/types/invitations.d.ts.map +1 -0
  153. package/dist/types/types/inviteContacts.d.ts +86 -0
  154. package/dist/types/types/inviteContacts.d.ts.map +1 -0
  155. package/dist/types/types/platformOperations.d.ts +185 -0
  156. package/dist/types/types/platformOperations.d.ts.map +1 -0
  157. package/dist/types/types/searchBox.d.ts +69 -0
  158. package/dist/types/types/searchBox.d.ts.map +1 -0
  159. package/dist/types/types/unfurlConfig.d.ts +34 -0
  160. package/dist/types/types/unfurlConfig.d.ts.map +1 -0
  161. package/dist/types/unfurlConfig.js +21 -0
  162. package/dist/types/unfurlConfig.js.map +1 -0
  163. package/dist/types/utils/analytics.d.ts +54 -0
  164. package/dist/types/utils/analytics.d.ts.map +1 -0
  165. package/dist/types/utils/configCache.d.ts +34 -0
  166. package/dist/types/utils/configCache.d.ts.map +1 -0
  167. package/dist/types/utils/contactUtils.d.ts +9 -0
  168. package/dist/types/utils/contactUtils.d.ts.map +1 -0
  169. package/dist/types/utils/featureWarnings.d.ts +56 -0
  170. package/dist/types/utils/featureWarnings.d.ts.map +1 -0
  171. package/dist/types/utils/formUtils.d.ts +93 -0
  172. package/dist/types/utils/formUtils.d.ts.map +1 -0
  173. package/dist/types/utils/gradientUtils.d.ts +67 -0
  174. package/dist/types/utils/gradientUtils.d.ts.map +1 -0
  175. package/dist/types/utils/invitationEvents.d.ts +21 -0
  176. package/dist/types/utils/invitationEvents.d.ts.map +1 -0
  177. package/dist/types/utils/moduleLoaders.d.ts +115 -0
  178. package/dist/types/utils/moduleLoaders.d.ts.map +1 -0
  179. package/dist/types/utils/moduleLoaders.web.d.ts +73 -0
  180. package/dist/types/utils/moduleLoaders.web.d.ts.map +1 -0
  181. package/dist/types/utils/nameUtils.d.ts +15 -0
  182. package/dist/types/utils/nameUtils.d.ts.map +1 -0
  183. package/dist/types/utils/themeUtils.d.ts +38 -0
  184. package/dist/types/utils/themeUtils.d.ts.map +1 -0
  185. package/dist/types/vortexInvite.d.ts +165 -0
  186. package/dist/types/vortexInvite.d.ts.map +1 -0
  187. package/dist/useInvitationFormLogic-Ct73M19B.d.mts +242 -0
  188. package/dist/useInvitationFormLogic-Ct73M19B.d.ts +242 -0
  189. package/dist/utils/analytics.js +92 -0
  190. package/dist/utils/analytics.js.map +1 -0
  191. package/dist/utils/configCache.js +68 -0
  192. package/dist/utils/configCache.js.map +1 -0
  193. package/dist/utils/contactUtils.d.mts +12 -0
  194. package/dist/utils/contactUtils.d.ts +12 -0
  195. package/dist/utils/contactUtils.js +37 -0
  196. package/dist/utils/contactUtils.js.map +1 -0
  197. package/dist/utils/contactUtils.mjs +12 -0
  198. package/dist/utils/contactUtils.mjs.map +1 -0
  199. package/dist/utils/featureWarnings.js +214 -0
  200. package/dist/utils/featureWarnings.js.map +1 -0
  201. package/dist/utils/formUtils.js +284 -0
  202. package/dist/utils/formUtils.js.map +1 -0
  203. package/dist/utils/gradientUtils.js +120 -0
  204. package/dist/utils/gradientUtils.js.map +1 -0
  205. package/dist/utils/invitationEvents.js +45 -0
  206. package/dist/utils/invitationEvents.js.map +1 -0
  207. package/dist/utils/moduleLoaders.js +275 -0
  208. package/dist/utils/moduleLoaders.js.map +1 -0
  209. package/dist/utils/moduleLoaders.web.js +72 -0
  210. package/dist/utils/moduleLoaders.web.js.map +1 -0
  211. package/dist/utils/nameUtils.js +51 -0
  212. package/dist/utils/nameUtils.js.map +1 -0
  213. package/dist/utils/themeUtils.js +141 -0
  214. package/dist/utils/themeUtils.js.map +1 -0
  215. package/dist/vortexInvite.js +83 -0
  216. package/dist/vortexInvite.js.map +1 -0
  217. package/package.json +21 -56
@@ -0,0 +1,657 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.VrtxIncomingInvitations = VrtxIncomingInvitations;
46
+ const react_1 = __importStar(require("react"));
47
+ const react_native_1 = require("react-native");
48
+ const analytics_client_1 = require("@teamvortexsoftware/analytics-client");
49
+ const VortexClient_1 = require("../VortexClient");
50
+ const VortexModulesContext_1 = require("../context/VortexModulesContext");
51
+ const isWeb = react_native_1.Platform.OS === 'web';
52
+ // Parse CSS linear-gradient to extract first color for fallback on native
53
+ function parseGradientFirstColor(gradientString) {
54
+ if (!gradientString || !gradientString.includes('linear-gradient')) {
55
+ return null;
56
+ }
57
+ const stopsRegex = /(rgba?\([^)]+\)|#[0-9a-fA-F]{3,8}|[a-z]+)\s+(\d+)%/i;
58
+ const match = stopsRegex.exec(gradientString);
59
+ if (match) {
60
+ return match[1].trim();
61
+ }
62
+ return null;
63
+ }
64
+ function ButtonWrapper({ children, style, gradientString, onPress, disabled, }) {
65
+ const { gradientModule, loaders } = (0, VortexModulesContext_1.useVortexModules)();
66
+ const styleArray = Array.isArray(style) ? style : [style];
67
+ // On web, use CSS gradients directly
68
+ if (gradientString && isWeb) {
69
+ return (<react_native_1.TouchableOpacity style={[...styleArray, { background: gradientString }]} onPress={onPress} disabled={disabled} activeOpacity={0.7}>
70
+ {children}
71
+ </react_native_1.TouchableOpacity>);
72
+ }
73
+ // On native, try to use gradient library if specified
74
+ if (gradientString && gradientModule && loaders) {
75
+ const GradientComponent = loaders.loadGradientComponent(gradientModule);
76
+ const parsed = loaders.parseCSSLinearGradient(gradientString);
77
+ if (GradientComponent && parsed) {
78
+ const points = loaders.angleToGradientPoints(parsed.angle);
79
+ return (<react_native_1.TouchableOpacity onPress={onPress} disabled={disabled} activeOpacity={0.7}>
80
+ <GradientComponent colors={parsed.colors} locations={parsed.locations} start={points.start} end={points.end} style={styleArray}>
81
+ {children}
82
+ </GradientComponent>
83
+ </react_native_1.TouchableOpacity>);
84
+ }
85
+ }
86
+ // Fallback: solid color from first gradient stop
87
+ const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;
88
+ const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;
89
+ return (<react_native_1.TouchableOpacity style={finalStyle} onPress={onPress} disabled={disabled} activeOpacity={0.7}>
90
+ {children}
91
+ </react_native_1.TouchableOpacity>);
92
+ }
93
+ // Animated item wrapper for fade-out effect
94
+ function AnimatedInvitationItem({ item, renderContent, onRemove, }) {
95
+ const fadeAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
96
+ const heightAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
97
+ const animateOut = (0, react_1.useCallback)(() => {
98
+ react_native_1.Animated.parallel([
99
+ react_native_1.Animated.timing(fadeAnim, {
100
+ toValue: 0,
101
+ duration: 200,
102
+ useNativeDriver: true,
103
+ }),
104
+ react_native_1.Animated.timing(heightAnim, {
105
+ toValue: 0,
106
+ duration: 200,
107
+ useNativeDriver: true,
108
+ }),
109
+ ]).start(() => {
110
+ onRemove(item.id);
111
+ });
112
+ }, [fadeAnim, heightAnim, item.id, onRemove]);
113
+ return (<react_native_1.Animated.View style={{
114
+ opacity: fadeAnim,
115
+ transform: [{ scaleY: heightAnim }],
116
+ }}>
117
+ {renderContent(Object.assign(Object.assign({}, item), { metadata: Object.assign(Object.assign({}, item.metadata), { animateOut }) }))}
118
+ </react_native_1.Animated.View>);
119
+ }
120
+ function VrtxIncomingInvitations({ block, incomingInvitationsConfig, apiUrl, jwt, triggerHaptic, theme, onAnalyticsEvent, }) {
121
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
122
+ // Local state for managing the displayed invitations (for animate-out)
123
+ const [displayedInvitations, setDisplayedInvitations] = (0, react_1.useState)((incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.invitations) || []);
124
+ const [actionInProgress, setActionInProgress] = (0, react_1.useState)(null);
125
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
126
+ // Fetch invitations from API in the background.
127
+ // Note: This component may remount multiple times due to parent re-renders
128
+ // (EditableWrapper is defined inside InviteFormCore's render body).
129
+ // To avoid flashing a loading spinner on each remount, we show config
130
+ // invitations immediately and only show loading if there are none.
131
+ (0, react_1.useEffect)(() => {
132
+ var _a, _b;
133
+ if (!apiUrl || !jwt)
134
+ return;
135
+ let cancelled = false;
136
+ const hasConfigInvitations = ((_b = (_a = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.invitations) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
137
+ // Only show loading spinner if we have NO config invitations to display
138
+ if (!hasConfigInvitations) {
139
+ setIsLoading(true);
140
+ }
141
+ const loadInvitations = () => __awaiter(this, void 0, void 0, function* () {
142
+ try {
143
+ const client = new VortexClient_1.VortexClient({ jwt, baseURL: apiUrl });
144
+ const apiInvitations = yield client.getIncomingInvitations();
145
+ // Filter out already accepted invitations (client-side filter)
146
+ const pendingInvitations = apiInvitations.filter((inv) => {
147
+ var _a, _b;
148
+ const status = (_b = (_a = inv.status) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
149
+ return status !== 'accepted' && status !== 'accepted_elsewhere';
150
+ });
151
+ // Map API invitations to InvitationItem format
152
+ const mappedInvitations = pendingInvitations.map((inv) => ({
153
+ id: inv.id,
154
+ name: inv.creatorName || inv.senderIdentifier || 'Unknown',
155
+ userId: inv.foreignCreatorId || undefined,
156
+ avatarUrl: inv.creatorAvatarUrl || inv.avatarUrl,
157
+ isVortexInvitation: true,
158
+ metadata: inv.metadata || undefined,
159
+ }));
160
+ if (!cancelled) {
161
+ // Merge config invitations with API invitations, deduplicating by userId.
162
+ const configInvitations = (incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.invitations) || [];
163
+ const apiUserIds = new Set(mappedInvitations
164
+ .filter((inv) => inv.userId)
165
+ .map((inv) => inv.userId));
166
+ const dedupedConfig = configInvitations.filter((inv) => !inv.userId || !apiUserIds.has(inv.userId));
167
+ setDisplayedInvitations([...dedupedConfig, ...mappedInvitations]);
168
+ }
169
+ }
170
+ catch (error) {
171
+ // Silently fail - just show config invitations
172
+ if (__DEV__) {
173
+ console.warn('[VrtxIncomingInvitations] Failed to fetch incoming invitations:', error);
174
+ }
175
+ }
176
+ finally {
177
+ if (!cancelled) {
178
+ setIsLoading(false);
179
+ }
180
+ }
181
+ });
182
+ loadInvitations();
183
+ return () => { cancelled = true; };
184
+ }, [apiUrl, jwt, incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.invitations]);
185
+ // Extract customization from block settings or config props, with defaults
186
+ const blockCustomizations = (_a = block === null || block === void 0 ? void 0 : block.settings) === null || _a === void 0 ? void 0 : _a.customizations;
187
+ const acceptButtonText = (_d = (_c = (_b = blockCustomizations === null || blockCustomizations === void 0 ? void 0 : blockCustomizations.acceptButton) === null || _b === void 0 ? void 0 : _b.textContent) !== null && _c !== void 0 ? _c : incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.acceptButtonText) !== null && _d !== void 0 ? _d : 'Accept';
188
+ const deleteButtonText = (_g = (_f = (_e = blockCustomizations === null || blockCustomizations === void 0 ? void 0 : blockCustomizations.deleteButton) === null || _e === void 0 ? void 0 : _e.textContent) !== null && _f !== void 0 ? _f : incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.deleteButtonText) !== null && _g !== void 0 ? _g : 'Delete';
189
+ const emptyStateMessage = (_k = (_j = (_h = blockCustomizations === null || blockCustomizations === void 0 ? void 0 : blockCustomizations.emptyStateMessage) === null || _h === void 0 ? void 0 : _h.textContent) !== null && _j !== void 0 ? _j : incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.emptyStateMessage) !== null && _k !== void 0 ? _k : 'No incoming invitations';
190
+ // Confirmation dialog texts
191
+ const acceptConfirmTitle = (_l = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.acceptConfirmTitle) !== null && _l !== void 0 ? _l : 'Accept Invitation';
192
+ const acceptConfirmMessage = (_m = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.acceptConfirmMessage) !== null && _m !== void 0 ? _m : 'Accept invitation from {name}?';
193
+ const deleteConfirmTitle = (_o = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.deleteConfirmTitle) !== null && _o !== void 0 ? _o : 'Delete Invitation';
194
+ const deleteConfirmMessage = (_p = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.deleteConfirmMessage) !== null && _p !== void 0 ? _p : 'Delete invitation from {name}?';
195
+ const confirmButtonText = (_q = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.confirmButtonText) !== null && _q !== void 0 ? _q : 'Confirm';
196
+ const cancelButtonText = (_r = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.cancelButtonText) !== null && _r !== void 0 ? _r : 'Cancel';
197
+ // Helper to get theme option value from block.theme.options
198
+ const getBlockThemeValue = (key) => {
199
+ var _a;
200
+ const options = (_a = block === null || block === void 0 ? void 0 : block.theme) === null || _a === void 0 ? void 0 : _a.options;
201
+ if (!options || !Array.isArray(options))
202
+ return undefined;
203
+ const option = options.find((opt) => opt.key === key);
204
+ return (option === null || option === void 0 ? void 0 : option.value) || undefined;
205
+ };
206
+ // Theme colors with defaults
207
+ const colors = {
208
+ primaryBackground: (_s = theme === null || theme === void 0 ? void 0 : theme.primaryBackground) !== null && _s !== void 0 ? _s : '#6291d5',
209
+ primaryForeground: (_t = theme === null || theme === void 0 ? void 0 : theme.primaryForeground) !== null && _t !== void 0 ? _t : '#ffffff',
210
+ secondaryBackground: (_u = theme === null || theme === void 0 ? void 0 : theme.secondaryBackground) !== null && _u !== void 0 ? _u : '#ffffff',
211
+ secondaryForeground: (_v = theme === null || theme === void 0 ? void 0 : theme.secondaryForeground) !== null && _v !== void 0 ? _v : '#353e5c',
212
+ foreground: (_w = theme === null || theme === void 0 ? void 0 : theme.foreground) !== null && _w !== void 0 ? _w : '#334153',
213
+ border: (_x = theme === null || theme === void 0 ? void 0 : theme.border) !== null && _x !== void 0 ? _x : '#cccccc',
214
+ };
215
+ // Button styles from block.theme.options (microTheme)
216
+ const acceptButtonStyles = {
217
+ background: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-background') ||
218
+ colors.primaryBackground,
219
+ color: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-color') ||
220
+ colors.primaryForeground,
221
+ borderRadius: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-border-radius'),
222
+ border: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-border'),
223
+ padding: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-padding'),
224
+ fontSize: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-font-size'),
225
+ fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-accept-button-font-weight'),
226
+ };
227
+ const deleteButtonStyles = {
228
+ background: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-background') ||
229
+ colors.secondaryBackground,
230
+ color: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-color') ||
231
+ colors.secondaryForeground,
232
+ borderRadius: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-border-radius'),
233
+ border: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-border'),
234
+ padding: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-padding'),
235
+ fontSize: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-font-size'),
236
+ fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-delete-button-font-weight'),
237
+ };
238
+ // Avatar/initials styles from block.theme.options (microTheme)
239
+ const avatarStyles = {
240
+ background: getBlockThemeValue('--vrtx-incoming-invitations-avatar-background') ||
241
+ colors.primaryBackground,
242
+ color: getBlockThemeValue('--vrtx-incoming-invitations-avatar-color') || colors.primaryForeground,
243
+ };
244
+ // Contact name styles from block.theme.options (microTheme)
245
+ const nameStyles = {
246
+ color: getBlockThemeValue('--vrtx-incoming-invitations-name-color') || colors.foreground,
247
+ fontFamily: getBlockThemeValue('--vrtx-incoming-invitations-name-font-family'),
248
+ fontSize: getBlockThemeValue('--vrtx-incoming-invitations-name-font-size'),
249
+ fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-name-font-weight'),
250
+ };
251
+ // Subtitle styles from block.theme.options (microTheme)
252
+ const subtitleStyles = {
253
+ color: getBlockThemeValue('--vrtx-incoming-invitations-subtitle-color') ||
254
+ colors.secondaryForeground,
255
+ fontFamily: getBlockThemeValue('--vrtx-incoming-invitations-subtitle-font-family'),
256
+ fontSize: getBlockThemeValue('--vrtx-incoming-invitations-subtitle-font-size'),
257
+ };
258
+ // Title styles from block.theme.options (microTheme)
259
+ const titleStyles = {
260
+ color: getBlockThemeValue('--vrtx-incoming-invitations-title-color') || colors.foreground,
261
+ fontFamily: getBlockThemeValue('--vrtx-incoming-invitations-title-font-family'),
262
+ fontSize: getBlockThemeValue('--vrtx-incoming-invitations-title-font-size'),
263
+ fontWeight: getBlockThemeValue('--vrtx-incoming-invitations-title-font-weight'),
264
+ };
265
+ // Remove invitation from displayed list (after animation)
266
+ const handleRemoveFromDisplay = (0, react_1.useCallback)((id) => {
267
+ setDisplayedInvitations((prev) => prev.filter((inv) => inv.id !== id));
268
+ }, []);
269
+ // Show confirmation dialog
270
+ const showConfirmation = (0, react_1.useCallback)((title, message, onConfirm) => {
271
+ if (isWeb) {
272
+ // Web: use window.confirm
273
+ const confirmed = window.confirm(message);
274
+ if (confirmed) {
275
+ onConfirm();
276
+ }
277
+ }
278
+ else {
279
+ // Native: use Alert
280
+ react_native_1.Alert.alert(title, message, [
281
+ {
282
+ text: cancelButtonText,
283
+ style: 'cancel',
284
+ },
285
+ {
286
+ text: confirmButtonText,
287
+ onPress: onConfirm,
288
+ },
289
+ ]);
290
+ }
291
+ }, [confirmButtonText, cancelButtonText]);
292
+ // Handle Accept button press
293
+ const handleAccept = (0, react_1.useCallback)((invitation, animateOut) => __awaiter(this, void 0, void 0, function* () {
294
+ const message = acceptConfirmMessage.replace('{name}', invitation.name);
295
+ showConfirmation(acceptConfirmTitle, message, () => __awaiter(this, void 0, void 0, function* () {
296
+ setActionInProgress(invitation.id);
297
+ yield (triggerHaptic === null || triggerHaptic === void 0 ? void 0 : triggerHaptic('light'));
298
+ // Emit analytics event for accept button click
299
+ onAnalyticsEvent === null || onAnalyticsEvent === void 0 ? void 0 : onAnalyticsEvent({
300
+ name: analytics_client_1.EventNames.INBOUND_INVITATION_ACCEPT_CLICKED,
301
+ payload: { invitationId: invitation.id, inviterName: invitation.name },
302
+ });
303
+ try {
304
+ // Call the callback if provided and check return value
305
+ let shouldProceed = true;
306
+ if (incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.onAccept) {
307
+ const result = yield incomingInvitationsConfig.onAccept(invitation);
308
+ // If callback returns false explicitly, don't proceed
309
+ if (result === false) {
310
+ shouldProceed = false;
311
+ }
312
+ }
313
+ if (!shouldProceed) {
314
+ setActionInProgress(null);
315
+ return;
316
+ }
317
+ // Only call Vortex API for Vortex invitations
318
+ if (invitation.isVortexInvitation && apiUrl && jwt) {
319
+ const client = new VortexClient_1.VortexClient({ jwt, baseURL: apiUrl });
320
+ const result = yield client.acceptIncomingInvitation(invitation.id);
321
+ if (!result.success) {
322
+ console.error('[VrtxIncomingInvitations] API accept failed:', result.message);
323
+ throw new Error(result.message || 'Failed to accept invitation');
324
+ }
325
+ }
326
+ // Animate out after successful action
327
+ if (animateOut) {
328
+ animateOut();
329
+ }
330
+ else {
331
+ handleRemoveFromDisplay(invitation.id);
332
+ }
333
+ }
334
+ catch (err) {
335
+ console.error('[VrtxIncomingInvitations] Accept failed:', err);
336
+ }
337
+ finally {
338
+ setActionInProgress(null);
339
+ }
340
+ }));
341
+ }), [
342
+ incomingInvitationsConfig,
343
+ apiUrl,
344
+ jwt,
345
+ triggerHaptic,
346
+ acceptConfirmTitle,
347
+ acceptConfirmMessage,
348
+ showConfirmation,
349
+ handleRemoveFromDisplay,
350
+ onAnalyticsEvent,
351
+ ]);
352
+ // Handle Delete button press
353
+ const handleDelete = (0, react_1.useCallback)((invitation, animateOut) => __awaiter(this, void 0, void 0, function* () {
354
+ const message = deleteConfirmMessage.replace('{name}', invitation.name);
355
+ showConfirmation(deleteConfirmTitle, message, () => __awaiter(this, void 0, void 0, function* () {
356
+ setActionInProgress(invitation.id);
357
+ yield (triggerHaptic === null || triggerHaptic === void 0 ? void 0 : triggerHaptic('light'));
358
+ // Emit analytics event for delete button click
359
+ onAnalyticsEvent === null || onAnalyticsEvent === void 0 ? void 0 : onAnalyticsEvent({
360
+ name: analytics_client_1.EventNames.INBOUND_INVITATION_DELETE_CLICKED,
361
+ payload: { invitationId: invitation.id, inviterName: invitation.name },
362
+ });
363
+ try {
364
+ // Call the callback if provided and check return value
365
+ let shouldProceed = true;
366
+ if (incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.onDelete) {
367
+ const result = yield incomingInvitationsConfig.onDelete(invitation);
368
+ // If callback returns false explicitly, don't proceed
369
+ if (result === false) {
370
+ shouldProceed = false;
371
+ }
372
+ }
373
+ if (!shouldProceed) {
374
+ setActionInProgress(null);
375
+ return;
376
+ }
377
+ // Only call Vortex API for Vortex invitations
378
+ if (invitation.isVortexInvitation && apiUrl && jwt) {
379
+ const client = new VortexClient_1.VortexClient({ jwt, baseURL: apiUrl });
380
+ const result = yield client.deleteIncomingInvitation(invitation.id);
381
+ if (!result.success) {
382
+ console.error('[VrtxIncomingInvitations] API delete failed:', result.message);
383
+ throw new Error(result.message || 'Failed to delete invitation');
384
+ }
385
+ }
386
+ // Animate out after successful action
387
+ if (animateOut) {
388
+ animateOut();
389
+ }
390
+ else {
391
+ handleRemoveFromDisplay(invitation.id);
392
+ }
393
+ }
394
+ catch (err) {
395
+ console.error('[VrtxIncomingInvitations] Delete failed:', err);
396
+ }
397
+ finally {
398
+ setActionInProgress(null);
399
+ }
400
+ }));
401
+ }), [
402
+ incomingInvitationsConfig,
403
+ apiUrl,
404
+ jwt,
405
+ triggerHaptic,
406
+ deleteConfirmTitle,
407
+ deleteConfirmMessage,
408
+ showConfirmation,
409
+ handleRemoveFromDisplay,
410
+ onAnalyticsEvent,
411
+ ]);
412
+ // Helper to parse CSS padding string to React Native padding object
413
+ const parsePadding = (paddingStr) => {
414
+ if (!paddingStr)
415
+ return {};
416
+ const parts = paddingStr.trim().split(/\s+/);
417
+ if (parts.length === 1) {
418
+ const val = parseInt(parts[0], 10);
419
+ return isNaN(val) ? {} : { paddingVertical: val, paddingHorizontal: val };
420
+ }
421
+ if (parts.length === 2) {
422
+ const vertical = parseInt(parts[0], 10);
423
+ const horizontal = parseInt(parts[1], 10);
424
+ return Object.assign(Object.assign({}, (isNaN(vertical) ? {} : { paddingVertical: vertical })), (isNaN(horizontal) ? {} : { paddingHorizontal: horizontal }));
425
+ }
426
+ return {};
427
+ };
428
+ // Helper to parse border string (e.g., "1px solid #ccc")
429
+ const parseBorder = (borderStr) => {
430
+ if (!borderStr)
431
+ return {};
432
+ const match = borderStr.match(/^(\d+)px\s+(\w+)\s+(.+)$/);
433
+ if (match) {
434
+ return {
435
+ borderWidth: parseInt(match[1], 10),
436
+ borderColor: match[3],
437
+ };
438
+ }
439
+ return {};
440
+ };
441
+ // Render avatar or initials
442
+ const renderAvatar = (invitation) => {
443
+ if (invitation.avatarUrl) {
444
+ return <react_native_1.Image source={{ uri: invitation.avatarUrl }} style={styles.avatar}/>;
445
+ }
446
+ // Generate initials from name
447
+ const initials = invitation.name
448
+ .split(' ')
449
+ .map((part) => part[0])
450
+ .join('')
451
+ .toUpperCase()
452
+ .slice(0, 2);
453
+ // Handle avatar background with gradient support
454
+ const avatarBackground = avatarStyles.background;
455
+ const isAvatarGradient = avatarBackground === null || avatarBackground === void 0 ? void 0 : avatarBackground.includes('linear-gradient');
456
+ const avatarBgStyle = {};
457
+ if (isWeb && avatarBackground) {
458
+ avatarBgStyle.background = avatarBackground;
459
+ }
460
+ else if (isAvatarGradient && avatarBackground) {
461
+ const fallbackColor = parseGradientFirstColor(avatarBackground);
462
+ avatarBgStyle.backgroundColor = fallbackColor || colors.primaryBackground;
463
+ }
464
+ else {
465
+ avatarBgStyle.backgroundColor = avatarBackground || colors.primaryBackground;
466
+ }
467
+ return (<react_native_1.View style={[styles.avatarPlaceholder, avatarBgStyle]}>
468
+ <react_native_1.Text style={[styles.avatarInitials, { color: avatarStyles.color }]}>{initials}</react_native_1.Text>
469
+ </react_native_1.View>);
470
+ };
471
+ // Build button style with gradient support
472
+ const buildButtonStyle = (buttonStyles, fallbackBg) => {
473
+ const backgroundValue = buttonStyles.background;
474
+ const isGradient = backgroundValue === null || backgroundValue === void 0 ? void 0 : backgroundValue.includes('linear-gradient');
475
+ const dynamicButtonStyle = Object.assign(Object.assign(Object.assign({}, (buttonStyles.borderRadius
476
+ ? { borderRadius: parseInt(buttonStyles.borderRadius, 10) }
477
+ : {})), parsePadding(buttonStyles.padding)), parseBorder(buttonStyles.border));
478
+ if (isWeb && backgroundValue) {
479
+ dynamicButtonStyle.background = backgroundValue;
480
+ }
481
+ else if (isGradient && backgroundValue) {
482
+ const fallbackColor = parseGradientFirstColor(backgroundValue);
483
+ dynamicButtonStyle.backgroundColor = fallbackColor || fallbackBg;
484
+ }
485
+ else {
486
+ dynamicButtonStyle.backgroundColor = backgroundValue || fallbackBg;
487
+ }
488
+ return dynamicButtonStyle;
489
+ };
490
+ // Render a single invitation item
491
+ const renderInvitationContent = (item) => {
492
+ var _a, _b, _c;
493
+ const isLoading = actionInProgress === item.id;
494
+ const animateOut = (_a = item.metadata) === null || _a === void 0 ? void 0 : _a.animateOut;
495
+ // Build dynamic button styles
496
+ const deleteButtonDynamicStyle = buildButtonStyle(deleteButtonStyles, colors.secondaryBackground);
497
+ const acceptButtonDynamicStyle = buildButtonStyle(acceptButtonStyles, colors.primaryBackground);
498
+ // Build dynamic text styles
499
+ const deleteTextStyle = Object.assign(Object.assign({ color: deleteButtonStyles.color }, (deleteButtonStyles.fontSize ? { fontSize: parseInt(deleteButtonStyles.fontSize, 10) } : {})), (deleteButtonStyles.fontWeight ? { fontWeight: deleteButtonStyles.fontWeight } : {}));
500
+ const acceptTextStyle = Object.assign(Object.assign({ color: acceptButtonStyles.color }, (acceptButtonStyles.fontSize ? { fontSize: parseInt(acceptButtonStyles.fontSize, 10) } : {})), (acceptButtonStyles.fontWeight ? { fontWeight: acceptButtonStyles.fontWeight } : {}));
501
+ // Build dynamic name style
502
+ const dynamicNameStyle = Object.assign(Object.assign(Object.assign({ color: nameStyles.color }, (nameStyles.fontFamily ? { fontFamily: nameStyles.fontFamily } : {})), (nameStyles.fontSize ? { fontSize: parseInt(nameStyles.fontSize, 10) } : {})), (nameStyles.fontWeight ? { fontWeight: nameStyles.fontWeight } : {}));
503
+ // Build dynamic subtitle style
504
+ const dynamicSubtitleStyle = Object.assign(Object.assign({ color: subtitleStyles.color }, (subtitleStyles.fontFamily ? { fontFamily: subtitleStyles.fontFamily } : {})), (subtitleStyles.fontSize ? { fontSize: parseInt(subtitleStyles.fontSize, 10) } : {}));
505
+ return (<react_native_1.View style={styles.invitationItem}>
506
+ {renderAvatar(item)}
507
+ <react_native_1.View style={styles.invitationInfo}>
508
+ <react_native_1.Text style={[styles.invitationName, dynamicNameStyle]} numberOfLines={1}>
509
+ {item.name}
510
+ </react_native_1.Text>
511
+ {(() => {
512
+ var _a;
513
+ const displaySubtitle = (_a = incomingInvitationsConfig === null || incomingInvitationsConfig === void 0 ? void 0 : incomingInvitationsConfig.getSubtitle) === null || _a === void 0 ? void 0 : _a.call(incomingInvitationsConfig, item);
514
+ return displaySubtitle ? (<react_native_1.Text style={[styles.invitationSubtitle, dynamicSubtitleStyle]} numberOfLines={1}>
515
+ {displaySubtitle}
516
+ </react_native_1.Text>) : null;
517
+ })()}
518
+ </react_native_1.View>
519
+ <react_native_1.View style={styles.buttonContainer}>
520
+ {/* Delete button (left) */}
521
+ <ButtonWrapper style={[styles.actionButton, deleteButtonDynamicStyle, styles.deleteButton]} gradientString={((_b = deleteButtonStyles.background) === null || _b === void 0 ? void 0 : _b.includes('gradient')) ? deleteButtonStyles.background : null} onPress={() => handleDelete(item, animateOut)} disabled={isLoading}>
522
+ {isLoading ? (<react_native_1.ActivityIndicator size="small" color={deleteButtonStyles.color}/>) : (<react_native_1.Text style={[styles.actionButtonText, deleteTextStyle]}>{deleteButtonText}</react_native_1.Text>)}
523
+ </ButtonWrapper>
524
+ {/* Accept button (right) */}
525
+ <ButtonWrapper style={[styles.actionButton, acceptButtonDynamicStyle]} gradientString={((_c = acceptButtonStyles.background) === null || _c === void 0 ? void 0 : _c.includes('gradient')) ? acceptButtonStyles.background : null} onPress={() => handleAccept(item, animateOut)} disabled={isLoading}>
526
+ {isLoading ? (<react_native_1.ActivityIndicator size="small" color={acceptButtonStyles.color}/>) : (<react_native_1.Text style={[styles.actionButtonText, acceptTextStyle]}>{acceptButtonText}</react_native_1.Text>)}
527
+ </ButtonWrapper>
528
+ </react_native_1.View>
529
+ </react_native_1.View>);
530
+ };
531
+ // Render item with animation wrapper
532
+ const renderItem = ({ item }) => {
533
+ return (<AnimatedInvitationItem item={item} renderContent={renderInvitationContent} onRemove={handleRemoveFromDisplay}/>);
534
+ };
535
+ // Show placeholder if no config provided and no API credentials
536
+ if (!incomingInvitationsConfig && !(apiUrl && jwt)) {
537
+ const label = ((_y = block === null || block === void 0 ? void 0 : block.attributes) === null || _y === void 0 ? void 0 : _y.label) || '';
538
+ return (<react_native_1.View style={styles.container}>
539
+ {label ? <react_native_1.Text style={[styles.label, { color: colors.foreground }]}>{label}</react_native_1.Text> : null}
540
+ <react_native_1.Text style={[styles.placeholderText, { color: colors.secondaryForeground }]}>
541
+ Incoming Invitations component - provide incomingInvitationsConfig or apiUrl+jwt to enable
542
+ </react_native_1.Text>
543
+ </react_native_1.View>);
544
+ }
545
+ // Loading state — only shown when there are no config invitations to display
546
+ if (isLoading) {
547
+ return (<react_native_1.View style={styles.container}>
548
+ <react_native_1.ActivityIndicator size="large" color={colors.primaryBackground}/>
549
+ </react_native_1.View>);
550
+ }
551
+ // Empty state - render nothing (0 height) when no invitations, like iOS
552
+ if (displayedInvitations.length === 0) {
553
+ return null;
554
+ }
555
+ // Get title from block attributes (configured in editor as "Title")
556
+ const title = (_z = block === null || block === void 0 ? void 0 : block.attributes) === null || _z === void 0 ? void 0 : _z.title;
557
+ // Build dynamic title style
558
+ const dynamicTitleStyle = Object.assign(Object.assign(Object.assign({ color: titleStyles.color }, (titleStyles.fontFamily ? { fontFamily: titleStyles.fontFamily } : {})), (titleStyles.fontSize ? { fontSize: parseInt(titleStyles.fontSize, 10) } : {})), (titleStyles.fontWeight ? { fontWeight: titleStyles.fontWeight } : {}));
559
+ // Main view: Invitations list
560
+ // Note: Using View + map instead of FlatList to avoid "VirtualizedLists should never be nested" warning
561
+ // when this component is rendered inside a ScrollView (which InviteFormCore uses)
562
+ return (<react_native_1.View style={styles.listContainer}>
563
+ {title && (<react_native_1.Text style={[styles.title, dynamicTitleStyle]}>{title}</react_native_1.Text>)}
564
+ <react_native_1.View style={styles.listContent}>
565
+ {displayedInvitations.map((item) => (<react_native_1.View key={item.id}>
566
+ {renderItem({ item })}
567
+ </react_native_1.View>))}
568
+ </react_native_1.View>
569
+ </react_native_1.View>);
570
+ }
571
+ const styles = react_native_1.StyleSheet.create({
572
+ container: {
573
+ padding: 16,
574
+ alignItems: 'center',
575
+ justifyContent: 'center',
576
+ minHeight: 120,
577
+ },
578
+ listContainer: {
579
+ flex: 1,
580
+ },
581
+ title: {
582
+ fontSize: 16,
583
+ fontWeight: '600',
584
+ marginBottom: 12,
585
+ },
586
+ label: {
587
+ fontSize: 16,
588
+ fontWeight: '500',
589
+ marginBottom: 12,
590
+ },
591
+ placeholderText: {
592
+ fontSize: 14,
593
+ textAlign: 'center',
594
+ },
595
+ emptyText: {
596
+ fontSize: 14,
597
+ textAlign: 'center',
598
+ },
599
+ listContent: {
600
+ paddingBottom: 16,
601
+ },
602
+ invitationItem: {
603
+ flexDirection: 'row',
604
+ alignItems: 'center',
605
+ paddingVertical: 12,
606
+ },
607
+ avatar: {
608
+ width: 44,
609
+ height: 44,
610
+ borderRadius: 22,
611
+ },
612
+ avatarPlaceholder: {
613
+ width: 44,
614
+ height: 44,
615
+ borderRadius: 22,
616
+ alignItems: 'center',
617
+ justifyContent: 'center',
618
+ },
619
+ avatarInitials: {
620
+ fontSize: 16,
621
+ fontWeight: '600',
622
+ },
623
+ invitationInfo: {
624
+ flex: 1,
625
+ marginLeft: 12,
626
+ marginRight: 12,
627
+ },
628
+ invitationName: {
629
+ fontSize: 16,
630
+ fontWeight: '500',
631
+ },
632
+ invitationSubtitle: {
633
+ fontSize: 13,
634
+ marginTop: 2,
635
+ },
636
+ buttonContainer: {
637
+ flexDirection: 'row',
638
+ alignItems: 'center',
639
+ gap: 8,
640
+ },
641
+ actionButton: {
642
+ paddingHorizontal: 12,
643
+ paddingVertical: 8,
644
+ borderRadius: 8,
645
+ minWidth: 70,
646
+ alignItems: 'center',
647
+ justifyContent: 'center',
648
+ },
649
+ deleteButton: {
650
+ marginRight: 8,
651
+ },
652
+ actionButtonText: {
653
+ fontSize: 14,
654
+ fontWeight: '600',
655
+ },
656
+ });
657
+ //# sourceMappingURL=VrtxIncomingInvitations.js.map