be-components 7.7.2 → 7.7.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 (24) hide show
  1. package/lib/commonjs/Assets/fonts/Barlow-Bold.ttf +0 -0
  2. package/lib/commonjs/Assets/fonts/Barlow-Regular.ttf +0 -0
  3. package/lib/commonjs/Assets/fonts/Barlow-SemiBold.ttf +0 -0
  4. package/lib/commonjs/Assets/images/powered_by_be.webp +0 -0
  5. package/lib/commonjs/BetRouter/components/MyOpportunities.tsx.bak +440 -0
  6. package/lib/commonjs/BetRouter/types/ADMIN_PORTAL.md +863 -0
  7. package/lib/commonjs/BetRouter/types/ADMIN_PORTAL_SIMPLIFIED.md +1881 -0
  8. package/lib/commonjs/BetRouter/types/CREDENTIALS_EXAMPLE.md +350 -0
  9. package/lib/commonjs/BetRouter/types/LIQUIDITY_CLIENT_GUIDE.md +399 -0
  10. package/lib/commonjs/BetRouter/types/MARKET_LINKING_WORKFLOW.md +682 -0
  11. package/lib/commonjs/BetRouter/types/MARKET_LINKING_WORKFLOW_V2.md +627 -0
  12. package/lib/commonjs/BetRouter/types/README.md +249 -0
  13. package/lib/commonjs/Charts/README.md +310 -0
  14. package/lib/commonjs/NotificationManager/components/ScheduleNotification.js +1 -16
  15. package/lib/commonjs/NotificationManager/components/ScheduleNotification.js.map +1 -1
  16. package/lib/commonjs/NotificationManager/components/shared/GroupSelector.js +74 -4
  17. package/lib/commonjs/NotificationManager/components/shared/GroupSelector.js.map +1 -1
  18. package/lib/commonjs/NotificationManager/index.js +49 -5
  19. package/lib/commonjs/NotificationManager/index.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/ApiOverrides/index.ts +2 -2
  22. package/src/NotificationManager/components/ScheduleNotification.tsx +1 -17
  23. package/src/NotificationManager/components/shared/GroupSelector.tsx +83 -6
  24. package/src/NotificationManager/index.tsx +52 -5
@@ -1,14 +1,16 @@
1
- import React from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import { FlatList, TouchableOpacity, ActivityIndicator } from 'react-native';
3
- import { View, Text, Button } from '../../../Components/Themed';
3
+ import { View, Text, Button, TextInput } from '../../../Components/Themed';
4
4
  import { useColors } from '../../../constants/useColors';
5
+ import { NotificationApi } from '../../api';
6
+ import Pagination from '../../../Components/Pagination';
5
7
  import type { NotificationGroupProps, FocusPositionProps } from '../../../types';
6
8
 
7
9
  interface GroupSelectorProps {
8
10
  visible: boolean;
9
11
  onClose: () => void;
10
12
  onSelectGroup: (group: NotificationGroupProps) => void;
11
- groups: NotificationGroupProps[];
13
+ groups?: NotificationGroupProps[]; // Optional: if provided, will use these instead of fetching
12
14
  loading?: boolean;
13
15
  selectedGroup?: NotificationGroupProps | null;
14
16
  showCustomOption?: boolean;
@@ -20,14 +22,65 @@ const GroupSelector = ({
20
22
  visible,
21
23
  onClose,
22
24
  onSelectGroup,
23
- groups,
24
- loading = false,
25
+ groups: externalGroups,
26
+ loading: externalLoading = false,
25
27
  selectedGroup,
26
28
  showCustomOption = true,
27
29
  customGroup
28
30
  }: GroupSelectorProps) => {
29
31
  const Colors = useColors();
30
32
 
33
+ // Internal state for fetching groups when not provided externally
34
+ const [internalGroups, setInternalGroups] = useState<NotificationGroupProps[]>([]);
35
+ const [internalLoading, setInternalLoading] = useState(false);
36
+
37
+ // Pagination state
38
+ const [currentPage, setCurrentPage] = useState(0);
39
+ const pageSize = 20;
40
+ const [hasMore, setHasMore] = useState(false);
41
+
42
+ // Search state
43
+ const [searchQuery, setSearchQuery] = useState('');
44
+
45
+ // Determine if we're using external or internal groups
46
+ const useExternalGroups = externalGroups !== undefined;
47
+ const groups = useExternalGroups ? externalGroups : internalGroups;
48
+ const loading = useExternalGroups ? externalLoading : internalLoading;
49
+
50
+ // Load groups when modal opens or search/page changes (only if not using external groups)
51
+ useEffect(() => {
52
+ if (visible && !useExternalGroups) {
53
+ loadGroups();
54
+ }
55
+ }, [visible, searchQuery, currentPage, useExternalGroups]);
56
+
57
+ // Reset state when modal opens
58
+ useEffect(() => {
59
+ if (visible) {
60
+ setSearchQuery('');
61
+ setCurrentPage(0);
62
+ }
63
+ }, [visible]);
64
+
65
+ const loadGroups = async () => {
66
+ setInternalLoading(true);
67
+ const offset = currentPage * pageSize;
68
+ const fetchedGroups = await NotificationApi.getNotificationGroupsByStatus(
69
+ 'active',
70
+ pageSize,
71
+ offset,
72
+ searchQuery || undefined
73
+ );
74
+ setHasMore(fetchedGroups.length === pageSize);
75
+ setInternalGroups(fetchedGroups);
76
+ setInternalLoading(false);
77
+ };
78
+
79
+ const handleSearchChange = (text: string) => {
80
+ setSearchQuery(text);
81
+ setCurrentPage(0); // Reset to first page when search changes
82
+ };
83
+
31
84
  if (!visible) return null;
32
85
 
33
86
  // Combine custom group with regular groups if enabled
@@ -35,6 +88,14 @@ const GroupSelector = ({
35
88
  ? [customGroup, ...groups]
36
89
  : groups;
37
90
 
91
+ // For external groups, filter by search query client-side
92
+ const displayGroups = useExternalGroups && searchQuery
93
+ ? allGroups.filter(g =>
94
+ g.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
95
+ (g.description && g.description.toLowerCase().includes(searchQuery.toLowerCase()))
96
+ )
97
+ : allGroups;
98
+
38
99
  return (
39
100
  <View type='blur' style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, padding: 20 }}>
40
101
  <View float style={{ flex: 1 }}>
@@ -44,6 +105,13 @@ const GroupSelector = ({
44
105
  <Text theme='description' style={{ marginTop: 3 }}>Select a group to send to</Text>
45
106
  </View>
46
107
  </View>
108
+ <View style={{ padding: 10, borderBottomWidth: 1, borderColor: Colors.borders.light }}>
109
+ <TextInput
110
+ placeholder="Search groups..."
111
+ value={searchQuery}
112
+ onChangeText={handleSearchChange}
113
+ />
114
+ </View>
47
115
  <View style={{ flex: 1 }}>
48
116
  {loading ? (
49
117
  <View style={{ padding: 40, alignItems: 'center' }}>
@@ -51,7 +119,7 @@ const GroupSelector = ({
51
119
  </View>
52
120
  ) : (
53
121
  <FlatList
54
- data={allGroups}
122
+ data={displayGroups}
55
123
  keyExtractor={(item) => item.notification_group_id}
56
124
  renderItem={({ item }) => {
57
125
  const isSelected = selectedGroup?.notification_group_id === item.notification_group_id;
@@ -114,6 +182,15 @@ const GroupSelector = ({
114
182
  />
115
183
  )}
116
184
  </View>
185
+ {!loading && !useExternalGroups && groups.length > 0 && (
186
+ <View style={{ padding: 10, borderTopWidth: 1, borderColor: Colors.borders.light }}>
187
+ <Pagination
188
+ offset={currentPage}
189
+ onPrevious={currentPage > 0 ? () => setCurrentPage(p => p - 1) : undefined}
190
+ onNext={hasMore ? () => setCurrentPage(p => p + 1) : undefined}
191
+ />
192
+ </View>
193
+ )}
117
194
  <View type='footer' style={{ flexDirection: 'row', alignItems: 'center', padding: 10, borderBottomRightRadius: 8, borderBottomLeftRadius: 8 }}>
118
195
  <Button
119
196
  style={{ flex: 1 }}
@@ -6,6 +6,7 @@ import { NotificationApi, NotificationHelpers } from './api';
6
6
  import type { PlayerNotificationProps, MyPlayerProps, NotificationGroupProps, FocusPositionProps } from '../types';
7
7
  import { Icons } from '../Components';
8
8
  import DropDown from '../Components/Dropdown';
9
+ import Pagination from '../Components/Pagination';
9
10
  import { showConfirmAlert } from '../Components/ConfirmAlert';
10
11
 
11
12
  type NotificationManagerProps = {
@@ -54,6 +55,14 @@ const NotificationManager = ({
54
55
  const [customGroupCsv, setCustomGroupCsv] = useState('');
55
56
  const [sendingProgress, setSendingProgress] = useState<{ current: number; total: number } | null>(null);
56
57
 
58
+ // Pagination state for group selector
59
+ const [groupsCurrentPage, setGroupsCurrentPage] = useState(0);
60
+ const groupsPageSize = 20;
61
+ const [groupsHasMore, setGroupsHasMore] = useState(false);
62
+
63
+ // Search state for group selector
64
+ const [groupSearchQuery, setGroupSearchQuery] = useState('');
65
+
57
66
  // Create a custom group (always available, even if player_ids is empty)
58
67
  const customGroup: NotificationGroupProps = {
59
68
  notification_group_id: 'custom_group',
@@ -105,11 +114,36 @@ const NotificationManager = ({
105
114
 
106
115
  const loadNotificationGroups = async () => {
107
116
  setLoadingGroups(true);
108
- const groups = await NotificationApi.getActiveNotificationGroups();
117
+ const offset = groupsCurrentPage * groupsPageSize;
118
+ const groups = await NotificationApi.getNotificationGroupsByStatus(
119
+ 'active',
120
+ groupsPageSize,
121
+ offset,
122
+ groupSearchQuery || undefined
123
+ );
124
+ setGroupsHasMore(groups.length === groupsPageSize);
109
125
  setNotificationGroups(groups);
110
126
  setLoadingGroups(false);
111
127
  };
112
128
 
129
+ // Reload groups when search or page changes
130
+ useEffect(() => {
131
+ if (showGroupsModal) {
132
+ loadNotificationGroups();
133
+ }
134
+ }, [groupSearchQuery, groupsCurrentPage, showGroupsModal]);
135
+
136
+ const handleGroupSearchChange = (text: string) => {
137
+ setGroupSearchQuery(text);
138
+ setGroupsCurrentPage(0); // Reset to first page when search changes
139
+ };
140
+
141
+ const handleOpenGroupsModal = () => {
142
+ setGroupSearchQuery('');
143
+ setGroupsCurrentPage(0);
144
+ setShowGroupsModal(true);
145
+ };
146
+
113
147
  const handleSelectGroup = async (group_id: string) => {
114
148
  setLoadingGroups(true);
115
149
 
@@ -444,10 +478,7 @@ const NotificationManager = ({
444
478
  </View>
445
479
  <Button
446
480
  type="action"
447
- onPress={() => {
448
- loadNotificationGroups();
449
- setShowGroupsModal(true);
450
- }}
481
+ onPress={handleOpenGroupsModal}
451
482
  style={{ padding: 8 }}
452
483
  >
453
484
  <Text theme="h1" color={Colors.text.white}>
@@ -806,6 +837,13 @@ const NotificationManager = ({
806
837
  <Text theme='description' style={{ marginTop:3 }}>Select a group to send to</Text>
807
838
  </View>
808
839
  </View>
840
+ <View style={{ padding: 10, borderBottomWidth: 1, borderColor: Colors.borders.light }}>
841
+ <TextInput
842
+ placeholder="Search groups..."
843
+ value={groupSearchQuery}
844
+ onChangeText={handleGroupSearchChange}
845
+ />
846
+ </View>
809
847
  <View style={{flex:1}}>
810
848
  {loadingGroups ? (
811
849
  <View style={{ padding: 40, alignItems: 'center' }}>
@@ -866,6 +904,15 @@ const NotificationManager = ({
866
904
  />
867
905
  )}
868
906
  </View>
907
+ {!loadingGroups && notificationGroups.length > 0 && (
908
+ <View style={{ padding: 10, borderTopWidth: 1, borderColor: Colors.borders.light }}>
909
+ <Pagination
910
+ offset={groupsCurrentPage}
911
+ onPrevious={groupsCurrentPage > 0 ? () => setGroupsCurrentPage(p => p - 1) : undefined}
912
+ onNext={groupsHasMore ? () => setGroupsCurrentPage(p => p + 1) : undefined}
913
+ />
914
+ </View>
915
+ )}
869
916
  <View type='footer' style={{ flexDirection:'row', alignItems:'center', padding:10, borderBottomRightRadius:8, borderBottomLeftRadius:8 }}>
870
917
  <Button
871
918
  style={{ flex:1 }}