react-native-fpay 0.2.9 → 0.3.2
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/module/FountainPayProvider.js +5 -1
- package/lib/module/FountainPayProvider.js.map +1 -1
- package/lib/module/core/api/index.js +22 -12
- package/lib/module/core/api/index.js.map +1 -1
- package/lib/module/engine/BLEReceiverService.js.map +1 -1
- package/lib/module/engine/FPEngine.js +24 -13
- package/lib/module/engine/FPEngine.js.map +1 -1
- package/lib/module/engine/useIsForeground.js +17 -0
- package/lib/module/engine/useIsForeground.js.map +1 -0
- package/lib/module/ui/components/AnimatedDots.js +68 -0
- package/lib/module/ui/components/AnimatedDots.js.map +1 -0
- package/lib/module/ui/components/ConfirmScreen.js +333 -0
- package/lib/module/ui/components/ConfirmScreen.js.map +1 -0
- package/lib/module/ui/modals/FPPaymentRequestModal.js +6 -8
- package/lib/module/ui/modals/FPPaymentRequestModal.js.map +1 -1
- package/lib/module/ui/modals/FPShell.js +7 -4
- package/lib/module/ui/modals/FPShell.js.map +1 -1
- package/lib/module/ui/screens/ReceiveScreen.js +379 -274
- package/lib/module/ui/screens/ReceiveScreen.js.map +1 -1
- package/lib/module/ui/screens/SendScreen.js +154 -45
- package/lib/module/ui/screens/SendScreen.js.map +1 -1
- package/lib/module/ui/screens/styles.js +89 -0
- package/lib/module/ui/screens/styles.js.map +1 -0
- package/lib/module/ui/screens/sub/receivePayment/Nfc/index.js +361 -0
- package/lib/module/ui/screens/sub/receivePayment/Nfc/index.js.map +1 -0
- package/lib/module/ui/screens/sub/receivePayment/Qr/index.js +338 -0
- package/lib/module/ui/screens/sub/receivePayment/Qr/index.js.map +1 -0
- package/lib/module/ui/screens/sub/receivePayment/Transfer/index.js +453 -0
- package/lib/module/ui/screens/sub/receivePayment/Transfer/index.js.map +1 -0
- package/lib/module/ui/screens/sub/{BluetoothSubScreen.js → sendPayment/BluetoothSubScreen.js} +25 -32
- package/lib/module/ui/screens/sub/sendPayment/BluetoothSubScreen.js.map +1 -0
- package/lib/module/ui/screens/sub/sendPayment/NFCSubScreen.js +354 -0
- package/lib/module/ui/screens/sub/sendPayment/NFCSubScreen.js.map +1 -0
- package/lib/module/ui/screens/sub/sendPayment/NQRSubScreen.js +440 -0
- package/lib/module/ui/screens/sub/sendPayment/NQRSubScreen.js.map +1 -0
- package/lib/module/ui/screens/sub/{ProximitySubScreen.js → sendPayment/ProximitySubScreen.js} +20 -111
- package/lib/module/ui/screens/sub/sendPayment/ProximitySubScreen.js.map +1 -0
- package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js +327 -0
- package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js.map +1 -0
- package/lib/typescript/src/FountainPayProvider.d.ts.map +1 -1
- package/lib/typescript/src/core/api/index.d.ts +20 -27
- package/lib/typescript/src/core/api/index.d.ts.map +1 -1
- package/lib/typescript/src/core/types/index.d.ts +56 -13
- package/lib/typescript/src/core/types/index.d.ts.map +1 -1
- package/lib/typescript/src/engine/BLEReceiverService.d.ts +2 -0
- package/lib/typescript/src/engine/BLEReceiverService.d.ts.map +1 -1
- package/lib/typescript/src/engine/FPEngine.d.ts +3 -1
- package/lib/typescript/src/engine/FPEngine.d.ts.map +1 -1
- package/lib/typescript/src/engine/useIsForeground.d.ts +2 -0
- package/lib/typescript/src/engine/useIsForeground.d.ts.map +1 -0
- package/lib/typescript/src/ui/components/AnimatedDots.d.ts +2 -0
- package/lib/typescript/src/ui/components/AnimatedDots.d.ts.map +1 -0
- package/lib/typescript/src/ui/components/ConfirmScreen.d.ts +10 -0
- package/lib/typescript/src/ui/components/ConfirmScreen.d.ts.map +1 -0
- package/lib/typescript/src/ui/components/OtpInput/Styles.d.ts +3 -3
- package/lib/typescript/src/ui/modals/FPPaymentRequestModal.d.ts.map +1 -1
- package/lib/typescript/src/ui/modals/FPShell.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/ReceiveScreen.d.ts +2 -9
- package/lib/typescript/src/ui/screens/ReceiveScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/SendScreen.d.ts +4 -2
- package/lib/typescript/src/ui/screens/SendScreen.d.ts.map +1 -1
- package/lib/typescript/src/ui/screens/styles.d.ts +1390 -0
- package/lib/typescript/src/ui/screens/styles.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/receivePayment/Nfc/index.d.ts +10 -0
- package/lib/typescript/src/ui/screens/sub/receivePayment/Nfc/index.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/receivePayment/Qr/index.d.ts +10 -0
- package/lib/typescript/src/ui/screens/sub/receivePayment/Qr/index.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/receivePayment/Transfer/index.d.ts +5 -0
- package/lib/typescript/src/ui/screens/sub/receivePayment/Transfer/index.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/{BluetoothSubScreen.d.ts → sendPayment/BluetoothSubScreen.d.ts} +2 -11
- package/lib/typescript/src/ui/screens/sub/sendPayment/BluetoothSubScreen.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/sendPayment/NFCSubScreen.d.ts +3 -0
- package/lib/typescript/src/ui/screens/sub/sendPayment/NFCSubScreen.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/sendPayment/NQRSubScreen.d.ts +3 -0
- package/lib/typescript/src/ui/screens/sub/sendPayment/NQRSubScreen.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/{ProximitySubScreen.d.ts → sendPayment/ProximitySubScreen.d.ts} +2 -10
- package/lib/typescript/src/ui/screens/sub/sendPayment/ProximitySubScreen.d.ts.map +1 -0
- package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts +3 -0
- package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/FountainPayProvider.tsx +7 -1
- package/src/core/api/index.ts +34 -19
- package/src/core/types/index.ts +67 -13
- package/src/engine/BLEReceiverService.ts +2 -0
- package/src/engine/FPEngine.ts +29 -14
- package/src/engine/useIsForeground.ts +18 -0
- package/src/ui/components/AnimatedDots.tsx +81 -0
- package/src/ui/components/ConfirmScreen.tsx +421 -0
- package/src/ui/modals/FPPaymentRequestModal.tsx +7 -6
- package/src/ui/modals/FPShell.tsx +9 -9
- package/src/ui/screens/ReceiveScreen.tsx +266 -115
- package/src/ui/screens/SendScreen.tsx +141 -19
- package/src/ui/screens/styles.ts +101 -0
- package/src/ui/screens/sub/receivePayment/Nfc/index.tsx +418 -0
- package/src/ui/screens/sub/receivePayment/Qr/index.tsx +391 -0
- package/src/ui/screens/sub/receivePayment/Transfer/index.tsx +512 -0
- package/src/ui/screens/sub/{BluetoothSubScreen.tsx → sendPayment/BluetoothSubScreen.tsx} +27 -46
- package/src/ui/screens/sub/sendPayment/NFCSubScreen.tsx +302 -0
- package/src/ui/screens/sub/sendPayment/NQRSubScreen.tsx +490 -0
- package/src/ui/screens/sub/{ProximitySubScreen.tsx → sendPayment/ProximitySubScreen.tsx} +24 -44
- package/src/ui/screens/sub/sendPayment/TransferSubScreen.tsx +345 -0
- package/lib/module/ui/screens/sub/BluetoothSubScreen.js.map +0 -1
- package/lib/module/ui/screens/sub/NFCSubScreen.js +0 -164
- package/lib/module/ui/screens/sub/NFCSubScreen.js.map +0 -1
- package/lib/module/ui/screens/sub/NQRSubScreen.js +0 -131
- package/lib/module/ui/screens/sub/NQRSubScreen.js.map +0 -1
- package/lib/module/ui/screens/sub/ProximitySubScreen.js.map +0 -1
- package/lib/module/ui/screens/sub/TransferSubScreen.js +0 -353
- package/lib/module/ui/screens/sub/TransferSubScreen.js.map +0 -1
- package/lib/typescript/src/ui/screens/sub/BluetoothSubScreen.d.ts.map +0 -1
- package/lib/typescript/src/ui/screens/sub/NFCSubScreen.d.ts +0 -18
- package/lib/typescript/src/ui/screens/sub/NFCSubScreen.d.ts.map +0 -1
- package/lib/typescript/src/ui/screens/sub/NQRSubScreen.d.ts +0 -12
- package/lib/typescript/src/ui/screens/sub/NQRSubScreen.d.ts.map +0 -1
- package/lib/typescript/src/ui/screens/sub/ProximitySubScreen.d.ts.map +0 -1
- package/lib/typescript/src/ui/screens/sub/TransferSubScreen.d.ts +0 -11
- package/lib/typescript/src/ui/screens/sub/TransferSubScreen.d.ts.map +0 -1
- package/src/ui/screens/sub/NFCSubScreen.tsx +0 -86
- package/src/ui/screens/sub/NQRSubScreen.tsx +0 -62
- package/src/ui/screens/sub/TransferSubScreen.tsx +0 -147
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Text, TouchableOpacity } from "react-native";
|
|
2
|
+
import styled from "styled-components/native";
|
|
3
|
+
|
|
4
|
+
export const ButtonContainer = styled.View`
|
|
5
|
+
width: 100%;
|
|
6
|
+
`;
|
|
7
|
+
|
|
8
|
+
export const CTAButton = styled.TouchableOpacity`
|
|
9
|
+
width: 100%;
|
|
10
|
+
padding: 16px;
|
|
11
|
+
background-color: rgba(255, 255, 255, 0.15);
|
|
12
|
+
border: 2px solid rgba(255, 255, 255, 0.4);
|
|
13
|
+
border-radius: 30px;
|
|
14
|
+
align-items: center;
|
|
15
|
+
backdrop-filter: blur(10px);
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const CTAText = styled.Text`
|
|
19
|
+
color: #ffffff;
|
|
20
|
+
font-size: 17px;
|
|
21
|
+
font-weight: 600;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const HomeIndicator = styled.View`
|
|
25
|
+
width: 140px;
|
|
26
|
+
height: 5px;
|
|
27
|
+
background-color: #ffffff;
|
|
28
|
+
border-radius: 3px;
|
|
29
|
+
align-self: center;
|
|
30
|
+
margin-top: 16px;
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export const ContentContainer = styled.View`
|
|
34
|
+
flex: 1;
|
|
35
|
+
align-items: center;
|
|
36
|
+
justify-content: space-between;
|
|
37
|
+
padding: 40px 24px 60px;
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
export const List = styled(TouchableOpacity)`
|
|
41
|
+
padding: 9px 5px;
|
|
42
|
+
|
|
43
|
+
flex-direction: row;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
|
|
47
|
+
border-bottom-width: 1px;
|
|
48
|
+
border-bottom-color: #f9f9f9;
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export const ListText = styled(Text)`
|
|
53
|
+
font-size: 16px;
|
|
54
|
+
font-weight: 200;
|
|
55
|
+
color: #1f2937;
|
|
56
|
+
padding: 3px 0px;
|
|
57
|
+
width: 95%;
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
export const InputContainer = styled.View`
|
|
62
|
+
padding: 0 24px;
|
|
63
|
+
margin-top: 24px;
|
|
64
|
+
`;
|
|
65
|
+
|
|
66
|
+
export const AccountBox = styled.View`
|
|
67
|
+
background-color: rgba(74, 222, 128, 0.3);
|
|
68
|
+
border-radius: 16px;
|
|
69
|
+
padding: 8px 20px;
|
|
70
|
+
flex-direction: row;
|
|
71
|
+
justify-content: space-between;
|
|
72
|
+
align-items: center;
|
|
73
|
+
width: 250px;
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
export const AccountText = styled.Text`
|
|
77
|
+
color: #d1d5db;
|
|
78
|
+
font-size: 16px;
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
export const Label = styled.Text`
|
|
82
|
+
color: #fff;
|
|
83
|
+
font-size: 14px;
|
|
84
|
+
font-weight: 600;
|
|
85
|
+
margin-bottom: 12px;
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
export const InputBox = styled.View`
|
|
89
|
+
background-color: rgba(255, 255, 255, 0.3);;
|
|
90
|
+
border-radius: 16px;
|
|
91
|
+
padding: 16px 20px;
|
|
92
|
+
flex-direction: row;
|
|
93
|
+
align-items: center;
|
|
94
|
+
color: #d1d5db;
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
export const StyledTextInput = styled.TextInput`
|
|
98
|
+
flex: 1;
|
|
99
|
+
color: #d1d5db;
|
|
100
|
+
font-size: 16px;
|
|
101
|
+
`;
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, Easing, Vibration } from 'react-native';
|
|
3
|
+
import Ionicons from 'react-native-vector-icons/Ionicons';
|
|
4
|
+
import styled from 'styled-components/native';
|
|
5
|
+
import NfcManager, { Ndef, NfcTech } from 'react-native-nfc-manager';
|
|
6
|
+
import { PulseAnimation } from '../../../../components/PulseAnimation';
|
|
7
|
+
|
|
8
|
+
// Styled Components
|
|
9
|
+
const Container = styled.View`
|
|
10
|
+
flex: 1;
|
|
11
|
+
background-color: #f5f5f5;
|
|
12
|
+
padding-bottom: 60%;
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
const ScrollContainer = styled.ScrollView`
|
|
16
|
+
flex: 1;
|
|
17
|
+
`;
|
|
18
|
+
const Header = styled.View`
|
|
19
|
+
flex-direction: row;
|
|
20
|
+
align-items: center;
|
|
21
|
+
padding: 16px;
|
|
22
|
+
padding-top: 40px;
|
|
23
|
+
background-color: #ffffff;
|
|
24
|
+
border-bottom-width: 1px;
|
|
25
|
+
border-bottom-color: #e0e0e0;
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
const BackButton = styled.TouchableOpacity`
|
|
29
|
+
padding: 8px;
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
const BackIcon = styled.Text`
|
|
33
|
+
font-size: 24px;
|
|
34
|
+
color: #000000;
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const HeaderTitle = styled.Text`
|
|
38
|
+
flex: 1;
|
|
39
|
+
font-size: 18px;
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
color: #000000;
|
|
42
|
+
text-align: center;
|
|
43
|
+
margin-right: 40px;
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
const ContentContainer = styled.View`
|
|
47
|
+
flex: 1;
|
|
48
|
+
padding: 24px;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
align-items: center;
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
const AmountCard = styled.View`
|
|
54
|
+
background-color: #ffffff;
|
|
55
|
+
border-radius: 16px;
|
|
56
|
+
padding: 24px;
|
|
57
|
+
width: 100%;
|
|
58
|
+
align-items: center;
|
|
59
|
+
margin-bottom: 40px;
|
|
60
|
+
shadow-color: #000;
|
|
61
|
+
shadow-offset: 0px 2px;
|
|
62
|
+
shadow-opacity: 0.05;
|
|
63
|
+
shadow-radius: 8px;
|
|
64
|
+
elevation: 3;
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
const AmountLabel = styled.Text`
|
|
68
|
+
font-size: 14px;
|
|
69
|
+
color: #666666;
|
|
70
|
+
margin-bottom: 8px;
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
const AmountText = styled.Text`
|
|
74
|
+
font-size: 42px;
|
|
75
|
+
font-weight: 700;
|
|
76
|
+
color: #0a3d2e;
|
|
77
|
+
`;
|
|
78
|
+
|
|
79
|
+
const NFCAnimationContainer = styled.View`
|
|
80
|
+
align-items: center;
|
|
81
|
+
justify-content: center;
|
|
82
|
+
margin-bottom: 40px;
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
const NFCIconContainer = styled(Animated.View)`
|
|
86
|
+
width: 140px;
|
|
87
|
+
height: 140px;
|
|
88
|
+
border-radius: 90px;
|
|
89
|
+
background-color: #E8F5F1;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
margin-bottom: 24px;
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
const NFCIcon = styled.Text`
|
|
96
|
+
font-size: 80px;
|
|
97
|
+
`;
|
|
98
|
+
|
|
99
|
+
const PulseRing = styled(Animated.View)<{ delay?: number }>`
|
|
100
|
+
position: absolute;
|
|
101
|
+
width: 200px;
|
|
102
|
+
height: 200px;
|
|
103
|
+
border-radius: 100%;
|
|
104
|
+
border-width: 2px;
|
|
105
|
+
border-color: #0a3d2e;
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
const StatusTextContainer = styled.View`
|
|
109
|
+
align-items: center;
|
|
110
|
+
margin-bottom: 8px;
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
const StatusText = styled.Text`
|
|
114
|
+
font-size: 18px;
|
|
115
|
+
font-weight: 600;
|
|
116
|
+
color: #333333;
|
|
117
|
+
text-align: center;
|
|
118
|
+
margin-bottom: 8px;
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
const StatusSubText = styled.Text`
|
|
122
|
+
font-size: 14px;
|
|
123
|
+
color: #666666;
|
|
124
|
+
text-align: center;
|
|
125
|
+
`;
|
|
126
|
+
|
|
127
|
+
const InstructionCard = styled.View`
|
|
128
|
+
background-color: #ffffff;
|
|
129
|
+
border-radius: 16px;
|
|
130
|
+
padding: 20px;
|
|
131
|
+
width: 100%;
|
|
132
|
+
margin-bottom: 24px;
|
|
133
|
+
shadow-color: #000;
|
|
134
|
+
shadow-offset: 0px 2px;
|
|
135
|
+
shadow-opacity: 0.05;
|
|
136
|
+
shadow-radius: 8px;
|
|
137
|
+
elevation: 3;
|
|
138
|
+
`;
|
|
139
|
+
|
|
140
|
+
const InstructionTitle = styled.Text`
|
|
141
|
+
font-size: 15px;
|
|
142
|
+
font-weight: 600;
|
|
143
|
+
color: #333333;
|
|
144
|
+
margin-bottom: 12px;
|
|
145
|
+
`;
|
|
146
|
+
|
|
147
|
+
const InstructionItem = styled.View`
|
|
148
|
+
flex-direction: row;
|
|
149
|
+
align-items: flex-start;
|
|
150
|
+
margin-bottom: 10px;
|
|
151
|
+
`;
|
|
152
|
+
|
|
153
|
+
const InstructionNumber = styled.View`
|
|
154
|
+
width: 24px;
|
|
155
|
+
height: 24px;
|
|
156
|
+
border-radius: 12px;
|
|
157
|
+
background-color: #0a3d2e;
|
|
158
|
+
align-items: center;
|
|
159
|
+
justify-content: center;
|
|
160
|
+
margin-right: 12px;
|
|
161
|
+
`;
|
|
162
|
+
|
|
163
|
+
const InstructionNumberText = styled.Text`
|
|
164
|
+
font-size: 12px;
|
|
165
|
+
font-weight: 600;
|
|
166
|
+
color: #ffffff;
|
|
167
|
+
`;
|
|
168
|
+
|
|
169
|
+
const InstructionText = styled.Text`
|
|
170
|
+
flex: 1;
|
|
171
|
+
font-size: 14px;
|
|
172
|
+
color: #666666;
|
|
173
|
+
line-height: 20px;
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
const InfoBanner = styled.View`
|
|
177
|
+
background-color: #FFF3E0;
|
|
178
|
+
border-radius: 12px;
|
|
179
|
+
padding: 16px;
|
|
180
|
+
width: 100%;
|
|
181
|
+
margin-bottom: 24px;
|
|
182
|
+
flex-direction: row;
|
|
183
|
+
align-items: center;
|
|
184
|
+
`;
|
|
185
|
+
|
|
186
|
+
const InfoIcon = styled.Text`
|
|
187
|
+
font-size: 20px;
|
|
188
|
+
margin-right: 12px;
|
|
189
|
+
`;
|
|
190
|
+
|
|
191
|
+
const InfoText = styled.Text`
|
|
192
|
+
flex: 1;
|
|
193
|
+
font-size: 13px;
|
|
194
|
+
color: #F57C00;
|
|
195
|
+
line-height: 18px;
|
|
196
|
+
`;
|
|
197
|
+
|
|
198
|
+
const CancelButton = styled.TouchableOpacity`
|
|
199
|
+
background-color: #ffffff;
|
|
200
|
+
border: 1.5px solid #E0E0E0;
|
|
201
|
+
border-radius: 28px;
|
|
202
|
+
padding: 16px;
|
|
203
|
+
align-items: center;
|
|
204
|
+
width: 100%;
|
|
205
|
+
`;
|
|
206
|
+
|
|
207
|
+
const CancelButtonText = styled.Text`
|
|
208
|
+
font-size: 15px;
|
|
209
|
+
font-weight: 600;
|
|
210
|
+
color: #666666;
|
|
211
|
+
`;
|
|
212
|
+
|
|
213
|
+
const ConnectionStatusBadge = styled.View<{ connected: boolean }>`
|
|
214
|
+
background-color: ${props => props.connected ? '#0a3d2e' : '#E0E0E0'};
|
|
215
|
+
border-radius: 20px;
|
|
216
|
+
padding: 8px 16px;
|
|
217
|
+
margin-top: 16px;
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
const ConnectionStatusText = styled.Text<{ connected: boolean }>`
|
|
221
|
+
font-size: 12px;
|
|
222
|
+
font-weight: 600;
|
|
223
|
+
color: ${props => props.connected ? '#ffffff' : '#666666'};
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
// Main Component
|
|
228
|
+
interface ReceiveNFCScreenProps {
|
|
229
|
+
amount: number;
|
|
230
|
+
description?: string;
|
|
231
|
+
onClose?: () => void;
|
|
232
|
+
onPaymentReceived?: (data: any) => void;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const Nfc: React.FC<ReceiveNFCScreenProps> = ({
|
|
236
|
+
amount = 5000,
|
|
237
|
+
description,
|
|
238
|
+
onClose,
|
|
239
|
+
onPaymentReceived,
|
|
240
|
+
}) => {
|
|
241
|
+
const [nfcEnabled, setNfcEnabled] = useState(true);
|
|
242
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
243
|
+
const iconScale = useRef(new Animated.Value(1)).current;
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
const writeNFC = async(userId: string, userName: string) => {
|
|
247
|
+
await NfcManager.requestTechnology(NfcTech.Ndef);
|
|
248
|
+
const bytes = Ndef.encodeMessage([
|
|
249
|
+
Ndef.textRecord(JSON.stringify({ userId, userName }))
|
|
250
|
+
]);
|
|
251
|
+
await NfcManager.ndefHandler.writeNdefMessage(bytes);
|
|
252
|
+
await NfcManager.cancelTechnologyRequest();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Sender reads NFC tag
|
|
256
|
+
const readNFC=async() => {
|
|
257
|
+
await NfcManager.requestTechnology(NfcTech.Ndef);
|
|
258
|
+
const tag: any = await NfcManager.getTag();
|
|
259
|
+
const paymentInfo = JSON.parse(tag?.ndefMessage[0].payload);
|
|
260
|
+
await NfcManager.cancelTechnologyRequest();
|
|
261
|
+
return paymentInfo;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
const checkNFCAvailability = () => {
|
|
269
|
+
// In production, check actual NFC status
|
|
270
|
+
// For now, simulate it's available
|
|
271
|
+
NfcManager.start()
|
|
272
|
+
.then(() => setNfcEnabled(true))
|
|
273
|
+
.catch(err => console.log('NFC start error:', err));
|
|
274
|
+
|
|
275
|
+
return () => {
|
|
276
|
+
NfcManager.cancelTechnologyRequest().catch(() => {});
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const formatAmount = (value: number): string => {
|
|
282
|
+
return value.toLocaleString('en-NG', {
|
|
283
|
+
minimumFractionDigits: 2,
|
|
284
|
+
maximumFractionDigits: 2,
|
|
285
|
+
});
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const handleNFCDetection = () => {
|
|
289
|
+
// Simulate NFC detection
|
|
290
|
+
setIsConnecting(true);
|
|
291
|
+
Vibration.vibrate(100);
|
|
292
|
+
|
|
293
|
+
// In production, handle actual NFC tag detection
|
|
294
|
+
setTimeout(() => {
|
|
295
|
+
setIsConnecting(false);
|
|
296
|
+
// Call onPaymentReceived callback
|
|
297
|
+
}, 2000);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
useEffect(() => {
|
|
301
|
+
// Simulate NFC availability check
|
|
302
|
+
// In production, use actual NFC library to check availability
|
|
303
|
+
checkNFCAvailability();
|
|
304
|
+
|
|
305
|
+
// Icon breathing animation
|
|
306
|
+
Animated.loop(
|
|
307
|
+
Animated.sequence([
|
|
308
|
+
Animated.timing(iconScale, {
|
|
309
|
+
toValue: 1.1,
|
|
310
|
+
duration: 1500,
|
|
311
|
+
easing: Easing.inOut(Easing.ease),
|
|
312
|
+
useNativeDriver: true,
|
|
313
|
+
}),
|
|
314
|
+
Animated.timing(iconScale, {
|
|
315
|
+
toValue: 1,
|
|
316
|
+
duration: 1500,
|
|
317
|
+
easing: Easing.inOut(Easing.ease),
|
|
318
|
+
useNativeDriver: true,
|
|
319
|
+
}),
|
|
320
|
+
])
|
|
321
|
+
).start();
|
|
322
|
+
}, []);
|
|
323
|
+
|
|
324
|
+
return (
|
|
325
|
+
<Container>
|
|
326
|
+
{/* Header */}
|
|
327
|
+
<Header>
|
|
328
|
+
<BackButton onPress={onClose}>
|
|
329
|
+
<Ionicons name="close" size={24} />
|
|
330
|
+
</BackButton>
|
|
331
|
+
<HeaderTitle>Receive via NFC</HeaderTitle>
|
|
332
|
+
</Header>
|
|
333
|
+
|
|
334
|
+
{/* Content */}
|
|
335
|
+
<ScrollContainer showsVerticalScrollIndicator={false}>
|
|
336
|
+
<ContentContainer>
|
|
337
|
+
{/* Amount Display */}
|
|
338
|
+
<AmountCard>
|
|
339
|
+
<AmountLabel>Amount to Receive</AmountLabel>
|
|
340
|
+
<AmountText>₦{formatAmount(amount)}</AmountText>
|
|
341
|
+
</AmountCard>
|
|
342
|
+
|
|
343
|
+
{/* NFC Animation */}
|
|
344
|
+
<NFCAnimationContainer>
|
|
345
|
+
<PulseAnimation />
|
|
346
|
+
<NFCIconContainer style={{ transform: [{ scale: iconScale }] }}>
|
|
347
|
+
<NFCIcon>📡</NFCIcon>
|
|
348
|
+
</NFCIconContainer>
|
|
349
|
+
|
|
350
|
+
<StatusTextContainer>
|
|
351
|
+
<StatusText>
|
|
352
|
+
{isConnecting ? 'Connecting...' : 'Ready to Receive'}
|
|
353
|
+
</StatusText>
|
|
354
|
+
<StatusSubText>Hold devices back-to-back</StatusSubText>
|
|
355
|
+
</StatusTextContainer>
|
|
356
|
+
|
|
357
|
+
<ConnectionStatusBadge connected={nfcEnabled}>
|
|
358
|
+
<ConnectionStatusText connected={nfcEnabled}>
|
|
359
|
+
{nfcEnabled ? 'NFC Enabled' : 'NFC Disabled'}
|
|
360
|
+
</ConnectionStatusText>
|
|
361
|
+
</ConnectionStatusBadge>
|
|
362
|
+
</NFCAnimationContainer>
|
|
363
|
+
|
|
364
|
+
{/* Instructions */}
|
|
365
|
+
<InstructionCard>
|
|
366
|
+
<InstructionTitle>How to receive payment</InstructionTitle>
|
|
367
|
+
|
|
368
|
+
<InstructionItem>
|
|
369
|
+
<InstructionNumber>
|
|
370
|
+
<InstructionNumberText>1</InstructionNumberText>
|
|
371
|
+
</InstructionNumber>
|
|
372
|
+
<InstructionText>
|
|
373
|
+
Ask the payer to open their payment app and select "Pay via NFC"
|
|
374
|
+
</InstructionText>
|
|
375
|
+
</InstructionItem>
|
|
376
|
+
|
|
377
|
+
<InstructionItem>
|
|
378
|
+
<InstructionNumber>
|
|
379
|
+
<InstructionNumberText>2</InstructionNumberText>
|
|
380
|
+
</InstructionNumber>
|
|
381
|
+
<InstructionText>
|
|
382
|
+
Hold the back of both phones together
|
|
383
|
+
</InstructionText>
|
|
384
|
+
</InstructionItem>
|
|
385
|
+
|
|
386
|
+
<InstructionItem>
|
|
387
|
+
<InstructionNumber>
|
|
388
|
+
<InstructionNumberText>3</InstructionNumberText>
|
|
389
|
+
</InstructionNumber>
|
|
390
|
+
<InstructionText>
|
|
391
|
+
Keep devices steady until you feel a vibration
|
|
392
|
+
</InstructionText>
|
|
393
|
+
</InstructionItem>
|
|
394
|
+
</InstructionCard>
|
|
395
|
+
|
|
396
|
+
{/* Info Banner */}
|
|
397
|
+
{!nfcEnabled && (
|
|
398
|
+
<InfoBanner>
|
|
399
|
+
<InfoIcon>⚠️</InfoIcon>
|
|
400
|
+
<InfoText>
|
|
401
|
+
NFC is disabled on your device. Please enable it in your phone
|
|
402
|
+
settings to receive payments.
|
|
403
|
+
</InfoText>
|
|
404
|
+
</InfoBanner>
|
|
405
|
+
)}
|
|
406
|
+
|
|
407
|
+
{/* Cancel Button */}
|
|
408
|
+
<CancelButton onPress={onClose}>
|
|
409
|
+
<CancelButtonText>Cancel</CancelButtonText>
|
|
410
|
+
</CancelButton>
|
|
411
|
+
</ContentContainer>
|
|
412
|
+
</ScrollContainer>
|
|
413
|
+
|
|
414
|
+
</Container>
|
|
415
|
+
);
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
export default Nfc;
|