be-components 7.6.3 → 7.6.4

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 (138) hide show
  1. package/lib/commonjs/NotificationManager/NotificationManagerTabs.js +188 -0
  2. package/lib/commonjs/NotificationManager/NotificationManagerTabs.js.map +1 -0
  3. package/lib/commonjs/NotificationManager/api/index.js +235 -6
  4. package/lib/commonjs/NotificationManager/api/index.js.map +1 -1
  5. package/lib/commonjs/NotificationManager/components/GroupManagement.js +1038 -0
  6. package/lib/commonjs/NotificationManager/components/GroupManagement.js.map +1 -0
  7. package/lib/commonjs/NotificationManager/components/JobManagement.js +783 -0
  8. package/lib/commonjs/NotificationManager/components/JobManagement.js.map +1 -0
  9. package/lib/commonjs/NotificationManager/components/ScheduleNotification.js +407 -0
  10. package/lib/commonjs/NotificationManager/components/ScheduleNotification.js.map +1 -0
  11. package/lib/commonjs/NotificationManager/components/index.js +56 -0
  12. package/lib/commonjs/NotificationManager/components/index.js.map +1 -0
  13. package/lib/commonjs/NotificationManager/components/shared/DateTimePicker.js +113 -0
  14. package/lib/commonjs/NotificationManager/components/shared/DateTimePicker.js.map +1 -0
  15. package/lib/commonjs/NotificationManager/components/shared/GroupSelector.js +191 -0
  16. package/lib/commonjs/NotificationManager/components/shared/GroupSelector.js.map +1 -0
  17. package/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.js +509 -0
  18. package/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.js.map +1 -0
  19. package/lib/commonjs/NotificationManager/components/shared/StatusBadge.js +69 -0
  20. package/lib/commonjs/NotificationManager/components/shared/StatusBadge.js.map +1 -0
  21. package/lib/commonjs/NotificationManager/index.js +38 -23
  22. package/lib/commonjs/NotificationManager/index.js.map +1 -1
  23. package/lib/commonjs/index.js +7 -0
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/types.d.js +2 -0
  26. package/lib/commonjs/types.d.js.map +1 -1
  27. package/lib/module/NotificationManager/NotificationManagerTabs.js +180 -0
  28. package/lib/module/NotificationManager/NotificationManagerTabs.js.map +1 -0
  29. package/lib/module/NotificationManager/api/index.js +235 -6
  30. package/lib/module/NotificationManager/api/index.js.map +1 -1
  31. package/lib/module/NotificationManager/components/GroupManagement.js +1030 -0
  32. package/lib/module/NotificationManager/components/GroupManagement.js.map +1 -0
  33. package/lib/module/NotificationManager/components/JobManagement.js +775 -0
  34. package/lib/module/NotificationManager/components/JobManagement.js.map +1 -0
  35. package/lib/module/NotificationManager/components/ScheduleNotification.js +399 -0
  36. package/lib/module/NotificationManager/components/ScheduleNotification.js.map +1 -0
  37. package/lib/module/NotificationManager/components/index.js +8 -0
  38. package/lib/module/NotificationManager/components/index.js.map +1 -0
  39. package/lib/module/NotificationManager/components/shared/DateTimePicker.js +106 -0
  40. package/lib/module/NotificationManager/components/shared/DateTimePicker.js.map +1 -0
  41. package/lib/module/NotificationManager/components/shared/GroupSelector.js +184 -0
  42. package/lib/module/NotificationManager/components/shared/GroupSelector.js.map +1 -0
  43. package/lib/module/NotificationManager/components/shared/NotificationBuilderForm.js +501 -0
  44. package/lib/module/NotificationManager/components/shared/NotificationBuilderForm.js.map +1 -0
  45. package/lib/module/NotificationManager/components/shared/StatusBadge.js +62 -0
  46. package/lib/module/NotificationManager/components/shared/StatusBadge.js.map +1 -0
  47. package/lib/module/NotificationManager/index.js +32 -23
  48. package/lib/module/NotificationManager/index.js.map +1 -1
  49. package/lib/module/index.js +2 -1
  50. package/lib/module/index.js.map +1 -1
  51. package/lib/module/types.d.js +2 -0
  52. package/lib/module/types.d.js.map +1 -1
  53. package/lib/typescript/lib/commonjs/NotificationManager/NotificationManagerTabs.d.ts +17 -0
  54. package/lib/typescript/lib/commonjs/NotificationManager/NotificationManagerTabs.d.ts.map +1 -0
  55. package/lib/typescript/lib/commonjs/NotificationManager/api/index.d.ts +17 -2
  56. package/lib/typescript/lib/commonjs/NotificationManager/api/index.d.ts.map +1 -1
  57. package/lib/typescript/lib/commonjs/NotificationManager/components/GroupManagement.d.ts +6 -0
  58. package/lib/typescript/lib/commonjs/NotificationManager/components/GroupManagement.d.ts.map +1 -0
  59. package/lib/typescript/lib/commonjs/NotificationManager/components/JobManagement.d.ts +7 -0
  60. package/lib/typescript/lib/commonjs/NotificationManager/components/JobManagement.d.ts.map +1 -0
  61. package/lib/typescript/lib/commonjs/NotificationManager/components/ScheduleNotification.d.ts +8 -0
  62. package/lib/typescript/lib/commonjs/NotificationManager/components/ScheduleNotification.d.ts.map +1 -0
  63. package/lib/typescript/lib/commonjs/NotificationManager/components/index.d.ts +9 -0
  64. package/lib/typescript/lib/commonjs/NotificationManager/components/index.d.ts.map +1 -0
  65. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/DateTimePicker.d.ts +9 -0
  66. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/DateTimePicker.d.ts.map +1 -0
  67. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/GroupSelector.d.ts +13 -0
  68. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/GroupSelector.d.ts.map +1 -0
  69. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.d.ts +10 -0
  70. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.d.ts.map +1 -0
  71. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/StatusBadge.d.ts +6 -0
  72. package/lib/typescript/lib/commonjs/NotificationManager/components/shared/StatusBadge.d.ts.map +1 -0
  73. package/lib/typescript/lib/commonjs/NotificationManager/index.d.ts +18 -2
  74. package/lib/typescript/lib/commonjs/NotificationManager/index.d.ts.map +1 -1
  75. package/lib/typescript/lib/commonjs/index.d.ts +18 -2
  76. package/lib/typescript/lib/commonjs/index.d.ts.map +1 -1
  77. package/lib/typescript/lib/module/NotificationManager/NotificationManagerTabs.d.ts +17 -0
  78. package/lib/typescript/lib/module/NotificationManager/NotificationManagerTabs.d.ts.map +1 -0
  79. package/lib/typescript/lib/module/NotificationManager/api/index.d.ts +17 -2
  80. package/lib/typescript/lib/module/NotificationManager/api/index.d.ts.map +1 -1
  81. package/lib/typescript/lib/module/NotificationManager/components/GroupManagement.d.ts +6 -0
  82. package/lib/typescript/lib/module/NotificationManager/components/GroupManagement.d.ts.map +1 -0
  83. package/lib/typescript/lib/module/NotificationManager/components/JobManagement.d.ts +7 -0
  84. package/lib/typescript/lib/module/NotificationManager/components/JobManagement.d.ts.map +1 -0
  85. package/lib/typescript/lib/module/NotificationManager/components/ScheduleNotification.d.ts +8 -0
  86. package/lib/typescript/lib/module/NotificationManager/components/ScheduleNotification.d.ts.map +1 -0
  87. package/lib/typescript/lib/module/NotificationManager/components/index.d.ts +8 -0
  88. package/lib/typescript/lib/module/NotificationManager/components/index.d.ts.map +1 -0
  89. package/lib/typescript/lib/module/NotificationManager/components/shared/DateTimePicker.d.ts +9 -0
  90. package/lib/typescript/lib/module/NotificationManager/components/shared/DateTimePicker.d.ts.map +1 -0
  91. package/lib/typescript/lib/module/NotificationManager/components/shared/GroupSelector.d.ts +13 -0
  92. package/lib/typescript/lib/module/NotificationManager/components/shared/GroupSelector.d.ts.map +1 -0
  93. package/lib/typescript/lib/module/NotificationManager/components/shared/NotificationBuilderForm.d.ts +10 -0
  94. package/lib/typescript/lib/module/NotificationManager/components/shared/NotificationBuilderForm.d.ts.map +1 -0
  95. package/lib/typescript/lib/module/NotificationManager/components/shared/StatusBadge.d.ts +6 -0
  96. package/lib/typescript/lib/module/NotificationManager/components/shared/StatusBadge.d.ts.map +1 -0
  97. package/lib/typescript/lib/module/NotificationManager/index.d.ts +1 -0
  98. package/lib/typescript/lib/module/NotificationManager/index.d.ts.map +1 -1
  99. package/lib/typescript/lib/module/index.d.ts +2 -1
  100. package/lib/typescript/lib/module/index.d.ts.map +1 -1
  101. package/lib/typescript/src/NotificationManager/NotificationManagerTabs.d.ts +20 -0
  102. package/lib/typescript/src/NotificationManager/NotificationManagerTabs.d.ts.map +1 -0
  103. package/lib/typescript/src/NotificationManager/api/index.d.ts +74 -3
  104. package/lib/typescript/src/NotificationManager/api/index.d.ts.map +1 -1
  105. package/lib/typescript/src/NotificationManager/components/GroupManagement.d.ts +8 -0
  106. package/lib/typescript/src/NotificationManager/components/GroupManagement.d.ts.map +1 -0
  107. package/lib/typescript/src/NotificationManager/components/JobManagement.d.ts +9 -0
  108. package/lib/typescript/src/NotificationManager/components/JobManagement.d.ts.map +1 -0
  109. package/lib/typescript/src/NotificationManager/components/ScheduleNotification.d.ts +10 -0
  110. package/lib/typescript/src/NotificationManager/components/ScheduleNotification.d.ts.map +1 -0
  111. package/lib/typescript/src/NotificationManager/components/index.d.ts +8 -0
  112. package/lib/typescript/src/NotificationManager/components/index.d.ts.map +1 -0
  113. package/lib/typescript/src/NotificationManager/components/shared/DateTimePicker.d.ts +12 -0
  114. package/lib/typescript/src/NotificationManager/components/shared/DateTimePicker.d.ts.map +1 -0
  115. package/lib/typescript/src/NotificationManager/components/shared/GroupSelector.d.ts +16 -0
  116. package/lib/typescript/src/NotificationManager/components/shared/GroupSelector.d.ts.map +1 -0
  117. package/lib/typescript/src/NotificationManager/components/shared/NotificationBuilderForm.d.ts +12 -0
  118. package/lib/typescript/src/NotificationManager/components/shared/NotificationBuilderForm.d.ts.map +1 -0
  119. package/lib/typescript/src/NotificationManager/components/shared/StatusBadge.d.ts +8 -0
  120. package/lib/typescript/src/NotificationManager/components/shared/StatusBadge.d.ts.map +1 -0
  121. package/lib/typescript/src/NotificationManager/index.d.ts +1 -0
  122. package/lib/typescript/src/NotificationManager/index.d.ts.map +1 -1
  123. package/lib/typescript/src/index.d.ts +2 -1
  124. package/lib/typescript/src/index.d.ts.map +1 -1
  125. package/package.json +1 -1
  126. package/src/NotificationManager/NotificationManagerTabs.tsx +178 -0
  127. package/src/NotificationManager/api/index.ts +239 -6
  128. package/src/NotificationManager/components/GroupManagement.tsx +854 -0
  129. package/src/NotificationManager/components/JobManagement.tsx +569 -0
  130. package/src/NotificationManager/components/ScheduleNotification.tsx +388 -0
  131. package/src/NotificationManager/components/index.ts +7 -0
  132. package/src/NotificationManager/components/shared/DateTimePicker.tsx +94 -0
  133. package/src/NotificationManager/components/shared/GroupSelector.tsx +130 -0
  134. package/src/NotificationManager/components/shared/NotificationBuilderForm.tsx +364 -0
  135. package/src/NotificationManager/components/shared/StatusBadge.tsx +72 -0
  136. package/src/NotificationManager/index.tsx +43 -24
  137. package/src/index.tsx +2 -0
  138. package/src/types.d.ts +38 -3
@@ -0,0 +1,1030 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { FlatList, ActivityIndicator, TouchableOpacity, ScrollView } from 'react-native';
3
+ import { View, Text, Button, TextInput } from '../../Components/Themed';
4
+ import { useColors } from '../../constants/useColors';
5
+ import { NotificationApi } from '../api';
6
+ import { showConfirmAlert } from '../../Components/ConfirmAlert';
7
+ import { Icons } from '../../Components';
8
+ import DropDown from '../../Components/Dropdown';
9
+ import Pagination from '../../Components/Pagination';
10
+ const GROUPING_FUNCTIONS = [{
11
+ label: 'Flash Bettors',
12
+ value: 'flashBettors'
13
+ }
14
+ // Add more as they're implemented in the backend
15
+ ];
16
+ const GroupManagement = ({
17
+ onFocusPosition
18
+ }) => {
19
+ const Colors = useColors();
20
+ const [loading, setLoading] = useState(false);
21
+ const [groups, setGroups] = useState([]);
22
+ const [showFormModal, setShowFormModal] = useState(false);
23
+ const [showManageMembersModal, setShowManageMembersModal] = useState(false);
24
+ const [editingGroup, setEditingGroup] = useState(null);
25
+ const [selectedGroupForMembers, setSelectedGroupForMembers] = useState(null);
26
+
27
+ // Pagination state
28
+ const [currentPage, setCurrentPage] = useState(0);
29
+ const pageSize = 20;
30
+ const [hasMore, setHasMore] = useState(false);
31
+
32
+ // Search state
33
+ const [searchQuery, setSearchQuery] = useState('');
34
+
35
+ // Manage Members modal state
36
+ const [manageMembersMode, setManageMembersMode] = useState('reset');
37
+ const [editMode, setEditMode] = useState('replace');
38
+ const [csvInput, setCsvInput] = useState('');
39
+ const [memberSearchQuery, setMemberSearchQuery] = useState('');
40
+ const [existingPlayerIds, setExistingPlayerIds] = useState([]);
41
+ const [removedPlayerIds, setRemovedPlayerIds] = useState(new Set());
42
+ const [formData, setFormData] = useState({
43
+ name: '',
44
+ description: '',
45
+ grouping_function: undefined,
46
+ status: 'active'
47
+ });
48
+ useEffect(() => {
49
+ loadGroups();
50
+ }, []);
51
+ useEffect(() => {
52
+ // Reload groups when search or current page changes
53
+ loadGroups();
54
+ }, [searchQuery, currentPage]);
55
+ const loadGroups = async () => {
56
+ setLoading(true);
57
+ const offset = currentPage * pageSize;
58
+ const fetchedGroups = await NotificationApi.getAllNotificationGroups(pageSize, offset, searchQuery || undefined);
59
+ console.log('=== LOADED GROUPS ===');
60
+ console.log('Total groups fetched:', fetchedGroups.length);
61
+ console.log('Full groups data:', fetchedGroups);
62
+ if (fetchedGroups && fetchedGroups.length > 0) {
63
+ console.log('First group sample:', fetchedGroups[0]);
64
+ console.log('Does first group have members?', !!fetchedGroups[0]?.members);
65
+ if (fetchedGroups[0]?.members) {
66
+ console.log('First group members:', fetchedGroups[0].members);
67
+ }
68
+ }
69
+ console.log('=====================');
70
+
71
+ // Check if there are more results
72
+ setHasMore(fetchedGroups.length === pageSize);
73
+ setGroups(fetchedGroups);
74
+ setLoading(false);
75
+ };
76
+ const handleSearchChange = text => {
77
+ setSearchQuery(text);
78
+ setCurrentPage(0); // Reset to first page when search changes
79
+ };
80
+ const handlePreviousPage = () => {
81
+ if (currentPage > 0) {
82
+ setCurrentPage(currentPage - 1);
83
+ }
84
+ };
85
+ const handleNextPage = () => {
86
+ if (hasMore) {
87
+ setCurrentPage(currentPage + 1);
88
+ }
89
+ };
90
+ const handleSelectPage = page => {
91
+ setCurrentPage(page);
92
+ };
93
+
94
+ // Build list data for FlatList
95
+ const listData = React.useMemo(() => {
96
+ const data = [];
97
+
98
+ // Always add header and search sections
99
+ data.push({
100
+ type: 'header'
101
+ });
102
+ data.push({
103
+ type: 'search'
104
+ });
105
+
106
+ // If loading, show loading indicator
107
+ if (loading) {
108
+ data.push({
109
+ type: 'loading'
110
+ });
111
+ return data;
112
+ }
113
+
114
+ // If no groups, show empty state
115
+ if (groups.length === 0) {
116
+ data.push({
117
+ type: 'empty'
118
+ });
119
+ return data;
120
+ }
121
+
122
+ // Show results count
123
+ data.push({
124
+ type: 'results-count'
125
+ });
126
+
127
+ // Add all group items
128
+ groups.forEach(group => {
129
+ data.push({
130
+ type: 'group',
131
+ data: group
132
+ });
133
+ });
134
+
135
+ // Add pagination
136
+ data.push({
137
+ type: 'pagination'
138
+ });
139
+ return data;
140
+ }, [loading, groups, currentPage, searchQuery]);
141
+ const handleCreateNew = () => {
142
+ setEditingGroup(null);
143
+ setFormData({
144
+ name: '',
145
+ description: '',
146
+ grouping_function: undefined,
147
+ status: 'active'
148
+ });
149
+ setShowFormModal(true);
150
+ };
151
+ const handleEdit = group => {
152
+ setEditingGroup(group);
153
+ setFormData({
154
+ notification_group_id: group.notification_group_id,
155
+ name: group.name,
156
+ description: group.description,
157
+ grouping_function: group.grouping_function,
158
+ status: group.status
159
+ });
160
+ setShowFormModal(true);
161
+ };
162
+ const handleSave = async () => {
163
+ try {
164
+ setLoading(true);
165
+ if (editingGroup) {
166
+ // Update existing group
167
+ await NotificationApi.updateNotificationGroup({
168
+ ...editingGroup,
169
+ name: formData.name,
170
+ description: formData.description,
171
+ grouping_function: formData.grouping_function,
172
+ status: formData.status
173
+ });
174
+ } else {
175
+ // Create new group
176
+ await NotificationApi.createNotificationGroup(formData);
177
+ }
178
+ setShowFormModal(false);
179
+ await loadGroups();
180
+ } catch (error) {
181
+ console.error('Error saving group:', error);
182
+ alert('Failed to save group. Please try again.');
183
+ } finally {
184
+ setLoading(false);
185
+ }
186
+ };
187
+ const handleDelete = group => {
188
+ showConfirmAlert('Inactivate Group', `Are you sure you want to inactivate "${group.name}"? This will not delete members, but the group will no longer be available for new notifications.`, async () => {
189
+ try {
190
+ setLoading(true);
191
+ await NotificationApi.inactivateNotificationGroup(group.notification_group_id);
192
+ await loadGroups();
193
+ } catch (error) {
194
+ console.error('Error inactivating group:', error);
195
+ alert('Failed to inactivate group. Please try again.');
196
+ } finally {
197
+ setLoading(false);
198
+ }
199
+ });
200
+ };
201
+ const handleOpenManageMembers = async group => {
202
+ setSelectedGroupForMembers(group);
203
+ setManageMembersMode(group.grouping_function ? 'reset' : 'edit');
204
+ setEditMode('replace');
205
+ setCsvInput('');
206
+ setMemberSearchQuery('');
207
+ setRemovedPlayerIds(new Set());
208
+
209
+ // Extract existing player IDs from members if available
210
+ if (group.members && group.members.length > 0) {
211
+ console.log('Using members from group object:', group.members);
212
+ const allPlayerIds = group.members.filter(m => m.status === 'active').flatMap(m => m.player_ids);
213
+ setExistingPlayerIds(allPlayerIds);
214
+ } else {
215
+ // Fallback: fetch members separately if not included in group
216
+ console.log('Members not in group object, fetching separately for:', group.notification_group_id);
217
+ try {
218
+ const members = await NotificationApi.getNotificationGroupMembersByGroup(group.notification_group_id);
219
+ console.log('Fetched members separately:', members);
220
+ if (members && members.length > 0) {
221
+ const allPlayerIds = members.filter(m => m.status === 'active').flatMap(m => m.player_ids);
222
+ setExistingPlayerIds(allPlayerIds);
223
+ } else {
224
+ setExistingPlayerIds([]);
225
+ }
226
+ } catch (error) {
227
+ console.error('Error fetching group members:', error);
228
+ setExistingPlayerIds([]);
229
+ }
230
+ }
231
+ setShowManageMembersModal(true);
232
+ };
233
+ const handleResetMembers = () => {
234
+ if (!selectedGroupForMembers) return;
235
+ showConfirmAlert('Reset Group Members', `This will run the grouping function to update members for "${selectedGroupForMembers.name}". Continue?`, async () => {
236
+ try {
237
+ setLoading(true);
238
+ await NotificationApi.updateGroupMembers(selectedGroupForMembers.notification_group_id);
239
+ await loadGroups();
240
+ setShowManageMembersModal(false);
241
+ alert('Group members reset successfully!');
242
+ } catch (error) {
243
+ console.error('Error resetting members:', error);
244
+ alert('Failed to reset members. Please try again.');
245
+ } finally {
246
+ setLoading(false);
247
+ }
248
+ });
249
+ };
250
+ const handleEditMembers = () => {
251
+ if (!selectedGroupForMembers) return;
252
+
253
+ // Parse CSV - handle commas, newlines, spaces, and semicolons
254
+ const newPlayerIds = csvInput.split(/[,\n;\s]+/).map(id => id.trim()).filter(id => id.length > 0);
255
+ let finalPlayerIds;
256
+ if (editMode === 'replace') {
257
+ // Replace mode: must have CSV input
258
+ if (!csvInput.trim()) {
259
+ alert('Please enter player IDs to replace members');
260
+ return;
261
+ }
262
+ // Replace mode: use only new player IDs (dedupe)
263
+ finalPlayerIds = [...new Set(newPlayerIds)];
264
+ } else {
265
+ // Append mode: combine existing (minus removed) with new
266
+ const remainingExisting = existingPlayerIds.filter(id => !removedPlayerIds.has(String(id)));
267
+ console.log('=== EDIT MEMBERS DEBUG ===');
268
+ console.log('existingPlayerIds:', existingPlayerIds);
269
+ console.log('removedPlayerIds:', Array.from(removedPlayerIds));
270
+ console.log('remainingExisting:', remainingExisting);
271
+ console.log('newPlayerIds:', newPlayerIds);
272
+
273
+ // Convert all to strings for consistent comparison and dedupe
274
+ const remainingExistingStrings = remainingExisting.map(id => String(id));
275
+ const newPlayerIdsStrings = newPlayerIds.map(id => String(id));
276
+
277
+ // Combine and dedupe
278
+ finalPlayerIds = [...new Set([...remainingExistingStrings, ...newPlayerIdsStrings])];
279
+ console.log('finalPlayerIds:', finalPlayerIds);
280
+
281
+ // Check if there are any changes (removed IDs or new IDs added)
282
+ const hasRemovedIds = removedPlayerIds.size > 0;
283
+ const hasNewIds = newPlayerIds.length > 0;
284
+ console.log('hasRemovedIds:', hasRemovedIds);
285
+ console.log('hasNewIds:', hasNewIds);
286
+ if (!hasRemovedIds && !hasNewIds) {
287
+ alert('Please add new player IDs or remove existing ones');
288
+ return;
289
+ }
290
+
291
+ // Additional check: verify the final list is actually different
292
+ const originalSet = new Set(existingPlayerIds.map(id => String(id)));
293
+ const finalSet = new Set(finalPlayerIds);
294
+ console.log('originalSet:', Array.from(originalSet));
295
+ console.log('finalSet:', Array.from(finalSet));
296
+ console.log('originalSet.size:', originalSet.size);
297
+ console.log('finalSet.size:', finalSet.size);
298
+
299
+ // Check if sets are equal (same size and all elements match)
300
+ const hasChanges = originalSet.size !== finalSet.size || ![...originalSet].every(id => finalSet.has(id));
301
+ console.log('hasChanges:', hasChanges);
302
+ console.log('========================');
303
+ if (!hasChanges) {
304
+ alert('No changes detected. The member list is the same.');
305
+ return;
306
+ }
307
+ }
308
+ if (finalPlayerIds.length === 0) {
309
+ alert('No player IDs to save');
310
+ return;
311
+ }
312
+
313
+ // Calculate stats for confirmation message
314
+ const duplicatesRemoved = editMode === 'append' ? existingPlayerIds.length - removedPlayerIds.size + newPlayerIds.length - finalPlayerIds.length : newPlayerIds.length - finalPlayerIds.length;
315
+ let actionText = editMode === 'replace' ? `replace all members with ${finalPlayerIds.length} player(s)` : `update members (${finalPlayerIds.length} total after changes)`;
316
+ if (duplicatesRemoved > 0) {
317
+ actionText += `. ${duplicatesRemoved} duplicate(s) removed`;
318
+ }
319
+ showConfirmAlert('Update Members', `This will ${actionText} for "${selectedGroupForMembers.name}". Continue?`, async () => {
320
+ try {
321
+ setLoading(true);
322
+ await NotificationApi.updateGroupMembers(selectedGroupForMembers.notification_group_id, finalPlayerIds);
323
+ await loadGroups();
324
+ setShowManageMembersModal(false);
325
+ setCsvInput('');
326
+ alert(`Successfully updated members!`);
327
+ } catch (error) {
328
+ console.error('Error updating members:', error);
329
+ alert('Failed to update members. Please try again.');
330
+ } finally {
331
+ setLoading(false);
332
+ }
333
+ });
334
+ };
335
+ const handleRemovePlayerId = playerId => {
336
+ // Always store as string for consistent comparison
337
+ setRemovedPlayerIds(prev => new Set(prev).add(String(playerId)));
338
+ };
339
+
340
+ // Filter existing player IDs by search query
341
+ const filteredExistingPlayerIds = React.useMemo(() => {
342
+ const filtered = memberSearchQuery ? existingPlayerIds.filter(id => String(id).includes(memberSearchQuery)) : existingPlayerIds.slice(0, 5); // Show only first 5 unless searching
343
+ return filtered;
344
+ }, [existingPlayerIds, memberSearchQuery]);
345
+
346
+ // Render functions for each section type
347
+ const renderHeader = () => /*#__PURE__*/React.createElement(View, {
348
+ type: "header",
349
+ style: {
350
+ flexDirection: 'row',
351
+ alignItems: 'center',
352
+ padding: 10
353
+ }
354
+ }, /*#__PURE__*/React.createElement(View, {
355
+ transparent: true,
356
+ style: {
357
+ flex: 1
358
+ }
359
+ }, /*#__PURE__*/React.createElement(Text, {
360
+ theme: "h1"
361
+ }, "Manage Groups"), /*#__PURE__*/React.createElement(Text, {
362
+ theme: "description",
363
+ style: {
364
+ marginTop: 3
365
+ }
366
+ }, "Create and manage notification groups")), /*#__PURE__*/React.createElement(Button, {
367
+ type: "action",
368
+ onPress: handleCreateNew,
369
+ style: {
370
+ padding: 10,
371
+ flexDirection: 'row',
372
+ alignItems: 'center',
373
+ justifyContent: 'center'
374
+ }
375
+ }, /*#__PURE__*/React.createElement(Icons.PlusCircleIcon, {
376
+ size: 14,
377
+ color: Colors.text.white
378
+ }), /*#__PURE__*/React.createElement(Text, {
379
+ theme: "h1",
380
+ color: Colors.text.white,
381
+ style: {
382
+ marginLeft: 6
383
+ }
384
+ }, "New Group")));
385
+ const renderSearch = () => /*#__PURE__*/React.createElement(View, {
386
+ type: "row",
387
+ style: {
388
+ padding: 10,
389
+ margin: 10,
390
+ marginBottom: 5
391
+ }
392
+ }, /*#__PURE__*/React.createElement(View, {
393
+ transparent: true,
394
+ style: {
395
+ flex: 1,
396
+ flexDirection: 'row',
397
+ alignItems: 'center'
398
+ }
399
+ }, /*#__PURE__*/React.createElement(Icons.SearchIcon, {
400
+ size: 16,
401
+ color: Colors.text.h2
402
+ }), /*#__PURE__*/React.createElement(TextInput, {
403
+ placeholder: "Search groups by name or description...",
404
+ value: searchQuery,
405
+ onFocusPosition: onFocusPosition,
406
+ onChangeText: handleSearchChange,
407
+ style: {
408
+ flex: 1,
409
+ padding: 10,
410
+ fontSize: 14,
411
+ marginLeft: 5
412
+ }
413
+ }), searchQuery.length > 0 && /*#__PURE__*/React.createElement(TouchableOpacity, {
414
+ onPress: () => handleSearchChange(''),
415
+ style: {
416
+ padding: 8
417
+ }
418
+ }, /*#__PURE__*/React.createElement(Icons.CloseIcon, {
419
+ size: 14,
420
+ color: Colors.text.h2
421
+ }))));
422
+ const renderResultsCount = () => /*#__PURE__*/React.createElement(View, {
423
+ transparent: true,
424
+ style: {
425
+ paddingHorizontal: 20,
426
+ paddingVertical: 5
427
+ }
428
+ }, /*#__PURE__*/React.createElement(Text, {
429
+ theme: "description",
430
+ style: {
431
+ fontSize: 12
432
+ }
433
+ }, "Showing ", groups.length, " result", groups.length !== 1 ? 's' : '', " on page ", currentPage + 1, searchQuery && ` (filtered by search)`));
434
+ const renderGroupCard = group => {
435
+ return /*#__PURE__*/React.createElement(View, {
436
+ float: true,
437
+ style: {
438
+ margin: 10
439
+ }
440
+ }, /*#__PURE__*/React.createElement(View, {
441
+ type: "header",
442
+ style: {
443
+ flexDirection: 'row',
444
+ alignItems: 'center',
445
+ padding: 10,
446
+ borderTopRightRadius: 8,
447
+ borderTopLeftRadius: 8
448
+ }
449
+ }, /*#__PURE__*/React.createElement(View, {
450
+ transparent: true,
451
+ style: {
452
+ flex: 1
453
+ }
454
+ }, /*#__PURE__*/React.createElement(Text, {
455
+ theme: "h1"
456
+ }, group.name), /*#__PURE__*/React.createElement(Text, {
457
+ theme: "description",
458
+ style: {
459
+ marginTop: 3
460
+ }
461
+ }, "Members: ", group.player_count?.toLocaleString() || 0, " | Function: ", group.grouping_function || 'Manual')), /*#__PURE__*/React.createElement(Button, {
462
+ type: "text",
463
+ onPress: () => handleEdit(group),
464
+ style: {
465
+ padding: 10
466
+ }
467
+ }, /*#__PURE__*/React.createElement(Icons.EditIcon, {
468
+ size: 14,
469
+ color: Colors.text.white
470
+ })), /*#__PURE__*/React.createElement(Button, {
471
+ type: "text",
472
+ onPress: () => handleOpenManageMembers(group),
473
+ style: {
474
+ padding: 10
475
+ }
476
+ }, /*#__PURE__*/React.createElement(Icons.UserIcon, {
477
+ size: 14,
478
+ color: Colors.text.white
479
+ }))), /*#__PURE__*/React.createElement(View, {
480
+ transparent: true,
481
+ style: {
482
+ flexDirection: 'row',
483
+ padding: 10
484
+ }
485
+ }, /*#__PURE__*/React.createElement(Button, {
486
+ type: "error",
487
+ onPress: () => handleDelete(group),
488
+ style: {
489
+ flex: 1,
490
+ flexDirection: 'row',
491
+ alignItems: 'center',
492
+ justifyContent: 'center',
493
+ padding: 10,
494
+ marginRight: 4,
495
+ marginBottom: 4
496
+ }
497
+ }, /*#__PURE__*/React.createElement(Icons.CloseIcon, {
498
+ size: 10,
499
+ color: Colors.text.white
500
+ }), /*#__PURE__*/React.createElement(Text, {
501
+ theme: "description",
502
+ color: Colors.text.white,
503
+ style: {
504
+ marginLeft: 6
505
+ }
506
+ }, "Inactivate"))));
507
+ };
508
+ const renderEmpty = () => /*#__PURE__*/React.createElement(View, {
509
+ style: {
510
+ padding: 40,
511
+ alignItems: 'center'
512
+ }
513
+ }, /*#__PURE__*/React.createElement(Text, {
514
+ theme: "description"
515
+ }, searchQuery ? 'No groups match your search query.' : 'No groups found. Create your first group!'));
516
+ const renderLoading = () => /*#__PURE__*/React.createElement(View, {
517
+ style: {
518
+ padding: 40,
519
+ justifyContent: 'center',
520
+ alignItems: 'center'
521
+ }
522
+ }, /*#__PURE__*/React.createElement(ActivityIndicator, {
523
+ size: "large",
524
+ color: Colors.text.action
525
+ }));
526
+ const renderPagination = () => /*#__PURE__*/React.createElement(View, {
527
+ transparent: true,
528
+ style: {
529
+ padding: 15,
530
+ paddingBottom: 20
531
+ }
532
+ }, /*#__PURE__*/React.createElement(Pagination, {
533
+ offset: currentPage,
534
+ pages: hasMore ? currentPage + 2 : currentPage + 1,
535
+ onPrevious: handlePreviousPage,
536
+ onNext: handleNextPage,
537
+ onSelectPage: handleSelectPage
538
+ }));
539
+
540
+ // Main render item function with switch statement
541
+ const renderItem = ({
542
+ item
543
+ }) => {
544
+ switch (item.type) {
545
+ case 'header':
546
+ return renderHeader();
547
+ case 'search':
548
+ return renderSearch();
549
+ case 'results-count':
550
+ return renderResultsCount();
551
+ case 'group':
552
+ return renderGroupCard(item.data);
553
+ case 'empty':
554
+ return renderEmpty();
555
+ case 'loading':
556
+ return renderLoading();
557
+ case 'pagination':
558
+ return renderPagination();
559
+ default:
560
+ return null;
561
+ }
562
+ };
563
+ const getItemKey = (item, index) => {
564
+ if (item.type === 'group') {
565
+ return item.data.notification_group_id;
566
+ }
567
+ return `${item.type}-${index}`;
568
+ };
569
+ return /*#__PURE__*/React.createElement(View, {
570
+ style: {
571
+ flex: 1
572
+ }
573
+ }, /*#__PURE__*/React.createElement(FlatList, {
574
+ data: listData,
575
+ keyExtractor: getItemKey,
576
+ renderItem: renderItem,
577
+ showsVerticalScrollIndicator: true
578
+ }), showFormModal && /*#__PURE__*/React.createElement(View, {
579
+ type: "blur",
580
+ style: {
581
+ position: 'absolute',
582
+ top: 0,
583
+ left: 0,
584
+ right: 0,
585
+ bottom: 0,
586
+ padding: 20
587
+ }
588
+ }, /*#__PURE__*/React.createElement(View, {
589
+ float: true,
590
+ style: {
591
+ maxWidth: 600,
592
+ alignSelf: 'center',
593
+ width: '100%'
594
+ }
595
+ }, /*#__PURE__*/React.createElement(View, {
596
+ type: "header",
597
+ style: {
598
+ flexDirection: 'row',
599
+ alignItems: 'center',
600
+ padding: 10,
601
+ borderTopRightRadius: 8,
602
+ borderTopLeftRadius: 8
603
+ }
604
+ }, /*#__PURE__*/React.createElement(View, {
605
+ transparent: true,
606
+ style: {
607
+ flex: 1
608
+ }
609
+ }, /*#__PURE__*/React.createElement(Text, {
610
+ theme: "h1"
611
+ }, editingGroup ? 'Edit Group' : 'Create New Group'), /*#__PURE__*/React.createElement(Text, {
612
+ theme: "description",
613
+ style: {
614
+ marginTop: 3
615
+ }
616
+ }, editingGroup ? 'Update group details' : 'Set up a new notification group'))), /*#__PURE__*/React.createElement(ScrollView, {
617
+ style: {
618
+ maxHeight: 500
619
+ }
620
+ }, /*#__PURE__*/React.createElement(View, {
621
+ style: {
622
+ padding: 15
623
+ }
624
+ }, /*#__PURE__*/React.createElement(View, {
625
+ transparent: true,
626
+ style: {
627
+ marginBottom: 15
628
+ }
629
+ }, /*#__PURE__*/React.createElement(Text, {
630
+ theme: "h2",
631
+ style: {
632
+ marginBottom: 8
633
+ }
634
+ }, "Group Name"), /*#__PURE__*/React.createElement(TextInput, {
635
+ value: formData.name,
636
+ onFocusPosition: onFocusPosition,
637
+ placeholder: "Enter group name",
638
+ onChangeText: name => setFormData({
639
+ ...formData,
640
+ name
641
+ }),
642
+ style: {
643
+ padding: 12,
644
+ borderRadius: 8
645
+ }
646
+ })), /*#__PURE__*/React.createElement(View, {
647
+ transparent: true,
648
+ style: {
649
+ marginBottom: 15
650
+ }
651
+ }, /*#__PURE__*/React.createElement(Text, {
652
+ theme: "h2",
653
+ style: {
654
+ marginBottom: 8
655
+ }
656
+ }, "Description"), /*#__PURE__*/React.createElement(TextInput, {
657
+ value: formData.description,
658
+ onFocusPosition: onFocusPosition,
659
+ placeholder: "Describe this group",
660
+ onChangeText: description => setFormData({
661
+ ...formData,
662
+ description
663
+ }),
664
+ multiline: true,
665
+ numberOfLines: 3,
666
+ style: {
667
+ padding: 12,
668
+ borderRadius: 8,
669
+ minHeight: 80
670
+ }
671
+ })), /*#__PURE__*/React.createElement(View, {
672
+ type: "row",
673
+ style: {
674
+ marginBottom: 15,
675
+ padding: 10
676
+ }
677
+ }, /*#__PURE__*/React.createElement(Text, {
678
+ theme: "h2",
679
+ style: {
680
+ flex: 1
681
+ }
682
+ }, "Grouping Function"), /*#__PURE__*/React.createElement(DropDown, {
683
+ selected_value: GROUPING_FUNCTIONS.find(f => f.value === formData.grouping_function)?.label ?? '',
684
+ dropdown_options: [{
685
+ value: 'function',
686
+ eligible_options: GROUPING_FUNCTIONS.map(f => f.label)
687
+ }],
688
+ onOptionSelect: selected => {
689
+ const func = GROUPING_FUNCTIONS.find(f => f.label === selected)?.value;
690
+ if (func) {
691
+ setFormData({
692
+ ...formData,
693
+ grouping_function: func
694
+ });
695
+ }
696
+ }
697
+ })), /*#__PURE__*/React.createElement(View, {
698
+ type: "row",
699
+ style: {
700
+ marginBottom: 15,
701
+ padding: 10
702
+ }
703
+ }, /*#__PURE__*/React.createElement(Text, {
704
+ theme: "h2",
705
+ style: {
706
+ flex: 1
707
+ }
708
+ }, "Status"), /*#__PURE__*/React.createElement(DropDown, {
709
+ selected_value: formData.status === 'active' ? 'Active' : 'Inactive',
710
+ dropdown_options: [{
711
+ value: 'status',
712
+ eligible_options: ['Active', 'Inactive']
713
+ }],
714
+ onOptionSelect: selected => {
715
+ setFormData({
716
+ ...formData,
717
+ status: selected.toLowerCase()
718
+ });
719
+ }
720
+ })))), /*#__PURE__*/React.createElement(View, {
721
+ type: "footer",
722
+ style: {
723
+ flexDirection: 'row',
724
+ alignItems: 'center',
725
+ padding: 10,
726
+ borderBottomRightRadius: 8,
727
+ borderBottomLeftRadius: 8
728
+ }
729
+ }, /*#__PURE__*/React.createElement(Button, {
730
+ style: {
731
+ flex: 1,
732
+ marginRight: 5
733
+ },
734
+ type: "close",
735
+ title: "CANCEL",
736
+ onPress: () => setShowFormModal(false)
737
+ }), /*#__PURE__*/React.createElement(Button, {
738
+ style: {
739
+ flex: 1,
740
+ marginLeft: 5
741
+ },
742
+ type: "action",
743
+ title: editingGroup ? 'UPDATE' : 'CREATE',
744
+ onPress: handleSave,
745
+ disabled: !formData.name || !formData.description
746
+ })))), showManageMembersModal && selectedGroupForMembers && /*#__PURE__*/React.createElement(View, {
747
+ type: "blur",
748
+ style: {
749
+ position: 'absolute',
750
+ top: 0,
751
+ left: 0,
752
+ right: 0,
753
+ bottom: 0,
754
+ padding: 20
755
+ }
756
+ }, /*#__PURE__*/React.createElement(View, {
757
+ float: true,
758
+ style: {
759
+ maxWidth: 600,
760
+ alignSelf: 'center',
761
+ width: '100%',
762
+ maxHeight: '90%'
763
+ }
764
+ }, /*#__PURE__*/React.createElement(View, {
765
+ type: "header",
766
+ style: {
767
+ flexDirection: 'row',
768
+ alignItems: 'center',
769
+ padding: 10,
770
+ borderTopRightRadius: 8,
771
+ borderTopLeftRadius: 8
772
+ }
773
+ }, /*#__PURE__*/React.createElement(View, {
774
+ transparent: true,
775
+ style: {
776
+ flex: 1
777
+ }
778
+ }, /*#__PURE__*/React.createElement(Text, {
779
+ theme: "h1"
780
+ }, "Manage Members - ", selectedGroupForMembers.name), /*#__PURE__*/React.createElement(Text, {
781
+ theme: "description",
782
+ style: {
783
+ marginTop: 3
784
+ }
785
+ }, "Choose how to manage this group's members"))), /*#__PURE__*/React.createElement(ScrollView, {
786
+ style: {
787
+ flex: 1
788
+ }
789
+ }, /*#__PURE__*/React.createElement(View, {
790
+ style: {
791
+ padding: 15
792
+ }
793
+ }, /*#__PURE__*/React.createElement(View, {
794
+ transparent: true,
795
+ style: {
796
+ marginBottom: 20
797
+ }
798
+ }, /*#__PURE__*/React.createElement(Text, {
799
+ theme: "h2",
800
+ style: {
801
+ marginBottom: 10
802
+ }
803
+ }, "Management Mode"), /*#__PURE__*/React.createElement(View, {
804
+ transparent: true,
805
+ style: {
806
+ flexDirection: 'row'
807
+ }
808
+ }, selectedGroupForMembers.grouping_function && /*#__PURE__*/React.createElement(TouchableOpacity, {
809
+ onPress: () => setManageMembersMode('reset'),
810
+ style: {
811
+ flexDirection: 'row',
812
+ alignItems: 'center',
813
+ marginRight: 20
814
+ }
815
+ }, /*#__PURE__*/React.createElement(View, {
816
+ style: {
817
+ width: 20,
818
+ height: 20,
819
+ borderRadius: 10,
820
+ borderWidth: 2,
821
+ borderColor: Colors.text.action,
822
+ backgroundColor: manageMembersMode === 'reset' ? Colors.text.action : 'transparent',
823
+ marginRight: 8
824
+ }
825
+ }), /*#__PURE__*/React.createElement(Text, {
826
+ theme: "h2"
827
+ }, "Reset Members")), /*#__PURE__*/React.createElement(TouchableOpacity, {
828
+ onPress: () => setManageMembersMode('edit'),
829
+ style: {
830
+ flexDirection: 'row',
831
+ alignItems: 'center'
832
+ }
833
+ }, /*#__PURE__*/React.createElement(View, {
834
+ style: {
835
+ width: 20,
836
+ height: 20,
837
+ borderRadius: 10,
838
+ borderWidth: 2,
839
+ borderColor: Colors.text.action,
840
+ backgroundColor: manageMembersMode === 'edit' ? Colors.text.action : 'transparent',
841
+ marginRight: 8
842
+ }
843
+ }), /*#__PURE__*/React.createElement(Text, {
844
+ theme: "h2"
845
+ }, "Edit Members")))), manageMembersMode === 'reset' && /*#__PURE__*/React.createElement(View, {
846
+ transparent: true
847
+ }, /*#__PURE__*/React.createElement(Text, {
848
+ theme: "description",
849
+ style: {
850
+ marginBottom: 10
851
+ }
852
+ }, "This will run the grouping function \"", selectedGroupForMembers.grouping_function, "\" to recalculate and update all members for this group."), /*#__PURE__*/React.createElement(Text, {
853
+ theme: "description",
854
+ style: {
855
+ fontSize: 11,
856
+ fontStyle: 'italic'
857
+ }
858
+ }, "Current member count: ", selectedGroupForMembers.player_count || 0)), manageMembersMode === 'edit' && /*#__PURE__*/React.createElement(View, {
859
+ transparent: true
860
+ }, /*#__PURE__*/React.createElement(View, {
861
+ transparent: true,
862
+ style: {
863
+ marginBottom: 15
864
+ }
865
+ }, /*#__PURE__*/React.createElement(Text, {
866
+ theme: "h2",
867
+ style: {
868
+ marginBottom: 10
869
+ }
870
+ }, "Edit Mode"), /*#__PURE__*/React.createElement(View, {
871
+ transparent: true,
872
+ style: {
873
+ flexDirection: 'row'
874
+ }
875
+ }, /*#__PURE__*/React.createElement(TouchableOpacity, {
876
+ onPress: () => setEditMode('replace'),
877
+ style: {
878
+ flexDirection: 'row',
879
+ alignItems: 'center',
880
+ marginRight: 20
881
+ }
882
+ }, /*#__PURE__*/React.createElement(View, {
883
+ style: {
884
+ width: 20,
885
+ height: 20,
886
+ borderRadius: 10,
887
+ borderWidth: 2,
888
+ borderColor: Colors.text.action,
889
+ backgroundColor: editMode === 'replace' ? Colors.text.action : 'transparent',
890
+ marginRight: 8
891
+ }
892
+ }), /*#__PURE__*/React.createElement(Text, {
893
+ theme: "h2"
894
+ }, "Replace All")), /*#__PURE__*/React.createElement(TouchableOpacity, {
895
+ onPress: () => setEditMode('append'),
896
+ style: {
897
+ flexDirection: 'row',
898
+ alignItems: 'center'
899
+ }
900
+ }, /*#__PURE__*/React.createElement(View, {
901
+ style: {
902
+ width: 20,
903
+ height: 20,
904
+ borderRadius: 10,
905
+ borderWidth: 2,
906
+ borderColor: Colors.text.action,
907
+ backgroundColor: editMode === 'append' ? Colors.text.action : 'transparent',
908
+ marginRight: 8
909
+ }
910
+ }), /*#__PURE__*/React.createElement(Text, {
911
+ theme: "h2"
912
+ }, "Update Existing")))), editMode === 'append' && existingPlayerIds.length > 0 && /*#__PURE__*/React.createElement(View, {
913
+ transparent: true,
914
+ style: {
915
+ marginBottom: 15
916
+ }
917
+ }, /*#__PURE__*/React.createElement(Text, {
918
+ theme: "h2",
919
+ style: {
920
+ marginBottom: 8
921
+ }
922
+ }, "Current Members (", existingPlayerIds.length - removedPlayerIds.size, " of ", existingPlayerIds.length, ")"), /*#__PURE__*/React.createElement(TextInput, {
923
+ value: memberSearchQuery,
924
+ placeholder: "Search player IDs to find and remove...",
925
+ onChangeText: setMemberSearchQuery,
926
+ onFocusPosition: onFocusPosition,
927
+ style: {
928
+ padding: 10,
929
+ borderRadius: 8,
930
+ marginBottom: 8
931
+ }
932
+ }), !memberSearchQuery && existingPlayerIds.length > 5 && /*#__PURE__*/React.createElement(Text, {
933
+ theme: "description",
934
+ style: {
935
+ fontSize: 11,
936
+ marginBottom: 8,
937
+ fontStyle: 'italic'
938
+ }
939
+ }, "Showing first 5 of ", existingPlayerIds.length, ". Use search to find specific player IDs."), /*#__PURE__*/React.createElement(ScrollView, {
940
+ style: {
941
+ maxHeight: 150,
942
+ borderRadius: 8,
943
+ backgroundColor: Colors.views.background,
944
+ padding: 10
945
+ }
946
+ }, filteredExistingPlayerIds.filter(id => !removedPlayerIds.has(String(id))).map(playerId => /*#__PURE__*/React.createElement(View, {
947
+ key: playerId,
948
+ transparent: true,
949
+ style: {
950
+ flexDirection: 'row',
951
+ alignItems: 'center',
952
+ justifyContent: 'space-between',
953
+ paddingVertical: 4
954
+ }
955
+ }, /*#__PURE__*/React.createElement(Text, {
956
+ theme: "description"
957
+ }, playerId), /*#__PURE__*/React.createElement(TouchableOpacity, {
958
+ onPress: () => handleRemovePlayerId(playerId)
959
+ }, /*#__PURE__*/React.createElement(Icons.CloseIcon, {
960
+ size: 14,
961
+ color: Colors.text.error
962
+ })))), filteredExistingPlayerIds.filter(id => !removedPlayerIds.has(String(id))).length === 0 && /*#__PURE__*/React.createElement(Text, {
963
+ theme: "description",
964
+ style: {
965
+ textAlign: 'center',
966
+ paddingVertical: 10
967
+ }
968
+ }, memberSearchQuery ? 'No matching player IDs' : 'No members'))), /*#__PURE__*/React.createElement(View, {
969
+ transparent: true,
970
+ style: {
971
+ marginBottom: 15
972
+ }
973
+ }, /*#__PURE__*/React.createElement(Text, {
974
+ theme: "h2",
975
+ style: {
976
+ marginBottom: 8
977
+ }
978
+ }, editMode === 'replace' ? 'New Player IDs (CSV)' : 'Add Player IDs (CSV)'), /*#__PURE__*/React.createElement(TextInput, {
979
+ value: csvInput,
980
+ onFocusPosition: onFocusPosition,
981
+ placeholder: "e.g. player1, player2, player3\nor one per line",
982
+ onChangeText: setCsvInput,
983
+ multiline: true,
984
+ numberOfLines: 8,
985
+ style: {
986
+ padding: 12,
987
+ borderRadius: 8,
988
+ minHeight: 150,
989
+ textAlignVertical: 'top'
990
+ }
991
+ }), /*#__PURE__*/React.createElement(Text, {
992
+ theme: "description",
993
+ style: {
994
+ marginTop: 6,
995
+ fontSize: 11
996
+ }
997
+ }, "Accepts comma, space, semicolon, or newline separated values"))))), /*#__PURE__*/React.createElement(View, {
998
+ type: "footer",
999
+ style: {
1000
+ flexDirection: 'row',
1001
+ alignItems: 'center',
1002
+ padding: 10,
1003
+ borderBottomRightRadius: 8,
1004
+ borderBottomLeftRadius: 8
1005
+ }
1006
+ }, /*#__PURE__*/React.createElement(Button, {
1007
+ style: {
1008
+ flex: 1,
1009
+ marginRight: 5
1010
+ },
1011
+ type: "close",
1012
+ title: "CANCEL",
1013
+ onPress: () => {
1014
+ setShowManageMembersModal(false);
1015
+ setCsvInput('');
1016
+ setMemberSearchQuery('');
1017
+ setRemovedPlayerIds(new Set());
1018
+ }
1019
+ }), /*#__PURE__*/React.createElement(Button, {
1020
+ style: {
1021
+ flex: 1,
1022
+ marginLeft: 5
1023
+ },
1024
+ type: "action",
1025
+ title: manageMembersMode === 'reset' ? 'RESET' : 'UPDATE',
1026
+ onPress: manageMembersMode === 'reset' ? handleResetMembers : handleEditMembers
1027
+ })))));
1028
+ };
1029
+ export default GroupManagement;
1030
+ //# sourceMappingURL=GroupManagement.js.map