be-components 7.6.3 → 7.6.5

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