be-components 3.2.5 → 3.2.7

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 (52) hide show
  1. package/lib/commonjs/Components/Button.js +1 -3
  2. package/lib/commonjs/Components/Button.js.map +1 -1
  3. package/lib/commonjs/Components/Toggle.js +91 -0
  4. package/lib/commonjs/Components/Toggle.js.map +1 -0
  5. package/lib/commonjs/MarketComponents/api/index.js +76 -1
  6. package/lib/commonjs/MarketComponents/api/index.js.map +1 -1
  7. package/lib/commonjs/MarketComponents/components/ExternalPriceComparison.js +300 -0
  8. package/lib/commonjs/MarketComponents/components/ExternalPriceComparison.js.map +1 -0
  9. package/lib/commonjs/MarketComponents/index.js +2 -0
  10. package/lib/commonjs/MarketComponents/index.js.map +1 -1
  11. package/lib/module/Components/Button.js +1 -3
  12. package/lib/module/Components/Button.js.map +1 -1
  13. package/lib/module/Components/Toggle.js +82 -0
  14. package/lib/module/Components/Toggle.js.map +1 -0
  15. package/lib/module/MarketComponents/api/index.js +76 -1
  16. package/lib/module/MarketComponents/api/index.js.map +1 -1
  17. package/lib/module/MarketComponents/components/ExternalPriceComparison.js +291 -0
  18. package/lib/module/MarketComponents/components/ExternalPriceComparison.js.map +1 -0
  19. package/lib/module/MarketComponents/index.js +2 -0
  20. package/lib/module/MarketComponents/index.js.map +1 -1
  21. package/lib/typescript/lib/commonjs/Components/Button.d.ts.map +1 -1
  22. package/lib/typescript/lib/commonjs/Components/Toggle.d.ts +15 -0
  23. package/lib/typescript/lib/commonjs/Components/Toggle.d.ts.map +1 -0
  24. package/lib/typescript/lib/commonjs/MarketComponents/api/index.d.ts +6 -0
  25. package/lib/typescript/lib/commonjs/MarketComponents/api/index.d.ts.map +1 -1
  26. package/lib/typescript/lib/commonjs/MarketComponents/components/ExternalPriceComparison.d.ts +15 -0
  27. package/lib/typescript/lib/commonjs/MarketComponents/components/ExternalPriceComparison.d.ts.map +1 -0
  28. package/lib/typescript/lib/commonjs/MarketComponents/index.d.ts +1 -0
  29. package/lib/typescript/lib/module/Components/Button.d.ts.map +1 -1
  30. package/lib/typescript/lib/module/Components/Spring.d.ts +1 -1
  31. package/lib/typescript/lib/module/Components/Toggle.d.ts +16 -0
  32. package/lib/typescript/lib/module/Components/Toggle.d.ts.map +1 -0
  33. package/lib/typescript/lib/module/MarketComponents/api/index.d.ts +6 -0
  34. package/lib/typescript/lib/module/MarketComponents/api/index.d.ts.map +1 -1
  35. package/lib/typescript/lib/module/MarketComponents/components/ExternalPriceComparison.d.ts +16 -0
  36. package/lib/typescript/lib/module/MarketComponents/components/ExternalPriceComparison.d.ts.map +1 -0
  37. package/lib/typescript/lib/module/MarketComponents/index.d.ts +2 -0
  38. package/lib/typescript/lib/module/MarketComponents/index.d.ts.map +1 -1
  39. package/lib/typescript/src/Components/Toggle.d.ts +19 -0
  40. package/lib/typescript/src/Components/Toggle.d.ts.map +1 -0
  41. package/lib/typescript/src/MarketComponents/api/index.d.ts +8 -2
  42. package/lib/typescript/src/MarketComponents/api/index.d.ts.map +1 -1
  43. package/lib/typescript/src/MarketComponents/components/ExternalPriceComparison.d.ts +16 -0
  44. package/lib/typescript/src/MarketComponents/components/ExternalPriceComparison.d.ts.map +1 -0
  45. package/lib/typescript/src/MarketComponents/index.d.ts +12 -0
  46. package/lib/typescript/src/MarketComponents/index.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/src/Components/Button.tsx +2 -2
  49. package/src/Components/Toggle.tsx +78 -0
  50. package/src/MarketComponents/api/index.ts +61 -3
  51. package/src/MarketComponents/components/ExternalPriceComparison.tsx +211 -0
  52. package/src/MarketComponents/index.tsx +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/MarketComponents/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;qBA4B6rB,CAAC;mBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAN3sB,CAAJ;qBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAM0lB,CAAC;mBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAAjmB,CAAC;qBAAkB,CAAC;;;;;;;;;;;;;AAdlD,wBAcC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/MarketComponents/index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;qBA8BolB,CAAC;mBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAX/lB,CAAC;qBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAWye,CAAC;mBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAJlhB,CAAH;qBAAkB,CAAC;;;;;;;;;;;;;AAXpB,wBAeC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "be-components",
3
- "version": "3.2.5",
3
+ "version": "3.2.7",
4
4
  "description": "Components for BettorEdge Apps",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -38,7 +38,7 @@ const Button = ({ title, style, title_weight, disabled, loading, title_size, pad
38
38
 
39
39
  <TouchableOpacity
40
40
  disabled={disabled}
41
- style={{ ...getBorderRadiusOverride(), flexDirection:'row', alignItems:'center', justifyContent:'center', flex:1, padding:padding??8, backgroundColor:backgroundColor??Colors.brand.electric, borderWidth:borderWidth??0, borderColor:borderColor, ...input_style }}
41
+ style={{ ...getBorderRadiusOverride(), flexDirection:'row', alignItems:'center', justifyContent:'center', padding:padding??8, backgroundColor:backgroundColor??Colors.brand.electric, borderWidth:borderWidth??0, borderColor:borderColor, ...input_style }}
42
42
  onPress={(ev) => onPress(ev)}>
43
43
  {avatar_url ?
44
44
  <Image
@@ -47,7 +47,7 @@ const Button = ({ title, style, title_weight, disabled, loading, title_size, pad
47
47
  resizeMode='cover'
48
48
  />
49
49
  :<></>}
50
- <View style={{ marginLeft:5, marginRight:5, flexGrow:1 }}>
50
+ <View style={{ marginLeft:5, marginRight:5 }}>
51
51
  <Text size={title_size??14} weight={title_weight ?? 'bold'} textAlign="center" color={title_color??Colors.brand.midnight}>{title}</Text>
52
52
  {loading ?
53
53
  <View style={{ position:'absolute', top:0, bottom:0, left:0, right:0 }}>
@@ -0,0 +1,78 @@
1
+ import React, { useState } from "react"
2
+ import { FlatList, StyleSheet, TouchableOpacity, View } from "react-native"
3
+ import Text from "./Text"
4
+ import Colors from "../constants/colors"
5
+
6
+
7
+ type ToggleProps = {
8
+ options: {key:string, label:string}[],
9
+ background_color?:string,
10
+ toggle_padding?:number,
11
+ border_radius?:number,
12
+ active_toggle_color?:string,
13
+ inactive_toggle_color?:string,
14
+ inactive_title_color?:string,
15
+ active_title_color?:string,
16
+ selected_option?: string,
17
+ onSelectOption:(key:string) => void
18
+ }
19
+ const Toggle = ({ options, background_color, active_title_color, toggle_padding, border_radius, inactive_title_color, inactive_toggle_color ,active_toggle_color, selected_option, onSelectOption }:ToggleProps) => {
20
+ const [ toggle_width, setToggleWidth ] = useState(300);
21
+ const MIN_OPTION_WIDTH = 110
22
+ let option_width = toggle_width - 4
23
+ if(options.length > 0){
24
+ option_width = toggle_width / options.length
25
+ if(option_width < MIN_OPTION_WIDTH){ option_width = MIN_OPTION_WIDTH }
26
+ }
27
+
28
+ const renderOptions = (data:{item:{ key:string, label:string }, index:number}) => {
29
+ const selected = selected_option == data.item.key ? true : false
30
+ const last = data.index == options.length -1 ? true: false
31
+ const first = data.index == 0 ? true : false
32
+ return (
33
+ <TouchableOpacity
34
+ style={{
35
+ width: option_width,
36
+ padding:toggle_padding ?? 15,
37
+ backgroundColor:selected?active_toggle_color ?? Colors.brand.midnight : inactive_toggle_color ?? Colors.shades.white,
38
+ borderTopLeftRadius: first ? border_radius ?? 8 : 0,
39
+ borderBottomLeftRadius: first? border_radius ?? 8 : 0,
40
+ borderTopRightRadius: last ? border_radius ?? 8 : 0,
41
+ borderBottomRightRadius: last ? border_radius ?? 8 : 0,
42
+ ...style.float
43
+
44
+ }}
45
+ onPress={() => onSelectOption(data.item.key)}
46
+ >
47
+ <Text
48
+ textAlign='center'
49
+ size={14}
50
+ color={selected?active_title_color??Colors.shades.white: inactive_title_color ?? Colors.brand.midnight}
51
+ weight={selected?'bold':'regular'}>{data.item.label}</Text>
52
+ </TouchableOpacity>
53
+ )
54
+ }
55
+
56
+ return (
57
+ <View style={{ borderRadius:border_radius ?? 8, backgroundColor:background_color ?? Colors.shades.white, padding:2 }} onLayout={(ev) => {
58
+ const { width } = ev.nativeEvent.layout;
59
+ setToggleWidth(width)
60
+ }}>
61
+ <FlatList
62
+ key='toggle'
63
+ data={options}
64
+ showsHorizontalScrollIndicator={false}
65
+ horizontal
66
+ renderItem={renderOptions}
67
+ keyExtractor={(item) => item.key.toString()}
68
+ />
69
+ </View>
70
+ )
71
+ }
72
+
73
+ const style = StyleSheet.create({
74
+ float: { shadowColor: "rgba(0, 0, 0, 0.06)", shadowOffset: { width: 0, height: 10 }, shadowRadius: 10, shadowOpacity: 1 }
75
+
76
+ })
77
+
78
+ export default Toggle
@@ -1,6 +1,6 @@
1
1
  import axios from 'axios';
2
2
  import { APIOverrides } from "../../ApiOverrides"
3
- import type { AthleteProps, BestAvailableResponseProps, ContestStatProps, EventOrderStatProps, EventProps, LeagueProps, MarketProps, MarketSideOptionProps, MatchProps, OrderProps, PodcastProps, TeamProps, TournamentProps } from "../../types"
3
+ import type { AthleteProps, BestAvailableResponseProps, ContestStatProps, EventOrderStatProps, EventProps, ExternalPriceProps, LeagueProps, MarketProps, MarketSideOptionProps, MatchProps, OrderProps, PodcastProps, TeamProps, TournamentProps, TradeProps } from "../../types"
4
4
  import moment from 'moment-mini';
5
5
 
6
6
  let EVENT_SVC_API = ''
@@ -27,7 +27,7 @@ const MarketComponentApi = {
27
27
  return []
28
28
  }
29
29
  },
30
- getLatestTradesByEvents: async(event_type: string, event_ids:string[]) => {
30
+ getLatestTradesByEvents: async(event_type: string, event_ids:string[]):Promise<TradeProps[]> => {
31
31
  try {
32
32
  if(event_ids.length == 0){ return [] }
33
33
  const resp = await axios.post(`${MK_SVC_API}/v1/trades/event/latest/bulk/get`, { event_type, event_ids })
@@ -37,6 +37,25 @@ const MarketComponentApi = {
37
37
  return []
38
38
  }
39
39
  },
40
+ getExternalPrices: async(contest_type:string, contest_id:string, market_id:string, side?:string, participant_id?:string, participant_type?:string, external_name?:string):Promise<ExternalPriceProps[]> => {
41
+ try {
42
+ let url = `${EVENT_SVC_API}/v1/prices/latest/${contest_id}/${contest_type}?market_id=${market_id}`
43
+ if(side){
44
+ url += `&side=${side}`
45
+ }
46
+ if(participant_type && participant_id){
47
+ url += `&participant_id=${participant_id}`
48
+ }
49
+ if(external_name){
50
+ url += `&external_name=${external_name}`
51
+ }
52
+ const resp = await axios.get(url);
53
+ return resp.data.prices
54
+
55
+ } catch (e) {
56
+ return []
57
+ }
58
+ },
40
59
  getMyAction:async():Promise<OrderProps[]> => {
41
60
  try {
42
61
  const resp = await axios.get(`${MK_SVC_API}/v1/orders/action/me`);
@@ -165,7 +184,6 @@ const MarketComponentApi = {
165
184
  },
166
185
  getContestStatsByEvent: async(contest_id:string):Promise<ContestStatProps[]> => {
167
186
  try {
168
- console.log(EVENT_SVC_API)
169
187
  const resp = await axios.get(`${EVENT_SVC_API}/v1/events/stats/event/${contest_id}`)
170
188
  return resp.data.contest_stats
171
189
  } catch (e) {
@@ -377,5 +395,45 @@ const MarketComponentHelpers = {
377
395
  }
378
396
  })
379
397
  return new_title
398
+ },
399
+ getExternalPriceDetails: (contest_type:string, market?:MarketProps, event?:EventProps, tournament?:TournamentProps, match?:MatchProps) => {
400
+ let fail_response = { contest_title: '', o_side_label:'', trade_side_label: '' }
401
+ if(!market){ return fail_response }
402
+ fail_response.o_side_label = market.side_options.find(so => so.side != market.trade_side)?.side.toUpperCase() ?? '',
403
+ fail_response.trade_side_label = market.trade_side.toUpperCase()
404
+
405
+ let contest_title = ''
406
+ let o_side_label = fail_response.o_side_label
407
+ let trade_side_label = fail_response.trade_side_label
408
+
409
+ market.side_options.map(so => {
410
+ if(so.id_source == 'side'){
411
+ if(so.side == market.trade_side){ trade_side_label = so.side.toUpperCase() }
412
+ else { o_side_label = so.side.toUpperCase() }
413
+ return
414
+ }
415
+ switch(contest_type){
416
+ case 'team':
417
+ if(!event){ break }
418
+ contest_title = event.event_title
419
+ if(so.id_source == 'team'){
420
+ if(so.side == market.trade_side){ trade_side_label = event[so.side as keyof EventProps]?.abbr }
421
+ else { o_side_label = event[so.side as keyof EventProps]?.abbr }
422
+ break
423
+ }
424
+ break
425
+ case 'tournament':
426
+ if(!tournament){ break }
427
+ contest_title = tournament.tournament_name
428
+ break
429
+ case 'match':
430
+ if(!match){ return }
431
+ contest_title = match.match_title
432
+ break
433
+ default:
434
+ }
435
+ })
436
+ return { contest_title, o_side_label, trade_side_label }
437
+
380
438
  }
381
439
  }
@@ -0,0 +1,211 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { ActivityIndicator, FlatList, View } from 'react-native';
3
+ import { Button, Text } from '../../Components';
4
+ import Colors from '../../constants/colors';
5
+ import type { AthleteProps, EventProps, ExternalPriceProps, MarketProps, MatchProps, TeamProps, TournamentProps, TradeProps } from '../../types';
6
+ import { MarketComponentApi, MarketComponentHelpers } from '../api';
7
+ import Toggle from '../../Components/Toggle';
8
+ import moment from 'moment-mini';
9
+ import { view_styles } from '../../constants/styles';
10
+
11
+ type ExternalPriceComparisonProps = {
12
+ price_key:string,
13
+ contest_id:string,
14
+ contest_type:string,
15
+ market_id:string,
16
+ maxHeight?:number,
17
+ participant_type?:string,
18
+ external_name?:string,
19
+ participant_id?:string,
20
+ init_side?:string,
21
+ onClose:() => void
22
+ }
23
+
24
+
25
+ const ExternalPriceComparison = ({ price_key, contest_id, contest_type, maxHeight, market_id, participant_id, participant_type, external_name, init_side, onClose }:ExternalPriceComparisonProps) => {
26
+ const [ module_data, setModuleData ] = useState<{
27
+ loading:boolean,
28
+ market?:MarketProps,
29
+ selected_side:string,
30
+ athlete?:AthleteProps,
31
+ team?:TeamProps,
32
+ trades:TradeProps[],
33
+ event?:EventProps,
34
+ tournament?:TournamentProps,
35
+ match?:MatchProps,
36
+ external_prices:ExternalPriceProps[]
37
+ }>({
38
+ loading:false,
39
+ selected_side: '',
40
+ trades:[],
41
+ external_prices: []
42
+ });
43
+ const { loading, event, athlete, team, market, selected_side, tournament, match, trades, external_prices } = module_data;
44
+
45
+ useEffect(() => {
46
+ MarketComponentApi.setEnvironment();
47
+ if(!price_key || !contest_id){ return }
48
+ getData()
49
+ },[price_key]);
50
+
51
+ const getData = async() => {
52
+ setModuleData({ ...module_data, loading:true });
53
+ const prices = await MarketComponentApi.getExternalPrices(contest_type, contest_id, market_id, undefined, participant_id, participant_type, external_name);
54
+ const ts = await MarketComponentApi.getLatestTradesByEvents(contest_type, [contest_id]);
55
+ let market_ts = ts.filter(lt => lt.market_id == market_id && lt.market_type == 'FOR_MONEY');
56
+ let a:AthleteProps | undefined = undefined
57
+ let tm:TeamProps | undefined = undefined
58
+ if(participant_id){
59
+ market_ts = market_ts.filter(lt => lt.side_id == participant_id);
60
+ if(participant_type == 'athlete'){
61
+ let as = await MarketComponentApi.getAthletesByIds([participant_id])
62
+ a = as[0]
63
+ }
64
+ if(participant_type == 'team'){
65
+ let tms = await MarketComponentApi.getTeamsByIds([participant_id])
66
+ tm = tms[0]
67
+ }
68
+ }
69
+ const markets = await MarketComponentApi.getMarkets();
70
+ const mk = markets.find(m => m.market_id == market_id)
71
+
72
+ let e:EventProps | undefined = undefined
73
+ let t:TournamentProps | undefined = undefined
74
+ let m:MatchProps | undefined = undefined
75
+
76
+ if(contest_type == 'team'){
77
+ let es = await MarketComponentApi.getEventsByEventIds([contest_id])
78
+ e = es[0]
79
+ }
80
+ if(contest_type == 'tournament'){
81
+ let ts = await MarketComponentApi.getTournamentsByTournamentIds([contest_id])
82
+ t = ts[0]
83
+ }
84
+ if(contest_type == 'match'){
85
+ let ms = await MarketComponentApi.getMatchesByMatchIds([contest_id])
86
+ m = ms[0]
87
+ }
88
+
89
+
90
+
91
+ setModuleData({
92
+ ...module_data,
93
+ loading: false,
94
+ athlete: a,
95
+ team: tm,
96
+ external_prices: prices,
97
+ event: e,
98
+ tournament:t,
99
+ trades: market_ts,
100
+ match: m,
101
+ market:mk,
102
+ selected_side: init_side ?? mk?.trade_side ?? ''
103
+ })
104
+ }
105
+
106
+ const renderPrices = (data:{item:ExternalPriceProps, index:number}) => {
107
+ if(!market){ return <></> }
108
+ return (
109
+ <View style={{ ...view_styles.body_row }}>
110
+ <View style={{ flex:1 }}>
111
+ <Text theme='header_2'>{data.item.external_name}</Text>
112
+ <Text style={{ marginTop:3 }} size={10} color={Colors.brand.slate} weight='regular'>{(data.item.vig_pct*100).toFixed(2)}% Vig</Text>
113
+ </View>
114
+ <View style={{ alignItems:'flex-end' }}>
115
+ <Text theme='header_2'>{market.var_1_required ? `${MarketComponentHelpers.getVar1Label(market, data.item.var_1)} `:''}{MarketComponentHelpers.getOddsLabel(data.item.odds)}</Text>
116
+ <Text style={{ marginTop:3 }} size={10} color={Colors.brand.slate} weight='regular'>As of: {moment(data.item.last_update_datetime).fromNow()}</Text>
117
+ </View>
118
+ </View>
119
+ )
120
+ }
121
+
122
+ const { o_side_label, trade_side_label } = MarketComponentHelpers.getExternalPriceDetails(contest_type, market, event, tournament, match)
123
+ let visible_prices = external_prices.filter(p => p.side == selected_side).sort((a,b) => a.external_name.localeCompare(b.external_name))
124
+ const consensus_price = visible_prices.find(p => p.external_name.toLowerCase() == 'consensus');
125
+ visible_prices = visible_prices.filter(p => p.external_name.toLowerCase() != 'consensus');
126
+
127
+ const latest_trade = trades.find(t => t.side == selected_side)
128
+ return (
129
+ <View style={{ ...view_styles.section, maxHeight }}>
130
+ <View style={{ ...view_styles.section_header }}>
131
+ <View style={{ flexGrow:1 }}>
132
+ <Text theme='header'>External Price Comparison</Text>
133
+ {market ?
134
+ <Text theme='body' style={{ marginTop:3 }}>{athlete?`${athlete.abbr_name} `:team?`${team.abbr} `:''}{market.type == 'Stat' ? market.stat_label : market.type}</Text>
135
+ :<></>}
136
+ </View>
137
+ <View style={{ flexDirection:'row' }}>
138
+ <Button
139
+ title='X'
140
+ padding={10}
141
+ backgroundColor={Colors.shades.shade100}
142
+ onPress={() => onClose()}
143
+ />
144
+ </View>
145
+ </View>
146
+ <View style={{ ...view_styles.section_body }}>
147
+ {loading ?
148
+ <ActivityIndicator size='large' color={Colors.brand.midnight} style={{ padding:20, alignSelf:'center' }}/>
149
+ :<></>}
150
+ {market ?
151
+ <Toggle
152
+ background_color={Colors.shades.shade100}
153
+ options={[{ key: market.side_options.find(so => so.side != market.trade_side)?.side ?? '', label: o_side_label }, { key: market.trade_side, label: trade_side_label }]}
154
+ onSelectOption={(option) => setModuleData({ ...module_data, selected_side: option })}
155
+ selected_option={selected_side}
156
+ />
157
+ :<></>}
158
+
159
+ <View nativeID='header_trades' style={{ paddingTop:20, borderBottomWidth:1, borderColor:Colors.shades.shade600, paddingBottom:10 }}>
160
+ {latest_trade && market ?
161
+ <View style={{ ...view_styles.body_row }}>
162
+ <View style={{ flex:1 }}>
163
+ <Text theme='header'>BettorEdge</Text>
164
+ <Text style={{ marginTop:3 }} size={10} color={Colors.brand.slate} weight='regular'>{0}% Vig</Text>
165
+ </View>
166
+ <View style={{ alignItems:'flex-end' }}>
167
+ <Text theme='header_2'>{market.var_1_required ? `${MarketComponentHelpers.getVar1Label(market, latest_trade.var_1)} `:''}{MarketComponentHelpers.getOddsLabel(latest_trade.odds)}</Text>
168
+ <Text style={{ marginTop:3 }} size={10} color={Colors.brand.slate} weight='regular'>Traded: {moment(latest_trade.last_update_datetime).fromNow()}</Text>
169
+ </View>
170
+ </View>
171
+ :<></>}
172
+ {consensus_price && market ?
173
+ <View style={{ ...view_styles.body_row }}>
174
+ <View style={{ flex:1 }}>
175
+ <Text theme='header_2'>Consensus</Text>
176
+ <Text style={{ marginTop:3 }} size={10} color={Colors.brand.slate} weight='regular'>{(consensus_price.vig_pct*100).toFixed(2)}% Vig</Text>
177
+ </View>
178
+ <View style={{ alignItems:'flex-end' }}>
179
+ <Text theme='header_2'>{market.var_1_required ? `${MarketComponentHelpers.getVar1Label(market, consensus_price.var_1)} `:''}{MarketComponentHelpers.getOddsLabel(consensus_price.odds)}</Text>
180
+ <Text style={{ marginTop:3 }} size={10} color={Colors.brand.slate} weight='regular'>As of: {moment(consensus_price.last_update_datetime).fromNow()}</Text>
181
+ </View>
182
+ </View>
183
+ :<></>}
184
+ </View>
185
+ <View style={{ marginTop:10 }}>
186
+ <FlatList
187
+ data={visible_prices}
188
+ renderItem={renderPrices}
189
+ keyExtractor={(item) => item.external_price_id.toString()}
190
+ />
191
+ </View>
192
+ </View>
193
+ <View style={{ ...view_styles.section_footer }}>
194
+ <Button
195
+ title='CLOSE'
196
+ backgroundColor={Colors.shades.white}
197
+ style={{ flex:1 }}
198
+ borderWidth={1}
199
+ borderRadius={4}
200
+ padding={12}
201
+ onPress={() => onClose()}
202
+ borderColor={Colors.brand.electric}
203
+ title_color={Colors.brand.electric}
204
+ />
205
+ </View>
206
+
207
+ </View>
208
+ )
209
+ }
210
+
211
+ export default ExternalPriceComparison
@@ -11,6 +11,7 @@ import OrderBookChart from './components/OrderBookChart';
11
11
  import BestAvailableOrderCard from './components/BestAvailableOrderCard';
12
12
  import OrderBookCard from './components/OrderBook';
13
13
  import MyOrderList from './components/MyOrderList';
14
+ import ExternalPriceComparison from './components/ExternalPriceComparison';
14
15
 
15
16
  export default {
16
17
  TeamEventMarket,
@@ -22,6 +23,7 @@ export default {
22
23
  OrderBookChart,
23
24
  AthleteTournamentMarket,
24
25
  TeamEventList,
26
+ ExternalPriceComparison,
25
27
  TournamentMarket,
26
28
  MatchMarket,
27
29
  TournamentList,