be-components 7.2.2 → 7.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/PartnerPortal/api/index.js +134 -1
- package/lib/commonjs/PartnerPortal/api/index.js.map +1 -1
- package/lib/commonjs/PartnerPortal/components/PromoSelector.js +100 -0
- package/lib/commonjs/PartnerPortal/components/PromoSelector.js.map +1 -0
- package/lib/commonjs/PartnerPortal/components/ReferralCodeManager.js +498 -0
- package/lib/commonjs/PartnerPortal/components/ReferralCodeManager.js.map +1 -0
- package/lib/commonjs/PartnerPortal/index.js +333 -2
- package/lib/commonjs/PartnerPortal/index.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.d.js.map +1 -1
- package/lib/module/PartnerPortal/api/index.js +133 -0
- package/lib/module/PartnerPortal/api/index.js.map +1 -1
- package/lib/module/PartnerPortal/components/PromoSelector.js +93 -0
- package/lib/module/PartnerPortal/components/PromoSelector.js.map +1 -0
- package/lib/module/PartnerPortal/components/ReferralCodeManager.js +490 -0
- package/lib/module/PartnerPortal/components/ReferralCodeManager.js.map +1 -0
- package/lib/module/PartnerPortal/index.js +335 -4
- package/lib/module/PartnerPortal/index.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.d.js.map +1 -1
- package/lib/typescript/lib/commonjs/PartnerPortal/api/index.d.ts +23 -0
- package/lib/typescript/lib/commonjs/PartnerPortal/api/index.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/PartnerPortal/components/PromoSelector.d.ts +10 -0
- package/lib/typescript/lib/commonjs/PartnerPortal/components/PromoSelector.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/PartnerPortal/components/ReferralCodeManager.d.ts +12 -0
- package/lib/typescript/lib/commonjs/PartnerPortal/components/ReferralCodeManager.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/PartnerPortal/index.d.ts +2 -1
- package/lib/typescript/lib/commonjs/PartnerPortal/index.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/index.d.ts +1 -0
- package/lib/typescript/lib/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/PartnerPortal/api/index.d.ts +23 -0
- package/lib/typescript/lib/module/PartnerPortal/api/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/PartnerPortal/components/PromoSelector.d.ts +10 -0
- package/lib/typescript/lib/module/PartnerPortal/components/PromoSelector.d.ts.map +1 -0
- package/lib/typescript/lib/module/PartnerPortal/components/ReferralCodeManager.d.ts +12 -0
- package/lib/typescript/lib/module/PartnerPortal/components/ReferralCodeManager.d.ts.map +1 -0
- package/lib/typescript/lib/module/PartnerPortal/index.d.ts +2 -1
- package/lib/typescript/lib/module/PartnerPortal/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/index.d.ts +2 -1
- package/lib/typescript/lib/module/index.d.ts.map +1 -1
- package/lib/typescript/src/PartnerPortal/api/index.d.ts +19 -1
- package/lib/typescript/src/PartnerPortal/api/index.d.ts.map +1 -1
- package/lib/typescript/src/PartnerPortal/components/PromoSelector.d.ts +12 -0
- package/lib/typescript/src/PartnerPortal/components/PromoSelector.d.ts.map +1 -0
- package/lib/typescript/src/PartnerPortal/components/ReferralCodeManager.d.ts +15 -0
- package/lib/typescript/src/PartnerPortal/components/ReferralCodeManager.d.ts.map +1 -0
- package/lib/typescript/src/PartnerPortal/index.d.ts +3 -2
- package/lib/typescript/src/PartnerPortal/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Authenticator/api/types.d.ts +1 -0
- package/src/PartnerPortal/api/index.ts +119 -1
- package/src/PartnerPortal/components/PromoSelector.tsx +61 -0
- package/src/PartnerPortal/components/ReferralCodeManager.tsx +303 -0
- package/src/PartnerPortal/index.tsx +164 -9
- package/src/index.tsx +2 -0
- package/src/types.d.ts +21 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { Button, Text, TextInput, View } from "../../Components/Themed";
|
|
3
|
+
import type { FocusPositionProps, PlayerReferralProps, PromoProps } from '../../types';
|
|
4
|
+
import { PartnerPortalApi, PartnerPortalHelpers } from '../api';
|
|
5
|
+
import { FlatList, ImageBackground, type ViewStyle } from 'react-native';
|
|
6
|
+
import PromoSelector from './PromoSelector';
|
|
7
|
+
import { useColors } from '../../constants/useColors';
|
|
8
|
+
import { showConfirmAlert } from '../../Components/ConfirmAlert';
|
|
9
|
+
|
|
10
|
+
type ReferralCodeManagerProps = {
|
|
11
|
+
player_referral_id?:string,
|
|
12
|
+
company_id?:string,
|
|
13
|
+
onFocusPosition?:(pos:FocusPositionProps) => void,
|
|
14
|
+
float?:boolean,
|
|
15
|
+
onClose: () => void,
|
|
16
|
+
header_style?:ViewStyle,
|
|
17
|
+
footer_style?:ViewStyle
|
|
18
|
+
}
|
|
19
|
+
const sections = ['header','info','code','promo','inactivate','activate','delete']
|
|
20
|
+
const ReferralCodeManager = ({ float, player_referral_id, company_id, header_style, footer_style, onFocusPosition, onClose }:ReferralCodeManagerProps) => {
|
|
21
|
+
const Colors = useColors();
|
|
22
|
+
const [ action_loading, setActionLoading ] = useState(false);
|
|
23
|
+
const [ size, setSize ] = useState({ height:0, width:0 });
|
|
24
|
+
const [ state, setState ] = useState<{
|
|
25
|
+
checked:boolean,
|
|
26
|
+
available:boolean,
|
|
27
|
+
promos:PromoProps[],
|
|
28
|
+
player_referral?:PlayerReferralProps,
|
|
29
|
+
draft_referral?:PlayerReferralProps
|
|
30
|
+
}>({
|
|
31
|
+
draft_referral: undefined,
|
|
32
|
+
player_referral:undefined,
|
|
33
|
+
promos:[],
|
|
34
|
+
checked:false,
|
|
35
|
+
available:false
|
|
36
|
+
});
|
|
37
|
+
const { draft_referral, promos, player_referral, checked, available } = state;
|
|
38
|
+
const active_promo = promos.find(p => p.promo_id == draft_referral?.promo_id);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
PartnerPortalApi.setEnvironment();
|
|
41
|
+
getData(player_referral_id);
|
|
42
|
+
},[player_referral_id]);
|
|
43
|
+
|
|
44
|
+
const getData = async(id?:string) => {
|
|
45
|
+
const s_promos = await PartnerPortalApi.CompanyApi.getPromos();
|
|
46
|
+
let s_refer:PlayerReferralProps | undefined
|
|
47
|
+
if(id){
|
|
48
|
+
s_refer = await PartnerPortalApi.CompanyApi.getReferralById(id);
|
|
49
|
+
if(!s_refer){ return alert('Unable to get referral. Please try again') }
|
|
50
|
+
} else {
|
|
51
|
+
s_refer = PartnerPortalHelpers.CompanyHelpers.generateNewReferral()
|
|
52
|
+
}
|
|
53
|
+
setState({
|
|
54
|
+
checked:id ? true : false,
|
|
55
|
+
available: id ? true : false,
|
|
56
|
+
promos:s_promos,
|
|
57
|
+
draft_referral: s_refer,
|
|
58
|
+
player_referral: id ? s_refer : undefined
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const isValid = () => {
|
|
63
|
+
let errors:string[] = []
|
|
64
|
+
if(!draft_referral){ return ['Please complete this form'] }
|
|
65
|
+
if(!draft_referral.referral_code){ errors.push('Please enter a valid code') }
|
|
66
|
+
if(!checked){ errors.push('Please check if the referral code is available') }
|
|
67
|
+
if(!available){ errors.push('This code is not available to use') }
|
|
68
|
+
if(!active_promo){ errors.push('Add a promo code') }
|
|
69
|
+
return errors
|
|
70
|
+
}
|
|
71
|
+
const errors = isValid();
|
|
72
|
+
|
|
73
|
+
const checkAvailability = async(code:string) => {
|
|
74
|
+
if(action_loading){ return }
|
|
75
|
+
if(!code){ return alert('Please enter a code') }
|
|
76
|
+
setActionLoading(true);
|
|
77
|
+
const resp = await PartnerPortalApi.CompanyApi.getReferralByCode(code.toLowerCase());
|
|
78
|
+
setState({ ...state, checked: true, available: resp.player_referral ? false : true });
|
|
79
|
+
setActionLoading(false)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const deactivate = async() => {
|
|
83
|
+
if(!player_referral){ return }
|
|
84
|
+
if(action_loading){ return }
|
|
85
|
+
setActionLoading(true);
|
|
86
|
+
const new_code = await PartnerPortalApi.CompanyApi.deactivateCode(player_referral.player_referral_id);
|
|
87
|
+
if(!new_code){ return alert('Unable to process. Please try again later') }
|
|
88
|
+
setState({ ...state, player_referral: new_code, draft_referral:new_code })
|
|
89
|
+
setActionLoading(false);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const activate = async() => {
|
|
93
|
+
if(!player_referral){ return }
|
|
94
|
+
if(action_loading){ return }
|
|
95
|
+
setActionLoading(true);
|
|
96
|
+
const new_code = await PartnerPortalApi.CompanyApi.activateCode(player_referral.player_referral_id);
|
|
97
|
+
if(!new_code){ return alert('Unable to process. Please try again later') }
|
|
98
|
+
setState({ ...state, player_referral: new_code, draft_referral:new_code })
|
|
99
|
+
setActionLoading(false);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const deleteCode = async() => {
|
|
103
|
+
if(!player_referral){ return }
|
|
104
|
+
if(action_loading){ return }
|
|
105
|
+
setActionLoading(true);
|
|
106
|
+
const new_code = await PartnerPortalApi.CompanyApi.deleteCode(player_referral.player_referral_id);
|
|
107
|
+
if(!new_code){ return alert('Unable to process. Please try again later') }
|
|
108
|
+
setState({ ...state, player_referral: new_code, draft_referral:new_code })
|
|
109
|
+
setActionLoading(false);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const handleUpdate = async(dr:PlayerReferralProps) => {
|
|
113
|
+
if(action_loading){ return }
|
|
114
|
+
setActionLoading(true);
|
|
115
|
+
const new_referral = await PartnerPortalApi.CompanyApi.updateCodeOnReferral(dr);
|
|
116
|
+
if(!new_referral){ return alert('Unable to process at this time') }
|
|
117
|
+
setState({
|
|
118
|
+
...state,
|
|
119
|
+
draft_referral: new_referral,
|
|
120
|
+
player_referral: new_referral
|
|
121
|
+
});
|
|
122
|
+
setActionLoading(false);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const handleCreate = async() => {
|
|
126
|
+
if(action_loading){ return }
|
|
127
|
+
if(!draft_referral){ return }
|
|
128
|
+
if(errors.length > 0){ return alert(errors.map(e => e)) }
|
|
129
|
+
setActionLoading(true);
|
|
130
|
+
const new_code = await PartnerPortalApi.CompanyApi.createCode({ ...draft_referral, company_id});
|
|
131
|
+
if(!new_code){ return alert('Unable to process. Please try again later') }
|
|
132
|
+
setState({ ...state, player_referral: new_code, draft_referral:new_code })
|
|
133
|
+
setActionLoading(false);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const renderSections = (data: { item:string, index:number }) => {
|
|
137
|
+
switch(data.item){
|
|
138
|
+
case 'header':
|
|
139
|
+
return (
|
|
140
|
+
<View type='header' style={{ flexDirection:'row', alignItems:'center', padding:10, ...header_style }}>
|
|
141
|
+
<View transparent style={{ flex:1 }}>
|
|
142
|
+
<Text theme='h1'>Manage Referral Code</Text>
|
|
143
|
+
<Text theme='description' style={{ marginTop:3 }}>Update or create your referral code below</Text>
|
|
144
|
+
</View>
|
|
145
|
+
</View>
|
|
146
|
+
)
|
|
147
|
+
case 'info':
|
|
148
|
+
return (
|
|
149
|
+
<ImageBackground
|
|
150
|
+
source={{ uri: 'https://res.cloudinary.com/hoabts6mc/image/upload/w_1000,ar_16:9,c_fill,g_auto,e_sharpen/v1758727070/ChatGPT_Image_Sep_24_2025_10_17_44_AM_w39gdn.png' }}
|
|
151
|
+
style={{ width: size.width, height:225, justifyContent:'flex-end', overflow:'hidden', ...header_style}}>
|
|
152
|
+
<View type='dark_blur' style={{ padding:20 }}>
|
|
153
|
+
<Text theme='h1' size={36}>Referral Code</Text>
|
|
154
|
+
<Text theme='description' size={16} style={{ marginTop:3 }}>Track the users that sign up for BettorEdge with referral codes</Text>
|
|
155
|
+
</View>
|
|
156
|
+
</ImageBackground>
|
|
157
|
+
)
|
|
158
|
+
case 'code':
|
|
159
|
+
if(!draft_referral){ return <></> }
|
|
160
|
+
return (
|
|
161
|
+
<View transparent style={{ padding:20, borderBottomWidth:1, borderColor:Colors.borders.light }}>
|
|
162
|
+
<View transparent style={{ marginBottom:10 }}>
|
|
163
|
+
<Text theme='h1'>Referral Code</Text>
|
|
164
|
+
<Text theme='description' style={{ marginTop:4 }}>Enter the referral code and check its availability</Text>
|
|
165
|
+
</View>
|
|
166
|
+
<View transparent type='row'>
|
|
167
|
+
<TextInput
|
|
168
|
+
value={draft_referral.referral_code}
|
|
169
|
+
onFocusPosition={onFocusPosition}
|
|
170
|
+
editable={player_referral ? false : true}
|
|
171
|
+
style={{ flex:1, marginLeft:5, textAlign:'center', borderColor:available?Colors.text.success:checked?Colors.text.error:Colors.text.warning }}
|
|
172
|
+
onChangeText={(text) => setState({ ...state, checked:false, available: false, draft_referral: { ...draft_referral, referral_code: text } })}
|
|
173
|
+
/>
|
|
174
|
+
{!player_referral ?
|
|
175
|
+
<Button
|
|
176
|
+
title='CHECK'
|
|
177
|
+
type='success'
|
|
178
|
+
loading={action_loading}
|
|
179
|
+
disabled={checked || !draft_referral.referral_code}
|
|
180
|
+
style={{ marginLeft:5, opacity: checked || !draft_referral.referral_code ? 0.5 : 1 }}
|
|
181
|
+
onPress={() => checkAvailability(draft_referral.referral_code)}
|
|
182
|
+
/>
|
|
183
|
+
:<></>}
|
|
184
|
+
</View>
|
|
185
|
+
{player_referral ?
|
|
186
|
+
<Text theme='error' style={{ marginTop:4 }}>To change the referral code. Please inactivate this one and create a new one</Text>
|
|
187
|
+
:checked && available?
|
|
188
|
+
<Text theme='success' style={{ marginTop:4 }}>Great! This code is available</Text>
|
|
189
|
+
:checked && !available ?
|
|
190
|
+
<Text theme='error' style={{ marginTop:4 }}>Sorry! This code is already taken</Text>
|
|
191
|
+
:<></>}
|
|
192
|
+
</View>
|
|
193
|
+
)
|
|
194
|
+
case 'promo':
|
|
195
|
+
if(!draft_referral){ return <></> }
|
|
196
|
+
return (
|
|
197
|
+
<View transparent style={{ padding:20 }}>
|
|
198
|
+
<View transparent style={{ marginBottom:10 }}>
|
|
199
|
+
<Text theme='h1'>Promotion Type</Text>
|
|
200
|
+
<Text theme='description' style={{ marginTop:4 }}>Select the type of promotion for this code</Text>
|
|
201
|
+
</View>
|
|
202
|
+
<PromoSelector
|
|
203
|
+
promos={promos}
|
|
204
|
+
limited_type='promo_code'
|
|
205
|
+
max_value={20}
|
|
206
|
+
active_promo={active_promo}
|
|
207
|
+
onSelectPromo={(promo) => setState({ ...state, draft_referral: { ...draft_referral, promo_id: promo.promo_id } })}
|
|
208
|
+
/>
|
|
209
|
+
</View>
|
|
210
|
+
)
|
|
211
|
+
case 'inactivate':
|
|
212
|
+
if(!player_referral){ return <></> }
|
|
213
|
+
if(player_referral.status != 'pending'){ return <></> }
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<View transparent style={{ padding:20 }}>
|
|
217
|
+
<Button
|
|
218
|
+
title='DEACTIVATE CODE'
|
|
219
|
+
loading={action_loading}
|
|
220
|
+
type='error'
|
|
221
|
+
onPress={() => deactivate()}
|
|
222
|
+
/>
|
|
223
|
+
</View>
|
|
224
|
+
)
|
|
225
|
+
case 'activate':
|
|
226
|
+
if(!player_referral){ return <></> }
|
|
227
|
+
if(player_referral.status != 'inactive'){ return <></> }
|
|
228
|
+
return (
|
|
229
|
+
<View transparent style={{ flexDirection:'row', padding:20 }}>
|
|
230
|
+
<Button
|
|
231
|
+
title='ARCHVE'
|
|
232
|
+
loading={action_loading}
|
|
233
|
+
type='error'
|
|
234
|
+
style={{ flex:1, marginRight:5 }}
|
|
235
|
+
onPress={() => {
|
|
236
|
+
showConfirmAlert('Are You Sure?', 'Once archived the code can no longer be activated or used',
|
|
237
|
+
() => deleteCode(),
|
|
238
|
+
() => console.log('')
|
|
239
|
+
)
|
|
240
|
+
}}
|
|
241
|
+
/>
|
|
242
|
+
<Button
|
|
243
|
+
title='ACTIVATE CODE'
|
|
244
|
+
loading={action_loading}
|
|
245
|
+
type='success'
|
|
246
|
+
style={{ flex:3 }}
|
|
247
|
+
onPress={() => activate()}
|
|
248
|
+
/>
|
|
249
|
+
</View>
|
|
250
|
+
)
|
|
251
|
+
default: return <></>
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const is_changed = JSON.stringify(player_referral) != JSON.stringify(draft_referral) ? true : false
|
|
255
|
+
return (
|
|
256
|
+
<View float={float} style={{ flex:1 }} onLayout={(ev) => {
|
|
257
|
+
const { width, height } = ev.nativeEvent.layout
|
|
258
|
+
setSize({ width, height })
|
|
259
|
+
}}>
|
|
260
|
+
<FlatList
|
|
261
|
+
data={sections}
|
|
262
|
+
key='code_sections'
|
|
263
|
+
keyExtractor={item => item}
|
|
264
|
+
renderItem={renderSections}
|
|
265
|
+
/>
|
|
266
|
+
{player_referral?.status == 'closed' ?
|
|
267
|
+
<View type='blur' style={{ position:'absolute', top:0, left:0, right:0, bottom:0, justifyContent:'center', alignItems:'center' }}>
|
|
268
|
+
<View float style={{ height:200, width:200, justifyContent:'center', alignItems:'center' }}>
|
|
269
|
+
<Text theme='h1' textAlign='center'>CODE HAS BEEN ARCHIVED</Text>
|
|
270
|
+
</View>
|
|
271
|
+
</View>
|
|
272
|
+
:<></>}
|
|
273
|
+
<View type='footer' style={{ flexDirection:'row', alignItems:'center', padding:10, ...footer_style }}>
|
|
274
|
+
<Button
|
|
275
|
+
title='CLOSE'
|
|
276
|
+
type='close'
|
|
277
|
+
style={{ flex:1 }}
|
|
278
|
+
onPress={() => onClose()}
|
|
279
|
+
/>
|
|
280
|
+
{player_referral && draft_referral ?
|
|
281
|
+
<Button
|
|
282
|
+
title='SAVE CODE'
|
|
283
|
+
style={{ flex:3, marginLeft:5, opacity: is_changed && !action_loading ? 1 : 0.5 }}
|
|
284
|
+
loading={action_loading}
|
|
285
|
+
type='success'
|
|
286
|
+
disabled={!is_changed || action_loading}
|
|
287
|
+
onPress={() => handleUpdate(draft_referral)}
|
|
288
|
+
/>
|
|
289
|
+
:
|
|
290
|
+
<Button
|
|
291
|
+
title='CREATE CODE'
|
|
292
|
+
style={{ flex:3, marginLeft:5, opacity: errors.length == 0 && !action_loading ? 1 : 0.5 }}
|
|
293
|
+
loading={action_loading}
|
|
294
|
+
type='success'
|
|
295
|
+
disabled={action_loading}
|
|
296
|
+
onPress={() => handleCreate()}
|
|
297
|
+
/>
|
|
298
|
+
}
|
|
299
|
+
</View>
|
|
300
|
+
</View>
|
|
301
|
+
)
|
|
302
|
+
}
|
|
303
|
+
export default ReferralCodeManager
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { Button, Text, View } from "../Components/Themed"
|
|
3
|
-
import type { BracketCompetitionProps, CompanyEmbedProps, CompanyProps, CompetitionProps, EmbedPropertyProps, EmbedProps, ExternalKeyProps, MyPlayerProps, PollCampaignProps, PublicPlayerProps, SquaresCompetitionProps } from '../types';
|
|
3
|
+
import type { BracketCompetitionProps, CompanyEmbedProps, CompanyPlayerProps, CompanyPlayerStatProps, CompanyProps, CompetitionProps, EmbedPropertyProps, EmbedProps, ExternalKeyProps, MyPlayerProps, PlayerReferralProps, PollCampaignProps, PromoProps, PublicPlayerProps, SquaresCompetitionProps } from '../types';
|
|
4
4
|
import type { CompanyMemberProps } from '../Authenticator/api/types';
|
|
5
5
|
import { PartnerPortalApi } from './api';
|
|
6
|
-
import { FlatList, Image } from 'react-native';
|
|
6
|
+
import { FlatList, Image, ScrollView } from 'react-native';
|
|
7
7
|
import { useColors } from '../constants/useColors';
|
|
8
8
|
import ImageUploader from '../Components/ImageUploader';
|
|
9
9
|
import moment from 'moment-mini';
|
|
10
|
-
import { Icons } from '../Components';
|
|
10
|
+
import { Icons, SearchBox } from '../Components';
|
|
11
|
+
import Pagination from '../Components/Pagination';
|
|
11
12
|
|
|
12
13
|
type PartnerPortalProps = {
|
|
13
14
|
me:MyPlayerProps,
|
|
14
15
|
company_id:string,
|
|
15
16
|
refresh_key?:string,
|
|
16
17
|
onCreateEmbed:() => void,
|
|
18
|
+
onManageReferral: (pr?:PlayerReferralProps) => void,
|
|
17
19
|
onCreateEngagement: (init_engagement?:string) => void,
|
|
18
20
|
onSelectCompanyEmbed: (company_embed:CompanyEmbedProps) => void,
|
|
19
21
|
onSelectCompetition: (competition:CompetitionProps) => void,
|
|
@@ -22,9 +24,9 @@ type PartnerPortalProps = {
|
|
|
22
24
|
onSelectFlashCampaign: (flash_campaign:PollCampaignProps) => void
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
const sections = ['top_row','second_row','third_row']
|
|
27
|
+
const sections = ['top_row','stats','referrals','second_row','third_row']
|
|
26
28
|
|
|
27
|
-
const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSelectBracketCompetition, onCreateEmbed, onSelectCompanyEmbed, onSelectCompetition, onSelectFlashCampaign, onSelectSquaresCompetition }:PartnerPortalProps) => {
|
|
29
|
+
const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSelectBracketCompetition, onManageReferral, onCreateEmbed, onSelectCompanyEmbed, onSelectCompetition, onSelectFlashCampaign, onSelectSquaresCompetition }:PartnerPortalProps) => {
|
|
28
30
|
const Colors = useColors();
|
|
29
31
|
const [ engagement_state, setEngagementState ] = useState<{
|
|
30
32
|
loading: boolean,
|
|
@@ -50,17 +52,30 @@ const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSele
|
|
|
50
52
|
loading: boolean,
|
|
51
53
|
company?:CompanyProps,
|
|
52
54
|
my_member?:CompanyMemberProps,
|
|
55
|
+
company_player_stats:CompanyPlayerStatProps[],
|
|
56
|
+
company_players:CompanyPlayerProps[],
|
|
57
|
+
company_players_offset:number,
|
|
58
|
+
player_referrals:PlayerReferralProps[],
|
|
59
|
+
promos:PromoProps[],
|
|
53
60
|
company_members:CompanyMemberProps[],
|
|
54
61
|
external_keys:ExternalKeyProps[],
|
|
55
62
|
players:PublicPlayerProps[],
|
|
56
63
|
}>({
|
|
57
64
|
loading:false,
|
|
58
65
|
company_members: [],
|
|
66
|
+
company_players_offset: 0,
|
|
59
67
|
external_keys: [],
|
|
68
|
+
player_referrals:[],
|
|
69
|
+
company_player_stats:[],
|
|
70
|
+
company_players:[],
|
|
71
|
+
promos:[],
|
|
60
72
|
players: []
|
|
61
|
-
})
|
|
62
|
-
const
|
|
63
|
-
|
|
73
|
+
});
|
|
74
|
+
const [ referral_search, setReferralSearch ] = useState('');
|
|
75
|
+
const [ player_search, setPlayerSearch ] = useState('');
|
|
76
|
+
const { company, promos, company_players_offset, company_player_stats, company_players, player_referrals, external_keys, players, company_members } = state;
|
|
77
|
+
const filtered_referrals = player_referrals.filter(r => r.referral_code.toLowerCase().includes(referral_search.toLowerCase())).slice(0,5);
|
|
78
|
+
const filtered_players = company_players.sort((a,b) => b.revenue - a.revenue).filter(p => p.username.toLowerCase().includes(player_search.toLowerCase())).slice(0,5);
|
|
64
79
|
useEffect(() => {
|
|
65
80
|
PartnerPortalApi.setEnvironment();
|
|
66
81
|
getStateData();
|
|
@@ -75,16 +90,32 @@ const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSele
|
|
|
75
90
|
const s_playes = await PartnerPortalApi.getPlayersByPlayerIds(player_ids);
|
|
76
91
|
const my_co_member = company_response?.company_members.find(cm => cm.player_id == me.player_id);
|
|
77
92
|
const s_keys = await PartnerPortalApi.CompanyApi.getApiKeys(company_id);
|
|
93
|
+
const s_refer = await PartnerPortalApi.CompanyApi.getReferralCodesByCompanyId(company_id);
|
|
94
|
+
const s_stats = await PartnerPortalApi.CompanyApi.getCompanyPlayerStats(company_id);
|
|
95
|
+
const s_cps = await PartnerPortalApi.CompanyApi.getCompanyPlayers(company_id, 0);
|
|
78
96
|
setState({
|
|
79
97
|
...state,
|
|
80
98
|
loading: false,
|
|
81
99
|
company: company_response?.company,
|
|
82
100
|
external_keys: s_keys,
|
|
101
|
+
promos: s_refer.promos,
|
|
102
|
+
company_players: s_cps,
|
|
103
|
+
player_referrals: s_refer.player_referrals,
|
|
104
|
+
company_player_stats: s_stats,
|
|
83
105
|
players: s_playes,
|
|
106
|
+
company_players_offset: 0,
|
|
84
107
|
my_member:my_co_member,
|
|
85
108
|
company_members: company_response?.company_members ?? []
|
|
86
109
|
});
|
|
87
110
|
}
|
|
111
|
+
const getAdditionalPlayers = async(page:number) => {
|
|
112
|
+
const s_cps = await PartnerPortalApi.CompanyApi.getCompanyPlayers(company_id, page);
|
|
113
|
+
setState({
|
|
114
|
+
...state,
|
|
115
|
+
company_players: s_cps,
|
|
116
|
+
company_players_offset: page
|
|
117
|
+
})
|
|
118
|
+
}
|
|
88
119
|
|
|
89
120
|
const getActiveEngagementData = async() => {
|
|
90
121
|
setEngagementState({ ...engagement_state, loading:true });
|
|
@@ -217,6 +248,57 @@ const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSele
|
|
|
217
248
|
)
|
|
218
249
|
}
|
|
219
250
|
|
|
251
|
+
const renderPlayers = (data:{ item:CompanyPlayerProps, index:number }) => {
|
|
252
|
+
return (
|
|
253
|
+
<View transparent type='row' style={{ padding:10, margin:4, minWidth:300, flexGrow:1, borderBottomWidth:1, borderColor:Colors.borders.light }}>
|
|
254
|
+
<Image
|
|
255
|
+
source={{ uri: data.item.profile_pic }}
|
|
256
|
+
style={{ height:40, width:40, borderRadius:100 }}
|
|
257
|
+
resizeMode='cover'
|
|
258
|
+
/>
|
|
259
|
+
<View float style={{ marginRight:10, marginLeft:10, padding:5, borderRadius:22, backgroundColor:data.item.vouched_status == 'verified' ? Colors.text.success : data.item.vouched_status == 'unverified' ? Colors.text.action : Colors.text.error }}>
|
|
260
|
+
<Text theme='h1' color={Colors.text.white}>{data.item.vouched_status.toUpperCase()}</Text>
|
|
261
|
+
</View>
|
|
262
|
+
<View transparent style={{ flex:1, minWidth:200, marginLeft:10 }}>
|
|
263
|
+
<Text theme='h1'>{data.item.username}</Text>
|
|
264
|
+
<Text theme='description' style={{ marginTop:3 }}>Used Code {data.item.code_used}</Text>
|
|
265
|
+
</View>
|
|
266
|
+
<View float style={{ marginRight:25, padding:5, borderRadius:22, backgroundColor:data.item.verified ? Colors.text.success : Colors.text.error }}>
|
|
267
|
+
<Text theme='h1' color={Colors.text.white}>Email</Text>
|
|
268
|
+
</View>
|
|
269
|
+
<View float style={{ marginRight:25, padding:5, borderRadius:22, backgroundColor:data.item.phone_verified ? Colors.text.success : Colors.text.error }}>
|
|
270
|
+
<Text theme='h1' color={Colors.text.white}>Phone</Text>
|
|
271
|
+
</View>
|
|
272
|
+
<View transparent style={{ alignItems:'flex-end' }}>
|
|
273
|
+
<Text theme='h1' color={Colors.text.success}>${data.item.revenue.toFixed(2)}</Text>
|
|
274
|
+
<Text theme='description' style={{ marginTop:3 }}>Revenue Generated</Text>
|
|
275
|
+
</View>
|
|
276
|
+
</View>
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const renderReferrals = (data:{ item:PlayerReferralProps, index:number }) => {
|
|
281
|
+
const promo = promos.find(e => e.promo_id == data.item.promo_id);
|
|
282
|
+
if(!promo){ return <></> }
|
|
283
|
+
const stats = company_player_stats.filter(ps => ps.referral_code.toLowerCase() == data.item.referral_code.toLowerCase());
|
|
284
|
+
const players_generated = stats.reduce((a,b) => a + b.player_count, 0)
|
|
285
|
+
return (
|
|
286
|
+
<Button
|
|
287
|
+
transparent
|
|
288
|
+
style={{ padding:10, borderRadius:0, flexDirection:'row', alignItems:'center', borderBottomWidth:1, borderColor:Colors.borders.light }}
|
|
289
|
+
onPress={() => onManageReferral(data.item)}>
|
|
290
|
+
<View transparent style={{ flex:1, marginLeft:10 }}>
|
|
291
|
+
<Text theme='h1'>{data.item.referral_code}</Text>
|
|
292
|
+
<Text theme='description' style={{ marginTop:3 }}>{data.item.status == 'pending' ? 'ACTIVE': data.item.status.toUpperCase()} - {promo.description}</Text>
|
|
293
|
+
</View>
|
|
294
|
+
<View transparent style={{ alignItems:'flex-end' }}>
|
|
295
|
+
<Text theme='h1' color={Colors.text.action}>{players_generated}</Text>
|
|
296
|
+
<Text theme='description' style={{ marginTop:3 }}>Players Generated</Text>
|
|
297
|
+
</View>
|
|
298
|
+
</Button>
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
|
|
220
302
|
const renderMembers = (data:{ item:CompanyMemberProps, index:number }) => {
|
|
221
303
|
const player = players.find(p => p.player_id == data.item.player_id);
|
|
222
304
|
if(!player){ return <></> }
|
|
@@ -235,6 +317,7 @@ const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSele
|
|
|
235
317
|
)
|
|
236
318
|
}
|
|
237
319
|
|
|
320
|
+
|
|
238
321
|
const renderSections = (data:{ item:string, index:number }) => {
|
|
239
322
|
switch(data.item){
|
|
240
323
|
case 'top_row':
|
|
@@ -281,7 +364,7 @@ const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSele
|
|
|
281
364
|
:<></>}
|
|
282
365
|
</View>
|
|
283
366
|
<View transparent style={{ flexDirection:'row', flexWrap:'wrap'}}>
|
|
284
|
-
{company_members.map((m,i) => {
|
|
367
|
+
{company_members.filter(cm => !cm.hidden).map((m,i) => {
|
|
285
368
|
return renderMembers({ item: m, index:i })
|
|
286
369
|
})}
|
|
287
370
|
</View>
|
|
@@ -314,6 +397,78 @@ const PartnerPortal = ({ me, company_id, refresh_key, onCreateEngagement, onSele
|
|
|
314
397
|
|
|
315
398
|
</View>
|
|
316
399
|
)
|
|
400
|
+
case 'stats':
|
|
401
|
+
const player_count = company_player_stats.reduce((a,b) => a + b.player_count, 0);
|
|
402
|
+
return (
|
|
403
|
+
<View transparent style={{ flexDirection:'row', flexWrap:'wrap' }}>
|
|
404
|
+
<View float nativeID='player_count' style={{ flexGrow:1, minWidth: 250, margin:10 }}>
|
|
405
|
+
<View transparent style={{ justifyContent:'center', alignItems:'center', padding:10 }}>
|
|
406
|
+
<Text theme='h1' size={40}>{player_count}</Text>
|
|
407
|
+
</View>
|
|
408
|
+
<View type='footer' style={{ flexDirection:'row', alignItems:'center', padding:10, borderBottomRightRadius:8, borderBottomLeftRadius:8 }}>
|
|
409
|
+
<View transparent style={{ flex:1 }}>
|
|
410
|
+
<Text theme='h1' color={Colors.text.success}>Users Generated</Text>
|
|
411
|
+
</View>
|
|
412
|
+
</View>
|
|
413
|
+
</View>
|
|
414
|
+
<View float nativeID='company_referrals' style={{ flexGrow:4, minWidth:300, margin:10 }}>
|
|
415
|
+
<View type='header' style={{ flexDirection:'row', alignItems:'center', padding:10, borderTopRightRadius:8, borderTopLeftRadius:8 }}>
|
|
416
|
+
<View transparent style={{ flex:1 }}>
|
|
417
|
+
<Text theme='h1'>Players Generated</Text>
|
|
418
|
+
<Text theme='description' style={{ marginTop:3 }}>See all players that have joined BettorEdge using your referral code</Text>
|
|
419
|
+
</View>
|
|
420
|
+
</View>
|
|
421
|
+
<View style={{ padding:10 }}>
|
|
422
|
+
<SearchBox hide_search_button onChange={(text) => setPlayerSearch(text)} />
|
|
423
|
+
</View>
|
|
424
|
+
<ScrollView horizontal={true} contentContainerStyle={{ flexGrow: 1 }}>
|
|
425
|
+
<View transparent type='body' style={{ flex:1 }}>
|
|
426
|
+
<FlatList
|
|
427
|
+
data={filtered_players}
|
|
428
|
+
key={'company_players'}
|
|
429
|
+
keyExtractor={item => item.player_id.toString()}
|
|
430
|
+
renderItem={renderPlayers}
|
|
431
|
+
/>
|
|
432
|
+
</View>
|
|
433
|
+
</ScrollView>
|
|
434
|
+
<Pagination offset={company_players_offset} onNext={() => getAdditionalPlayers(company_players_offset + 1)} onPrevious={() => getAdditionalPlayers(company_players_offset - 1)} />
|
|
435
|
+
</View>
|
|
436
|
+
<View />
|
|
437
|
+
</View>
|
|
438
|
+
)
|
|
439
|
+
case 'referrals':
|
|
440
|
+
return (
|
|
441
|
+
<View transparent style={{ flexDirection:'row', flexWrap:'wrap' }}>
|
|
442
|
+
<View float nativeID='company_referrals' style={{ flexGrow:4, flexBasis:4, minWidth:300, margin:10 }}>
|
|
443
|
+
<View type='header' style={{ flexDirection:'row', alignItems:'center', padding:10, borderTopRightRadius:8, borderTopLeftRadius:8 }}>
|
|
444
|
+
<View transparent style={{ flex:1 }}>
|
|
445
|
+
<Text theme='h1'>Referral Codes</Text>
|
|
446
|
+
<Text theme='description' style={{ marginTop:3 }}>Active Referral Codes</Text>
|
|
447
|
+
</View>
|
|
448
|
+
<View transparent style={{ padding:10 }}>
|
|
449
|
+
<Text theme='h1' color={Colors.text.action}>{player_referrals.length}</Text>
|
|
450
|
+
</View>
|
|
451
|
+
<Button
|
|
452
|
+
title='CREATE'
|
|
453
|
+
type='success'
|
|
454
|
+
style={{ padding:10 }}
|
|
455
|
+
onPress={() => onManageReferral()}
|
|
456
|
+
/>
|
|
457
|
+
</View>
|
|
458
|
+
<View style={{ padding:10 }}>
|
|
459
|
+
<SearchBox hide_search_button onChange={(text) => setReferralSearch(text)} />
|
|
460
|
+
</View>
|
|
461
|
+
<View transparent type='body'>
|
|
462
|
+
<FlatList
|
|
463
|
+
data={filtered_referrals.sort((a,b) => moment(a.create_datetime).unix() - moment(b.create_datetime).unix())}
|
|
464
|
+
key={'company_referrals'}
|
|
465
|
+
keyExtractor={item => item.player_referral_id.toString()}
|
|
466
|
+
renderItem={renderReferrals}
|
|
467
|
+
/>
|
|
468
|
+
</View>
|
|
469
|
+
</View>
|
|
470
|
+
</View>
|
|
471
|
+
)
|
|
317
472
|
case 'second_row':
|
|
318
473
|
const active_embeds = company_embeds.length
|
|
319
474
|
return (
|
package/src/index.tsx
CHANGED
|
@@ -66,10 +66,12 @@ import ManageFlashMarket from './FlashMarket/components/ManageFlashMarket';
|
|
|
66
66
|
import PartnerPortal from './PartnerPortal';
|
|
67
67
|
import EmbedManager from './PartnerPortal/components/EmbedManager';
|
|
68
68
|
import CreateEmbed from './PartnerPortal/components/CreateEmbed';
|
|
69
|
+
import ReferralCodeManager from './PartnerPortal/components/ReferralCodeManager';
|
|
69
70
|
export {
|
|
70
71
|
Authenticator,
|
|
71
72
|
Observer,
|
|
72
73
|
CreateEmbed,
|
|
74
|
+
ReferralCodeManager,
|
|
73
75
|
CreateEngagement,
|
|
74
76
|
DiscordConnectionManager,
|
|
75
77
|
BEEventApi,
|
package/src/types.d.ts
CHANGED
|
@@ -436,6 +436,27 @@ export interface CompanyProps {
|
|
|
436
436
|
last_update_datetime: any
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
+
export interface CompanyPlayerStatProps {
|
|
440
|
+
player_count: number,
|
|
441
|
+
referral_code:string,
|
|
442
|
+
vouched_status:string,
|
|
443
|
+
revenue: number
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export interface CompanyPlayerProps {
|
|
447
|
+
player_id:string,
|
|
448
|
+
username:string,
|
|
449
|
+
email:string,
|
|
450
|
+
profile_pic?:string,
|
|
451
|
+
phone:number,
|
|
452
|
+
verified:boolean,
|
|
453
|
+
phone_verified:boolean,
|
|
454
|
+
vouched_status:'verified'|'unverified'|'failed'
|
|
455
|
+
code_used:string,
|
|
456
|
+
revenue:number,
|
|
457
|
+
create_datetime:any
|
|
458
|
+
}
|
|
459
|
+
|
|
439
460
|
export interface PlayerPodcastProps {
|
|
440
461
|
player_podcast_id:string,
|
|
441
462
|
player_id:string,
|