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.
- package/lib/commonjs/Components/Spring.js +9 -52
- package/lib/commonjs/Components/Spring.js.map +1 -1
- package/lib/commonjs/NotificationManager/NotificationManagerTabs.js +188 -0
- package/lib/commonjs/NotificationManager/NotificationManagerTabs.js.map +1 -0
- package/lib/commonjs/NotificationManager/api/index.js +237 -7
- package/lib/commonjs/NotificationManager/api/index.js.map +1 -1
- package/lib/commonjs/NotificationManager/components/GroupManagement.js +1038 -0
- package/lib/commonjs/NotificationManager/components/GroupManagement.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/JobManagement.js +783 -0
- package/lib/commonjs/NotificationManager/components/JobManagement.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/ScheduleNotification.js +407 -0
- package/lib/commonjs/NotificationManager/components/ScheduleNotification.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/index.js +56 -0
- package/lib/commonjs/NotificationManager/components/index.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/shared/DateTimePicker.js +113 -0
- package/lib/commonjs/NotificationManager/components/shared/DateTimePicker.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/shared/GroupSelector.js +191 -0
- package/lib/commonjs/NotificationManager/components/shared/GroupSelector.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.js +509 -0
- package/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.js.map +1 -0
- package/lib/commonjs/NotificationManager/components/shared/StatusBadge.js +69 -0
- package/lib/commonjs/NotificationManager/components/shared/StatusBadge.js.map +1 -0
- package/lib/commonjs/NotificationManager/index.js +38 -23
- package/lib/commonjs/NotificationManager/index.js.map +1 -1
- package/lib/commonjs/Notifications/index.js +2 -2
- package/lib/commonjs/Notifications/index.js.map +1 -1
- package/lib/commonjs/ProfileManager/Components/BettorVouch.js +1 -1
- package/lib/commonjs/ProfileManager/Components/BettorVouch.js.map +1 -1
- package/lib/commonjs/SocialComponents/PostCard/index.js +1 -1
- package/lib/commonjs/SocialComponents/PostCard/index.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.d.js +2 -0
- package/lib/commonjs/types.d.js.map +1 -1
- package/lib/module/Components/Spring.js +10 -53
- package/lib/module/Components/Spring.js.map +1 -1
- package/lib/module/NotificationManager/NotificationManagerTabs.js +180 -0
- package/lib/module/NotificationManager/NotificationManagerTabs.js.map +1 -0
- package/lib/module/NotificationManager/api/index.js +237 -7
- package/lib/module/NotificationManager/api/index.js.map +1 -1
- package/lib/module/NotificationManager/components/GroupManagement.js +1030 -0
- package/lib/module/NotificationManager/components/GroupManagement.js.map +1 -0
- package/lib/module/NotificationManager/components/JobManagement.js +775 -0
- package/lib/module/NotificationManager/components/JobManagement.js.map +1 -0
- package/lib/module/NotificationManager/components/ScheduleNotification.js +399 -0
- package/lib/module/NotificationManager/components/ScheduleNotification.js.map +1 -0
- package/lib/module/NotificationManager/components/index.js +8 -0
- package/lib/module/NotificationManager/components/index.js.map +1 -0
- package/lib/module/NotificationManager/components/shared/DateTimePicker.js +106 -0
- package/lib/module/NotificationManager/components/shared/DateTimePicker.js.map +1 -0
- package/lib/module/NotificationManager/components/shared/GroupSelector.js +184 -0
- package/lib/module/NotificationManager/components/shared/GroupSelector.js.map +1 -0
- package/lib/module/NotificationManager/components/shared/NotificationBuilderForm.js +501 -0
- package/lib/module/NotificationManager/components/shared/NotificationBuilderForm.js.map +1 -0
- package/lib/module/NotificationManager/components/shared/StatusBadge.js +62 -0
- package/lib/module/NotificationManager/components/shared/StatusBadge.js.map +1 -0
- package/lib/module/NotificationManager/index.js +32 -23
- package/lib/module/NotificationManager/index.js.map +1 -1
- package/lib/module/Notifications/index.js +2 -2
- package/lib/module/Notifications/index.js.map +1 -1
- package/lib/module/ProfileManager/Components/BettorVouch.js +1 -1
- package/lib/module/ProfileManager/Components/BettorVouch.js.map +1 -1
- package/lib/module/SocialComponents/PostCard/index.js +1 -1
- package/lib/module/SocialComponents/PostCard/index.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.d.js +2 -0
- package/lib/module/types.d.js.map +1 -1
- package/lib/typescript/lib/commonjs/Components/Spring.d.ts +1 -5
- package/lib/typescript/lib/commonjs/Components/Spring.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/NotificationManager/NotificationManagerTabs.d.ts +17 -0
- package/lib/typescript/lib/commonjs/NotificationManager/NotificationManagerTabs.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/api/index.d.ts +75 -2
- package/lib/typescript/lib/commonjs/NotificationManager/api/index.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/NotificationManager/components/GroupManagement.d.ts +6 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/GroupManagement.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/JobManagement.d.ts +7 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/JobManagement.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/ScheduleNotification.d.ts +8 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/ScheduleNotification.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/index.d.ts +9 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/index.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/DateTimePicker.d.ts +9 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/DateTimePicker.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/GroupSelector.d.ts +13 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/GroupSelector.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.d.ts +10 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/NotificationBuilderForm.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/StatusBadge.d.ts +6 -0
- package/lib/typescript/lib/commonjs/NotificationManager/components/shared/StatusBadge.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/NotificationManager/index.d.ts +76 -2
- package/lib/typescript/lib/commonjs/NotificationManager/index.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/index.d.ts +76 -2
- package/lib/typescript/lib/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/AdServer/index.d.ts +1 -3
- package/lib/typescript/lib/module/AdServer/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Authenticator/Components/AuthStrategyIdentifier.d.ts +1 -3
- package/lib/typescript/lib/module/Authenticator/Components/AuthStrategyIdentifier.d.ts.map +1 -1
- package/lib/typescript/lib/module/Authenticator/Components/LoginForm.d.ts +1 -3
- package/lib/typescript/lib/module/Authenticator/Components/LoginForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/Authenticator/Components/StrategyForm.d.ts +1 -3
- package/lib/typescript/lib/module/Authenticator/Components/StrategyForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/BetRouter/components/admin/LeagueContests.d.ts +1 -3
- package/lib/typescript/lib/module/BetRouter/components/admin/LeagueContests.d.ts.map +1 -1
- package/lib/typescript/lib/module/BetRouter/components/admin/LeagueParticipants.d.ts +1 -3
- package/lib/typescript/lib/module/BetRouter/components/admin/LeagueParticipants.d.ts.map +1 -1
- package/lib/typescript/lib/module/BetRouter/index.d.ts +1 -3
- package/lib/typescript/lib/module/BetRouter/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Bracket/components/BracketCompetitionCard.d.ts +1 -3
- package/lib/typescript/lib/module/Bracket/components/BracketCompetitionCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Bracket/components/BracketCompetitionSelector.d.ts +1 -3
- package/lib/typescript/lib/module/Bracket/components/BracketCompetitionSelector.d.ts.map +1 -1
- package/lib/typescript/lib/module/Bracket/components/EditPlayerBracket.d.ts +1 -3
- package/lib/typescript/lib/module/Bracket/components/EditPlayerBracket.d.ts.map +1 -1
- package/lib/typescript/lib/module/Bracket/components/Navigator.d.ts +1 -3
- package/lib/typescript/lib/module/Bracket/components/Navigator.d.ts.map +1 -1
- package/lib/typescript/lib/module/Bracket/components/PlayerBracketManager.d.ts +1 -3
- package/lib/typescript/lib/module/Bracket/components/PlayerBracketManager.d.ts.map +1 -1
- package/lib/typescript/lib/module/Bracket/components/RoomHome.d.ts +1 -3
- package/lib/typescript/lib/module/Bracket/components/RoomHome.d.ts.map +1 -1
- package/lib/typescript/lib/module/Campaign/components/AutoManager.d.ts +1 -3
- package/lib/typescript/lib/module/Campaign/components/AutoManager.d.ts.map +1 -1
- package/lib/typescript/lib/module/Campaign/components/ProgressTimer.d.ts +1 -3
- package/lib/typescript/lib/module/Campaign/components/ProgressTimer.d.ts.map +1 -1
- package/lib/typescript/lib/module/Checkout/components/ItemSummaryCard.d.ts +1 -3
- package/lib/typescript/lib/module/Checkout/components/ItemSummaryCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/AthleteMarketCard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/AthleteMarketCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/CompetitionCard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/CompetitionCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/CompetitionInfoCard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/CompetitionInfoCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/CompetitionLeaderboard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/CompetitionLeaderboard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/CompetitionPlay.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/CompetitionPlay.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/CompetitionTypeCard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/CompetitionTypeCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/MatchMarketCard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/MatchMarketCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Competition/components/TeamEventCard.d.ts +1 -3
- package/lib/typescript/lib/module/Competition/components/TeamEventCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionManager/components/CompetitionInfoForm.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionManager/components/CompetitionInfoForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionManager/components/CompetitionMatchMarketCard.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionManager/components/CompetitionMatchMarketCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionManager/components/CompetitionSettingsForm.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionManager/components/CompetitionSettingsForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionManager/components/ContestSettingsForm.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionManager/components/ContestSettingsForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionSeasonManager/components/CreateSeasonForm.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionSeasonManager/components/CreateSeasonForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionSeasonManager/components/SeasonInfoForm.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionSeasonManager/components/SeasonInfoForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/CompetitionSeasonManager/components/SeasonSettingsForm.d.ts +1 -3
- package/lib/typescript/lib/module/CompetitionSeasonManager/components/SeasonSettingsForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/Components/Spring.d.ts +3 -1126
- package/lib/typescript/lib/module/Components/Spring.d.ts.map +1 -1
- package/lib/typescript/lib/module/EventComponents/TeamProfile/index.d.ts +1 -3
- package/lib/typescript/lib/module/EventComponents/TeamProfile/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/FlashMarket/components/MarketTimer.d.ts +1 -3
- package/lib/typescript/lib/module/FlashMarket/components/MarketTimer.d.ts.map +1 -1
- package/lib/typescript/lib/module/FlashMarket/components/ProgressTimer.d.ts +1 -3
- package/lib/typescript/lib/module/FlashMarket/components/ProgressTimer.d.ts.map +1 -1
- package/lib/typescript/lib/module/FlashMarket/index.d.ts +1 -3
- package/lib/typescript/lib/module/FlashMarket/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Guide/index.d.ts +1 -3
- package/lib/typescript/lib/module/Guide/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Leaders/components/LeaderboardCard.d.ts +1 -3
- package/lib/typescript/lib/module/Leaders/components/LeaderboardCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketComponents/components/BetScopeIndicator.d.ts +1 -3
- package/lib/typescript/lib/module/MarketComponents/components/BetScopeIndicator.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketComponents/components/EventScoringCard.d.ts +1 -3
- package/lib/typescript/lib/module/MarketComponents/components/EventScoringCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketComponents/components/MatchMarket/index.d.ts +1 -3
- package/lib/typescript/lib/module/MarketComponents/components/MatchMarket/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketComponents/components/OrderGradeBar.d.ts +1 -3
- package/lib/typescript/lib/module/MarketComponents/components/OrderGradeBar.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketComponents/components/TeamEventMarket/index.d.ts +1 -3
- package/lib/typescript/lib/module/MarketComponents/components/TeamEventMarket/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketMaker/components/ManageFundForm.d.ts +1 -3
- package/lib/typescript/lib/module/MarketMaker/components/ManageFundForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketMaker/components/OrderForm.d.ts +1 -3
- package/lib/typescript/lib/module/MarketMaker/components/OrderForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/MarketMaker/components/SetMarketForm.d.ts +1 -3
- package/lib/typescript/lib/module/MarketMaker/components/SetMarketForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/NotificationManager/NotificationManagerTabs.d.ts +17 -0
- package/lib/typescript/lib/module/NotificationManager/NotificationManagerTabs.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/api/index.d.ts +75 -2
- package/lib/typescript/lib/module/NotificationManager/api/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/NotificationManager/components/GroupManagement.d.ts +6 -0
- package/lib/typescript/lib/module/NotificationManager/components/GroupManagement.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/JobManagement.d.ts +7 -0
- package/lib/typescript/lib/module/NotificationManager/components/JobManagement.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/ScheduleNotification.d.ts +8 -0
- package/lib/typescript/lib/module/NotificationManager/components/ScheduleNotification.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/index.d.ts +8 -0
- package/lib/typescript/lib/module/NotificationManager/components/index.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/DateTimePicker.d.ts +9 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/DateTimePicker.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/GroupSelector.d.ts +13 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/GroupSelector.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/NotificationBuilderForm.d.ts +10 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/NotificationBuilderForm.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/StatusBadge.d.ts +6 -0
- package/lib/typescript/lib/module/NotificationManager/components/shared/StatusBadge.d.ts.map +1 -0
- package/lib/typescript/lib/module/NotificationManager/index.d.ts +1 -0
- package/lib/typescript/lib/module/NotificationManager/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Observer/Observer.d.ts +1 -3
- package/lib/typescript/lib/module/Observer/Observer.d.ts.map +1 -1
- package/lib/typescript/lib/module/PlayerRecommender/components/ContactsSelector.d.ts +1 -3
- package/lib/typescript/lib/module/PlayerRecommender/components/ContactsSelector.d.ts.map +1 -1
- package/lib/typescript/lib/module/Premium/components/ALaCartePremium.d.ts +1 -3
- package/lib/typescript/lib/module/Premium/components/ALaCartePremium.d.ts.map +1 -1
- package/lib/typescript/lib/module/RankingsCard/index.d.ts +1 -3
- package/lib/typescript/lib/module/RankingsCard/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +1 -3
- package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/GifSelector/WebSelector.d.ts +1 -3
- package/lib/typescript/lib/module/SocialComponents/GifSelector/WebSelector.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/PlayerFollowButton.d.ts +1 -3
- package/lib/typescript/lib/module/SocialComponents/PlayerFollowButton.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/PlayerProfile/components/PostsList.d.ts +1 -3
- package/lib/typescript/lib/module/SocialComponents/PlayerProfile/components/PostsList.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/PostCard/components/DraftTextViewer.d.ts +1 -3
- package/lib/typescript/lib/module/SocialComponents/PostCard/components/DraftTextViewer.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/Poster/index.d.ts +1 -3
- package/lib/typescript/lib/module/SocialComponents/Poster/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Socket/index.d.ts +1 -3
- package/lib/typescript/lib/module/Socket/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/BoardStats.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/BoardStats.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/Countdown.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/Countdown.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/EventCard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/EventCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/MySquaresCard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/MySquaresCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/MyStatsCard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/MyStatsCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/OfferForm.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/OfferForm.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/PrizeCard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/PrizeCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/ResultsCard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/ResultsCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/SquareOfferCard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/SquareOfferCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/SquareOwners.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/SquareOwners.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/SquaresBoard.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/SquaresBoard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Squares/components/SquaresDetails.d.ts +1 -3
- package/lib/typescript/lib/module/Squares/components/SquaresDetails.d.ts.map +1 -1
- package/lib/typescript/lib/module/Wallet/components/ItemOrderDetailCard.d.ts +1 -3
- package/lib/typescript/lib/module/Wallet/components/ItemOrderDetailCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/Wallet/components/VerifyACHAccount.d.ts +1 -3
- package/lib/typescript/lib/module/Wallet/components/VerifyACHAccount.d.ts.map +1 -1
- package/lib/typescript/lib/module/Wallet/components/WalletSettings.d.ts +1 -3
- package/lib/typescript/lib/module/Wallet/components/WalletSettings.d.ts.map +1 -1
- package/lib/typescript/lib/module/index.d.ts +2 -1
- package/lib/typescript/lib/module/index.d.ts.map +1 -1
- package/lib/typescript/src/Components/AutoPageFlatList.d.ts +1 -1
- package/lib/typescript/src/Components/AutoPageFlatList.d.ts.map +1 -1
- package/lib/typescript/src/Components/Spring.d.ts +1 -1
- package/lib/typescript/src/Components/Spring.d.ts.map +1 -1
- package/lib/typescript/src/NotificationManager/NotificationManagerTabs.d.ts +20 -0
- package/lib/typescript/src/NotificationManager/NotificationManagerTabs.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/api/index.d.ts +132 -3
- package/lib/typescript/src/NotificationManager/api/index.d.ts.map +1 -1
- package/lib/typescript/src/NotificationManager/components/GroupManagement.d.ts +8 -0
- package/lib/typescript/src/NotificationManager/components/GroupManagement.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/JobManagement.d.ts +9 -0
- package/lib/typescript/src/NotificationManager/components/JobManagement.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/ScheduleNotification.d.ts +10 -0
- package/lib/typescript/src/NotificationManager/components/ScheduleNotification.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/index.d.ts +8 -0
- package/lib/typescript/src/NotificationManager/components/index.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/shared/DateTimePicker.d.ts +12 -0
- package/lib/typescript/src/NotificationManager/components/shared/DateTimePicker.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/shared/GroupSelector.d.ts +16 -0
- package/lib/typescript/src/NotificationManager/components/shared/GroupSelector.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/shared/NotificationBuilderForm.d.ts +12 -0
- package/lib/typescript/src/NotificationManager/components/shared/NotificationBuilderForm.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/components/shared/StatusBadge.d.ts +8 -0
- package/lib/typescript/src/NotificationManager/components/shared/StatusBadge.d.ts.map +1 -0
- package/lib/typescript/src/NotificationManager/index.d.ts +1 -0
- package/lib/typescript/src/NotificationManager/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +36 -35
- package/src/Components/AutoPageFlatList.tsx +1 -1
- package/src/Components/Spring.tsx +13 -44
- package/src/NotificationManager/NotificationManagerTabs.tsx +178 -0
- package/src/NotificationManager/api/index.ts +240 -7
- package/src/NotificationManager/components/GroupManagement.tsx +854 -0
- package/src/NotificationManager/components/JobManagement.tsx +569 -0
- package/src/NotificationManager/components/ScheduleNotification.tsx +388 -0
- package/src/NotificationManager/components/index.ts +7 -0
- package/src/NotificationManager/components/shared/DateTimePicker.tsx +94 -0
- package/src/NotificationManager/components/shared/GroupSelector.tsx +130 -0
- package/src/NotificationManager/components/shared/NotificationBuilderForm.tsx +364 -0
- package/src/NotificationManager/components/shared/StatusBadge.tsx +72 -0
- package/src/NotificationManager/index.tsx +43 -24
- package/src/Notifications/index.tsx +2 -2
- package/src/ProfileManager/Components/BettorVouch.tsx +1 -1
- package/src/SocialComponents/PostCard/index.tsx +1 -1
- package/src/index.tsx +2 -0
- 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 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;
|