be-components 0.2.7 → 0.2.9

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 (119) hide show
  1. package/lib/commonjs/ApiOverrides/index.js +41 -3
  2. package/lib/commonjs/ApiOverrides/index.js.map +1 -1
  3. package/lib/commonjs/Authenticator/Components/LoginForm.js +1 -1
  4. package/lib/commonjs/BettorSearch/api/index.js +42 -0
  5. package/lib/commonjs/BettorSearch/api/index.js.map +1 -0
  6. package/lib/commonjs/BettorSearch/index.js +129 -0
  7. package/lib/commonjs/BettorSearch/index.js.map +1 -0
  8. package/lib/commonjs/Components/Icons.js +69 -3
  9. package/lib/commonjs/Components/Icons.js.map +1 -1
  10. package/lib/commonjs/ProfileManager/Components/CodeRedeem.js.map +1 -1
  11. package/lib/commonjs/ProfileManager/Components/ProfileWizard.js +56 -0
  12. package/lib/commonjs/ProfileManager/Components/ProfileWizard.js.map +1 -1
  13. package/lib/commonjs/ProfileManager/Components/SettingsManager.js +219 -0
  14. package/lib/commonjs/ProfileManager/Components/SettingsManager.js.map +1 -0
  15. package/lib/commonjs/ProfileManager/api/index.js +13 -0
  16. package/lib/commonjs/ProfileManager/api/index.js.map +1 -1
  17. package/lib/commonjs/ProfileManager/index.js +8 -0
  18. package/lib/commonjs/ProfileManager/index.js.map +1 -1
  19. package/lib/commonjs/SocialComponents/PlayerCard.js +119 -0
  20. package/lib/commonjs/SocialComponents/PlayerCard.js.map +1 -0
  21. package/lib/commonjs/SocialComponents/PlayerFollowButton.js +89 -0
  22. package/lib/commonjs/SocialComponents/PlayerFollowButton.js.map +1 -0
  23. package/lib/commonjs/SocialComponents/PlayerList.js +105 -0
  24. package/lib/commonjs/SocialComponents/PlayerList.js.map +1 -0
  25. package/lib/commonjs/SocialComponents/api/index.js +29 -0
  26. package/lib/commonjs/SocialComponents/api/index.js.map +1 -0
  27. package/lib/commonjs/SocialComponents/index.js +21 -0
  28. package/lib/commonjs/SocialComponents/index.js.map +1 -0
  29. package/lib/commonjs/constants/styles.js +4 -5
  30. package/lib/commonjs/constants/styles.js.map +1 -1
  31. package/lib/commonjs/index.js +10 -0
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/commonjs/types.d.js +2 -0
  34. package/lib/commonjs/types.d.js.map +1 -0
  35. package/lib/module/ApiOverrides/index.js +41 -3
  36. package/lib/module/ApiOverrides/index.js.map +1 -1
  37. package/lib/module/Authenticator/Components/LoginForm.js +1 -1
  38. package/lib/module/BettorSearch/api/index.js +36 -0
  39. package/lib/module/BettorSearch/api/index.js.map +1 -0
  40. package/lib/module/BettorSearch/index.js +120 -0
  41. package/lib/module/BettorSearch/index.js.map +1 -0
  42. package/lib/module/Components/Icons.js +69 -3
  43. package/lib/module/Components/Icons.js.map +1 -1
  44. package/lib/module/ProfileManager/Components/CodeRedeem.js.map +1 -1
  45. package/lib/module/ProfileManager/Components/ProfileWizard.js +56 -0
  46. package/lib/module/ProfileManager/Components/ProfileWizard.js.map +1 -1
  47. package/lib/module/ProfileManager/Components/SettingsManager.js +210 -0
  48. package/lib/module/ProfileManager/Components/SettingsManager.js.map +1 -0
  49. package/lib/module/ProfileManager/api/index.js +13 -0
  50. package/lib/module/ProfileManager/api/index.js.map +1 -1
  51. package/lib/module/ProfileManager/index.js +8 -0
  52. package/lib/module/ProfileManager/index.js.map +1 -1
  53. package/lib/module/SocialComponents/PlayerCard.js +112 -0
  54. package/lib/module/SocialComponents/PlayerCard.js.map +1 -0
  55. package/lib/module/SocialComponents/PlayerFollowButton.js +82 -0
  56. package/lib/module/SocialComponents/PlayerFollowButton.js.map +1 -0
  57. package/lib/module/SocialComponents/PlayerList.js +96 -0
  58. package/lib/module/SocialComponents/PlayerList.js.map +1 -0
  59. package/lib/module/SocialComponents/api/index.js +23 -0
  60. package/lib/module/SocialComponents/api/index.js.map +1 -0
  61. package/lib/module/SocialComponents/index.js +4 -0
  62. package/lib/module/SocialComponents/index.js.map +1 -0
  63. package/lib/module/constants/styles.js +4 -5
  64. package/lib/module/constants/styles.js.map +1 -1
  65. package/lib/module/index.js +3 -1
  66. package/lib/module/index.js.map +1 -1
  67. package/lib/module/types.d.js +2 -0
  68. package/lib/module/types.d.js.map +1 -0
  69. package/lib/typescript/src/ApiOverrides/index.d.ts +8 -0
  70. package/lib/typescript/src/ApiOverrides/index.d.ts.map +1 -1
  71. package/lib/typescript/src/BettorSearch/api/index.d.ts +9 -0
  72. package/lib/typescript/src/BettorSearch/api/index.d.ts.map +1 -0
  73. package/lib/typescript/src/BettorSearch/index.d.ts +20 -0
  74. package/lib/typescript/src/BettorSearch/index.d.ts.map +1 -0
  75. package/lib/typescript/src/Components/Icons.d.ts +3 -1
  76. package/lib/typescript/src/Components/Icons.d.ts.map +1 -1
  77. package/lib/typescript/src/ProfileManager/Components/CodeRedeem.d.ts.map +1 -1
  78. package/lib/typescript/src/ProfileManager/Components/ProfileWizard.d.ts +7 -3
  79. package/lib/typescript/src/ProfileManager/Components/ProfileWizard.d.ts.map +1 -1
  80. package/lib/typescript/src/ProfileManager/Components/SettingsManager.d.ts +14 -0
  81. package/lib/typescript/src/ProfileManager/Components/SettingsManager.d.ts.map +1 -0
  82. package/lib/typescript/src/ProfileManager/api/index.d.ts +7 -1
  83. package/lib/typescript/src/ProfileManager/api/index.d.ts.map +1 -1
  84. package/lib/typescript/src/ProfileManager/index.d.ts +1 -1
  85. package/lib/typescript/src/ProfileManager/index.d.ts.map +1 -1
  86. package/lib/typescript/src/SocialComponents/PlayerCard.d.ts +18 -0
  87. package/lib/typescript/src/SocialComponents/PlayerCard.d.ts.map +1 -0
  88. package/lib/typescript/src/SocialComponents/PlayerFollowButton.d.ts +13 -0
  89. package/lib/typescript/src/SocialComponents/PlayerFollowButton.d.ts.map +1 -0
  90. package/lib/typescript/src/SocialComponents/PlayerList.d.ts +14 -0
  91. package/lib/typescript/src/SocialComponents/PlayerList.d.ts.map +1 -0
  92. package/lib/typescript/src/SocialComponents/api/index.d.ts +8 -0
  93. package/lib/typescript/src/SocialComponents/api/index.d.ts.map +1 -0
  94. package/lib/typescript/src/SocialComponents/index.d.ts +4 -0
  95. package/lib/typescript/src/SocialComponents/index.d.ts.map +1 -0
  96. package/lib/typescript/src/constants/styles.d.ts +1 -2
  97. package/lib/typescript/src/constants/styles.d.ts.map +1 -1
  98. package/lib/typescript/src/index.d.ts +3 -1
  99. package/lib/typescript/src/index.d.ts.map +1 -1
  100. package/package.json +1 -1
  101. package/src/ApiOverrides/index.ts +28 -3
  102. package/src/Authenticator/Components/LoginForm.tsx +1 -1
  103. package/src/BettorSearch/api/index.ts +30 -0
  104. package/src/BettorSearch/index.tsx +106 -0
  105. package/src/Components/Icons.tsx +35 -2
  106. package/src/ProfileManager/Components/CodeRedeem.tsx +2 -1
  107. package/src/ProfileManager/Components/ProfileWizard.tsx +63 -5
  108. package/src/ProfileManager/Components/SettingsManager.tsx +152 -0
  109. package/src/ProfileManager/api/index.ts +13 -1
  110. package/src/ProfileManager/api/types.d.ts +15 -25
  111. package/src/ProfileManager/index.tsx +13 -3
  112. package/src/SocialComponents/PlayerCard.tsx +86 -0
  113. package/src/SocialComponents/PlayerFollowButton.tsx +80 -0
  114. package/src/SocialComponents/PlayerList.tsx +81 -0
  115. package/src/SocialComponents/api/index.ts +23 -0
  116. package/src/SocialComponents/index.tsx +8 -0
  117. package/src/constants/styles.ts +1 -8
  118. package/src/index.tsx +4 -0
  119. package/src/types.d.ts +354 -0
@@ -0,0 +1,152 @@
1
+ import React, { useState } from 'react';
2
+ import { ScrollView, View, FlatList, StyleSheet, TouchableOpacity } from 'react-native';
3
+ import { Button, Icons, Text, TextInput } from '../../Components';
4
+ import Colors from '../../constants/colors';
5
+ import type { SettingProps } from '../api/types';
6
+ import type { PlayerSettingProps } from '../../types';
7
+ import { ProfileApi } from '../api';
8
+
9
+ type SettingsManagerProps = {
10
+ title: string,
11
+ description: string,
12
+ settings:SettingProps[],
13
+ icon:any,
14
+ player_settings: PlayerSettingProps[],
15
+ onUpdatePlayerSetting:(ps:PlayerSettingProps) => void
16
+ }
17
+
18
+ const SettingsManager = ({ title, description, icon, settings, player_settings, onUpdatePlayerSetting }:SettingsManagerProps) => {
19
+ const [ draft_setting, setDraftSetting ] = useState<PlayerSettingProps>()
20
+
21
+ const handleUpdateSetting = async(setting:SettingProps, option:string, status:'active'|'inactive', player_setting?:PlayerSettingProps) => {
22
+ if(player_setting){ player_setting.status = status }
23
+ else {
24
+ player_setting = {
25
+ player_setting_id:'',
26
+ player_id: '',
27
+ setting_id: setting.setting_id,
28
+ selected_option: option,
29
+ create_datetime: '', last_update_datetime: '',
30
+ status
31
+ }
32
+ }
33
+ player_setting = await ProfileApi.updatePlayerSetting(player_setting)
34
+ setDraftSetting(undefined)
35
+ onUpdatePlayerSetting(player_setting)
36
+ }
37
+
38
+ const renderPreferences = (data: { item:SettingProps, index:number }) => {
39
+ const my_settings = player_settings.filter(ps => ps.setting_id == data.item.setting_id);
40
+ const editing = data.item.setting_id == draft_setting?.setting_id ? true : false;
41
+ let shown_setting = editing ? draft_setting : my_settings[0]
42
+ const is_changed = shown_setting?.selected_option != my_settings[0]?.selected_option ? true : false
43
+
44
+ return (
45
+ <View style={local_styles.settings_container}>
46
+ <View style={{ padding:5, borderBottomWidth:1, borderColor:Colors.shades.shade600 }}>
47
+ <Text size={14} color={Colors.brand.midnight} weight='bold'>{data.item.setting_label}</Text>
48
+ <Text style={{ marginTop:5 }} size={12} color={Colors.brand.midnight}>{data.item.setting_description}</Text>
49
+ </View>
50
+ <View>
51
+ {data.item.option_type == 'number_input' ?
52
+ <View>
53
+ <View style={{flexDirection:'row', alignItems:'center', padding:10}}>
54
+ <Text style={{ flex:1 }} size={14} color={Colors.brand.midnight} weight='bold'>My Setting</Text>
55
+ <TextInput
56
+ style={{ padding:10 }}
57
+ editable={editing}
58
+ value={shown_setting?.selected_option}
59
+ onChangeText={(text) => {
60
+ if(!draft_setting){ return }
61
+ setDraftSetting({ ...draft_setting, selected_option: text })
62
+ }}
63
+ />
64
+ {!editing ?
65
+ <Button
66
+ title='EDIT'
67
+ style={{ marginLeft:5 }}
68
+ title_color={Colors.shades.white}
69
+ backgroundColor={Colors.brand.electric}
70
+ onPress={() => setDraftSetting(my_settings[0])}
71
+ />
72
+ :
73
+ <Button
74
+ title='X'
75
+ style={{ marginLeft:5 }}
76
+ title_color={Colors.utility.error}
77
+ borderColor={Colors.utility.error}
78
+ borderWidth={1}
79
+ onPress={() => setDraftSetting(undefined)}
80
+ />
81
+ }
82
+ </View>
83
+ {is_changed ?
84
+ <Button
85
+ title='SAVE'
86
+ backgroundColor={Colors.utility.success}
87
+ title_color={Colors.shades.white}
88
+ onPress={() => {
89
+ if(!shown_setting){ return }
90
+ handleUpdateSetting(data.item, shown_setting.selected_option, 'active', shown_setting)}
91
+ }
92
+ />
93
+ :<></>}
94
+ </View>
95
+ :data.item.option_type == 'select' ?
96
+ <View nativeID='setting_options' style={{ padding:15, flexDirection:'row', justifyContent:'space-between' }}>
97
+ {data.item.setting_options.map(so => {
98
+ const my_setting = my_settings.find(ms => ms.selected_option == so)
99
+ return (
100
+ <TouchableOpacity style={{ flexDirection:'row', alignItems:'center' }}
101
+ onPress={() => handleUpdateSetting(data.item, so, my_setting?.status == 'active' ? 'inactive' : 'active', my_setting)}>
102
+ <View style={{ height:20, width:20, justifyContent:'center', alignItems:'center', borderWidth:1, borderRadius:100, borderColor:Colors.brand.electric, backgroundColor:my_setting?.status == 'active' ? Colors.brand.electric : 'transparent' }}>
103
+ {my_setting?.status == 'active' ?
104
+ <Icons.CheckIcon color={Colors.shades.white} size={10} />
105
+ :<></>}
106
+ </View>
107
+ <Text style={{ marginLeft:10 }} size={12} color={Colors.brand.midnight} weight='semibold'>{so.toUpperCase()}</Text>
108
+ </TouchableOpacity>
109
+ )
110
+ })}
111
+ </View>
112
+ :<></>}
113
+ </View>
114
+ </View>
115
+ )
116
+ }
117
+
118
+ return (
119
+ <View style={{ flex:1 }}>
120
+ <ScrollView style={{ flex:1 }}>
121
+ <View nativeID='preference_settings' style={{ padding:20 }}>
122
+ <View nativeID='header' style={{ flexDirection:'row', alignItems:'center' }}>
123
+ <View style={{ padding:10, backgroundColor:Colors.brand.electric, borderRadius:8 }}>
124
+ {icon}
125
+ </View>
126
+ <View style={{ flex:1, marginLeft:5 }}>
127
+ <Text size={16} color={Colors.brand.midnight} weight='bold'>{title}</Text>
128
+ <Text style={{ marginTop:3 }} size={12} color={Colors.brand.midnight} weight='regular'>{description}</Text>
129
+ </View>
130
+ </View>
131
+ <View nativeID='notification_options' style={{ marginTop:20 }}>
132
+ <FlatList
133
+ data={settings}
134
+ renderItem={renderPreferences}
135
+ keyExtractor={(item) => item.setting_id.toString()}
136
+ />
137
+ </View>
138
+ </View>
139
+ </ScrollView>
140
+ </View>
141
+ )
142
+ }
143
+
144
+ const local_styles = StyleSheet.create({
145
+ settings_container: {
146
+ margin:3,
147
+ backgroundColor:Colors.shades.shade100,
148
+ padding:10
149
+ }
150
+ })
151
+
152
+ export default SettingsManager
@@ -1,6 +1,7 @@
1
1
  import axios from 'axios';
2
- import type { CodeRequestProps, MyPlayerProps, PasswordStateProps, PlayerBalanceProps, PlayerReferralProps, PromoProps, PublicPlayerProps, RewardOptionProps } from './types';
2
+ import type { CodeRequestProps, MyPlayerProps, PasswordStateProps, PlayerBalanceProps, PlayerReferralProps, PromoProps, RewardOptionProps, SettingProps } from './types';
3
3
  import { APIOverrides } from '../../ApiOverrides';
4
+ import type { PlayerSettingProps, PublicPlayerProps } from '../../types';
4
5
 
5
6
  let AUTH_SVC_API = '';
6
7
  let VOUCH_ID = '';
@@ -56,6 +57,7 @@ const ProfileApi = {
56
57
  },
57
58
  getMyDetails : async():Promise<MyPlayerProps> => {
58
59
  const resp = await axios.get(`${AUTH_SVC_API}/v1/players/player/me`)
60
+ console.log(resp.data)
59
61
  return resp.data.player
60
62
  },
61
63
  getMyBalance: async():Promise<PlayerBalanceProps> => {
@@ -66,6 +68,16 @@ const ProfileApi = {
66
68
  const resp = await axios.get(`${AUTH_SVC_API}/v1/promos/request/me`)
67
69
  return resp.data
68
70
  },
71
+ getMySettings: async():Promise<{ settings:SettingProps[], player_settings:PlayerSettingProps[] }> => {
72
+ const resp = await axios.get(`${AUTH_SVC_API}/v1/settings/me`)
73
+ console.log(resp.data)
74
+ return resp.data
75
+ },
76
+ updatePlayerSetting: async(player_setting:PlayerSettingProps):Promise<PlayerSettingProps> => {
77
+ const resp = await axios.post(`${AUTH_SVC_API}/v1/settings/player/update`, { player_setting })
78
+ console.log(resp.data)
79
+ return resp.data.player_setting
80
+ },
69
81
  redeemCode: async(code_request_id:string):Promise<{ code_request?:CodeRequestProps, promo?:PromoProps, player_referral?:PlayerReferralProps, referrer?:PublicPlayerProps, reward_option?:RewardOptionProps }> => {
70
82
  const resp = await axios.post(`${AUTH_SVC_API}/v1/promos/request/redeem`, { code_request_id })
71
83
  return resp.data
@@ -4,31 +4,6 @@ declare global {
4
4
  }
5
5
  }
6
6
 
7
- export interface PublicPlayerProps {
8
- player_id:string,
9
- username:string,
10
- email:string,
11
- dob?:string,
12
- first_name:string,
13
- phone:number,
14
- premium_tier_id?:string,
15
- zip?:string;
16
- last_name:string;
17
- type:string,
18
- role:'admin'|'player'|'company'|'support'|'guest',
19
- create_datetime:any,
20
- verified:boolean,
21
- home_location:string,
22
- anonymous?:boolean,
23
- auto_generated?:boolean,
24
- no_password?:boolean,
25
- show_name:string,
26
- profile_pic?:string,
27
- vouched_id?:string,
28
- phone_verified:boolean,
29
- bio?:string,
30
- vouched_status:'unverified' | 'failed' | 'verified',
31
- }
32
7
 
33
8
  export interface ProfileLevelProps {
34
9
  num:number, label:string, description:string, identifier:string, pct_complete:number, profile_steps:ProfileStepProps[]
@@ -46,6 +21,21 @@ export interface PasswordStateProps {
46
21
  error?:string
47
22
  }
48
23
 
24
+ export interface SettingProps {
25
+ setting_id:string,
26
+ setting: string,
27
+ setting_type: string,
28
+ setting_label: string,
29
+ setting_description: string,
30
+ setting_options: string[],
31
+ option_type: 'select'|'number_input'|'string_input',
32
+ status:string,
33
+ default_option: string,
34
+ multi_select:boolean,
35
+ create_datetime: any,
36
+ last_update_datetime: any
37
+ }
38
+
49
39
  export interface CodeRequestProps {
50
40
  code_request_id:string,
51
41
  player_id:string,
@@ -4,7 +4,8 @@ import Colors from '../constants/colors';
4
4
  import { Text } from '../Components';
5
5
  import ProfileWizard from './Components/ProfileWizard';
6
6
  import { ProfileApi } from './api';
7
- import type { MyPlayerProps, PlayerBalanceProps } from './api/types';
7
+ import type { MyPlayerProps, PlayerBalanceProps, SettingProps } from './api/types';
8
+ import type { PlayerSettingProps } from '../types';
8
9
 
9
10
  type ProfileOverviewProps = {
10
11
  width:number,
@@ -16,7 +17,7 @@ type ProfileOverviewProps = {
16
17
  onClose:() => void,
17
18
  onLogout:() => void,
18
19
  onPlayerUpdate?:(p:MyPlayerProps, attribute?:string) => void,
19
- profile_attribute?:'basic'|'phone'|'email'|'dob'|'password'|'vouch',
20
+ profile_attribute?:'basic'|'phone'|'email'|'dob'|'password'|'vouch'|'notification'|'preferences',
20
21
  walkthrough?:boolean
21
22
  }
22
23
 
@@ -24,7 +25,9 @@ const ProfileManager = ({ profile_attribute, onPlayerUpdate, show_welcome, hidde
24
25
  const [ loading, setLoading ] = useState(false);
25
26
  const [ draft_player, setDraftPlayer ] = useState<MyPlayerProps>();
26
27
  const [ player_balance, setPlayerBalance ] = useState<PlayerBalanceProps>();
27
-
28
+ const [ settings, setSettings ] = useState<SettingProps[]>([]);
29
+ const [ player_settings, setPlayerSettings ] = useState<PlayerSettingProps[]>([]);
30
+
28
31
  useEffect(() => {
29
32
  getPlayerFromServer()
30
33
  },[])
@@ -36,6 +39,9 @@ const ProfileManager = ({ profile_attribute, onPlayerUpdate, show_welcome, hidde
36
39
  try {
37
40
  const player = await ProfileApi.getMyDetails();
38
41
  const pb = await ProfileApi.getMyBalance();
42
+ const settings_response = await ProfileApi.getMySettings();
43
+ setSettings(settings_response.settings);
44
+ setPlayerSettings(settings_response.player_settings);
39
45
  setPlayerBalance(pb);
40
46
  setDraftPlayer(player);
41
47
  } catch (e) {
@@ -45,6 +51,7 @@ const ProfileManager = ({ profile_attribute, onPlayerUpdate, show_welcome, hidde
45
51
  setLoading(false);
46
52
  }
47
53
 
54
+
48
55
  const handleLogout = () => {
49
56
  setDraftPlayer(undefined);
50
57
  setPlayerBalance(undefined);
@@ -85,6 +92,8 @@ const ProfileManager = ({ profile_attribute, onPlayerUpdate, show_welcome, hidde
85
92
  <View style={{ marginTop:10, flex:1 }}>
86
93
  <ProfileWizard
87
94
  player={draft_player}
95
+ player_settings={player_settings}
96
+ settings={settings}
88
97
  show_welcome={show_welcome}
89
98
  width={width}
90
99
  hidden_groups={hidden_groups}
@@ -95,6 +104,7 @@ const ProfileManager = ({ profile_attribute, onPlayerUpdate, show_welcome, hidde
95
104
  onLogout={() => handleLogout()}
96
105
  profile_attribute={profile_attribute}
97
106
  onSelectLevel={(level) => console.log(level)}
107
+ onUpdatePlayerSetting={(new_ps) => setPlayerSettings(player_settings.filter(ps => ps.player_setting_id != new_ps.player_setting_id).concat(new_ps))}
98
108
  onPlayerUpdate={(player, attribute) => {
99
109
  setDraftPlayer(player)
100
110
  if(onPlayerUpdate){ onPlayerUpdate(player, attribute) }
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import type { PlayerFollowerProps, PublicPlayerProps } from "../types";
3
+ import { Image, View, TouchableOpacity, StyleSheet } from 'react-native';
4
+ import Colors from '../constants/colors';
5
+ import { Text } from '../Components';
6
+ import { view_styles } from '../constants/styles';
7
+ import PlayerFollowButton from './PlayerFollowButton';
8
+
9
+ type PlayerCardProps = {
10
+ player:PublicPlayerProps,
11
+ width:number,
12
+ follow_loading?:boolean,
13
+ alignment?:'vertical'|'horizontal',
14
+ player_follower?:PlayerFollowerProps,
15
+ player_following?:PlayerFollowerProps,
16
+ show_follow?:boolean,
17
+ style?:any,
18
+ float?:boolean,
19
+ onSelectPlayer:(p:PublicPlayerProps) => void,
20
+ onFollowingUpdate:(pf:PlayerFollowerProps) => void
21
+ }
22
+
23
+ const PlayerCard = ({ player, width, follow_loading, alignment, style, float, show_follow, player_follower, player_following, onSelectPlayer, onFollowingUpdate }:PlayerCardProps) => {
24
+
25
+ let player_style = alignment == 'vertical' ? local_styles.player_vertical : local_styles.player_horizontal;
26
+ let container_style = { ...local_styles.container }
27
+ if(float){ container_style = { ...container_style, ...view_styles.float } }
28
+ return (
29
+ <View style={{ ...container_style, ...style, width }}>
30
+ <TouchableOpacity style={player_style} onPress={() => onSelectPlayer(player)}>
31
+ {alignment == 'vertical' ?
32
+ <View>
33
+ <Image
34
+ source={{ uri: player.profile_pic }}
35
+ style={{ height:width * 0.5, width:width, borderTopRightRadius:8, borderTopLeftRadius:8 }}
36
+ resizeMode='cover'
37
+ />
38
+ </View>
39
+ :
40
+ <View style={{ }}>
41
+ <Image
42
+ source={{ uri: player.profile_pic }}
43
+ style={{ height:55, width:55, borderTopLeftRadius:8, borderBottomLeftRadius:8}}
44
+ resizeMode='cover'
45
+ />
46
+ </View>
47
+ }
48
+ <View style={{ flex:1, padding:10 }}>
49
+ <Text size={14} color={Colors.brand.midnight} weight='bold' textAlign={alignment == 'vertical' ? 'center' : 'left'}>{player.first_name} {player.last_name}</Text>
50
+ <Text style={{ marginTop:4 }} size={14} color={Colors.brand.midnight} weight='regular' textAlign={alignment == 'vertical' ? 'center' : 'left'}>@{player.username}</Text>
51
+ </View>
52
+ {show_follow ?
53
+ <View style={{ padding:10, paddingTop:alignment=='vertical'?0:10 }}>
54
+ <PlayerFollowButton
55
+ loading={follow_loading}
56
+ player_id={player.player_id}
57
+ follower={player_follower}
58
+ following={player_following}
59
+ onFollowingUpdate={onFollowingUpdate}
60
+ />
61
+ </View>
62
+ :<></>}
63
+ </TouchableOpacity>
64
+ </View>
65
+ )
66
+ }
67
+
68
+ const local_styles = StyleSheet.create({
69
+ container: {
70
+ flex:1,
71
+ backgroundColor:Colors.shades.white,
72
+ borderRadius:8
73
+ },
74
+ player_vertical: {
75
+ flex:1,
76
+ flexDirection:'column',
77
+ //alignItems:'center'
78
+ },
79
+ player_horizontal: {
80
+ flex:1,
81
+ flexDirection: 'row',
82
+ alignItems:'center'
83
+ }
84
+ })
85
+
86
+ export default PlayerCard
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { Button } from "../Components"
3
+ import Colors from "../constants/colors"
4
+ import type { PlayerFollowerProps } from "../types"
5
+ import { SocialComponentApi } from './api';
6
+
7
+ type PlayerFollowButtonProps = {
8
+ player_id:string,
9
+ style?:any,
10
+ loading?:boolean,
11
+ follower?:PlayerFollowerProps,
12
+ following?:PlayerFollowerProps
13
+ onFollowingUpdate:(pf:PlayerFollowerProps) => void
14
+ }
15
+
16
+ const PlayerFollowButton = ({ player_id, loading, style, follower, following, onFollowingUpdate }:PlayerFollowButtonProps) => {
17
+
18
+
19
+ const handleAction = async(status:'following'|'not_following', player_follower?:PlayerFollowerProps) => {
20
+ if(!player_follower){
21
+ player_follower = {
22
+ player_follower_id:'',
23
+ player_id: '',
24
+ following_id: player_id,
25
+ status,
26
+ create_datetime:'', last_update_datetime:''
27
+ }
28
+ }
29
+ player_follower.status = status
30
+ const new_following = await SocialComponentApi.savePlayerFollower(player_follower)
31
+ onFollowingUpdate(new_following)
32
+ }
33
+
34
+
35
+ const getButtonType = () => {
36
+ let button_type = { type: 'follow', label: 'FOLLOW' };
37
+ if(follower?.status == 'following'){ button_type = { type: 'follow', label: 'FOLLOW BACK' } }
38
+ if(following?.status == 'following'){ button_type = { type: 'unfollow', label: 'UNFOLLOW' } }
39
+
40
+ switch(button_type.type){
41
+ case 'follow':
42
+ return (
43
+ <Button
44
+ style={{ ...style }}
45
+ loading={loading}
46
+ padding={10}
47
+ title_size={12}
48
+ disabled={loading}
49
+ title={button_type.label}
50
+ title_color={Colors.shades.white}
51
+ backgroundColor={Colors.brand.electric}
52
+ onPress={() => handleAction('following', following)}
53
+ />
54
+ )
55
+ case 'unfollow':
56
+ return (
57
+ <Button
58
+ style={{ ...style }}
59
+ title={button_type.label}
60
+ title_size={12}
61
+ padding={10}
62
+ loading={loading}
63
+ disabled={loading}
64
+ title_color={Colors.brand.electric}
65
+ borderWidth={1}
66
+ borderColor={Colors.brand.electric}
67
+ onPress={() => handleAction('not_following', following)}
68
+ />
69
+ )
70
+ default: return <></>
71
+ }
72
+
73
+ }
74
+
75
+ return getButtonType()
76
+
77
+
78
+ }
79
+
80
+ export default PlayerFollowButton
@@ -0,0 +1,81 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { View, StyleSheet } from "react-native";
3
+ import { SocialComponentApi } from './api';
4
+ import PlayerCard from './PlayerCard';
5
+ import type { PlayerFollowerProps, PublicPlayerProps } from '../types';
6
+
7
+ type PlayerListProps = {
8
+ players:PublicPlayerProps[],
9
+ style?: any,
10
+ onPlayerSelect:(p:PublicPlayerProps) => void,
11
+ options: {
12
+ follow_status?:boolean,
13
+ direction: 'horizontal' | 'vertical',
14
+ }
15
+ }
16
+
17
+ const PlayerList = ({ players, style, options, onPlayerSelect }:PlayerListProps) => {
18
+ const [ size, setSize ] = useState({ width: 0, height:0 });
19
+ const [ follow_status_loading, setFollowStatusLoading ] = useState(false);
20
+ const [ player_followers, setPlayerFollowers ] = useState<PlayerFollowerProps[]>([]);
21
+
22
+ const { follow_status, direction } = options;
23
+
24
+ useEffect(() => { SocialComponentApi.setEnvironment() },[])
25
+
26
+ useEffect(() => {
27
+ if(players.length == 0){ return }
28
+ getListData();
29
+ },[players.length])
30
+
31
+ const getListData = async() => {
32
+ if(follow_status){
33
+ setFollowStatusLoading(true);
34
+ const player_followers = await SocialComponentApi.getBulkPlayerfollowers(players.map(p => p.player_id))
35
+ setPlayerFollowers(player_followers)
36
+ setFollowStatusLoading(false);
37
+ }
38
+ }
39
+ const new_style = direction == 'vertical' ? local_styles.container_vertical : local_styles.containter_horizontal
40
+ const alignment = direction == 'vertical' ? 'horizontal' : 'vertical'
41
+ const player_width = direction == 'vertical' ? size.width - 20: (size.width - 40) / 2
42
+ return (
43
+ <View style={{ ...new_style, ...style }} onLayout={(ev) => {
44
+ const { width, height } = ev.nativeEvent.layout
45
+ setSize({ width, height })
46
+ }}>
47
+ {players.map(p => {
48
+ let following = player_followers.find(pf => pf.following_id == p.player_id);
49
+ let follower = player_followers.find(pf => pf.player_id == p.player_id);
50
+ return (
51
+ <View key={p.player_id.toString()} style={{ width: player_width, margin:8 }}>
52
+ <PlayerCard
53
+ width={player_width}
54
+ style={{ borderRadius:8 }}
55
+ player={p}
56
+ float={true}
57
+ alignment={alignment}
58
+ player_following={following}
59
+ player_follower={follower}
60
+ show_follow={options.follow_status}
61
+ follow_loading={follow_status_loading}
62
+ onSelectPlayer={onPlayerSelect}
63
+ onFollowingUpdate={(new_pf) => {
64
+ setPlayerFollowers(player_followers.filter(pf => pf.player_follower_id != new_pf.player_follower_id).concat(new_pf))
65
+ }}
66
+ />
67
+ </View>
68
+
69
+ )
70
+ })}
71
+ </View>
72
+ )
73
+ }
74
+
75
+ const local_styles = StyleSheet.create({
76
+ container_vertical: { flexDirection:'column', alignItems:'center' },
77
+ containter_horizontal: { flexDirection:'row', flexWrap: 'wrap', justifyContent:'center' }
78
+ })
79
+
80
+
81
+ export default PlayerList
@@ -0,0 +1,23 @@
1
+ import axios from "axios";
2
+ import { APIOverrides } from "../../ApiOverrides";
3
+ import type { PlayerFollowerProps } from "../../types";
4
+
5
+ let SOCIAL_SVC_API = '';
6
+
7
+ export { SocialComponentApi }
8
+
9
+ const SocialComponentApi = {
10
+ setEnvironment: () => {
11
+ const endpoints = APIOverrides.getEndpoints();
12
+ SOCIAL_SVC_API = endpoints['SOCIAL_SVC_API'] as string;
13
+
14
+ },
15
+ getBulkPlayerfollowers: async(player_ids:string[]) => {
16
+ const resp = await axios.post(`${SOCIAL_SVC_API}/v1/followers/bulk/get`, { player_ids })
17
+ return resp.data.player_followers
18
+ },
19
+ savePlayerFollower: async(player_follower:PlayerFollowerProps):Promise<PlayerFollowerProps> => {
20
+ const resp = await axios.post(`${SOCIAL_SVC_API}/v1/followers/player/create`, { player_follower })
21
+ return resp.data.player_follower
22
+ }
23
+ }
@@ -0,0 +1,8 @@
1
+ import PlayerCard from "./PlayerCard";
2
+ import PlayerList from "./PlayerList";
3
+
4
+
5
+ export {
6
+ PlayerCard,
7
+ PlayerList
8
+ }
@@ -10,14 +10,7 @@ export const view_styles = StyleSheet.create({
10
10
  borderTopLeftRadius:22
11
11
  },
12
12
  float: {
13
- shadowColor: "#000",
14
- shadowOffset: {
15
- width: 0,
16
- height: 2
17
- },
18
- shadowOpacity: 0.25,
19
- shadowRadius: 3.84,
20
- elevation: 5
13
+ shadowColor: "rgba(0, 0, 0, 0.06)", shadowOffset: { width: 0, height: 10 }, shadowRadius: 10, shadowOpacity: 1
21
14
  }
22
15
  })
23
16
 
package/src/index.tsx CHANGED
@@ -1,10 +1,12 @@
1
1
  import Authenticator from "./Authenticator";
2
2
  import ProfileManager from "./ProfileManager";
3
3
  import * as Components from './Components';
4
+ import * as SocialComponents from './SocialComponents';
4
5
  import { APIOverrides } from "./ApiOverrides";
5
6
  import LinearGradient from "react-native-linear-gradient";
6
7
  import Colors from "./constants/colors";
7
8
  import Observer, { BEEventApi, BELinkApi } from './Observer';
9
+ import BettorSearch from "./BettorSearch";
8
10
 
9
11
 
10
12
  export {
@@ -14,7 +16,9 @@ export {
14
16
  BELinkApi,
15
17
  ProfileManager,
16
18
  Components,
19
+ SocialComponents,
17
20
  APIOverrides,
18
21
  LinearGradient,
22
+ BettorSearch,
19
23
  Colors
20
24
  }