be-components 1.4.5 → 1.4.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 (57) hide show
  1. package/lib/commonjs/CompetitionManager/api/index.js +6 -0
  2. package/lib/commonjs/CompetitionManager/api/index.js.map +1 -1
  3. package/lib/commonjs/CompetitionManager/components/AdminCompetitionList.js +198 -0
  4. package/lib/commonjs/CompetitionManager/components/AdminCompetitionList.js.map +1 -0
  5. package/lib/commonjs/Engage/api/index.js +140 -0
  6. package/lib/commonjs/Engage/api/index.js.map +1 -0
  7. package/lib/commonjs/Engage/components/BracketCompetitionCard.js +221 -0
  8. package/lib/commonjs/Engage/components/BracketCompetitionCard.js.map +1 -0
  9. package/lib/commonjs/Engage/components/CompetitionCard.js +253 -0
  10. package/lib/commonjs/Engage/components/CompetitionCard.js.map +1 -0
  11. package/lib/commonjs/Engage/components/SquaresCompetitionCard.js +191 -0
  12. package/lib/commonjs/Engage/components/SquaresCompetitionCard.js.map +1 -0
  13. package/lib/commonjs/Engage/index.js +299 -0
  14. package/lib/commonjs/Engage/index.js.map +1 -0
  15. package/lib/commonjs/index.js +14 -0
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/module/CompetitionManager/api/index.js +6 -0
  18. package/lib/module/CompetitionManager/api/index.js.map +1 -1
  19. package/lib/module/CompetitionManager/components/AdminCompetitionList.js +189 -0
  20. package/lib/module/CompetitionManager/components/AdminCompetitionList.js.map +1 -0
  21. package/lib/module/Engage/api/index.js +134 -0
  22. package/lib/module/Engage/api/index.js.map +1 -0
  23. package/lib/module/Engage/components/BracketCompetitionCard.js +214 -0
  24. package/lib/module/Engage/components/BracketCompetitionCard.js.map +1 -0
  25. package/lib/module/Engage/components/CompetitionCard.js +246 -0
  26. package/lib/module/Engage/components/CompetitionCard.js.map +1 -0
  27. package/lib/module/Engage/components/SquaresCompetitionCard.js +184 -0
  28. package/lib/module/Engage/components/SquaresCompetitionCard.js.map +1 -0
  29. package/lib/module/Engage/index.js +290 -0
  30. package/lib/module/Engage/index.js.map +1 -0
  31. package/lib/module/index.js +3 -1
  32. package/lib/module/index.js.map +1 -1
  33. package/lib/typescript/src/CompetitionManager/api/index.d.ts +1 -0
  34. package/lib/typescript/src/CompetitionManager/api/index.d.ts.map +1 -1
  35. package/lib/typescript/src/CompetitionManager/components/AdminCompetitionList.d.ts +12 -0
  36. package/lib/typescript/src/CompetitionManager/components/AdminCompetitionList.d.ts.map +1 -0
  37. package/lib/typescript/src/Engage/api/index.d.ts +25 -0
  38. package/lib/typescript/src/Engage/api/index.d.ts.map +1 -0
  39. package/lib/typescript/src/Engage/components/BracketCompetitionCard.d.ts +15 -0
  40. package/lib/typescript/src/Engage/components/BracketCompetitionCard.d.ts.map +1 -0
  41. package/lib/typescript/src/Engage/components/CompetitionCard.d.ts +14 -0
  42. package/lib/typescript/src/Engage/components/CompetitionCard.d.ts.map +1 -0
  43. package/lib/typescript/src/Engage/components/SquaresCompetitionCard.d.ts +12 -0
  44. package/lib/typescript/src/Engage/components/SquaresCompetitionCard.d.ts.map +1 -0
  45. package/lib/typescript/src/Engage/index.d.ts +11 -0
  46. package/lib/typescript/src/Engage/index.d.ts.map +1 -0
  47. package/lib/typescript/src/index.d.ts +3 -1
  48. package/lib/typescript/src/index.d.ts.map +1 -1
  49. package/package.json +1 -1
  50. package/src/CompetitionManager/api/index.ts +6 -0
  51. package/src/CompetitionManager/components/AdminCompetitionList.tsx +144 -0
  52. package/src/Engage/api/index.ts +124 -0
  53. package/src/Engage/components/BracketCompetitionCard.tsx +117 -0
  54. package/src/Engage/components/CompetitionCard.tsx +126 -0
  55. package/src/Engage/components/SquaresCompetitionCard.tsx +92 -0
  56. package/src/Engage/index.tsx +261 -0
  57. package/src/index.tsx +6 -1
@@ -0,0 +1,144 @@
1
+ import React, { useEffect, useState } from "react"
2
+ import { View, FlatList, TouchableOpacity, Image, ActivityIndicator } from "react-native"
3
+ import { ManageCompetitionApi } from "../api"
4
+ import Colors from "../../constants/colors"
5
+ import { view_styles } from "../../constants/styles"
6
+ import { Button, Icons, Text } from "../../Components"
7
+ import type { CompetitionProps } from "../../types"
8
+
9
+ type AdminCompetitionListProps = {
10
+ width:number,
11
+ max_height?:number,
12
+ onSelectCompetition:(competition:CompetitionProps) => void,
13
+ onClose: () => void,
14
+ onCreateNew: () => void
15
+ }
16
+
17
+ const AdminCompetitionList = ({ width, max_height, onClose, onCreateNew, onSelectCompetition }:AdminCompetitionListProps) => {
18
+ const [ list_data, setData ] = useState<{
19
+ loading: boolean,
20
+ active_tab:'active'|'closed',
21
+ offset:number,
22
+ competitions:CompetitionProps[]
23
+ }>({
24
+ loading:false,
25
+ offset:0,
26
+ active_tab: 'active',
27
+ competitions: []
28
+ })
29
+ const { offset, active_tab, loading, competitions } = list_data;
30
+
31
+ useEffect(() => {
32
+ ManageCompetitionApi.setEnvironment();
33
+ getDataFromServer(0)
34
+ },[active_tab])
35
+
36
+ const getDataFromServer = async(offset:number) => {
37
+ setData({ ...list_data, loading:true });
38
+ const comps = await ManageCompetitionApi.getMyAdminCompetition(offset, active_tab);
39
+ setData({
40
+ ...list_data,
41
+ loading: false,
42
+ competitions: comps,
43
+ offset
44
+ })
45
+ }
46
+
47
+ const renderCompetitions = (data: { item:CompetitionProps, index:number }) => {
48
+ return (
49
+ <TouchableOpacity style={{ ...view_styles.body_row, padding:10, borderBottomWidth:1, borderColor:Colors.shades.shade600 }} onPress={() => onSelectCompetition(data.item)}>
50
+ <Image
51
+ source={{ uri: data.item.image?.url }}
52
+ style={{ height:30, width:30, borderRadius:4 }}
53
+ resizeMode="cover"
54
+ />
55
+ <View style={{ flex:1, marginLeft:10 }}>
56
+ <Text theme="header_2">{data.item.competition_name}</Text>
57
+ <Text style={{ marginTop:3 }} theme="body">{data.item.competition_description}</Text>
58
+ </View>
59
+ <Icons.ChevronIcon direction='right' size={8} color={Colors.brand.midnight}/>
60
+ </TouchableOpacity>
61
+ )
62
+ }
63
+
64
+ return (
65
+ <View style={{ maxWidth:width, minWidth:300, maxHeight:max_height ?? 700, backgroundColor:Colors.shades.white }}>
66
+ <View style={{ ...view_styles.section_header }}>
67
+ <View style={{ flex:1 }}>
68
+ <Text theme='header'>MY COMPETITIONS</Text>
69
+ <Text style={{ marginTop:3 }} theme="body">Below is a list of the competitions you have created</Text>
70
+ </View>
71
+ <Button
72
+ title="CREATE"
73
+ backgroundColor={Colors.utility.success}
74
+ title_color={Colors.shades.white}
75
+ onPress={() => onCreateNew()}
76
+ />
77
+ </View>
78
+ <View style={{ flexDirection:'row' }}>
79
+ <Button
80
+ title="ACTIVE"
81
+ title_color={active_tab == 'active' ? Colors.shades.white : Colors.brand.midnight}
82
+ backgroundColor={active_tab == 'active' ? Colors.brand.midnight: Colors.shades.white}
83
+ title_weight={active_tab == 'active' ? 'bold' : 'regular'}
84
+ borderRadius={0}
85
+ padding={15}
86
+ style={{ flex:1 }}
87
+ onPress={() => setData({ ...list_data, active_tab: 'active' })}
88
+ />
89
+ <Button
90
+ title="CLOSED"
91
+ title_color={active_tab == 'closed' ? Colors.shades.white : Colors.brand.midnight}
92
+ backgroundColor={active_tab == 'closed' ? Colors.brand.midnight: Colors.shades.white}
93
+ title_weight={active_tab == 'closed' ? 'bold' : 'regular'}
94
+ borderRadius={0}
95
+ padding={15}
96
+ style={{ flex:1 }}
97
+ onPress={() => setData({ ...list_data, active_tab: 'closed' })}
98
+ />
99
+ </View>
100
+ <View style={{ ...view_styles.section_body }}>
101
+ {loading ?
102
+ <ActivityIndicator style={{ padding:20, alignSelf:'center' }} size='large' color={Colors.brand.midnight} />
103
+ :<></>}
104
+ <FlatList
105
+ data={competitions}
106
+ renderItem={renderCompetitions}
107
+ keyExtractor={(item) => item.competition_id.toString()}
108
+ />
109
+ </View>
110
+ {active_tab == 'closed' ?
111
+ <View style={{ ...view_styles.section_footer }}>
112
+ {offset > 0 ?
113
+ <Button
114
+ title='PREV'
115
+ title_color={Colors.brand.electric}
116
+ backgroundColor='transparent'
117
+ onPress={() => getDataFromServer(offset - 1)}
118
+ />
119
+ :<View/>}
120
+ <View style={{ flex:1 }} />
121
+ <Button
122
+ title='NEXT'
123
+ title_color={Colors.brand.electric}
124
+ backgroundColor='transparent'
125
+ onPress={() => getDataFromServer(offset + 1)}
126
+ />
127
+ </View>
128
+ :<></>}
129
+ <View style={{ ...view_styles.section_footer }}>
130
+ <Button
131
+ title="CLOSE"
132
+ title_color={Colors.shades.white}
133
+ style={{ flex:1, marginRight:8 }}
134
+ padding={15}
135
+ backgroundColor={Colors.utility.error}
136
+ onPress={() => onClose()}
137
+ />
138
+ </View>
139
+ </View>
140
+ )
141
+ }
142
+
143
+
144
+ export default AdminCompetitionList
@@ -0,0 +1,124 @@
1
+ import axios from 'axios';
2
+ import { APIOverrides } from "../../ApiOverrides";
3
+ import type { BracketCompetitionProps, BracketProps, CompanyProps, CompetitionPayoutTypeProps, CompetitionProps, CompetitionResultTypeProps, CompetitionTypeProps, EventProps, LeagueProps, PublicPlayerProps, SquaresCompetitionProps } from '../../types';
4
+
5
+ let AUTH_SVC_API = ''
6
+ let TP_SVC_API = ''
7
+ let EVENT_SVC_API = ''
8
+
9
+ export { EngageApi, EngageHelpers }
10
+
11
+ const EngageApi = {
12
+ setEnvironment: () => {
13
+ const endpoints = APIOverrides.getEndpoints();
14
+ TP_SVC_API = endpoints['TP_SVC_API'] as string;
15
+ EVENT_SVC_API = endpoints['EVENT_SVC_API'] as string;
16
+ AUTH_SVC_API = endpoints['AUTH_SVC_API'] as string;
17
+ },
18
+ getActivePublicCompetitions: async():Promise<CompetitionProps[]> => {
19
+ try {
20
+ const resp = await axios.get(`${TP_SVC_API}/v2/competitions/public`)
21
+ return resp.data.competitions
22
+ } catch (e) {
23
+ console.log(e)
24
+ return []
25
+ }
26
+ },
27
+ getActivePublicSquares: async():Promise<SquaresCompetitionProps[]> => {
28
+ try {
29
+ const resp = await axios.get(`${TP_SVC_API}/v1/squares/public`)
30
+ return resp.data.squares_competitions
31
+ } catch (e) {
32
+ return []
33
+ }
34
+ },
35
+ getLeagues: async():Promise<LeagueProps[]> => {
36
+ try {
37
+ const resp = await axios.get(`${EVENT_SVC_API}/v1/leagues`)
38
+ return resp.data.leagues
39
+ } catch (e) {
40
+ console.log(e)
41
+ return []
42
+ }
43
+
44
+ },
45
+ getBracketsByIds: async(bracket_ids:string[]):Promise<BracketProps[]> => {
46
+ try {
47
+ if(bracket_ids.length == 0){ return [] }
48
+ const resp = await axios.post(`${EVENT_SVC_API}/v1/brackets/bulk/get`, { bracket_ids })
49
+ console.log(resp.data)
50
+ return resp.data.brackets
51
+ } catch (e) {
52
+ console.log(e)
53
+ return []
54
+ }
55
+ },
56
+ getEventsByEventIds: async(event_ids:string[]):Promise<EventProps[]> => {
57
+ try {
58
+ if(event_ids.length == 0){ return [] }
59
+ const resp = await axios.post(`${EVENT_SVC_API}/v1/events/bulk/get`, { attribute:'event_id', values: event_ids })
60
+ return resp.data.events
61
+ } catch (e) {
62
+ return []
63
+ }
64
+ },
65
+ getCompetitionOptions: async():Promise<{competition_types:CompetitionTypeProps[], competition_result_types:CompetitionResultTypeProps[], competition_payout_types:CompetitionPayoutTypeProps[]}> => {
66
+ const resp = await axios.get(`${TP_SVC_API}/v1/competitions/options`)
67
+ return resp.data
68
+ },
69
+ getActivePublicBrackets: async():Promise<BracketCompetitionProps[]> => {
70
+ try {
71
+ const resp = await axios.get(`${TP_SVC_API}/v1/brackets/public`)
72
+ console.log(resp.data)
73
+ return resp.data.bracket_competitions
74
+ } catch (e) {
75
+ return []
76
+ }
77
+ },
78
+ getCompaniesByIds: async(company_ids:string[]):Promise<CompanyProps[]> => {
79
+ try {
80
+ if(company_ids.length == 0){ return [] }
81
+ const resp = await axios.post(`${AUTH_SVC_API}/v1/companies/bulk/get`, { company_ids })
82
+ return resp.data.companies
83
+ } catch (e) {
84
+ console.log(e)
85
+ return []
86
+ }
87
+ },
88
+ getPlayersByPlayerIds : async(player_ids:string[]):Promise<PublicPlayerProps[]> => {
89
+ try {
90
+ if(player_ids.length == 0){ return [] }
91
+
92
+ const resp = await axios.post(`${AUTH_SVC_API}/v1/players/bulk/get`, { player_ids })
93
+ return resp.data.players
94
+ } catch (e) {
95
+ console.log(e)
96
+ return []
97
+ }
98
+ },
99
+ }
100
+
101
+
102
+ const EngageHelpers = {
103
+ getCompanyIdsFromEngage: (comps:CompetitionProps[], sq_comps:SquaresCompetitionProps[], brackets:BracketCompetitionProps[]) => {
104
+ let ids = comps.filter(c => c.company_id).map(c => c.company_id ?? '0')
105
+ ids = ids.concat(sq_comps.filter(s => s.company_id).map(s => s.company_id ?? '0'))
106
+ ids = ids.concat(brackets.filter(b => b.company_id).map(b => b.company_id ?? '0'))
107
+ return [ ...new Set(ids.map(id => id)) ]
108
+ },
109
+ getPlayerIdsFromEngage: (comps:CompetitionProps[], sq_comps:SquaresCompetitionProps[], brackets:BracketCompetitionProps[]) => {
110
+ let ids = comps.map(c => c.admin_id);
111
+ ids = ids.concat(comps.filter(c => c.pacer_id).map(c => c.pacer_id ?? '0'))
112
+ ids = ids.concat(sq_comps.map(s => s.admin_id))
113
+ ids = ids.concat(brackets.map(b => b.admin_id))
114
+ return [ ...new Set(ids.map(id => id)) ]
115
+ },
116
+ getEventIdsFromSquares: (squares:SquaresCompetitionProps[]) => {
117
+ const ids = squares.filter(s => s.event_id).map(s => s.event_id)
118
+ return [ ...new Set(ids.map(id => id)) ]
119
+ },
120
+ getBracketIdsFromBracketComps: (bc:BracketCompetitionProps[]) => {
121
+ const ids = bc.map(c => c.bracket_id)
122
+ return [ ...new Set(ids.map(id => id)) ]
123
+ }
124
+ }
@@ -0,0 +1,117 @@
1
+ import React from 'react';
2
+ import { View, Image, TouchableOpacity } from 'react-native';
3
+ import type { BracketCompetitionProps, BracketProps, CompanyProps, CompetitionResultTypeProps, LeagueProps, PublicPlayerProps } from '../../types';
4
+ import { view_styles } from '../../constants/styles';
5
+ import Colors from '../../constants/colors';
6
+ import { Icons, Text } from '../../Components';
7
+ import moment from 'moment-mini';
8
+
9
+ type BracketCompetitionCardProps = {
10
+ bracket_competition:BracketCompetitionProps,
11
+ competition_result_type:CompetitionResultTypeProps,
12
+ company?:CompanyProps,
13
+ admin?:PublicPlayerProps,
14
+ pacer?:PublicPlayerProps,
15
+ league?:LeagueProps,
16
+ bracket?:BracketProps,
17
+ onCompetitionSelect:(c:BracketCompetitionProps) => void
18
+ }
19
+ const BracketCompetitionCard = ({ bracket_competition, bracket, league, company, admin, onCompetitionSelect}:BracketCompetitionCardProps) => {
20
+ const cl = bracket_competition.market_type == 'FOR_MONEY' ? '$' : 'E'
21
+ let current_payout = bracket_competition.ticket_revenue
22
+ if(bracket_competition.promo_payout){ current_payout += bracket_competition.promo_payout }
23
+ if(bracket_competition.guaranteed_payout && bracket_competition.guaranteed_payout > current_payout){ current_payout = bracket_competition.guaranteed_payout }
24
+
25
+ const tickets_available = bracket_competition.max_brackets - bracket_competition.tickets_sold
26
+ const is_live = moment().isAfter(moment(bracket_competition.scheduled_datetime)) ? true : false
27
+
28
+ return (
29
+ <TouchableOpacity style={{ ...view_styles.section, padding:0 }} onPress={() => onCompetitionSelect(bracket_competition)}>
30
+ <View style={{ ...view_styles.section_header, backgroundColor:Colors.shades.shade100 }}>
31
+ <Image
32
+ source={{ uri: bracket_competition.image?.url ?? 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
33
+ style={{ height:45, width:45, borderRadius:4}}
34
+ resizeMode='cover'
35
+ />
36
+ <View style={{ flex:1, marginLeft:10, marginRight:10, borderRightWidth:1, borderRightColor:Colors.shades.shade600 }}>
37
+ <Text theme='header_2'>{bracket_competition.competition_name}</Text>
38
+ <Text style={{ marginTop:3 }} theme='body'>{bracket_competition.competition_description}</Text>
39
+ </View>
40
+ <Text size={20} color={Colors.brand.electric} weight='bold'>{cl}{bracket_competition.buy_in}</Text>
41
+ </View>
42
+ <View style={{ ...view_styles.section_body }}>
43
+ <View style={{ ...view_styles.body_row }}>
44
+ {bracket && league ?
45
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center', marginRight:10 }}>
46
+ <Image
47
+ source={{ uri: league.league_image }}
48
+ style={{ height:30, width:30, borderRadius:4 }}
49
+ resizeMode='cover'
50
+ />
51
+ <View style={{ flex:1, marginLeft:10 }}>
52
+ <Text theme='header_2'>{bracket.bracket_name}</Text>
53
+ </View>
54
+ </View>
55
+ :<></>}
56
+ {tickets_available > 0 ?
57
+ <View style={{ justifyContent:'center', alignItems:'center' }}>
58
+ <Text size={18} color={Colors.brand.midnight} weight='bold'>{tickets_available}</Text>
59
+ <Text style={{ marginTop:3 }} theme='body'>TICKETS</Text>
60
+ </View>
61
+ :
62
+ <View style={{ justifyContent:'center', alignItems:'center' }}>
63
+ <Text size={18} color={Colors.utility.error} weight='bold'>FULL</Text>
64
+ </View>
65
+ }
66
+ </View>
67
+ </View>
68
+
69
+ <View style={{ ...view_styles.section_footer, backgroundColor:company?Colors.incentive.gold_faded:Colors.shades.shade100 }}>
70
+ {company ?
71
+ <Image
72
+ source={{ uri: company.company_image?.url ?? 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
73
+ style={{ height:30, width:30, borderRadius:4}}
74
+ resizeMode='cover'
75
+ />
76
+ :admin ?
77
+ <Image
78
+ source={{ uri: admin.profile_pic && admin.profile_pic != '' ? admin.profile_pic : 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
79
+ style={{ height:30, width:30, borderRadius:4}}
80
+ resizeMode='cover'
81
+ />
82
+ :<></>}
83
+ {bracket_competition.prize_override ?
84
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center', marginLeft:10 }}>
85
+ <View style={{ flex:1, marginRight:10}}>
86
+ <Text size={12} weight='bold' color={Colors.brand.midnight}>ADDITIONAL PRIZE</Text>
87
+ <Text style={{ marginTop:3 }} size={10} color={Colors.incentive.gold} weight='bold'>{bracket_competition.prize_override}</Text>
88
+ </View>
89
+ {bracket_competition.prize_image?.url ?
90
+ <Image
91
+ source={{ uri: bracket_competition.prize_image.url }}
92
+ style={{ height:30, width:30, borderRadius:4}}
93
+ resizeMode='cover'
94
+ />
95
+ :
96
+ <Icons.AwardRibbonIcon size={24} color={Colors.incentive.gold} />
97
+ }
98
+ </View>
99
+ :
100
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center' }}>
101
+ <View style={{ flex:1, marginLeft:20, marginRight:20 }}>
102
+ <Text theme='header_2'>CURRENT PAYOUT</Text>
103
+ {is_live ?
104
+ <Text style={{ marginTop:3 }} color={Colors.utility.error} weight='bold' size={12}>IN PROGRESS</Text>
105
+ :
106
+ <Text style={{ marginTop:3 }} theme='body_2'>Join Until {moment(bracket_competition.scheduled_datetime).format('ddd hh:mm a')}</Text>
107
+ }
108
+ </View>
109
+ <Text color={Colors.utility.success} size={20} weight='bold'>{cl}{current_payout.toFixed(2)}</Text>
110
+ </View>
111
+ }
112
+ </View>
113
+ </TouchableOpacity>
114
+ )
115
+ }
116
+
117
+ export default BracketCompetitionCard
@@ -0,0 +1,126 @@
1
+ import React from 'react';
2
+ import { View, Image, TouchableOpacity } from 'react-native';
3
+ import type { CompanyProps, CompetitionProps, CompetitionResultTypeProps, CompetitionTypeProps, PublicPlayerProps } from '../../types';
4
+ import { view_styles } from '../../constants/styles';
5
+ import Colors from '../../constants/colors';
6
+ import { Icons, Text } from '../../Components';
7
+ import moment from 'moment-mini';
8
+
9
+ type CompetitionCardProps = {
10
+ competition:CompetitionProps,
11
+ competition_type:CompetitionTypeProps,
12
+ competition_result_type:CompetitionResultTypeProps,
13
+ company?:CompanyProps,
14
+ admin?:PublicPlayerProps,
15
+ pacer?:PublicPlayerProps,
16
+ onCompetitionSelect:(c:CompetitionProps) => void
17
+ }
18
+ const CompetitionCard = ({ competition, competition_type, company, admin, onCompetitionSelect }:CompetitionCardProps) => {
19
+ const cl = competition.market_type == 'FOR_MONEY' ? '$' : 'E'
20
+ let current_payout = competition.ticket_revenue
21
+ if(competition.promo_payout){ current_payout += competition.promo_payout }
22
+ if(competition.guaranteed_payout && competition.guaranteed_payout > current_payout){ current_payout = competition.guaranteed_payout }
23
+
24
+ const tickets_available = parseFloat(competition.available_tickets as string) - competition.tickets_sold
25
+ const is_live = moment().isAfter(moment(competition.scheduled_datetime)) ? true : false
26
+ const getTypeIcon = () => {
27
+ switch(competition_type.type){
28
+ case 'pick':
29
+ return <Icons.SelectorIcon size={20} color={Colors.brand.midnight} />
30
+ default: return <></>
31
+ }
32
+ }
33
+
34
+ return (
35
+ <TouchableOpacity style={{ ...view_styles.section, padding:0 }} onPress={() => onCompetitionSelect(competition)}>
36
+ <View style={{ ...view_styles.section_header, backgroundColor:Colors.shades.shade100 }}>
37
+ <Image
38
+ source={{ uri: competition.image?.url ?? 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
39
+ style={{ height:45, width:45, borderRadius:4}}
40
+ resizeMode='cover'
41
+ />
42
+ <View style={{ flex:1, marginLeft:10, marginRight:10, borderRightWidth:1, borderRightColor:Colors.shades.shade600 }}>
43
+ <Text theme='header_2'>{competition.competition_name}</Text>
44
+ <Text style={{ marginTop:3 }} theme='body'>{competition.competition_description}</Text>
45
+ </View>
46
+ <Text size={20} color={Colors.brand.electric} weight='bold'>{cl}{competition.buy_in}</Text>
47
+ </View>
48
+ <View style={{ ...view_styles.section_body }}>
49
+ <View style={{ ...view_styles.body_row }}>
50
+
51
+ {tickets_available > 0 ?
52
+ <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
53
+ <Text size={18} color={Colors.brand.midnight} weight='bold'>{tickets_available}</Text>
54
+ <Text style={{ marginTop:3 }} theme='body'>TICKETS</Text>
55
+ </View>
56
+ :
57
+ <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
58
+ <Text size={18} color={Colors.utility.error} weight='bold'>FULL</Text>
59
+ </View>
60
+ }
61
+ {competition_type.type == 'pick' ?
62
+ <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
63
+ <Text size={18} color={Colors.brand.midnight} weight='bold'>{competition.max_pick_count}</Text>
64
+ <Text style={{ marginTop:3 }} theme='body'>PICKS</Text>
65
+ </View>
66
+ :
67
+ <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
68
+ <Text size={18} color={Colors.brand.midnight} weight='bold' textAlign='center'>E{competition.initial_balance}</Text>
69
+ <Text style={{ marginTop:3 }} size={14} color={Colors.brand.midnight} textAlign='center'>STARTING BALANCE</Text>
70
+ </View>
71
+ }
72
+ <View style={{ flex:1, justifyContent:'center', alignItems:'center' }}>
73
+ {getTypeIcon()}
74
+ <Text style={{ marginTop:3 }} theme='body'>{competition_type.type_label.toUpperCase()}</Text>
75
+ </View>
76
+ </View>
77
+ </View>
78
+ <View style={{ ...view_styles.section_footer, backgroundColor:company?Colors.incentive.gold_faded:Colors.shades.shade100 }}>
79
+ {company ?
80
+ <Image
81
+ source={{ uri: company.company_image?.url ?? 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
82
+ style={{ height:30, width:30, borderRadius:4}}
83
+ resizeMode='cover'
84
+ />
85
+ :admin ?
86
+ <Image
87
+ source={{ uri: admin.profile_pic && admin.profile_pic != '' ? admin.profile_pic : 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
88
+ style={{ height:30, width:30, borderRadius:4}}
89
+ resizeMode='cover'
90
+ />
91
+ :<></>}
92
+ {competition.prize_override ?
93
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center', marginLeft:10 }}>
94
+ <View style={{ flex:1, marginRight:10}}>
95
+ <Text size={12} weight='bold' color={Colors.brand.midnight}>ADDITIONAL PRIZE</Text>
96
+ <Text style={{ marginTop:3 }} size={10} color={Colors.incentive.gold} weight='bold'>{competition.prize_override}</Text>
97
+ </View>
98
+ {competition.prize_image?.url ?
99
+ <Image
100
+ source={{ uri: competition.prize_image.url }}
101
+ style={{ height:30, width:30, borderRadius:4}}
102
+ resizeMode='cover'
103
+ />
104
+ :
105
+ <Icons.AwardRibbonIcon size={24} color={Colors.incentive.gold} />
106
+ }
107
+ </View>
108
+ :
109
+ <View style={{ flex:1, flexDirection:'row', alignItems:'center' }}>
110
+ <View style={{ flex:1, marginLeft:20, marginRight:20 }}>
111
+ <Text theme='header_2'>CURRENT PAYOUT</Text>
112
+ {is_live ?
113
+ <Text style={{ marginTop:3 }} color={Colors.utility.error} weight='bold' size={12}>IN PROGRESS</Text>
114
+ :
115
+ <Text style={{ marginTop:3 }} theme='body_2'>Join Until {moment(competition.scheduled_datetime).format('ddd hh:mm a')}</Text>
116
+ }
117
+ </View>
118
+ <Text color={Colors.utility.success} size={20} weight='bold'>{cl}{current_payout.toFixed(2)}</Text>
119
+ </View>
120
+ }
121
+ </View>
122
+ </TouchableOpacity>
123
+ )
124
+ }
125
+
126
+ export default CompetitionCard
@@ -0,0 +1,92 @@
1
+ import React from 'react';
2
+ import { Image, View, TouchableOpacity } from 'react-native';
3
+ import { view_styles } from '../../constants/styles';
4
+ import { Icons, Text } from '../../Components';
5
+ import Colors from '../../constants/colors';
6
+ import type { CompanyProps, EventProps, PublicPlayerProps, SquaresCompetitionProps } from '../../types';
7
+ import moment from 'moment-mini';
8
+
9
+ type SquaresCompetitionCardProps = {
10
+ squares_competition:SquaresCompetitionProps,
11
+ admin?:PublicPlayerProps,
12
+ event?:EventProps
13
+ company?:CompanyProps,
14
+ onSelectCompetition:(sq:SquaresCompetitionProps) => void
15
+ }
16
+
17
+ const SquaresCompetitionCard = ({ squares_competition, admin, event, company, onSelectCompetition }:SquaresCompetitionCardProps) => {
18
+ let current_payout = squares_competition.potential_winnings
19
+ if(squares_competition.guaranteed_payout && squares_competition.guaranteed_payout > current_payout){ current_payout = squares_competition.guaranteed_payout }
20
+ const is_live = moment().isAfter(moment(squares_competition.begin_datetime)) ? true : false
21
+ return (
22
+ <TouchableOpacity style={{ ...view_styles.section, padding:0 }} onPress={() => onSelectCompetition(squares_competition)}>
23
+ <View style={{ ...view_styles.section_header, backgroundColor:Colors.shades.shade100 }}>
24
+ <Image
25
+ source={{ uri: squares_competition.image?.url ?? 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
26
+ style={{ height:45, width:45, borderRadius:4}}
27
+ resizeMode='cover'
28
+ />
29
+ <View style={{ flex:1, marginLeft:10, marginRight:10, borderRightWidth:1, borderRightColor:Colors.shades.shade600 }}>
30
+ <Text theme='header_2'>{squares_competition.sq_comp_name}</Text>
31
+ <Text style={{ marginTop:3 }} theme='body'>{squares_competition.sq_comp_description}</Text>
32
+ </View>
33
+ <Text size={20} color={Colors.brand.electric} weight='bold'>${squares_competition.minimum_square_price}</Text>
34
+ </View>
35
+ <View style={{ ...view_styles.section_body, padding:10, paddingTop:20, paddingBottom:20 }}>
36
+ <View style={{ ...view_styles.body_row, padding:0 }}>
37
+ {event ?
38
+ <View style={{ flex:1, flexDirection:'row', marginRight:10, borderRightWidth:1, borderColor:Colors.shades.shade600 }}>
39
+ <View style={{ flexDirection:'row', alignItems:'center' }}>
40
+ <Image
41
+ source={{ uri: event.away?.image?.url }}
42
+ style={{ height:30, width:30 }}
43
+ resizeMode='cover'
44
+ />
45
+ <Text style={{ padding:5 }} theme='header_2'>VS</Text>
46
+ <Image
47
+ source={{ uri: event.home?.image?.url }}
48
+ style={{ height:30, width:30 }}
49
+ resizeMode='cover'
50
+ />
51
+ </View>
52
+ <View style={{ flex:1, marginLeft:10 }}>
53
+ <Text theme='header_2'>{event.event_title}</Text>
54
+ <Text style={{ marginTop:3 }} theme='body'>{event.time_detail == 'scheduled' ? moment(event.scheduled_datetime).format('MMM DD hh:mm a') : event.time_detail}</Text>
55
+ </View>
56
+ </View>
57
+ :<></>}
58
+ <View style={{ justifyContent:'center', alignItems:'center' }}>
59
+ <Icons.SquaresIcon size={24} color={Colors.brand.midnight} />
60
+ <Text style={{ marginTop:3 }} theme='header_2'>AUCTION</Text>
61
+ </View>
62
+ </View>
63
+ </View>
64
+ <View style={{ ...view_styles.section_footer, backgroundColor:company?Colors.incentive.gold_faded:Colors.shades.shade100 }}>
65
+ {company ?
66
+ <Image
67
+ source={{ uri: company.company_image?.url ?? 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
68
+ style={{ height:30, width:30, borderRadius:4}}
69
+ resizeMode='cover'
70
+ />
71
+ :admin ?
72
+ <Image
73
+ source={{ uri: admin.profile_pic && admin.profile_pic != '' ? admin.profile_pic : 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
74
+ style={{ height:30, width:30, borderRadius:4}}
75
+ resizeMode='cover'
76
+ />
77
+ :<></>}
78
+ <View style={{ flex:1, marginLeft:20, marginRight:20 }}>
79
+ <Text theme='header_2'>CURRENT PAYOUT</Text>
80
+ {is_live ?
81
+ <Text style={{ marginTop:3 }} color={Colors.utility.error} weight='bold' size={12}>AUCTION COMPLETE</Text>
82
+ :
83
+ <Text style={{ marginTop:3 }} theme='body_2'>Auction Ends {moment(squares_competition.begin_datetime).fromNow()}</Text>
84
+ }
85
+ </View>
86
+ <Text color={Colors.utility.success} size={20} weight='bold'>${current_payout.toFixed(2)}</Text>
87
+ </View>
88
+ </TouchableOpacity>
89
+ )
90
+ }
91
+
92
+ export default SquaresCompetitionCard