be-components 7.5.8 → 7.6.0

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 +5 -1
  2. package/lib/commonjs/ApiOverrides/index.js.map +1 -1
  3. package/lib/commonjs/BetRouter/components/MyOpportunities.js +14 -9
  4. package/lib/commonjs/BetRouter/components/MyOpportunities.js.map +1 -1
  5. package/lib/commonjs/BetRouter/components/OpportunityHistory.js +92 -41
  6. package/lib/commonjs/BetRouter/components/OpportunityHistory.js.map +1 -1
  7. package/lib/commonjs/Checkout/api/index.js +11 -3
  8. package/lib/commonjs/Checkout/api/index.js.map +1 -1
  9. package/lib/commonjs/Checkout/components/OrderSummaryCard.js +4 -4
  10. package/lib/commonjs/Checkout/components/OrderSummaryCard.js.map +1 -1
  11. package/lib/commonjs/Checkout/index.js.map +1 -1
  12. package/lib/commonjs/ProfileManager/Components/VouchCard.js +1 -1
  13. package/lib/commonjs/ProfileManager/Components/VouchCard.js.map +1 -1
  14. package/lib/commonjs/Wallet/api/index.js +21 -4
  15. package/lib/commonjs/Wallet/api/index.js.map +1 -1
  16. package/lib/commonjs/Wallet/components/LinkAccountManager.js +18 -2
  17. package/lib/commonjs/Wallet/components/LinkAccountManager.js.map +1 -1
  18. package/lib/commonjs/Wallet/components/ManageAccountCard.js +32 -2
  19. package/lib/commonjs/Wallet/components/ManageAccountCard.js.map +1 -1
  20. package/lib/commonjs/Wallet/components/ManualACHAdd.js +47 -5
  21. package/lib/commonjs/Wallet/components/ManualACHAdd.js.map +1 -1
  22. package/lib/commonjs/Wallet/components/WalletActionSelector.js +22 -2
  23. package/lib/commonjs/Wallet/components/WalletActionSelector.js.map +1 -1
  24. package/lib/commonjs/Wallet/components/WithdrawCard.js +56 -5
  25. package/lib/commonjs/Wallet/components/WithdrawCard.js.map +1 -1
  26. package/lib/commonjs/Wallet/index.js +43 -4
  27. package/lib/commonjs/Wallet/index.js.map +1 -1
  28. package/lib/commonjs/types.d.js.map +1 -1
  29. package/lib/module/ApiOverrides/index.js +5 -1
  30. package/lib/module/ApiOverrides/index.js.map +1 -1
  31. package/lib/module/BetRouter/components/MyOpportunities.js +14 -9
  32. package/lib/module/BetRouter/components/MyOpportunities.js.map +1 -1
  33. package/lib/module/BetRouter/components/OpportunityHistory.js +93 -42
  34. package/lib/module/BetRouter/components/OpportunityHistory.js.map +1 -1
  35. package/lib/module/Checkout/api/index.js +11 -3
  36. package/lib/module/Checkout/api/index.js.map +1 -1
  37. package/lib/module/Checkout/components/OrderSummaryCard.js +4 -4
  38. package/lib/module/Checkout/components/OrderSummaryCard.js.map +1 -1
  39. package/lib/module/Checkout/index.js.map +1 -1
  40. package/lib/module/ProfileManager/Components/VouchCard.js +1 -1
  41. package/lib/module/ProfileManager/Components/VouchCard.js.map +1 -1
  42. package/lib/module/Wallet/api/index.js +21 -4
  43. package/lib/module/Wallet/api/index.js.map +1 -1
  44. package/lib/module/Wallet/components/LinkAccountManager.js +18 -2
  45. package/lib/module/Wallet/components/LinkAccountManager.js.map +1 -1
  46. package/lib/module/Wallet/components/ManageAccountCard.js +32 -2
  47. package/lib/module/Wallet/components/ManageAccountCard.js.map +1 -1
  48. package/lib/module/Wallet/components/ManualACHAdd.js +47 -5
  49. package/lib/module/Wallet/components/ManualACHAdd.js.map +1 -1
  50. package/lib/module/Wallet/components/WalletActionSelector.js +22 -2
  51. package/lib/module/Wallet/components/WalletActionSelector.js.map +1 -1
  52. package/lib/module/Wallet/components/WithdrawCard.js +55 -5
  53. package/lib/module/Wallet/components/WithdrawCard.js.map +1 -1
  54. package/lib/module/Wallet/index.js +43 -4
  55. package/lib/module/Wallet/index.js.map +1 -1
  56. package/lib/module/types.d.js.map +1 -1
  57. package/lib/typescript/lib/commonjs/ApiOverrides/index.d.ts.map +1 -1
  58. package/lib/typescript/lib/commonjs/BetRouter/components/MyOpportunities.d.ts.map +1 -1
  59. package/lib/typescript/lib/commonjs/BetRouter/components/OpportunityHistory.d.ts +1 -2
  60. package/lib/typescript/lib/commonjs/BetRouter/components/OpportunityHistory.d.ts.map +1 -1
  61. package/lib/typescript/lib/commonjs/Checkout/api/index.d.ts.map +1 -1
  62. package/lib/typescript/lib/commonjs/Wallet/api/index.d.ts +1 -0
  63. package/lib/typescript/lib/commonjs/Wallet/api/index.d.ts.map +1 -1
  64. package/lib/typescript/lib/commonjs/Wallet/components/LinkAccountManager.d.ts.map +1 -1
  65. package/lib/typescript/lib/commonjs/Wallet/components/ManageAccountCard.d.ts.map +1 -1
  66. package/lib/typescript/lib/commonjs/Wallet/components/ManualACHAdd.d.ts +3 -1
  67. package/lib/typescript/lib/commonjs/Wallet/components/ManualACHAdd.d.ts.map +1 -1
  68. package/lib/typescript/lib/commonjs/Wallet/components/WalletActionSelector.d.ts.map +1 -1
  69. package/lib/typescript/lib/commonjs/Wallet/components/WithdrawCard.d.ts +4 -1
  70. package/lib/typescript/lib/commonjs/Wallet/components/WithdrawCard.d.ts.map +1 -1
  71. package/lib/typescript/lib/commonjs/Wallet/index.d.ts.map +1 -1
  72. package/lib/typescript/lib/module/ApiOverrides/index.d.ts.map +1 -1
  73. package/lib/typescript/lib/module/BetRouter/components/MyOpportunities.d.ts.map +1 -1
  74. package/lib/typescript/lib/module/BetRouter/components/OpportunityHistory.d.ts +1 -2
  75. package/lib/typescript/lib/module/BetRouter/components/OpportunityHistory.d.ts.map +1 -1
  76. package/lib/typescript/lib/module/Checkout/api/index.d.ts.map +1 -1
  77. package/lib/typescript/lib/module/Wallet/api/index.d.ts +1 -0
  78. package/lib/typescript/lib/module/Wallet/api/index.d.ts.map +1 -1
  79. package/lib/typescript/lib/module/Wallet/components/LinkAccountManager.d.ts.map +1 -1
  80. package/lib/typescript/lib/module/Wallet/components/ManageAccountCard.d.ts.map +1 -1
  81. package/lib/typescript/lib/module/Wallet/components/ManualACHAdd.d.ts +3 -1
  82. package/lib/typescript/lib/module/Wallet/components/ManualACHAdd.d.ts.map +1 -1
  83. package/lib/typescript/lib/module/Wallet/components/WalletActionSelector.d.ts.map +1 -1
  84. package/lib/typescript/lib/module/Wallet/components/WithdrawCard.d.ts +4 -1
  85. package/lib/typescript/lib/module/Wallet/components/WithdrawCard.d.ts.map +1 -1
  86. package/lib/typescript/lib/module/Wallet/index.d.ts.map +1 -1
  87. package/lib/typescript/src/ApiOverrides/index.d.ts.map +1 -1
  88. package/lib/typescript/src/BetRouter/components/MyOpportunities.d.ts.map +1 -1
  89. package/lib/typescript/src/BetRouter/components/OpportunityHistory.d.ts +1 -1
  90. package/lib/typescript/src/BetRouter/components/OpportunityHistory.d.ts.map +1 -1
  91. package/lib/typescript/src/Checkout/api/index.d.ts.map +1 -1
  92. package/lib/typescript/src/Checkout/index.d.ts.map +1 -1
  93. package/lib/typescript/src/ProfileManager/Components/VouchCard.d.ts.map +1 -1
  94. package/lib/typescript/src/Wallet/api/index.d.ts +1 -0
  95. package/lib/typescript/src/Wallet/api/index.d.ts.map +1 -1
  96. package/lib/typescript/src/Wallet/components/LinkAccountManager.d.ts.map +1 -1
  97. package/lib/typescript/src/Wallet/components/ManageAccountCard.d.ts.map +1 -1
  98. package/lib/typescript/src/Wallet/components/ManualACHAdd.d.ts +4 -2
  99. package/lib/typescript/src/Wallet/components/ManualACHAdd.d.ts.map +1 -1
  100. package/lib/typescript/src/Wallet/components/WalletActionSelector.d.ts.map +1 -1
  101. package/lib/typescript/src/Wallet/components/WithdrawCard.d.ts +3 -1
  102. package/lib/typescript/src/Wallet/components/WithdrawCard.d.ts.map +1 -1
  103. package/lib/typescript/src/Wallet/index.d.ts.map +1 -1
  104. package/package.json +1 -1
  105. package/src/ApiOverrides/index.ts +5 -1
  106. package/src/BetRouter/components/MyOpportunities.tsx +24 -21
  107. package/src/BetRouter/components/OpportunityHistory.tsx +72 -36
  108. package/src/Checkout/api/index.tsx +10 -2
  109. package/src/Checkout/components/OrderSummaryCard.tsx +4 -4
  110. package/src/Checkout/index.tsx +0 -1
  111. package/src/ProfileManager/Components/VouchCard.tsx +3 -4
  112. package/src/Wallet/api/index.ts +13 -5
  113. package/src/Wallet/components/LinkAccountManager.tsx +14 -6
  114. package/src/Wallet/components/ManageAccountCard.tsx +23 -2
  115. package/src/Wallet/components/ManualACHAdd.tsx +31 -8
  116. package/src/Wallet/components/WalletActionSelector.tsx +12 -2
  117. package/src/Wallet/components/WithdrawCard.tsx +41 -5
  118. package/src/Wallet/index.tsx +28 -1
  119. package/src/types.d.ts +3 -0
@@ -1,8 +1,8 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { Text, View, Button } from '../../Components/Themed';
3
3
  import { BetRouterApi } from '../api';
4
- import { FlatList, TouchableOpacity } from 'react-native';
5
- import type { OpportunityProps, OpportunitySummaryProps, OpportunityStatusLegProps, RouterOrderProps, RouterPartnerProps } from '../types';
4
+ import { FlatList, TouchableOpacity, ScrollView } from 'react-native';
5
+ import type { OpportunityProps, OpportunitySummaryProps, OpportunityStatusLegProps, RouterOrderProps, RouterPartnerProps, RouterContestProps } from '../types';
6
6
  import { useColors } from '../../constants/useColors';
7
7
  import DateTimePicker from 'react-datetime-picker';
8
8
  import 'react-datetime-picker/dist/DateTimePicker.css';
@@ -25,7 +25,7 @@ type OpportunityHistoryProps = {
25
25
 
26
26
  //const ITEMS_PER_PAGE = 5;
27
27
 
28
- const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: OpportunityHistoryProps) => {
28
+ const OpportunityHistory = ({ me, insets, partners = [] }: OpportunityHistoryProps) => {
29
29
  const Colors = useColors();
30
30
 
31
31
  const [state, setState] = useState<{
@@ -34,9 +34,11 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
34
34
  opportunitySummary: OpportunitySummaryProps[];
35
35
  opportunityStatusLegs: OpportunityStatusLegProps[];
36
36
  routerOrders: RouterOrderProps[];
37
+ routerContests: RouterContestProps[];
37
38
  pages: number;
38
39
  currentPage: number;
39
40
  searchText: string;
41
+ selectedFillStatus: string;
40
42
  selectedOpportunity: OpportunityProps | null;
41
43
  showDetailModal: boolean;
42
44
  }>({
@@ -45,9 +47,11 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
45
47
  opportunitySummary: [],
46
48
  opportunityStatusLegs: [],
47
49
  routerOrders: [],
50
+ routerContests: [],
48
51
  pages: 0,
49
52
  currentPage: 0,
50
53
  searchText: '',
54
+ selectedFillStatus: 'All',
51
55
  selectedOpportunity: null,
52
56
  showDetailModal: false
53
57
  });
@@ -64,7 +68,7 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
64
68
 
65
69
  const [showCustomPicker, setShowCustomPicker] = useState(false);
66
70
 
67
- const { loading, opportunities, opportunitySummary, routerOrders, pages, currentPage, searchText, selectedOpportunity, showDetailModal } = state;
71
+ const { loading, opportunities, opportunitySummary, routerOrders, routerContests, pages, currentPage, searchText, selectedFillStatus, selectedOpportunity, showDetailModal } = state;
68
72
 
69
73
  useEffect(() => {
70
74
  BetRouterApi.setEnvironment();
@@ -92,6 +96,7 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
92
96
  opportunitySummary: result.opportunity_summary,
93
97
  opportunityStatusLegs: result.opportunity_status_legs,
94
98
  routerOrders: result.router_orders,
99
+ routerContests: result.router_contests,
95
100
  pages: result.pages,
96
101
  currentPage: page,
97
102
  loading: false
@@ -136,13 +141,25 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
136
141
  setState({ ...state, selectedOpportunity: null, showDetailModal: false });
137
142
  };
138
143
 
139
- // Filter opportunities by search (client-side filter on current page only)
144
+ // Filter and sort opportunities by search and fill status (client-side filter on current page only)
140
145
  const filteredOpportunities = opportunities.filter(opp => {
146
+ // Filter by fill status
147
+ if (selectedFillStatus !== 'All') {
148
+ const statusMap: { [key: string]: string } = {
149
+ 'All Filled': 'all_filled',
150
+ 'Partially Filled': 'partially_filled',
151
+ 'Failed': 'failed',
152
+ 'Pending': 'pending'
153
+ };
154
+ if (opp.fill_status !== statusMap[selectedFillStatus]) return false;
155
+ }
156
+
157
+ // Filter by search text
141
158
  if (!searchText) return true;
142
159
  if (opp.opportunity_type.toLowerCase().includes(searchText.toLowerCase())) return true;
143
160
  const oppOrders = routerOrders.filter(order => order.opportunity_id === opp.opportunity_id);
144
161
  return oppOrders.some(order => order.title?.toLowerCase().includes(searchText.toLowerCase()));
145
- });
162
+ }).sort((a, b) => new Date(b.create_datetime).getTime() - new Date(a.create_datetime).getTime());
146
163
 
147
164
  // Use server-side pagination info
148
165
  const totalPages = pages;
@@ -154,15 +171,16 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
154
171
  const isProfitable = (opp.actual_profit || 0) >= 0;
155
172
  const oppOrders = routerOrders.filter(order => order.opportunity_id === opp.opportunity_id);
156
173
  const firstOrder = oppOrders[0];
174
+ const contest = routerContests.find(c => c.router_contest_id === opp.router_contest_id);
157
175
 
158
176
  return (
159
177
  <TouchableOpacity onPress={() => handleOpenDetail(opp)}>
160
178
  <View type='row' style={{ padding: 12, borderBottomWidth: 1, borderBottomColor: Colors.borders.light, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
161
179
  <View transparent style={{ flex: 1, flexDirection: 'row', alignItems: 'center', gap: 12 }}>
162
- {/* Type & Profit */}
180
+ {/* Contest/Type & Profit */}
163
181
  <View transparent style={{ minWidth: 60 }}>
164
182
  <Text theme='h2' size={11} numberOfLines={1}>
165
- {opp.opportunity_type.toUpperCase()}
183
+ {contest?.contest_label || opp.opportunity_type.toUpperCase()}
166
184
  </Text>
167
185
  <Text
168
186
  theme='h2'
@@ -216,7 +234,7 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
216
234
  };
217
235
 
218
236
  return (
219
- <View float style={{ flex: compact ? 0 : 1 }}>
237
+ <View float style={{ flex: 1 }}>
220
238
  <PlacedOpportunityModal
221
239
  visible={showDetailModal}
222
240
  opportunity={selectedOpportunity}
@@ -233,9 +251,11 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
233
251
  </Text>
234
252
  </View>
235
253
 
236
- <View type='body' style={{ flex: 1 }}>
254
+ <ScrollView style={{ flex: 1 }}>
255
+ <View type='body'>
237
256
  {/* Date Range Selector */}
238
257
  <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
258
+ <Text theme='description' size={11} style={{ marginBottom: 5 }}>Date Range</Text>
239
259
  <DropDown
240
260
  selected_value={dateRange.preset === 'yesterday' ? 'Yesterday' :
241
261
  dateRange.preset === 'last7' ? 'Last 7 Days' :
@@ -253,6 +273,20 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
253
273
  />
254
274
  </View>
255
275
 
276
+ {/* Fill Status Filter */}
277
+ <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
278
+ <Text theme='description' size={11} style={{ marginBottom: 5 }}>Fill Status</Text>
279
+ <DropDown
280
+ selected_value={selectedFillStatus}
281
+ dropdown_options={[
282
+ { value: 'All', eligible_options: ['All', 'All Filled', 'Partially Filled', 'Failed', 'Pending'] }
283
+ ]}
284
+ onOptionSelect={(option) => {
285
+ setState({ ...state, selectedFillStatus: option, currentPage: 0 });
286
+ }}
287
+ />
288
+ </View>
289
+
256
290
  {/* Custom Date Picker */}
257
291
  {showCustomPicker && (
258
292
  <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
@@ -276,14 +310,6 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
276
310
  </View>
277
311
  )}
278
312
 
279
- {/* Search */}
280
- <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
281
- <SearchBox
282
- onChange={(text) => setState({ ...state, searchText: text, currentPage: 0 })}
283
- hide_search_button
284
- />
285
- </View>
286
-
287
313
  {/* Overall Statistics */}
288
314
  {opportunitySummary.length > 0 && (
289
315
  <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
@@ -361,6 +387,32 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
361
387
  </View>
362
388
  )}
363
389
 
390
+ {/* Search */}
391
+ <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
392
+ <SearchBox
393
+ onChange={(text) => setState({ ...state, searchText: text, currentPage: 0 })}
394
+ hide_search_button
395
+ />
396
+ </View>
397
+
398
+ {/* Opportunity List */}
399
+ {loading ? (
400
+ <View transparent style={{ padding: 20, alignItems: 'center' }}>
401
+ <Text theme='description'>Loading...</Text>
402
+ </View>
403
+ ) : paginatedOpportunities.length === 0 ? (
404
+ <View transparent style={{ padding: 20, alignItems: 'center' }}>
405
+ <Text theme='description'>No past opportunities found</Text>
406
+ </View>
407
+ ) : (
408
+ <FlatList
409
+ data={paginatedOpportunities}
410
+ keyExtractor={(item) => item.opportunity_id}
411
+ renderItem={renderOpportunityCard}
412
+ scrollEnabled={false}
413
+ />
414
+ )}
415
+
364
416
  {/* Pagination */}
365
417
  {!loading && opportunities.length > 0 && totalPages > 1 && (
366
418
  <View transparent style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: Colors.borders.light }}>
@@ -383,24 +435,8 @@ const OpportunityHistory = ({ me, compact = false, insets, partners = [] }: Oppo
383
435
  />
384
436
  </View>
385
437
  )}
386
-
387
- {/* Opportunity List */}
388
- {loading ? (
389
- <View transparent style={{ padding: 20, alignItems: 'center' }}>
390
- <Text theme='description'>Loading...</Text>
391
- </View>
392
- ) : paginatedOpportunities.length === 0 ? (
393
- <View transparent style={{ padding: 20, alignItems: 'center' }}>
394
- <Text theme='description'>No past opportunities found</Text>
395
- </View>
396
- ) : (
397
- <FlatList
398
- data={paginatedOpportunities}
399
- keyExtractor={(item) => item.opportunity_id}
400
- renderItem={renderOpportunityCard}
401
- />
402
- )}
403
- </View>
438
+ </View>
439
+ </ScrollView>
404
440
  </View>
405
441
  );
406
442
  };
@@ -164,9 +164,17 @@ const CheckoutHelpers = {
164
164
  },
165
165
  genItemOrder: (draft_order:ItemOrderProps, items:ItemProps[], account:AccountProps):ItemOrderProps => {
166
166
  let amount = parseFloat(draft_order.amount as string);
167
- let fee_1 = 0
168
167
  let no_fee = items.find(i => i.no_fees) ? true : false
169
- if(!no_fee){ fee_1 = Math.round(((account.transaction_fee * amount) + Number.EPSILON) * 100) / 100 }
168
+ let item_fees = draft_order.items.reduce((a,b) => {
169
+ let b_item = items.find(i => i.item_id == b.item_id);
170
+ let b_fee = b_item && b_item.processing_fee ? b_item.processing_fee * b.amount : 0
171
+ return a + b_fee
172
+ }, 0);
173
+ let account_fee = Math.round(((account.transaction_fee * amount) + Number.EPSILON) * 100) / 100
174
+ let fee_1 = Math.max(item_fees, account_fee)
175
+ console.log('item fees are')
176
+ console.log(item_fees)
177
+ if(no_fee){ fee_1 = 0 }
170
178
  let total_amount = amount + fee_1
171
179
  return {
172
180
  ...draft_order,
@@ -13,23 +13,23 @@ const OrderSummaryCard = ({ item_order }:OrderSummaryCardProps) => {
13
13
  <View>
14
14
  <View style={{ flexDirection:'row', padding:5, paddingRight:10, paddingLeft:10 }}>
15
15
  <Text style={{ flex:1 }} size={14} theme='description'>Subtotal</Text>
16
- <Text size={14} theme='description'>${item_order.amount}</Text>
16
+ <Text size={14} theme='description'>${Number(item_order.amount).toFixed(2)}</Text>
17
17
  </View>
18
18
  {item_order.fee_1 ?
19
19
  <View style={{ flexDirection:'row', padding:5, paddingRight:10, paddingLeft:10 }}>
20
20
  <Text style={{ flex:1 }} size={14} theme='description'>{item_order.fee_1}</Text>
21
- <Text size={14} theme='description'>${item_order.fee_1_amount}</Text>
21
+ <Text size={14} theme='description'>${item_order.fee_1_amount?.toFixed(2)}</Text>
22
22
  </View>
23
23
  :<></>}
24
24
  {item_order.fee_2 ?
25
25
  <View style={{ flexDirection:'row', padding:5, paddingRight:10, paddingLeft:10 }}>
26
26
  <Text style={{ flex:1 }} size={14} theme='description'>{item_order.fee_2}</Text>
27
- <Text size={14} theme='description'>${item_order.fee_2_amount}</Text>
27
+ <Text size={14} theme='description'>${item_order.fee_2_amount?.toFixed(2)}</Text>
28
28
  </View>
29
29
  :<></>}
30
30
  <View style={{ flexDirection:'row', padding:5, paddingRight:10, paddingLeft:10 }}>
31
31
  <Text style={{ flex:1 }} size={14} theme='h1'>Total</Text>
32
- <Text size={14} theme='h1'>${item_order.total_amount}</Text>
32
+ <Text size={14} theme='h1'>${item_order.total_amount.toFixed(2)}</Text>
33
33
  </View>
34
34
  </View>
35
35
  )
@@ -156,7 +156,6 @@ const Checkout = ({ item_order, height, account_id, onCancel, onCompleteOrder, o
156
156
  setRedirectVisible(true);
157
157
  setLoading(false);
158
158
  }
159
-
160
159
  }
161
160
 
162
161
  const handleCancel = async() => {
@@ -186,8 +186,8 @@ const VouchCard = ({ player, view_mode, walkthrough, insets, code_details, onVou
186
186
  onPress={() => onClaimGift()}
187
187
  style={{flexDirection:'row', alignItems:'center', justifyContent:'center', alignSelf:'center' }}
188
188
  >
189
- <Text size={14} color={Colors.incentive.gold} weight='bold'>CLAIM ME NOW!</Text>
190
- <Icons.ChevronIcon direction='down' size={8} color={Colors.incentive.gold} />
189
+ <Text size={14} color={Colors.incentive.gold} weight='bold'>CLAIM ME NOW!</Text>
190
+ <Icons.ChevronIcon direction='down' size={8} color={Colors.incentive.gold} />
191
191
  </Button>
192
192
  :<></>}
193
193
  <Button
@@ -238,7 +238,6 @@ const VouchCard = ({ player, view_mode, walkthrough, insets, code_details, onVou
238
238
  return (
239
239
  <View transparent style={{ padding:5, flexDirection:'row', alignItems:'center' }}>
240
240
  <Text size={12} color={Colors.utility.warning} weight='bold'>{i+1} - {e}</Text>
241
-
242
241
  </View>
243
242
  )
244
243
  })}
@@ -292,7 +291,7 @@ const VouchCard = ({ player, view_mode, walkthrough, insets, code_details, onVou
292
291
  </View>
293
292
 
294
293
  <Modal
295
- visible={player?.vouched_status == 'unverified' && vouching ? true : false}
294
+ visible={['unverified','reverify'].includes(player?.vouched_status) && vouching ? true : false}
296
295
  transparent
297
296
  animationType={view_mode == 'desktop' ? 'fade' : 'slide'}
298
297
  style={{flex:1}}
@@ -114,6 +114,14 @@ const WalletApi = {
114
114
  const resp = await axios.post(`${WALLET_SVC_API}/v1/accounts/account/ach/add`, { account, ach_detail })
115
115
  return { account: resp.data.account, ach_detail: resp.data.ach_detail }
116
116
  },
117
+ addACHDetails: async(account_id:string, routing_number:string, account_number:string):Promise<ACHDetailProps | undefined> => {
118
+ try {
119
+ const resp = await axios.post(`${WALLET_SVC_API}/v1/accounts/account/ach/details/add`, { account_id, routing_number, account_number });
120
+ return resp.data.ach_details
121
+ } catch (e) {
122
+ return undefined
123
+ }
124
+ },
117
125
  verifyACHAccount: async(account_id:string, amount_1:number, amount_2:number):Promise<{ account:AccountProps, status:'success'|'fail' }> => {
118
126
  const resp = await axios.post(`${WALLET_SVC_API}/v1/accounts/account/ach/verify`, { account_id, amount_1, amount_2 })
119
127
  return { account: resp.data.account, status:resp.data.status }
@@ -308,7 +316,6 @@ const ItemOrderHelpers = {
308
316
  last_update_datetime: ''
309
317
  }
310
318
  },
311
-
312
319
  getDepositAvailable: (deposit_limit:PlayerDepositLimitProps, account:AccountProps) => {
313
320
  let deposit_available = 0
314
321
  if(deposit_limit){
@@ -502,10 +509,11 @@ const WalletHelpers = {
502
509
  if(!account){ console.log('') }
503
510
  return [
504
511
  { action_id: '1', action_type: 'deposit', action_title: 'Deposit Funds', action_description: 'Deposit to your BettorEdge balance using this account' },
505
- { action_id: '2', action_type: 'withdraw', action_title: 'Withdraw Funds', action_description: 'Withdraw funds to this bank account from your BettorEdge balance' },
506
- { action_id: '3', action_type: 'limits', action_title: 'Account Limits', action_description: 'Set personal deposit limits to manage how much you use BettorEdge' },
507
- { action_id: '4', action_type: 'snoozes', action_title: 'Snooze Account', action_description: 'Set snooze for this account to take a break from BettorEdge' },
508
- { action_id: '5', action_type: 'remove', action_title: 'Remove Account', action_description: 'Remove and delete this account from your profile' },
512
+ { action_id: '2', action_type: 'instant_withdraw', action_title: 'Instantly Withdraw Funds (with Fee)', action_description: 'Withdraw funds instantly to this bank account from your BettorEdge balance' },
513
+ { action_id: '3', action_type: 'withdraw', action_title: 'Withdraw Funds (Free)', action_description: 'Withdraw funds to this bank account from your BettorEdge balance' },
514
+ { action_id: '4', action_type: 'limits', action_title: 'Account Limits', action_description: 'Set personal deposit limits to manage how much you use BettorEdge' },
515
+ { action_id: '5', action_type: 'snoozes', action_title: 'Snooze Account', action_description: 'Set snooze for this account to take a break from BettorEdge' },
516
+ { action_id: '6', action_type: 'remove', action_title: 'Remove Account', action_description: 'Remove and delete this account from your profile' },
509
517
  ]
510
518
  },
511
519
  /**
@@ -134,12 +134,20 @@ const LinkAccountManager = ({ player_addresses, ibt_placeholer_account, onCancel
134
134
  :!show_addresses.selected_address ?
135
135
  <View style={{ marginTop:10, borderRadius:8, padding:20 }}>
136
136
  <Text size={14} theme='description'>Before we continue, we will need get the billing address associated with the account to be linked</Text>
137
- <Button
138
- style={{ marginTop:10 }}
139
- title={show_addresses.selected_address ?'CHANGE':'ADD BILLING ADDRESS'}
140
- type='success'
141
- onPress={() => setShowAddresses({ ...show_addresses, visible:true })}
142
- />
137
+ <View transparent style={{ flexDirection:'row', alignItems:'center', marginTop:10 }}>
138
+ <Button
139
+ title='CANCEL'
140
+ style={{ flex:1, marginRight:4 }}
141
+ type='error'
142
+ onPress={() => onCancel()}
143
+ />
144
+ <Button
145
+ style={{ flex:2, marginLeft:4 }}
146
+ title={show_addresses.selected_address ?'CHANGE':'ADD BILLING ADDRESS'}
147
+ type='success'
148
+ onPress={() => setShowAddresses({ ...show_addresses, visible:true })}
149
+ />
150
+ </View>
143
151
  </View>
144
152
  :<></>}
145
153
  <Modal
@@ -29,13 +29,14 @@ const manage_sections = ['header','actions']
29
29
  const ManageAccountCard = ({ player, view_mode, insets, wallet_settings, player_balance, account, deposit_limit, withdraw_limit, onAccountUpdate, onTransact, onClose }:ManageAccountCardProps) => {
30
30
  const Colors = useColors();
31
31
  const [ active_action, setActiveAction ] = useState('select');
32
-
33
32
  const account_actions = WalletHelpers.getAccountOptions(account)
34
33
 
35
34
  const renderIcon = (action:AccountActionProps) => {
36
35
  switch(action.action_type){
37
36
  case 'deposit':
38
37
  return <Icons.DepositIcon color={Colors.text.white} size={20} />
38
+ case 'instant_withdraw':
39
+ return <Icons.WithdrawIcon color={Colors.text.gold} size={20} />
39
40
  case 'withdraw':
40
41
  return <Icons.WithdrawIcon color={Colors.text.white} size={20} />
41
42
  case 'limits':
@@ -55,7 +56,8 @@ const ManageAccountCard = ({ player, view_mode, insets, wallet_settings, player_
55
56
  if(data.item.action_type == 'remove' && account.ibt_placeholder){ return <></> }
56
57
  if(data.item.action_type == 'withdraw' && account.account_type == 'card'){ return <></> }
57
58
  if(data.item.action_type == 'remove' && account.account_type === 'paypal'){ return <></> }
58
-
59
+ if(data.item.action_type == 'instant_withdraw' && !account.ach_detail){ return <></> }
60
+ if(data.item.action_type == 'instant_withdraw' && !account.ach_detail?.instant_allowed){ return <></> }
59
61
  //if(data.item.action_type == 'deposit' && account.account_type == 'card' && account?.card_detail?.card_type != 'debit'){ return <></> }
60
62
  return (
61
63
  <Button float style={{ flex:1, minHeight:80, margin:8 }} onPress={() => setActiveAction(data.item.action_type)}>
@@ -84,6 +86,11 @@ const ManageAccountCard = ({ player, view_mode, insets, wallet_settings, player_
84
86
  <Text style={{ marginTop:5}} theme='description'>Below are the available actions that can be performed on this account!</Text>
85
87
  :<></>}
86
88
  </View>
89
+ {account.ach_detail && account.ach_detail.ach_type == 'ibf' ?
90
+ <View transparent style={{ marginLeft:10 }}>
91
+ <Icons.BankInstantIcon color={Colors.text.gold} size={20} />
92
+ </View>
93
+ :<></>}
87
94
  </View>
88
95
  )
89
96
  case 'actions':
@@ -144,6 +151,20 @@ const ManageAccountCard = ({ player, view_mode, insets, wallet_settings, player_
144
151
  wallet_settings={wallet_settings}
145
152
  player_balance={player_balance}
146
153
  account={account}
154
+ onAccountUpdate={onAccountUpdate}
155
+ withdraw_limit={withdraw_limit}
156
+ onTransact={onTransact}
157
+ onCancel={() => setActiveAction('select')}
158
+ />
159
+ :active_action == 'instant_withdraw'?
160
+ <WithdrawCard
161
+ player={player}
162
+ instant
163
+ deposit_limit={deposit_limit}
164
+ wallet_settings={wallet_settings}
165
+ player_balance={player_balance}
166
+ account={account}
167
+ onAccountUpdate={onAccountUpdate}
147
168
  withdraw_limit={withdraw_limit}
148
169
  onTransact={onTransact}
149
170
  onCancel={() => setActiveAction('select')}
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Checkbox } from '../../Components';
3
3
  import { WalletApi, WalletHelpers } from '../api';
4
- import type { AccountProps, FocusPositionProps, MyPlayerProps } from '../../types';
4
+ import type { AccountProps, ACHDetailProps, FocusPositionProps, MyPlayerProps } from '../../types';
5
5
  import { useColors } from '../../constants/useColors';
6
6
  import { Button, Text, TextInput, View } from '../../Components/Themed';
7
7
  import { FlatList, KeyboardAvoidingView, Platform } from 'react-native';
@@ -9,13 +9,15 @@ const validator = require('us-bank-account-validator');
9
9
 
10
10
  type ManualACHAddProps = {
11
11
  player:MyPlayerProps,
12
+ account_id?:string,
12
13
  onFocusPosition?:(pos:FocusPositionProps) => void,
14
+ onUpdateAchDetails:(ach_detail:ACHDetailProps) => void,
13
15
  onAddAccount:(account:AccountProps) => void,
14
16
  onCancel:() => void
15
17
  }
16
18
 
17
19
  const ach_sections = ['header','name','bank_name','routing_number','account_number','disclaimer']
18
- const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:ManualACHAddProps) => {
20
+ const ManualACHAdd = ({ player, account_id, onUpdateAchDetails, onAddAccount, onCancel, onFocusPosition }:ManualACHAddProps) => {
19
21
  const Colors = useColors();
20
22
  const [ loading, setLoading ] = useState(false);
21
23
  const [ error, setError ] = useState<string>();
@@ -29,8 +31,10 @@ const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:Manual
29
31
  const bank_valid = ach_details.bank_name ? true : false;
30
32
  const routing_valid = validator.routingNumber(ach_details.routing_number);
31
33
  const account_valid = validator.accountNumber(ach_details.account_number);
32
- const valid = bank_valid && routing_valid && account_valid && disclaimer ? true : false
33
-
34
+ let valid = routing_valid && account_valid ? true : false
35
+ if(!account_id && !bank_valid){ valid = false }
36
+ if(!account_id && !disclaimer){ valid = false }
37
+
34
38
  const handleAddAccount = async() => {
35
39
  if(!valid || loading){ return }
36
40
  setLoading(true);
@@ -45,9 +49,27 @@ const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:Manual
45
49
  setLoading(false);
46
50
  }
47
51
 
52
+ const handleAddAchDetails = async() => {
53
+ if(!valid || loading || !account_id){ return }
54
+ if(!ach_details.account_number || !ach_details.routing_number){ return }
55
+ setLoading(true)
56
+ const new_ach_detail = await WalletApi.addACHDetails(account_id, ach_details.routing_number, ach_details.account_number);
57
+ if(!new_ach_detail){ setError('Sorry, we were not able to confirm this account. Please try again.') }
58
+ else { onUpdateAchDetails(new_ach_detail) }
59
+ setLoading(false)
60
+ }
61
+
48
62
  const renderSections = (data:{item:string,index:number}) => {
49
63
  switch(data.item){
50
64
  case 'header':
65
+ if(account_id){
66
+ return (
67
+ <View type='header' style={{ padding:20 }}>
68
+ <Text theme='h1'>CONFIRM ACCOUNT DETAILS</Text>
69
+ <Text style={{ marginTop:4 }} theme='description'>Please confirm your account details below to continue.</Text>
70
+ </View>
71
+ )
72
+ }
51
73
  return (
52
74
  <View type='header' style={{ padding:20 }}>
53
75
  <Text theme='h1'>MANUAL ACH ACCOUNT</Text>
@@ -68,6 +90,7 @@ const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:Manual
68
90
  </View>
69
91
  )
70
92
  case 'bank_name':
93
+ if(account_id){ return <></> }
71
94
  return (
72
95
  <View style={{ padding:10 }}>
73
96
  <Text size={14} theme='h2'>Bank Name</Text>
@@ -126,7 +149,6 @@ const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:Manual
126
149
  return (
127
150
  <View style={{ flex:1 }}>
128
151
  <KeyboardAvoidingView style={{ flex:1 }} behavior={Platform.OS == 'ios' ? 'padding' : 'height'}>
129
-
130
152
  <FlatList
131
153
  key='manual_ach_sections'
132
154
  keyExtractor={(item) => item}
@@ -134,13 +156,14 @@ const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:Manual
134
156
  renderItem={renderSections}
135
157
  />
136
158
  </KeyboardAvoidingView>
137
-
159
+ {!account_id ?
138
160
  <View>
139
161
  <Button style={{ flexDirection:'row', alignItems:'center', paddingLeft:20, paddingRight:20 }} onPress={() => setDisclaimer(!disclaimer)}>
140
162
  <Checkbox size={30} checked={disclaimer} disabled onSelect={() => console.log('')}/>
141
163
  <Text style={{ marginLeft:10 }} size={14} theme='description'>I understand that by continuing, we will send 2 small deposits to this bank account to confirm ownership. Once received, I will enter the amounts here.</Text>
142
164
  </Button>
143
165
  </View>
166
+ :<></>}
144
167
  {error?
145
168
  <View style={{ padding:10 }}>
146
169
  <Text size={16} color={Colors.text.warning} textAlign='center' weight='semibold'>{error}</Text>
@@ -156,12 +179,12 @@ const ManualACHAdd = ({ player, onAddAccount, onCancel, onFocusPosition }:Manual
156
179
  onPress={() => onCancel()}
157
180
  />
158
181
  <Button
159
- title='ADD ACCOUNT'
182
+ title={account_id? 'CONFIRM ACCOUNT': 'ADD ACCOUNT'}
160
183
  style={{ flex:3, opacity:valid&&!loading&&!error?1:0.5 }}
161
184
  disabled={!valid || loading || error?true:false}
162
185
  loading={loading}
163
186
  type='success'
164
- onPress={() => handleAddAccount()}
187
+ onPress={() => account_id ? handleAddAchDetails() : handleAddAccount()}
165
188
  />
166
189
  </View>
167
190
  : account.status == 'verify' ?
@@ -45,7 +45,10 @@ const WalletActionSelector = ({ player, walkthrough_steps, player_balance, accou
45
45
  action :'deposit', label: "Make A Deposit", icon:<Icons.DepositIcon size={20} color={Colors.text.h1} />, description: 'Fund your BettorEdge real-money balance by making a deposit from an existing account or new one.'
46
46
  },
47
47
  {
48
- action :'withdraw', label: "Make A Withdrawal", icon:<Icons.WithdrawIcon size={20} color={Colors.text.h1} />, description: 'Move funds from your BettorEdge real-money balance to a connected ACH account.'
48
+ action :'withdraw', label: "Withdraw Funds (FREE)", icon:<Icons.WithdrawIcon size={20} color={Colors.text.h1} />, description: 'Move funds from your BettorEdge real-money balance to a connected ACH account. (Up to 3 biz days)'
49
+ },
50
+ {
51
+ action :'instant_withdraw', label: "Instantly Withdraw Funds", icon:<Icons.WithdrawIcon size={20} color={Colors.text.h1} />, description: 'Instantly Move funds from your BettorEdge real-money balance to a connected ACH account.'
49
52
  },
50
53
 
51
54
  ]
@@ -59,9 +62,16 @@ const WalletActionSelector = ({ player, walkthrough_steps, player_balance, accou
59
62
  if(!default_account){ default_account = accounts.find(a => a.account_type == 'paypal')}
60
63
  return onActionSelect(action, default_account)
61
64
  case 'withdraw':
62
- let withdraw_account = accounts.find(a => !a.ibt_placeholder && a.account_type == 'ach' && a.status == 'active')
65
+ let withdraw_account = accounts.find(a => !a.ibt_placeholder && a.account_type == 'ach' && a.status == 'active');
63
66
  if(!withdraw_account){ return onActionSelect({ action: 'ach_add' }) }
64
67
  return onActionSelect(action, withdraw_account)
68
+ case 'instant_withdraw':
69
+ let instant_withdraw_account = accounts.find(a => a.status == 'active' && a.account_type == 'ach' && a.ach_detail?.ach_type == 'ibf');
70
+ if(instant_withdraw_account){ return onActionSelect(action, instant_withdraw_account) }
71
+ //Ok lets get the ibt_placeholder one!
72
+ let ibt_placeholder = accounts.find(a => a.ibt_placeholder);
73
+ if(ibt_placeholder){ return onActionSelect(action, ibt_placeholder) }
74
+ return //Dont do anything if we dont have an ibt acccount possible
65
75
  default: onActionSelect(action)
66
76
  }
67
77
  }