@kiosinc/commons-rn 0.1.61 → 0.1.63

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 (103) hide show
  1. package/lib/commonjs/api/customer.js +75 -0
  2. package/lib/commonjs/api/customer.js.map +1 -0
  3. package/lib/commonjs/auth/hooks/useAuthentication.js +6 -0
  4. package/lib/commonjs/auth/hooks/useAuthentication.js.map +1 -1
  5. package/lib/commonjs/auth/hooks/useTermsOfService.js +8 -10
  6. package/lib/commonjs/auth/hooks/useTermsOfService.js.map +1 -1
  7. package/lib/commonjs/auth/providers/authentication/AuthenticationProvider.js +2 -1
  8. package/lib/commonjs/auth/providers/authentication/AuthenticationProvider.js.map +1 -1
  9. package/lib/commonjs/auth/providers/authentication/reducer/authentication.reducer.js +19 -1
  10. package/lib/commonjs/auth/providers/authentication/reducer/authentication.reducer.js.map +1 -1
  11. package/lib/commonjs/hooks/useCheckCustomer.js +57 -0
  12. package/lib/commonjs/hooks/useCheckCustomer.js.map +1 -0
  13. package/lib/commonjs/hooks/useCustomer.js +251 -0
  14. package/lib/commonjs/hooks/useCustomer.js.map +1 -0
  15. package/lib/commonjs/index.js +32 -0
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/commonjs/screens/SavedCards/CardRow.js +79 -0
  18. package/lib/commonjs/screens/SavedCards/CardRow.js.map +1 -0
  19. package/lib/commonjs/screens/SavedCards/SavedCards.js +180 -0
  20. package/lib/commonjs/screens/SavedCards/SavedCards.js.map +1 -0
  21. package/lib/commonjs/selectBusiness/queryKeys.js +6 -1
  22. package/lib/commonjs/selectBusiness/queryKeys.js.map +1 -1
  23. package/lib/commonjs/types/customer.d.js +7 -0
  24. package/lib/commonjs/types/customer.d.js.map +1 -0
  25. package/lib/commonjs/utils/checkout.js +11 -0
  26. package/lib/commonjs/utils/checkout.js.map +1 -0
  27. package/lib/commonjs/utils/currency.js +17 -0
  28. package/lib/commonjs/utils/currency.js.map +1 -0
  29. package/lib/commonjs/utils/square.js +39 -0
  30. package/lib/commonjs/utils/square.js.map +1 -0
  31. package/lib/module/api/customer.js +59 -0
  32. package/lib/module/api/customer.js.map +1 -0
  33. package/lib/module/auth/hooks/useAuthentication.js +6 -0
  34. package/lib/module/auth/hooks/useAuthentication.js.map +1 -1
  35. package/lib/module/auth/hooks/useTermsOfService.js +8 -10
  36. package/lib/module/auth/hooks/useTermsOfService.js.map +1 -1
  37. package/lib/module/auth/providers/authentication/AuthenticationProvider.js +2 -1
  38. package/lib/module/auth/providers/authentication/AuthenticationProvider.js.map +1 -1
  39. package/lib/module/auth/providers/authentication/reducer/authentication.reducer.js +19 -1
  40. package/lib/module/auth/providers/authentication/reducer/authentication.reducer.js.map +1 -1
  41. package/lib/module/hooks/useCheckCustomer.js +50 -0
  42. package/lib/module/hooks/useCheckCustomer.js.map +1 -0
  43. package/lib/module/hooks/useCustomer.js +243 -0
  44. package/lib/module/hooks/useCustomer.js.map +1 -0
  45. package/lib/module/index.js +4 -0
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/module/screens/SavedCards/CardRow.js +71 -0
  48. package/lib/module/screens/SavedCards/CardRow.js.map +1 -0
  49. package/lib/module/screens/SavedCards/SavedCards.js +170 -0
  50. package/lib/module/screens/SavedCards/SavedCards.js.map +1 -0
  51. package/lib/module/selectBusiness/queryKeys.js +6 -1
  52. package/lib/module/selectBusiness/queryKeys.js.map +1 -1
  53. package/lib/module/types/customer.d.js +5 -0
  54. package/lib/module/types/customer.d.js.map +1 -0
  55. package/lib/module/utils/checkout.js +4 -0
  56. package/lib/module/utils/checkout.js.map +1 -0
  57. package/lib/module/utils/currency.js +10 -0
  58. package/lib/module/utils/currency.js.map +1 -0
  59. package/lib/module/utils/square.js +36 -0
  60. package/lib/module/utils/square.js.map +1 -0
  61. package/lib/typescript/src/api/customer.d.ts +23 -0
  62. package/lib/typescript/src/api/customer.d.ts.map +1 -0
  63. package/lib/typescript/src/auth/hooks/useAuthentication.d.ts.map +1 -1
  64. package/lib/typescript/src/auth/hooks/useTermsOfService.d.ts.map +1 -1
  65. package/lib/typescript/src/auth/providers/authentication/AuthenticationProvider.d.ts.map +1 -1
  66. package/lib/typescript/src/auth/providers/authentication/reducer/authentication.reducer.d.ts.map +1 -1
  67. package/lib/typescript/src/auth/providers/authentication/types/authentication.types.d.ts +1 -0
  68. package/lib/typescript/src/auth/providers/authentication/types/authentication.types.d.ts.map +1 -1
  69. package/lib/typescript/src/hooks/useCheckCustomer.d.ts +4 -0
  70. package/lib/typescript/src/hooks/useCheckCustomer.d.ts.map +1 -0
  71. package/lib/typescript/src/hooks/useCustomer.d.ts +58 -0
  72. package/lib/typescript/src/hooks/useCustomer.d.ts.map +1 -0
  73. package/lib/typescript/src/index.d.ts +4 -0
  74. package/lib/typescript/src/index.d.ts.map +1 -1
  75. package/lib/typescript/src/screens/SavedCards/CardRow.d.ts +11 -0
  76. package/lib/typescript/src/screens/SavedCards/CardRow.d.ts.map +1 -0
  77. package/lib/typescript/src/screens/SavedCards/SavedCards.d.ts +7 -0
  78. package/lib/typescript/src/screens/SavedCards/SavedCards.d.ts.map +1 -0
  79. package/lib/typescript/src/selectBusiness/queryKeys.d.ts +5 -0
  80. package/lib/typescript/src/selectBusiness/queryKeys.d.ts.map +1 -1
  81. package/lib/typescript/src/utils/checkout.d.ts +3 -0
  82. package/lib/typescript/src/utils/checkout.d.ts.map +1 -0
  83. package/lib/typescript/src/utils/currency.d.ts +5 -0
  84. package/lib/typescript/src/utils/currency.d.ts.map +1 -0
  85. package/lib/typescript/src/utils/square.d.ts +6 -0
  86. package/lib/typescript/src/utils/square.d.ts.map +1 -0
  87. package/package.json +3 -1
  88. package/src/api/customer.ts +112 -0
  89. package/src/auth/hooks/useAuthentication.ts +4 -0
  90. package/src/auth/hooks/useTermsOfService.ts +8 -11
  91. package/src/auth/providers/authentication/AuthenticationProvider.tsx +1 -0
  92. package/src/auth/providers/authentication/reducer/authentication.reducer.ts +20 -0
  93. package/src/auth/providers/authentication/types/authentication.types.ts +1 -0
  94. package/src/hooks/useCheckCustomer.ts +42 -0
  95. package/src/hooks/useCustomer.ts +331 -0
  96. package/src/index.tsx +6 -0
  97. package/src/screens/SavedCards/CardRow.tsx +94 -0
  98. package/src/screens/SavedCards/SavedCards.tsx +197 -0
  99. package/src/selectBusiness/queryKeys.ts +5 -0
  100. package/src/types/customer.d.ts +70 -0
  101. package/src/utils/checkout.ts +5 -0
  102. package/src/utils/currency.ts +10 -0
  103. package/src/utils/square.ts +50 -0
@@ -0,0 +1,112 @@
1
+ import {
2
+ Address,
3
+ ConnectSquareCustomerRequest,
4
+ CustomerProfileProps,
5
+ SaveCardRequest,
6
+ } from '../types/customer';
7
+
8
+ import axios from 'axios';
9
+ import Config from 'react-native-config';
10
+
11
+ export const getCustomer = async (userId: string) => {
12
+ return await axios.get(`${Config.CHILDS_SERVER_ENV}/customers/${userId}`);
13
+ };
14
+
15
+ export const createCustomer = async ({
16
+ uid,
17
+ address = null,
18
+ }: {
19
+ uid: string;
20
+ address?: Address | null;
21
+ }) => {
22
+ return await axios.post(`${Config.CHILDS_SERVER_ENV}/customers/create`, {
23
+ uid,
24
+ props: {
25
+ Address: address,
26
+ },
27
+ });
28
+ };
29
+
30
+ export const updateCustomerProfile = async ({
31
+ uid,
32
+ props,
33
+ }: {
34
+ uid: string;
35
+ props: CustomerProfileProps;
36
+ }) => {
37
+ return await axios.post(
38
+ `${Config.CHILDS_SERVER_ENV}/customers/${uid}/update`,
39
+ {
40
+ props,
41
+ }
42
+ );
43
+ };
44
+
45
+ export const saveCustomerAddress = async ({
46
+ uid,
47
+ address,
48
+ }: {
49
+ uid: string;
50
+ address: Address;
51
+ }) => {
52
+ return await axios.post(
53
+ `${Config.CHILDS_SERVER_ENV}/customers/${uid}/address/create`,
54
+ {
55
+ address,
56
+ }
57
+ );
58
+ };
59
+
60
+ export const saveCustomerCard = async ({
61
+ uid,
62
+ props,
63
+ }: {
64
+ uid: string;
65
+ props: SaveCardRequest;
66
+ }) => {
67
+ return await axios.post(
68
+ `${Config.CHILDS_SERVER_ENV}/customers/${uid}/square/card/save`,
69
+ {
70
+ ...props,
71
+ }
72
+ );
73
+ };
74
+
75
+ export const connectSquareLoyalty = async (
76
+ uid: string,
77
+ props: ConnectSquareCustomerRequest
78
+ ) => {
79
+ return await axios.post(
80
+ `${Config.CHILDS_SERVER_ENV}/customers/${uid}/square/loyalty/connect`,
81
+ {
82
+ props,
83
+ }
84
+ );
85
+ };
86
+
87
+ export const connectSquareCustomer = async (
88
+ uid: string,
89
+ props: ConnectSquareCustomerRequest
90
+ ) => {
91
+ return await axios.post(
92
+ `${Config.CHILDS_SERVER_ENV}/customers/${uid}/square/customer/connect`,
93
+ {
94
+ props,
95
+ }
96
+ );
97
+ };
98
+
99
+ export const fetchSquareLoyalty = async (uid: string, businessId: string) => {
100
+ return await axios.post(
101
+ `${Config.CHILDS_SERVER_ENV}/customers/${uid}/square/loyalty/refresh`,
102
+ {
103
+ businessId,
104
+ }
105
+ );
106
+ };
107
+
108
+ export const fetchLoyaltyRewards = async (businessId: string) => {
109
+ return await axios.get(
110
+ `${Config.SQUARE_BASE_URL}/customers/loyalty/mainProgram/${businessId}`
111
+ );
112
+ };
@@ -16,6 +16,7 @@ import { checkIsRegisteredAPI, signUpAPI } from '../api/authentication';
16
16
  import Config from 'react-native-config';
17
17
  import { analytics } from '../../utils/analytics';
18
18
  import { analyticsKeys } from '../../constants/analyticsKeys';
19
+ import { createCustomer } from '../../api/customer';
19
20
 
20
21
  let confirmationResult: FirebaseAuthTypes.ConfirmationResult;
21
22
 
@@ -64,6 +65,9 @@ export const useAuthentication = () => {
64
65
  analytics.profile.set(analyticsKeys.registrationDate, now);
65
66
  analytics.profile.set(analyticsKeys.app, Config.APP_NAME);
66
67
  analytics.track(analyticsKeys.signupCompleted);
68
+
69
+ // Create new customer in customer collections
70
+ await createCustomer({ uid: auth().currentUser.uid });
67
71
  } catch (error: any) {
68
72
  console.log('error', error);
69
73
  // Sign out user if something goes wrong
@@ -4,6 +4,7 @@ import { DEFAULT_STALE_TIME, queryKeys } from '../../selectBusiness/queryKeys';
4
4
  import { useAuthentication } from '../providers/authentication';
5
5
  import { getCurrentTimestamp } from '../../utils';
6
6
  import { analytics } from '../../utils/analytics';
7
+ import { createCustomer } from '../../api/customer';
7
8
 
8
9
  export const useTermsOfService = () => {
9
10
  const queryClient = useQueryClient();
@@ -64,18 +65,14 @@ export const useTermsOfService = () => {
64
65
  const query = await firestore().doc(`customers/${user.uid}`);
65
66
  const customerSnapshot = await query.get();
66
67
 
67
- if (customerSnapshot.exists) {
68
- await query.update({
69
- updated: getCurrentTimestamp(),
70
- agreementsUpdated: new Date().toISOString(),
71
- });
72
- } else {
73
- await query.set({
74
- uid: user.uid,
75
- created: getCurrentTimestamp(),
76
- agreementsUpdated: new Date().toISOString(),
77
- });
68
+ if (!customerSnapshot.exists) {
69
+ await createCustomer({ uid: user!.uid });
78
70
  }
71
+ await query.update({
72
+ updated: getCurrentTimestamp(),
73
+ agreementsUpdated: new Date().toISOString(),
74
+ });
75
+
79
76
  analytics.track('term_of_service_accepted');
80
77
  await queryClient.invalidateQueries([
81
78
  user.uid,
@@ -31,6 +31,7 @@ export const AuthenticationProvider: FC<{ children: React.ReactNode }> = ({
31
31
  const [authentication, dispatch] = useReducer(authenticationReducer, {
32
32
  initializing: true,
33
33
  user: null,
34
+ isSignedIn: false,
34
35
  });
35
36
 
36
37
  const getToken = useCallback(async () => {
@@ -1,9 +1,28 @@
1
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
1
2
  import {
2
3
  type AuthenticationAction,
3
4
  AuthenticationActionType,
4
5
  type AuthenticationState,
5
6
  } from '../types/authentication.types';
6
7
 
8
+ const isSignedIn = (user: FirebaseAuthTypes.User) => {
9
+ if (user.isAnonymous) {
10
+ // User is anonymous; prompt login process.
11
+ return false;
12
+ } else if (user.email) {
13
+ // User has an email; verify if phone number is also provided to proceed.
14
+ if (user.phoneNumber) {
15
+ return true;
16
+ } else {
17
+ return false;
18
+ }
19
+ } else if (user.phoneNumber) {
20
+ // User lacks email but has a phone number; allow sign-in.
21
+ return true;
22
+ }
23
+ return false;
24
+ };
25
+
7
26
  export const authenticationReducer = (
8
27
  state: AuthenticationState,
9
28
  action: AuthenticationAction
@@ -14,6 +33,7 @@ export const authenticationReducer = (
14
33
  ...state,
15
34
  initializing: false,
16
35
  user: action.user,
36
+ isSignedIn: action.user ? isSignedIn(action.user) : false,
17
37
  };
18
38
  default:
19
39
  return state;
@@ -14,4 +14,5 @@ export type AuthenticationAction = {
14
14
  export interface AuthenticationState {
15
15
  user: User | null;
16
16
  initializing: boolean;
17
+ isSignedIn: boolean;
17
18
  }
@@ -0,0 +1,42 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { useCustomerQueries } from './useCustomer';
3
+ import { useAuthentication } from '../auth';
4
+
5
+ export const useCheckCustomer = () => {
6
+ const { user } = useAuthentication();
7
+ const isLoggedIn = user && !user.isAnonymous;
8
+ const {
9
+ useFetchCustomer,
10
+ useCreateCustomer,
11
+ useFetchSquareProgram,
12
+ useConnectSquareCustomer,
13
+ } = useCustomerQueries();
14
+ const { connectSquare } = useConnectSquareCustomer();
15
+
16
+ const { createCustomerHook } = useCreateCustomer();
17
+ const { data: customer } = useFetchCustomer();
18
+ const { refetch: fetchSquareProgram } = useFetchSquareProgram({
19
+ enabled: false,
20
+ refetchOnWindowFocus: false,
21
+ });
22
+
23
+ const checkIfprogramPresent = useCallback(() => {
24
+ fetchSquareProgram().then((res) => {
25
+ if (res.data === null) {
26
+ connectSquare();
27
+ }
28
+ });
29
+ }, [connectSquare, fetchSquareProgram]);
30
+
31
+ useEffect(() => {
32
+ if (isLoggedIn) {
33
+ if (customer?.customer === null) {
34
+ createCustomerHook();
35
+ } else if (customer?.uid) {
36
+ checkIfprogramPresent();
37
+ }
38
+ }
39
+ }, [customer, createCustomerHook, isLoggedIn, checkIfprogramPresent]);
40
+
41
+ return { customer };
42
+ };
@@ -0,0 +1,331 @@
1
+ import { useEffect } from 'react';
2
+ import { useAuthentication } from '../auth';
3
+ import { Alert } from '../components';
4
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
5
+ import firestore from '@react-native-firebase/firestore';
6
+ import uuid from 'react-native-uuid';
7
+
8
+ import {
9
+ connectSquareCustomer,
10
+ connectSquareLoyalty,
11
+ createCustomer,
12
+ fetchLoyaltyRewards,
13
+ fetchSquareLoyalty,
14
+ getCustomer,
15
+ saveCustomerAddress,
16
+ saveCustomerCard,
17
+ updateCustomerProfile,
18
+ } from '../api/customer';
19
+ import {
20
+ Address,
21
+ CustomerProfileProps,
22
+ SaveCardRequest,
23
+ } from '../types/customer';
24
+ import { useMMKVString } from 'react-native-mmkv';
25
+ import { MMKV_KEYS } from '../constants';
26
+ import { queryKeys } from '../selectBusiness/queryKeys';
27
+
28
+ export const useCustomerQueries = () => {
29
+ const queryClient = useQueryClient();
30
+ const { user } = useAuthentication();
31
+ const [selectedBusinessId] = useMMKVString(MMKV_KEYS.BUSINESS_ID);
32
+ const isLoggedIn = user && !user.isAnonymous;
33
+
34
+ useEffect(() => {
35
+ if (!isLoggedIn) {
36
+ queryClient.invalidateQueries([queryKeys.LOYALTY, user?.uid]);
37
+ }
38
+ }, [isLoggedIn, queryClient, user?.uid]);
39
+
40
+ return {
41
+ useFetchCustomer: () =>
42
+ useQuery(
43
+ [queryKeys.CUSTOMER, user?.uid],
44
+ async () => {
45
+ if (isLoggedIn) {
46
+ return await getCustomer(user!.uid);
47
+ } else {
48
+ return null;
49
+ }
50
+ },
51
+ {
52
+ select: (data) => data?.data?.customer,
53
+ }
54
+ ),
55
+ useCreateCustomer: () => {
56
+ const mutation = useMutation(
57
+ async () => {
58
+ if (isLoggedIn) {
59
+ const response = await createCustomer({ uid: user!.uid });
60
+ if (response?.data?.customer) {
61
+ await queryClient.invalidateQueries([
62
+ queryKeys.CUSTOMER,
63
+ user?.uid,
64
+ ]);
65
+ }
66
+ }
67
+ },
68
+ {
69
+ onError: (err: { code: string; message: string }) =>
70
+ Alert.show({
71
+ title: 'Code ' + err?.code,
72
+ description: err?.message,
73
+ }),
74
+ }
75
+ );
76
+
77
+ return {
78
+ createCustomerHook: mutation.mutateAsync,
79
+ createCustomerLoading: mutation.isLoading,
80
+ };
81
+ },
82
+ useUpdateCustomer: () => {
83
+ const mutation = useMutation(
84
+ async (props: CustomerProfileProps) => {
85
+ if (isLoggedIn) {
86
+ const response = await updateCustomerProfile({
87
+ uid: user.uid,
88
+ props,
89
+ });
90
+
91
+ if (response?.data?.customer) {
92
+ queryClient.invalidateQueries([queryKeys.CUSTOMER, user?.uid]);
93
+ }
94
+ }
95
+ },
96
+ {
97
+ onError: (err: { code: string; message: string }) =>
98
+ Alert.show({
99
+ title: 'Code ' + err?.code,
100
+ description: err?.message,
101
+ }),
102
+ }
103
+ );
104
+
105
+ return {
106
+ updateCustomer: mutation.mutate,
107
+ updateCustomerLoading: mutation.isLoading,
108
+ };
109
+ },
110
+ useSaveCustomerAddress: () => {
111
+ const mutation = useMutation(
112
+ async (address: Address) => {
113
+ if (isLoggedIn) {
114
+ const response = await saveCustomerAddress({
115
+ uid: user.uid,
116
+ address,
117
+ });
118
+
119
+ if (response?.data?.customer) {
120
+ queryClient.invalidateQueries([queryKeys.CUSTOMER, user?.uid]);
121
+ }
122
+ }
123
+ },
124
+ {
125
+ onError: (err: { code: string; message: string }) =>
126
+ Alert.show({
127
+ title: 'Code ' + err?.code,
128
+ description: err?.message,
129
+ }),
130
+ }
131
+ );
132
+
133
+ return {
134
+ useSaveAddress: mutation.mutate,
135
+ saveAddressLoading: mutation.isLoading,
136
+ };
137
+ },
138
+ useFetchSavedCards: () =>
139
+ useQuery(
140
+ [queryKeys.CARDS, user?.uid],
141
+ async () => {
142
+ if (isLoggedIn) {
143
+ const payments = await firestore()
144
+ .collection(`customers/${user?.uid}/payments`)
145
+ .orderBy('updated', 'desc')
146
+ .where('isActive', '==', true)
147
+ .get();
148
+ if (payments.docs.length > 0) {
149
+ return payments.docs.map((payment: any) => {
150
+ return { ...payment.data(), id: payment.id };
151
+ });
152
+ } else {
153
+ return [];
154
+ }
155
+ } else {
156
+ return [];
157
+ }
158
+ },
159
+ {
160
+ enabled: Boolean(isLoggedIn),
161
+ }
162
+ ),
163
+ useFetchSquareProgram: (queryOptions?: object) =>
164
+ useQuery(
165
+ [queryKeys.PROGRAM, user?.uid, selectedBusinessId],
166
+ async () => {
167
+ if (isLoggedIn) {
168
+ const programs = await firestore()
169
+ .collection(`customers/${user?.uid}/programs`)
170
+ .where('type', '==', 'customer')
171
+ .where('businessId', '==', selectedBusinessId)
172
+ .orderBy('updated', 'asc')
173
+ .get();
174
+ if (programs.docs.length > 0) {
175
+ return programs.docs.map((program: any) => program.data())[0];
176
+ } else {
177
+ return null;
178
+ }
179
+ } else {
180
+ return null;
181
+ }
182
+ },
183
+ {
184
+ ...queryOptions,
185
+ }
186
+ ),
187
+ useFetchSquareLoyalty: (queryOptions?: object) =>
188
+ useQuery(
189
+ [queryKeys.LOYALTY, user?.uid, selectedBusinessId],
190
+ async () => {
191
+ if (isLoggedIn && selectedBusinessId) {
192
+ return await fetchSquareLoyalty(user.uid, selectedBusinessId);
193
+ } else {
194
+ return { data: null };
195
+ }
196
+ },
197
+ {
198
+ select: (res) => res?.data,
199
+ ...queryOptions,
200
+ }
201
+ ),
202
+ useSaveCustomerCard: () => {
203
+ const mutation = useMutation(
204
+ async (data: SaveCardRequest) => {
205
+ if (isLoggedIn) {
206
+ console.log('here in useSaveCustomerCard');
207
+ const response = await saveCustomerCard({
208
+ uid: user?.uid,
209
+ props: data,
210
+ });
211
+ console.log('here in useSaveCustomerCard response', response.data);
212
+ }
213
+ },
214
+ {
215
+ onError: (err: { code: string; message: string }) =>
216
+ Alert.show({
217
+ title: 'Code ' + err?.code,
218
+ description: err?.message,
219
+ }),
220
+ onSuccess: () => {
221
+ queryClient.invalidateQueries([queryKeys.CARDS, user?.uid]);
222
+ },
223
+ }
224
+ );
225
+
226
+ return {
227
+ saveCard: mutation.mutate,
228
+ saveCardLoading: mutation.isLoading,
229
+ };
230
+ },
231
+ useDisableCard: () => {
232
+ const mutation = useMutation(
233
+ async (documentId: string) => {
234
+ if (isLoggedIn) {
235
+ return await firestore()
236
+ .collection(`customers/${user?.uid}/payments`)
237
+ .doc(documentId)
238
+ .update({
239
+ isActive: false,
240
+ });
241
+ }
242
+ },
243
+ {
244
+ onError: (err: { code: string; message: string }) =>
245
+ Alert.show({
246
+ title: 'Code ' + err?.code,
247
+ description: err?.message,
248
+ }),
249
+ onSuccess: () => {
250
+ queryClient.invalidateQueries([queryKeys.CARDS, user?.uid]);
251
+ },
252
+ }
253
+ );
254
+
255
+ return {
256
+ disableCard: mutation.mutate,
257
+ disableCardLoading: mutation.isLoading,
258
+ };
259
+ },
260
+ useConnectSquareLoyalty: () => {
261
+ const mutation = useMutation(
262
+ async () => {
263
+ if (isLoggedIn && selectedBusinessId) {
264
+ await connectSquareLoyalty(user?.uid, {
265
+ businessId: selectedBusinessId,
266
+ idempotentKey: uuid.v4() as string,
267
+ uid: user?.uid,
268
+ });
269
+ }
270
+ },
271
+ {
272
+ onError: (err: { code: string; message: string }) =>
273
+ Alert.show({
274
+ title: 'Code ' + err?.code,
275
+ description: err?.message,
276
+ }),
277
+ onSuccess: () => {
278
+ queryClient.invalidateQueries([queryKeys.LOYALTY, user?.uid]);
279
+ },
280
+ }
281
+ );
282
+
283
+ return {
284
+ connectSquareLoyalty: mutation.mutate,
285
+ connectLoyaltyLoading: mutation.isLoading,
286
+ };
287
+ },
288
+ useConnectSquareCustomer: () => {
289
+ const mutation = useMutation(
290
+ async () => {
291
+ if (isLoggedIn && selectedBusinessId) {
292
+ await connectSquareCustomer(user?.uid, {
293
+ businessId: selectedBusinessId,
294
+ idempotentKey: uuid.v4() as string,
295
+ uid: user?.uid,
296
+ });
297
+ }
298
+ },
299
+ {
300
+ onError: (err: { code: string; message: string }) =>
301
+ Alert.show({
302
+ title: 'Code ' + err?.code,
303
+ description: err?.message,
304
+ }),
305
+ onSuccess: () => {
306
+ queryClient.invalidateQueries([queryKeys.PROGRAM, user?.uid]);
307
+ },
308
+ }
309
+ );
310
+
311
+ return {
312
+ connectSquare: mutation.mutate,
313
+ connectSquareLoading: mutation.isLoading,
314
+ };
315
+ },
316
+ useFetchLoyaltyRewards: () =>
317
+ useQuery(
318
+ [queryKeys.REWARDS, selectedBusinessId],
319
+ async () => {
320
+ if (selectedBusinessId)
321
+ return await fetchLoyaltyRewards(selectedBusinessId);
322
+ else {
323
+ return {} as any;
324
+ }
325
+ },
326
+ {
327
+ select: (data) => data?.data,
328
+ }
329
+ ),
330
+ };
331
+ };
package/src/index.tsx CHANGED
@@ -1,3 +1,9 @@
1
+ export { Currency } from './utils/currency';
2
+
3
+ export { useCustomerQueries } from './hooks/useCustomer';
4
+ export { useCheckCustomer } from './hooks/useCheckCustomer';
5
+ export { SavedCards } from './screens/SavedCards/SavedCards';
6
+
1
7
  export {
2
8
  useMultiSnapBottomSheetRef,
3
9
  TMultiSnapBottomSheetRef,
@@ -0,0 +1,94 @@
1
+ import React from 'react';
2
+ import { Alert, Card, IconButton, Text, View } from '../../components';
3
+ import { RadioButton, useTheme } from 'react-native-paper';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { getCardName } from '../../utils/checkout';
6
+ import { CustomerCardPayment } from '../../types/customer';
7
+
8
+ export const CardRow = ({
9
+ card,
10
+ onDelete,
11
+ onSelect,
12
+ isSelectable,
13
+ isSelected,
14
+ isDisabled,
15
+ }: {
16
+ card: CustomerCardPayment;
17
+ onDelete: (id: string) => void;
18
+ onSelect: (linkedObjectId: string) => void;
19
+ isSelectable: boolean;
20
+ isSelected: boolean;
21
+ isDisabled: boolean;
22
+ }) => {
23
+ const name = getCardName(card);
24
+ const { t } = useTranslation();
25
+ const theme = useTheme();
26
+
27
+ const onDeleteCard = () => {
28
+ Alert.show({
29
+ title: t('checkout.confirmCardDelete'),
30
+ description: t('checkout.cardDeleteDesc', {
31
+ card: card.cardDetails.last4,
32
+ }),
33
+ buttons: [
34
+ {
35
+ label: t('delete'),
36
+ textColor: theme.colors.error,
37
+ onPress: () => onDelete(card.id),
38
+ },
39
+ {
40
+ label: t('cancel'),
41
+ textColor: theme.colors.onSurface,
42
+ },
43
+ ],
44
+ });
45
+ };
46
+
47
+ return (
48
+ <Card
49
+ disabled={isDisabled}
50
+ mode="outlined"
51
+ borderRadius="4"
52
+ mb="8"
53
+ {...(isSelectable
54
+ ? {
55
+ onPress: () => {
56
+ onSelect(card.linkedObjectId);
57
+ },
58
+ }
59
+ : {})}
60
+ >
61
+ <View
62
+ flexDirection="row"
63
+ px="8"
64
+ alignItems="center"
65
+ justifyContent="space-between"
66
+ >
67
+ {isSelectable && (
68
+ <RadioButton.Android
69
+ value={card.linkedObjectId}
70
+ status={isSelected ? 'checked' : 'unchecked'}
71
+ onPress={() => {
72
+ onSelect(card.linkedObjectId);
73
+ }}
74
+ />
75
+ )}
76
+ <View
77
+ paddingStart="8"
78
+ flexDirection="row"
79
+ flex={1}
80
+ alignItems="center"
81
+ justifyContent="space-between"
82
+ >
83
+ <Text variant="bodyMedium">{name}</Text>
84
+ <IconButton
85
+ disabled={isDisabled}
86
+ icon="trash-can-outline"
87
+ bg="background"
88
+ onPress={onDeleteCard}
89
+ />
90
+ </View>
91
+ </View>
92
+ </Card>
93
+ );
94
+ };