be-components 1.2.9 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/lib/commonjs/Competition/api/index.js +1 -1
  2. package/lib/commonjs/Competition/api/index.js.map +1 -1
  3. package/lib/commonjs/Competition/components/CompetitionPlay.js +1 -1
  4. package/lib/commonjs/Competition/components/CompetitionPlay.js.map +1 -1
  5. package/lib/commonjs/Competition/components/MarketsCard.js.map +1 -1
  6. package/lib/commonjs/Competition/index.js +1 -1
  7. package/lib/commonjs/Competition/index.js.map +1 -1
  8. package/lib/commonjs/CompetitionManager/api/index.js +153 -35
  9. package/lib/commonjs/CompetitionManager/api/index.js.map +1 -1
  10. package/lib/commonjs/CompetitionManager/components/AthleteSelector.js +170 -0
  11. package/lib/commonjs/CompetitionManager/components/AthleteSelector.js.map +1 -0
  12. package/lib/commonjs/CompetitionManager/components/CompetitionContestsForm.js +495 -423
  13. package/lib/commonjs/CompetitionManager/components/CompetitionContestsForm.js.map +1 -1
  14. package/lib/commonjs/CompetitionManager/components/CompetitionHeader.js +134 -0
  15. package/lib/commonjs/CompetitionManager/components/CompetitionHeader.js.map +1 -0
  16. package/lib/commonjs/CompetitionManager/components/CompetitionInfoForm.js +96 -73
  17. package/lib/commonjs/CompetitionManager/components/CompetitionInfoForm.js.map +1 -1
  18. package/lib/commonjs/CompetitionManager/components/CompetitionMatchMarketCard.js +147 -127
  19. package/lib/commonjs/CompetitionManager/components/CompetitionMatchMarketCard.js.map +1 -1
  20. package/lib/commonjs/CompetitionManager/components/CompetitionSettingsForm.js +38 -127
  21. package/lib/commonjs/CompetitionManager/components/CompetitionSettingsForm.js.map +1 -1
  22. package/lib/commonjs/CompetitionManager/components/ContestSelector.js +388 -0
  23. package/lib/commonjs/CompetitionManager/components/ContestSelector.js.map +1 -0
  24. package/lib/commonjs/CompetitionManager/components/ContestSettingsForm.js +436 -0
  25. package/lib/commonjs/CompetitionManager/components/ContestSettingsForm.js.map +1 -0
  26. package/lib/commonjs/CompetitionManager/components/MarketSelector.js +36 -26
  27. package/lib/commonjs/CompetitionManager/components/MarketSelector.js.map +1 -1
  28. package/lib/commonjs/CompetitionManager/index.js +477 -18
  29. package/lib/commonjs/CompetitionManager/index.js.map +1 -1
  30. package/lib/commonjs/Components/SearchBox.js +82 -0
  31. package/lib/commonjs/Components/SearchBox.js.map +1 -0
  32. package/lib/commonjs/Squares/components/Countdown.js +74 -0
  33. package/lib/commonjs/Squares/components/Countdown.js.map +1 -0
  34. package/lib/commonjs/Squares/components/SquaresBoard.js +95 -2
  35. package/lib/commonjs/Squares/components/SquaresBoard.js.map +1 -1
  36. package/lib/commonjs/Squares/index.js +1 -0
  37. package/lib/commonjs/Squares/index.js.map +1 -1
  38. package/lib/module/Competition/api/index.js +1 -1
  39. package/lib/module/Competition/api/index.js.map +1 -1
  40. package/lib/module/Competition/components/CompetitionPlay.js +1 -1
  41. package/lib/module/Competition/components/CompetitionPlay.js.map +1 -1
  42. package/lib/module/Competition/components/MarketsCard.js.map +1 -1
  43. package/lib/module/Competition/index.js +1 -1
  44. package/lib/module/Competition/index.js.map +1 -1
  45. package/lib/module/CompetitionManager/api/index.js +153 -35
  46. package/lib/module/CompetitionManager/api/index.js.map +1 -1
  47. package/lib/module/CompetitionManager/components/AthleteSelector.js +161 -0
  48. package/lib/module/CompetitionManager/components/AthleteSelector.js.map +1 -0
  49. package/lib/module/CompetitionManager/components/CompetitionContestsForm.js +493 -425
  50. package/lib/module/CompetitionManager/components/CompetitionContestsForm.js.map +1 -1
  51. package/lib/module/CompetitionManager/components/CompetitionHeader.js +127 -0
  52. package/lib/module/CompetitionManager/components/CompetitionHeader.js.map +1 -0
  53. package/lib/module/CompetitionManager/components/CompetitionInfoForm.js +99 -76
  54. package/lib/module/CompetitionManager/components/CompetitionInfoForm.js.map +1 -1
  55. package/lib/module/CompetitionManager/components/CompetitionMatchMarketCard.js +145 -127
  56. package/lib/module/CompetitionManager/components/CompetitionMatchMarketCard.js.map +1 -1
  57. package/lib/module/CompetitionManager/components/CompetitionSettingsForm.js +39 -131
  58. package/lib/module/CompetitionManager/components/CompetitionSettingsForm.js.map +1 -1
  59. package/lib/module/CompetitionManager/components/ContestSelector.js +379 -0
  60. package/lib/module/CompetitionManager/components/ContestSelector.js.map +1 -0
  61. package/lib/module/CompetitionManager/components/ContestSettingsForm.js +428 -0
  62. package/lib/module/CompetitionManager/components/ContestSettingsForm.js.map +1 -0
  63. package/lib/module/CompetitionManager/components/MarketSelector.js +34 -26
  64. package/lib/module/CompetitionManager/components/MarketSelector.js.map +1 -1
  65. package/lib/module/CompetitionManager/index.js +478 -19
  66. package/lib/module/CompetitionManager/index.js.map +1 -1
  67. package/lib/module/Components/SearchBox.js +73 -0
  68. package/lib/module/Components/SearchBox.js.map +1 -0
  69. package/lib/module/Squares/components/Countdown.js +65 -0
  70. package/lib/module/Squares/components/Countdown.js.map +1 -0
  71. package/lib/module/Squares/components/SquaresBoard.js +97 -4
  72. package/lib/module/Squares/components/SquaresBoard.js.map +1 -1
  73. package/lib/module/Squares/index.js +1 -0
  74. package/lib/module/Squares/index.js.map +1 -1
  75. package/lib/typescript/src/CompetitionManager/api/index.d.ts +32 -3
  76. package/lib/typescript/src/CompetitionManager/api/index.d.ts.map +1 -1
  77. package/lib/typescript/src/CompetitionManager/components/AthleteSelector.d.ts +18 -0
  78. package/lib/typescript/src/CompetitionManager/components/AthleteSelector.d.ts.map +1 -0
  79. package/lib/typescript/src/CompetitionManager/components/CompetitionContestsForm.d.ts +13 -1
  80. package/lib/typescript/src/CompetitionManager/components/CompetitionContestsForm.d.ts.map +1 -1
  81. package/lib/typescript/src/CompetitionManager/components/CompetitionHeader.d.ts +20 -0
  82. package/lib/typescript/src/CompetitionManager/components/CompetitionHeader.d.ts.map +1 -0
  83. package/lib/typescript/src/CompetitionManager/components/CompetitionInfoForm.d.ts +2 -1
  84. package/lib/typescript/src/CompetitionManager/components/CompetitionInfoForm.d.ts.map +1 -1
  85. package/lib/typescript/src/CompetitionManager/components/CompetitionMatchMarketCard.d.ts +1 -1
  86. package/lib/typescript/src/CompetitionManager/components/CompetitionMatchMarketCard.d.ts.map +1 -1
  87. package/lib/typescript/src/CompetitionManager/components/CompetitionSettingsForm.d.ts +3 -3
  88. package/lib/typescript/src/CompetitionManager/components/CompetitionSettingsForm.d.ts.map +1 -1
  89. package/lib/typescript/src/CompetitionManager/components/ContestSelector.d.ts +16 -0
  90. package/lib/typescript/src/CompetitionManager/components/ContestSelector.d.ts.map +1 -0
  91. package/lib/typescript/src/CompetitionManager/components/ContestSettingsForm.d.ts +15 -0
  92. package/lib/typescript/src/CompetitionManager/components/ContestSettingsForm.d.ts.map +1 -0
  93. package/lib/typescript/src/CompetitionManager/components/MarketSelector.d.ts +3 -2
  94. package/lib/typescript/src/CompetitionManager/components/MarketSelector.d.ts.map +1 -1
  95. package/lib/typescript/src/CompetitionManager/index.d.ts +1 -1
  96. package/lib/typescript/src/CompetitionManager/index.d.ts.map +1 -1
  97. package/lib/typescript/src/Components/SearchBox.d.ts +10 -0
  98. package/lib/typescript/src/Components/SearchBox.d.ts.map +1 -0
  99. package/lib/typescript/src/Squares/components/Countdown.d.ts +10 -0
  100. package/lib/typescript/src/Squares/components/Countdown.d.ts.map +1 -0
  101. package/lib/typescript/src/Squares/components/SquaresBoard.d.ts +2 -1
  102. package/lib/typescript/src/Squares/components/SquaresBoard.d.ts.map +1 -1
  103. package/lib/typescript/src/Squares/index.d.ts.map +1 -1
  104. package/package.json +2 -1
  105. package/src/Competition/api/index.ts +3 -3
  106. package/src/Competition/components/CompetitionPlay.tsx +1 -1
  107. package/src/Competition/components/MarketsCard.tsx +2 -2
  108. package/src/Competition/index.tsx +1 -1
  109. package/src/CompetitionManager/api/index.ts +71 -13
  110. package/src/CompetitionManager/components/AthleteSelector.tsx +127 -0
  111. package/src/CompetitionManager/components/CompetitionContestsForm.tsx +156 -261
  112. package/src/CompetitionManager/components/CompetitionHeader.tsx +101 -0
  113. package/src/CompetitionManager/components/CompetitionInfoForm.tsx +57 -45
  114. package/src/CompetitionManager/components/CompetitionMatchMarketCard.tsx +29 -70
  115. package/src/CompetitionManager/components/CompetitionSettingsForm.tsx +36 -103
  116. package/src/CompetitionManager/components/ContestSelector.tsx +269 -0
  117. package/src/CompetitionManager/components/ContestSettingsForm.tsx +281 -0
  118. package/src/CompetitionManager/components/MarketSelector.tsx +34 -23
  119. package/src/CompetitionManager/index.tsx +399 -15
  120. package/src/Components/SearchBox.tsx +54 -0
  121. package/src/Squares/components/Countdown.tsx +52 -0
  122. package/src/Squares/components/SquaresBoard.tsx +57 -5
  123. package/src/Squares/index.tsx +1 -0
  124. package/src/types.d.ts +38 -4
@@ -2,19 +2,42 @@ import React, { useEffect, useState } from 'react';
2
2
  import { ScrollView, View, ActivityIndicator } from "react-native"
3
3
  import { view_styles } from '../constants/styles';
4
4
  import CompetitionInfoForm from './components/CompetitionInfoForm';
5
- import type { AthleteProps, CompetitionMatchMarketProps, CompetitionMatchProps, CompetitionPayoutTypeProps, CompetitionProps, CompetitionResultTypeProps, CompetitionTypeProps, EventProps, LeagueProps, MarketProps, MatchProps, TeamProps, TournamentProps } from '../types';
5
+ import type { AthleteProps, CompetitionMatchMarketProps, CompetitionMatchProps, CompetitionPayoutTypeProps, CompetitionProps, CompetitionResultTypeProps, CompetitionSummaryProps, CompetitionTypeProps, EventProps, LeagueProps, MarketProps, MatchProps, TeamProps, TournamentProps, TradeProps } from '../types';
6
6
  import Colors from '../constants/colors';
7
- import { ManageCompetitionApi, ManageCompetitionMatchApi } from './api';
7
+ import { ManageCompetitionApi, ManageCompetitionHelpers, ManageCompetitionMarketApi, ManageCompetitionMatchApi } from './api';
8
8
  import CompetitionSettingsForm from './components/CompetitionSettingsForm';
9
9
  import CompetitionContestsForm from './components/CompetitionContestsForm';
10
+ import ContestSelector from './components/ContestSelector';
11
+ import MarketSelector from './components/MarketSelector';
12
+ import AthleteSelector from './components/AthleteSelector';
13
+ import ContestSettingsForm from './components/ContestSettingsForm';
14
+ import CompetitionHeader from './components/CompetitionHeader';
10
15
 
11
16
  type CompetitionManagerProps = {
12
17
  player_id?:string,
13
18
  competition_id:string
14
19
  }
15
20
 
16
- const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
21
+ const CompetitionManager = ({ player_id, competition_id }:CompetitionManagerProps) => {
17
22
  const [ module_size, setModuleSize ] = useState({ height:0, width:0 });
23
+ const [ action_loading, setActionLoading ] = useState(false);
24
+ const [ show_athletes, setShowAthletes ] = useState<{
25
+ contest_id?:string,
26
+ contest_type?:string,
27
+ market_id?:string,
28
+ filtered_positions:string[]
29
+ }>({
30
+ filtered_positions: []
31
+ });
32
+ const [ show_contests, setShowContests ] = useState<{
33
+ visible: boolean
34
+ }>({
35
+ visible: false
36
+ })
37
+ const [ show_markets, setShowMarkets ] = useState<{
38
+ contest_id?:string,
39
+ contest_type?:string
40
+ }>({})
18
41
  const [ competition_data, setCompetitionData ] = useState<{
19
42
  loaded:boolean,
20
43
  loading:boolean,
@@ -25,6 +48,8 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
25
48
  competition_types:CompetitionTypeProps[],
26
49
  competition_matches:CompetitionMatchProps[],
27
50
  competition_match_markets:CompetitionMatchMarketProps[],
51
+ competition_summaries: CompetitionSummaryProps[],
52
+ trades:TradeProps[],
28
53
  markets:MarketProps[],
29
54
  leagues:LeagueProps[],
30
55
  events:EventProps[],
@@ -37,6 +62,7 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
37
62
  loaded:false,
38
63
  loading:false,
39
64
  competition_result_types: [],
65
+ competition_summaries:[],
40
66
  competition_types: [],
41
67
  competition_matches: [],
42
68
  competition_payout_types:[],
@@ -44,14 +70,48 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
44
70
  markets: [],
45
71
  leagues:[],
46
72
  events: [],
73
+ trades:[],
47
74
  tournaments: [],
48
75
  matches:[],
49
76
  teams:[],
50
77
  athletes:[]
51
78
  })
79
+ const { contest_id, contest_type } = show_markets;
80
+ const { loaded, competition, competition_result_types, trades, competition_types, draft_competition, competition_matches, competition_match_markets, markets, leagues, events, tournaments, matches, teams, athletes } = competition_data;
81
+
82
+ //Market Selector Stuff
83
+ const showing_market_event = events.find(e => e.event_id == contest_id && contest_type == 'team');
84
+ const showing_market_event_matches = competition_matches.filter(cm => cm.event_type == 'team' && cm.event_id == contest_id);
85
+ const show_market_markets = competition_match_markets.filter(cmm => showing_market_event_matches.map(cm => cm.competition_match_id.toString()).includes(cmm.competition_match_id))
86
+ const show_market_id_overrides = showing_market_event_matches.filter(cm => cm.market_id_override).map(cm => cm.market_id_override??'0');
87
+
88
+ //AthleteSelectorStuff
89
+ const select_athlete_matches = competition_matches.filter(cm => cm.event_id == show_athletes.contest_id && cm.event_type == show_athletes.contest_type && cm.market_id_override == show_athletes.market_id);
90
+ const selected_athletes = select_athlete_matches.filter(m => m.side_type_override == 'athlete').map(m => m.side_id_override ?? '0');
91
+ const select_athlete_event = events.find(e => show_athletes.contest_type == 'team' && e.event_id == show_athletes.contest_id);
92
+ const select_athlete_positions = markets.find(m => m.market_id == show_athletes.market_id)?.supported_positions ?? []
93
+ //Filter Athletes to those with trades
94
+ let trade_athletes = [ ...new Set(trades.filter(t => t.market_type == 'FOR_MONEY' && t.market_id == show_athletes.market_id && t.side_type == 'athlete').map(t => t.side_id))]
95
+
96
+ //Lets figure out if we can add / remove a primary market for all of them
97
+ let primary_markets:{ market: MarketProps, included: boolean }[] = []
98
+ events.map(e => {
99
+ if(!e.supported_markets){ return }
100
+ e.supported_markets.map(sm => {
101
+ let market = markets.find(m => m.market_id == sm.market_id)
102
+ if(!market?.primary_market){ return }
103
+ let exists = primary_markets.find(pm => pm.market.market_id == sm.market_id)
104
+ if(!exists){
105
+ //check if this has been included or not!
106
+ let included = competition_match_markets.find(cmm => cmm.market_id == market.market_id) ? true : false
107
+ primary_markets.push({ market, included })
108
+
109
+ }
110
+ })
111
+ })
52
112
 
53
- const { loaded, competition, competition_result_types, competition_types, draft_competition, competition_matches, competition_match_markets, markets, leagues, events, tournaments, matches, teams, athletes } = competition_data;
54
113
 
114
+ const competition_valid = ManageCompetitionHelpers.isCompetitionValid(competition_types, competition_result_types, competition_matches, competition_match_markets, events, competition)
55
115
 
56
116
  useEffect(() => {
57
117
  if(!loaded){ ManageCompetitionApi.setEnvironment() }
@@ -64,6 +124,7 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
64
124
  const options = await ManageCompetitionApi.getCompetitionOptions()
65
125
  const lgs = await ManageCompetitionApi.getLeagues();
66
126
  const mks = await ManageCompetitionApi.getMarkets();
127
+ const summaries = await ManageCompetitionApi.getCompetitionSummaries(id);
67
128
  //Get unique contests
68
129
  let event_ids = cm_resp.competition_matches.filter(cm => cm.event_type == 'team').map(cm => cm.event_id);
69
130
  let tournament_ids = cm_resp.competition_matches.filter(cm => cm.event_type == 'tournament').map(cm => cm.event_id);
@@ -74,12 +135,14 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
74
135
 
75
136
  let c_events:EventProps[] = []
76
137
  if(event_ids.length > 0){ c_events = await ManageCompetitionMatchApi.getEventsByEventIds(event_ids) }
77
-
138
+ let e_trades = await ManageCompetitionMarketApi.getLatestTradesByEventIds(event_ids, 'team');
78
139
  let c_tournaments:TournamentProps[] = []
79
140
  if(tournament_ids.length > 0){ c_tournaments = await ManageCompetitionMatchApi.getTournamentsByTournamentIds(tournament_ids) }
141
+ let t_trades = await ManageCompetitionMarketApi.getLatestTradesByEventIds(tournament_ids, 'tournamet');
80
142
 
81
143
  let c_matches:MatchProps[] = []
82
144
  if(match_ids.length > 0){ c_matches = await ManageCompetitionMatchApi.getMatchesByMatchIds(match_ids) }
145
+ let m_trades = await ManageCompetitionMarketApi.getLatestTradesByEventIds(match_ids, 'match');
83
146
 
84
147
  let c_teams:TeamProps[] = []
85
148
  if(team_ids.length > 0){ c_teams = await ManageCompetitionMatchApi.getTeamsByIds(team_ids) }
@@ -92,6 +155,7 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
92
155
  loading: false,
93
156
  competition: c,
94
157
  leagues: lgs,
158
+ competition_summaries: summaries,
95
159
  competition_types: options.competition_types,
96
160
  competition_payout_types: options.competition_payout_types,
97
161
  competition_result_types: options.competition_result_types,
@@ -100,23 +164,245 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
100
164
  competition_match_markets: cm_resp.competition_match_markets,
101
165
  events: c_events,
102
166
  markets: mks,
167
+ trades: e_trades.concat(m_trades).concat(t_trades),
103
168
  tournaments: c_tournaments,
104
169
  matches: c_matches,
105
170
  teams: c_teams,
106
171
  athletes: c_athletes,
107
172
  })
173
+ }
174
+
175
+ const handleRemovePrimaryMarket = async(market:MarketProps) => {
176
+ setActionLoading(true);
177
+ //Grab all markets
178
+ let remove_markets = competition_match_markets.filter(cmm => cmm.market_id == market.market_id);
179
+ await ManageCompetitionMatchApi.deleteCompetitionMatchMarkets(remove_markets.map(cmm => cmm.competition_match_market_id));
180
+ setCompetitionData({
181
+ ...competition_data,
182
+ competition_match_markets: competition_match_markets.filter(cmm => cmm.market_id != market.market_id)
183
+ })
184
+ setActionLoading(false);
185
+ }
186
+
187
+ const handleAddPrimaryMarket = async(market:MarketProps) => {
188
+ setActionLoading(true);
189
+ let market_cmms:CompetitionMatchMarketProps[] = [];
190
+ let primary_matches = competition_matches.filter(cm => !cm.market_id_override);
191
+ primary_matches.map(cm => {
192
+ let existing_markets = competition_match_markets.filter(cmm => cmm.competition_match_id == cm.competition_match_id && cmm.market_id == market.market_id);
193
+ if(existing_markets.length > 0){ return } //Dont do anything on that one!
194
+ let market_trades = trades.filter(t => t.market_type == 'FOR_MONEY' && t.event_id == cm.event_id && t.event_type == cm.event_type && t.market_id == market.market_id);
195
+ if(market_trades.length != 2){ console.log(`no trades for event ${cm.event_id}`); return } //This event doesnt have the trades
196
+ let new_cmms:CompetitionMatchMarketProps[] = []
197
+ market_trades.map(t => {
198
+ new_cmms.push({ ...ManageCompetitionHelpers.createCompetitionMatchMarketFromTrade(t), competition_match_id: cm.competition_match_id })
199
+ })
200
+ market_cmms = market_cmms.concat(new_cmms)
201
+ })
202
+ market_cmms = await ManageCompetitionMatchApi.createCompetitionMatchMarkets(market_cmms);
203
+ setCompetitionData({
204
+ ...competition_data,
205
+ competition_match_markets: competition_match_markets.filter(cmm => !market_cmms.find(ncmm => ncmm.competition_match_market_id == cmm.competition_match_market_id)).concat(market_cmms)
206
+ })
207
+ setActionLoading(false)
208
+ }
209
+
210
+ const handleSelectTeamEvents = async(new_events:EventProps[]) => {
211
+ if(action_loading || !competition){ return }
212
+ setActionLoading(true);
213
+ let added_matches:CompetitionMatchProps[] = [];
214
+ const addEvents = new_events.map(async e => {
215
+ const cm = await ManageCompetitionMatchApi.createCompetitionMatch(competition_id, e.event_id, 'team', 'event', undefined, undefined, undefined);
216
+ added_matches.push(cm)
217
+ })
218
+ await Promise.all(addEvents);
219
+ const e_trades = await ManageCompetitionMarketApi.getLatestTradesByEventIds(new_events.map(e => e.event_id), 'team');
220
+ setCompetitionData({
221
+ ...competition_data,
222
+ competition: { ...competition, scheduled_datetime: undefined },
223
+ competition_matches: competition_matches.concat(added_matches),
224
+ events: events.filter(e => !new_events.find(ne => ne.event_id == e.event_id)).concat(new_events),
225
+ trades: trades.filter(t => !events.map(e => e.event_id.toString()).includes(t.event_id)).concat(e_trades)
226
+ })
227
+ setActionLoading(false)
228
+ }
229
+
230
+ const handleSelectTeamEvent = async(event:EventProps) => {
231
+ if(action_loading || !competition){ return }
232
+ setActionLoading(true);
233
+ const cm = await ManageCompetitionMatchApi.createCompetitionMatch(competition_id, event.event_id, 'team', 'event', undefined, undefined, undefined);
234
+ const e_trades = await ManageCompetitionMarketApi.getLatestTradesByEventIds([event.event_id], 'team');
235
+ setCompetitionData({
236
+ ...competition_data,
237
+ competition: { ...competition, scheduled_datetime: undefined },
238
+ competition_matches: competition_matches.concat(cm),
239
+ events: events.filter(e => e.event_id != event.event_id).concat(event),
240
+ trades: trades.filter(t => t.event_id != event.event_id).concat(e_trades)
241
+ })
242
+ setActionLoading(false);
243
+ }
244
+
245
+ const handleRemoveCompetitionMatch = async(competition_match_id:string) => {
246
+ if(action_loading){ return }
247
+ setActionLoading(true);
248
+ await ManageCompetitionMatchApi.deleteCompetitionMatch(competition_match_id);
249
+ setCompetitionData({
250
+ ...competition_data,
251
+ competition_matches: competition_matches.filter(cm => cm.competition_match_id != competition_match_id)
252
+ })
253
+ setActionLoading(false)
254
+ }
255
+
256
+ const handleRemoveCompetitionMatchMarkets = async(cmms:CompetitionMatchMarketProps[]) => {
257
+ if(action_loading){ return }
258
+ setActionLoading(true);
259
+ await ManageCompetitionMatchApi.deleteCompetitionMatchMarkets(cmms.map(cmm => cmm.competition_match_market_id));
260
+ setCompetitionData({
261
+ ...competition_data,
262
+ competition_match_markets: competition_match_markets.filter(cmm => !cmms.map(rmm => rmm.competition_match_market_id.toString()).includes(cmm.competition_match_market_id))
263
+ })
264
+ setActionLoading(false)
265
+ }
266
+
267
+ const handleDeselectTeamEvent = async(event:EventProps) => {
268
+ const cms = competition_matches.filter(cm => cm.event_id == event.event_id && cm.event_type == 'team');
269
+ const deleteCMS = cms.map(async cm => {
270
+ await ManageCompetitionMatchApi.deleteCompetitionMatch(cm.competition_match_id);
271
+ })
272
+ await Promise.all(deleteCMS);
273
+ setCompetitionData({
274
+ ...competition_data,
275
+ competition_matches: competition_matches.filter(cm => !cms.find(dcm => dcm.competition_match_id == cm.competition_match_id))
276
+ })
277
+ }
278
+ const handleSelectAthlete = async(athlete:AthleteProps) => {
279
+ if(!show_athletes?.contest_id || !show_athletes?.contest_type){ return }
280
+ let athlete_trades = trades.filter(t => t.market_type == 'FOR_MONEY' && t.side_type == 'athlete' && t.side_id == athlete.athlete_id && t.market_id == show_athletes.market_id);
281
+ if(athlete_trades.length != 2){ return alert('Unable to add') }
282
+
283
+ if(action_loading){ return }
284
+ setActionLoading(true);
285
+ //First check if there is an existing market_id override without a side_id_override and add it!
286
+ let existing_cm = competition_matches.find(cm => cm.event_id == show_athletes.contest_id && cm.event_type == show_athletes.contest_type && cm.market_id_override == show_athletes.market_id && !cm.side_id_override);
287
+ if(existing_cm){
288
+ existing_cm = await ManageCompetitionMatchApi.updateCompetitionMatch({ ...existing_cm, side_type_override: 'athlete', side_id_override: athlete.athlete_id });
289
+ } else {
290
+ console.log('CREATING NEW MATCH!!!')
291
+ existing_cm = await ManageCompetitionMatchApi.createCompetitionMatch(competition_id, show_athletes.contest_id, show_athletes.contest_type, 'athlete', show_athletes.market_id, 'athlete', athlete.athlete_id)
292
+ }
293
+ let new_cmms:CompetitionMatchMarketProps[] = []
294
+ athlete_trades.map(t => {
295
+ new_cmms.push({ ...ManageCompetitionHelpers.createCompetitionMatchMarketFromTrade(t), competition_match_id: existing_cm.competition_match_id })
296
+ })
297
+ new_cmms = await ManageCompetitionMatchApi.createCompetitionMatchMarkets(new_cmms);
298
+ setCompetitionData({
299
+ ...competition_data,
300
+ athletes: athletes.concat(athlete),
301
+ competition_matches: competition_matches.filter(cm => cm.competition_match_id != existing_cm.competition_match_id).concat(existing_cm),
302
+ competition_match_markets:competition_match_markets.filter(cmm => !new_cmms.find(ncmm => ncmm.competition_match_market_id == cmm.competition_match_market_id)).concat(new_cmms)
303
+ })
304
+ setActionLoading(false)
305
+ }
306
+
307
+ const handleDeselectAthlete = async(athlete:AthleteProps) => {
308
+ if(!show_athletes?.contest_id || !show_athletes?.contest_type || !show_athletes?.market_id){ return }
309
+ let athlete_cm = competition_matches.find(cm => cm.market_id_override == show_athletes.market_id && cm.side_id_override == athlete.athlete_id)
310
+ if(!athlete_cm){ return alert('Unable to remove') }
311
+ if(action_loading){ return }
312
+ setActionLoading(true);
313
+ let cmms = competition_match_markets.filter(cmm => cmm.competition_match_id == athlete_cm.competition_match_id);
314
+ await ManageCompetitionMatchApi.deleteCompetitionMatch(athlete_cm.competition_match_id);
315
+ await ManageCompetitionMatchApi.deleteCompetitionMatchMarkets(cmms.map(cmm => cmm.competition_match_id))
316
+ setCompetitionData({
317
+ ...competition_data,
318
+ competition_matches: competition_matches.filter(cm => cm.competition_match_id != athlete_cm.competition_match_id),
319
+ competition_match_markets: competition_match_markets.filter(cmm => !cmms.map(rmm => rmm.competition_match_market_id.toString()).includes(cmm.competition_match_market_id))
320
+ })
321
+ setActionLoading(false)
322
+ }
323
+
324
+ const handleRemoveMarket = async(contest_id:string, contest_type:string, market:MarketProps) => {
325
+ if(action_loading){ return }
326
+ setActionLoading(true);
327
+ let relevant_matches = competition_matches.filter(cm => cm.event_id == contest_id && cm.event_type == contest_type);
328
+ //First remove all the non_primary if there are any
329
+ let non_primary_matches = relevant_matches.filter(cm => cm.market_id_override == market.market_id);
330
+ let matches_removed:string[] = []
331
+ let markets_removed:string[] = []
332
+ const rem_non_primary = non_primary_matches.map(async cm => {
333
+ const del_response = await ManageCompetitionMatchApi.deleteCompetitionMatch(cm.competition_match_id);
334
+ matches_removed = matches_removed.concat(del_response.competition_match.competition_match_id)
335
+ markets_removed = markets_removed.concat(del_response.competition_match_markets.map(cmm => cmm.competition_match_market_id))
336
+ })
337
+ await Promise.all(rem_non_primary)
338
+
339
+ //Ok now lets looks for the primary market one
340
+ let primary_match = relevant_matches.find(cm => !cm.market_id_override)
341
+ if(primary_match){
342
+ let primary_cmms = competition_match_markets.filter(cmm => cmm.competition_match_id == primary_match.competition_match_id && cmm.market_id == market.market_id);
343
+
344
+ await ManageCompetitionMatchApi.deleteCompetitionMatchMarkets(primary_cmms.map(cmm => cmm.competition_match_market_id));
345
+ markets_removed = markets_removed.concat(primary_cmms.map(cmm => cmm.competition_match_market_id));
346
+ }
347
+ setCompetitionData({
348
+ ...competition_data,
349
+ competition_matches: competition_matches.filter(cm => !matches_removed.includes(cm.competition_match_id)),
350
+ competition_match_markets: competition_match_markets.filter(cmm => !markets_removed.includes(cmm.competition_match_market_id))
351
+ })
352
+ setActionLoading(false);
353
+ }
108
354
 
355
+ const handleAddMarket = async(contest_id:string, contest_type:string, market:MarketProps) => {
356
+ if(action_loading){ return }
357
+ setActionLoading(true);
358
+ //First check if this is a primary market
359
+ if(market.primary_market){
360
+ //Get the competition match that is available for it!
361
+ let primary_match = competition_matches.find(cm => cm.event_type == contest_type && cm.event_id == contest_id && !cm.market_id_override);
362
+ if(!primary_match){
363
+ setActionLoading(false)
364
+ return alert('Unable to add this market')
365
+ }
366
+ //Now lets get the trades!!
367
+ let market_trades = trades.filter(t => t.market_type == 'FOR_MONEY' && t.event_id == contest_id && t.event_type == contest_type && t.market_id == market.market_id)
368
+ let cmms:CompetitionMatchMarketProps[] = []
369
+ market_trades.map(t => {
370
+ cmms.push({ ...ManageCompetitionHelpers.createCompetitionMatchMarketFromTrade(t), competition_match_id: primary_match.competition_match_id })
371
+ })
372
+ if(cmms.length != 2){
373
+ setActionLoading(false)
374
+ return alert('Unable to add this market')
375
+ }
376
+ const new_cmms = await ManageCompetitionMatchApi.createCompetitionMatchMarkets(cmms);
377
+ setActionLoading(false);
378
+ return setCompetitionData({
379
+ ...competition_data,
380
+ competition_match_markets: competition_match_markets.filter(cmms => new_cmms.find(ncms => ncms.competition_match_market_id != cmms.competition_match_market_id)).concat(new_cmms)
381
+ })
382
+ }
383
+ //If this is not a primary market - we need to add a market_id override for the competition match!!
384
+ let existing_match = competition_matches.find(cm => cm.event_type == contest_type && cm.event_id == contest_id && cm.market_id_override == market.market_id);
385
+ if(existing_match){
386
+ setActionLoading(false)
387
+ return alert('Already added this market!')
388
+ }
389
+ const new_cm = await ManageCompetitionMatchApi.createCompetitionMatch(competition_id, contest_id, contest_type, market.level, market.market_id);
390
+ setCompetitionData({
391
+ ...competition_data,
392
+ competition_matches: competition_matches.concat(new_cm)
393
+ })
394
+ setActionLoading(false)
109
395
  }
110
396
 
111
397
 
112
- if(!competition || !draft_competition){
398
+ if(!competition || !draft_competition || player_id != competition.admin_id){
113
399
  return (
114
400
  <View style={{flex:1}}>
115
401
  <ActivityIndicator size='large' color={Colors.brand.midnight} style={{ padding:20, alignSelf:'center' }} />
116
402
  </View>
117
403
  )
118
404
  }
119
- console.log(module_size)
405
+
120
406
  return (
121
407
  <View style={{ flex:1 }}>
122
408
  <ScrollView style={{ flex:1 }} onLayout={(ev) => {
@@ -124,38 +410,136 @@ const CompetitionManager = ({ competition_id }:CompetitionManagerProps) => {
124
410
  setModuleSize({ height, width })
125
411
  }}>
126
412
  <View style={{ ...view_styles.wrapper }}>
413
+ <CompetitionHeader
414
+ action_loading={action_loading}
415
+ width={module_size.width}
416
+ competition={competition}
417
+ competition_valid={competition_valid}
418
+ onActivate={async() => {
419
+ setActionLoading(true);
420
+ const new_c = await ManageCompetitionApi.activateCompetition(competition_id)
421
+ setCompetitionData({ ...competition_data, competition: new_c })
422
+ setActionLoading(false);
423
+ }}
424
+ onPause={async() => {
425
+ setActionLoading(true);
426
+ const new_c = await ManageCompetitionApi.pauseCompetition(competition_id)
427
+ const new_summaries = await ManageCompetitionApi.getCompetitionSummaries(competition_id);
428
+ setCompetitionData({ ...competition_data, competition: new_c, competition_summaries: new_summaries })
429
+ setActionLoading(false);
430
+ }}
431
+ onResume={async() => {
432
+ setActionLoading(true);
433
+ const new_c = await ManageCompetitionApi.resumeCompetition(competition_id);
434
+ setCompetitionData({ ...competition_data, competition: new_c })
435
+ setActionLoading(false);
436
+
437
+ }}
438
+ />
127
439
  <CompetitionInfoForm
128
- competition={draft_competition}
440
+ is_valid={competition_valid.info}
441
+ competition={competition}
129
442
  width={module_size.width - 20}
130
- onCompetitionUpdate={(comp) => setCompetitionData({ ...competition_data, draft_competition: comp})}
443
+ onCompetitionUpdate={async(comp) => {
444
+ const new_c = await ManageCompetitionApi.updateCompetition(comp);
445
+ setCompetitionData({ ...competition_data, competition: new_c });
446
+ }}
131
447
  />
132
448
  <CompetitionSettingsForm
133
- competition={draft_competition}
449
+ is_valid={competition_valid.settings}
450
+ competition={competition}
134
451
  width={module_size.width - 20}
135
452
  competition_result_types={competition_result_types}
136
- competition_types={competition_types}
137
- onCompetitionUpdate={(comp) => setCompetitionData({ ...competition_data, draft_competition: comp})}
453
+ onCompetitionUpdate={async(comp) => {
454
+ const new_c = await ManageCompetitionApi.updateCompetition(comp);
455
+ setCompetitionData({ ...competition_data, competition: new_c });
456
+ }}
138
457
  />
139
458
  <CompetitionContestsForm
459
+ action_loading={action_loading}
460
+ is_valid={competition_valid.contests}
140
461
  width={module_size.width - 20}
141
- competition={draft_competition}
462
+ competition={competition}
142
463
  competition_matches={competition_matches}
143
464
  competition_match_markets={competition_match_markets}
144
465
  events={events}
466
+ primary_markets={primary_markets}
145
467
  teams={teams}
146
468
  athletes={athletes}
147
469
  tournaments={tournaments}
470
+ onAddPrimaryMarket={(market) => handleAddPrimaryMarket(market)}
471
+ onRemovePrimaryMarket={(market) => handleRemovePrimaryMarket(market)}
148
472
  matches={matches}
149
473
  leagues={leagues}
150
474
  markets={markets}
475
+ onDeleteMarket={(contest_id, contest_type, market) => handleRemoveMarket(contest_id, contest_type, market)}
476
+ onShowAthletes={(contest_id, contest_type, market_id) => setShowAthletes({ contest_id, contest_type, market_id, filtered_positions:[] })}
477
+ onShowMarkets={(contest_id, contest_type) => setShowMarkets({ contest_id, contest_type })}
478
+ onShowContests={() => setShowContests({ visible:true })}
151
479
  onSaveCompetitionMatch={() => console.log('SAVE EVENT')}
152
- onDeleteCompetitionMatch={() => console.log('DELEVE')}
480
+ onDeleteCompetitionMatch={(competition_match_id) => handleRemoveCompetitionMatch(competition_match_id)}
153
481
  onUpdateCompetitionMatch={() => console.log('UPDATE')}
154
482
  onSaveCompetitionMatchMarkets={(smms) => console.log(smms)}
155
- onDeleteCompetitionMatchMarkets={(cmms) => console.log(cmms)}
483
+ onDeleteCompetitionMatchMarkets={(cmms) => handleRemoveCompetitionMatchMarkets(cmms)}
484
+ />
485
+ <ContestSettingsForm
486
+ is_valid={competition_valid.contest_settings}
487
+ width={module_size.width - 20}
488
+ competition={competition}
489
+ competition_matches={competition_matches}
490
+ competition_match_markets={competition_match_markets}
491
+ competition_types={competition_types}
492
+ events={events}
493
+ onCompetitionUpdate={async(c) => {
494
+ const new_c = await ManageCompetitionApi.updateCompetition(c)
495
+ setCompetitionData({ ...competition_data, competition: new_c })
496
+ }}
156
497
  />
157
498
  </View>
158
499
  </ScrollView>
500
+ {show_contests.visible ?
501
+ <View style={{ position:'absolute', top:0, left:0, right:0, bottom:0, backgroundColor:Colors.shades.black_faded, justifyContent:'flex-end' }}>
502
+ <ContestSelector
503
+ action_loading={action_loading}
504
+ height={module_size.height}
505
+ width={module_size.width}
506
+ leagues={leagues}
507
+ onClose={() => setShowContests({ visible: false })}
508
+ onSelectTeamEvent={(event) => handleSelectTeamEvent(event)}
509
+ onSelectTeamEvents={(events) => handleSelectTeamEvents(events)}
510
+ onDeselectTeamEvent={(event) => handleDeselectTeamEvent(event)}
511
+ selected_team_events={events.filter(e => competition_matches.filter(cm => cm.event_type == 'team').map(cm => cm.event_id.toString()).includes(e.event_id.toString()))}
512
+ />
513
+ </View>
514
+ :<></>}
515
+ {show_athletes.contest_id ?
516
+ <View style={{ position:'absolute', top:0, left:0, right:0, bottom:0, backgroundColor:Colors.shades.black_faded, justifyContent:'flex-end' }}>
517
+ <AthleteSelector
518
+ width={module_size.width}
519
+ height={module_size.height}
520
+ event={select_athlete_event}
521
+ selected_athletes={selected_athletes}
522
+ filtered_positions={select_athlete_positions}
523
+ filtered_athletes={trade_athletes}
524
+ onSelectAthlete={(athlete) => handleSelectAthlete(athlete)}
525
+ onDeselectAthlete={(athlete) => handleDeselectAthlete(athlete)}
526
+ onClose={() => setShowAthletes({ filtered_positions: [] })}
527
+ />
528
+ </View>
529
+ :<></>}
530
+ {show_markets.contest_id && show_markets.contest_type && showing_market_event ?
531
+ <View style={{ position:'absolute', top:0, left:0, right:0, bottom:0, backgroundColor:Colors.shades.black_faded, justifyContent:'flex-end' }}>
532
+ <MarketSelector
533
+ height={module_size.height}
534
+ width={module_size.width}
535
+ markets={markets.filter(m => showing_market_event.supported_markets?.map(m => m.market_id.toString()).includes(m.market_id.toString()))}
536
+ onClose={() => setShowMarkets({})}
537
+ onDeselectMarket={(market) => handleRemoveMarket(show_markets.contest_id ?? '0', show_markets.contest_type ?? 'team', market)}
538
+ onSelectMarket={(market) => handleAddMarket(show_markets.contest_id ?? '0', show_markets.contest_type ?? 'team', market)}
539
+ selected_markets={[ ...new Set(show_market_markets.map(cmm => cmm.market_id).concat(show_market_id_overrides))]}
540
+ />
541
+ </View>
542
+ :<></>}
159
543
  </View>
160
544
  )
161
545
  }
@@ -0,0 +1,54 @@
1
+ import { TextInput, View } from "react-native"
2
+ import Button from "./Button";
3
+ import React, { useState } from "react";
4
+ import Icons from "./Icons";
5
+ import Colors from "../constants/colors";
6
+
7
+ type SearchBoxProps = {
8
+ onSearch?: (text:string) => void,
9
+ onChange? : (text:string) => void,
10
+ hide_search_button?:boolean,
11
+ placeholder?: string
12
+ }
13
+
14
+ const SearchBox = ({ placeholder, onSearch, onChange, hide_search_button }:SearchBoxProps) => {
15
+ const [ search_value, setSearchValue ] = useState('');
16
+
17
+ const handleSearch = () => {
18
+ if(!onSearch){ return }
19
+ if(search_value == ''){ return alert('Please provide search value') }
20
+ onSearch(search_value)
21
+ setSearchValue('')
22
+ }
23
+
24
+ return (
25
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center', padding:5 }}>
26
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center', marginRight:10, borderWidth:1, borderRadius:8, borderColor:Colors.shades.shade400 }}>
27
+ <View style={{ padding:10 }}>
28
+ <Icons.SearchIcon size={12} color={Colors.brand.midnight} />
29
+ </View>
30
+ <TextInput
31
+ placeholder={placeholder ?? 'Search'}
32
+ value={search_value}
33
+ placeholderTextColor={Colors.shades.shade400}
34
+ style={{ flex:1, padding:10, color:Colors.brand.midnight, fontFamily: 'barlow-semibold', fontSize:14 }}
35
+ onChangeText={(text) => {
36
+ setSearchValue(text)
37
+ if(onChange){ onChange(text) }
38
+ }}
39
+ />
40
+ </View>
41
+ {!hide_search_button ?
42
+ <Button
43
+ title="Search"
44
+ title_color={Colors.shades.white}
45
+ backgroundColor={Colors.brand.midnight}
46
+ borderRadius={8}
47
+ onPress={() => handleSearch()}
48
+ />
49
+ :<></>}
50
+ </View>
51
+ )
52
+ }
53
+
54
+ export default SearchBox
@@ -0,0 +1,52 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { View } from 'react-native';
3
+ import Colors from "../../constants/colors";
4
+ import type { Moment } from "moment-mini";
5
+ import moment from "moment-mini";
6
+ import { Text } from "../../Components";
7
+
8
+ type CountdownProps = {
9
+ end_datetime:Moment
10
+ label?:string,
11
+ onTimesUp: () => void
12
+ }
13
+ const Countdown = ({ end_datetime, label, onTimesUp }:CountdownProps) => {
14
+ const [ started, setStarted ] = useState(false);
15
+ const [ seconds_remaining, setSecondsRemaining ] = useState(-1);
16
+ const [ times_up, setTimesUp ] = useState(false);
17
+
18
+ useEffect(() => {
19
+ let diff_seconds = end_datetime.diff(moment(), 'seconds')
20
+ if(diff_seconds < 0){ return }
21
+ setSecondsRemaining(diff_seconds)
22
+ setStarted(true)
23
+ },[end_datetime])
24
+
25
+ useEffect(() => {
26
+ if(!started){ return }
27
+ if(seconds_remaining > 0){
28
+ setTimeout(() => setSecondsRemaining(seconds_remaining - 1), 1000);
29
+ } else {
30
+ setTimesUp(true)
31
+ }
32
+ },[seconds_remaining])
33
+
34
+
35
+ useEffect(() => {
36
+ if(!times_up){ return }
37
+ onTimesUp()
38
+ },[times_up])
39
+
40
+ if(seconds_remaining < 0 || seconds_remaining > 600){ return <></> }
41
+
42
+ return (
43
+ <View style={{ flexDirection:'row', alignItems:'center', minWidth:50, padding:10, borderRadius:22, backgroundColor:seconds_remaining < 30 ? Colors.utility.error : seconds_remaining < 100 ? Colors.utility.warning : Colors.utility.success }}>
44
+ {label ?
45
+ <Text style={{ marginRight:5 }} size={14} color={Colors.shades.white} weight='regular'>{label}</Text>
46
+ :<></>}
47
+ <Text textAlign="center" size={14} color={Colors.shades.white} weight='bold'>{seconds_remaining}</Text>
48
+ </View>
49
+ )
50
+ }
51
+
52
+ export default Countdown