@kiosinc/commons-rn 0.1.61 → 0.1.62

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 (88) 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/hooks/useCheckCustomer.js +57 -0
  8. package/lib/commonjs/hooks/useCheckCustomer.js.map +1 -0
  9. package/lib/commonjs/hooks/useCustomer.js +251 -0
  10. package/lib/commonjs/hooks/useCustomer.js.map +1 -0
  11. package/lib/commonjs/index.js +32 -0
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/commonjs/screens/SavedCards/CardRow.js +79 -0
  14. package/lib/commonjs/screens/SavedCards/CardRow.js.map +1 -0
  15. package/lib/commonjs/screens/SavedCards/SavedCards.js +180 -0
  16. package/lib/commonjs/screens/SavedCards/SavedCards.js.map +1 -0
  17. package/lib/commonjs/selectBusiness/queryKeys.js +6 -1
  18. package/lib/commonjs/selectBusiness/queryKeys.js.map +1 -1
  19. package/lib/commonjs/types/customer.d.js +7 -0
  20. package/lib/commonjs/types/customer.d.js.map +1 -0
  21. package/lib/commonjs/utils/checkout.js +11 -0
  22. package/lib/commonjs/utils/checkout.js.map +1 -0
  23. package/lib/commonjs/utils/currency.js +17 -0
  24. package/lib/commonjs/utils/currency.js.map +1 -0
  25. package/lib/commonjs/utils/square.js +39 -0
  26. package/lib/commonjs/utils/square.js.map +1 -0
  27. package/lib/module/api/customer.js +59 -0
  28. package/lib/module/api/customer.js.map +1 -0
  29. package/lib/module/auth/hooks/useAuthentication.js +6 -0
  30. package/lib/module/auth/hooks/useAuthentication.js.map +1 -1
  31. package/lib/module/auth/hooks/useTermsOfService.js +8 -10
  32. package/lib/module/auth/hooks/useTermsOfService.js.map +1 -1
  33. package/lib/module/hooks/useCheckCustomer.js +50 -0
  34. package/lib/module/hooks/useCheckCustomer.js.map +1 -0
  35. package/lib/module/hooks/useCustomer.js +243 -0
  36. package/lib/module/hooks/useCustomer.js.map +1 -0
  37. package/lib/module/index.js +4 -0
  38. package/lib/module/index.js.map +1 -1
  39. package/lib/module/screens/SavedCards/CardRow.js +71 -0
  40. package/lib/module/screens/SavedCards/CardRow.js.map +1 -0
  41. package/lib/module/screens/SavedCards/SavedCards.js +170 -0
  42. package/lib/module/screens/SavedCards/SavedCards.js.map +1 -0
  43. package/lib/module/selectBusiness/queryKeys.js +6 -1
  44. package/lib/module/selectBusiness/queryKeys.js.map +1 -1
  45. package/lib/module/types/customer.d.js +5 -0
  46. package/lib/module/types/customer.d.js.map +1 -0
  47. package/lib/module/utils/checkout.js +4 -0
  48. package/lib/module/utils/checkout.js.map +1 -0
  49. package/lib/module/utils/currency.js +10 -0
  50. package/lib/module/utils/currency.js.map +1 -0
  51. package/lib/module/utils/square.js +36 -0
  52. package/lib/module/utils/square.js.map +1 -0
  53. package/lib/typescript/src/api/customer.d.ts +23 -0
  54. package/lib/typescript/src/api/customer.d.ts.map +1 -0
  55. package/lib/typescript/src/auth/hooks/useAuthentication.d.ts.map +1 -1
  56. package/lib/typescript/src/auth/hooks/useTermsOfService.d.ts.map +1 -1
  57. package/lib/typescript/src/hooks/useCheckCustomer.d.ts +4 -0
  58. package/lib/typescript/src/hooks/useCheckCustomer.d.ts.map +1 -0
  59. package/lib/typescript/src/hooks/useCustomer.d.ts +58 -0
  60. package/lib/typescript/src/hooks/useCustomer.d.ts.map +1 -0
  61. package/lib/typescript/src/index.d.ts +4 -0
  62. package/lib/typescript/src/index.d.ts.map +1 -1
  63. package/lib/typescript/src/screens/SavedCards/CardRow.d.ts +11 -0
  64. package/lib/typescript/src/screens/SavedCards/CardRow.d.ts.map +1 -0
  65. package/lib/typescript/src/screens/SavedCards/SavedCards.d.ts +7 -0
  66. package/lib/typescript/src/screens/SavedCards/SavedCards.d.ts.map +1 -0
  67. package/lib/typescript/src/selectBusiness/queryKeys.d.ts +5 -0
  68. package/lib/typescript/src/selectBusiness/queryKeys.d.ts.map +1 -1
  69. package/lib/typescript/src/utils/checkout.d.ts +3 -0
  70. package/lib/typescript/src/utils/checkout.d.ts.map +1 -0
  71. package/lib/typescript/src/utils/currency.d.ts +5 -0
  72. package/lib/typescript/src/utils/currency.d.ts.map +1 -0
  73. package/lib/typescript/src/utils/square.d.ts +6 -0
  74. package/lib/typescript/src/utils/square.d.ts.map +1 -0
  75. package/package.json +3 -1
  76. package/src/api/customer.ts +112 -0
  77. package/src/auth/hooks/useAuthentication.ts +4 -0
  78. package/src/auth/hooks/useTermsOfService.ts +8 -11
  79. package/src/hooks/useCheckCustomer.ts +42 -0
  80. package/src/hooks/useCustomer.ts +331 -0
  81. package/src/index.tsx +6 -0
  82. package/src/screens/SavedCards/CardRow.tsx +94 -0
  83. package/src/screens/SavedCards/SavedCards.tsx +197 -0
  84. package/src/selectBusiness/queryKeys.ts +5 -0
  85. package/src/types/customer.d.ts +70 -0
  86. package/src/utils/checkout.ts +5 -0
  87. package/src/utils/currency.ts +10 -0
  88. package/src/utils/square.ts +50 -0
@@ -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
+ };
@@ -0,0 +1,197 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import {
3
+ Alert,
4
+ Button,
5
+ LineLoader,
6
+ RefreshControl,
7
+ Text,
8
+ View,
9
+ } from '../../components';
10
+ import { ActivityIndicator, useTheme } from 'react-native-paper';
11
+ import uuid from 'react-native-uuid';
12
+ import { useTranslation } from 'react-i18next';
13
+ import { FlatList } from 'react-native';
14
+ import { onStartCardEntry } from '../../utils/square';
15
+ import { useCustomerQueries } from '../../hooks/useCustomer';
16
+ import { useCheckCustomer } from '../../hooks/useCheckCustomer';
17
+ import { CardRow } from './CardRow';
18
+ import { CustomerCardPayment } from '../../types/customer';
19
+
20
+ export const SavedCards = ({
21
+ onCheckout,
22
+ total,
23
+ }: {
24
+ onCheckout?: (selectedCard: CustomerCardPayment) => void;
25
+ total?: string;
26
+ }) => {
27
+ const { t } = useTranslation();
28
+ const theme = useTheme();
29
+ const { customer } = useCheckCustomer();
30
+ const {
31
+ useSaveCustomerCard,
32
+ useFetchSavedCards,
33
+ useDisableCard,
34
+ useUpdateCustomer,
35
+ } = useCustomerQueries();
36
+ const { saveCard, saveCardLoading } = useSaveCustomerCard();
37
+ const { disableCard, disableCardLoading } = useDisableCard();
38
+ const [selectedPaymentId, onSelectPaymentId] = useState('');
39
+ const { updateCustomer, updateCustomerLoading } = useUpdateCustomer();
40
+
41
+ useEffect(() => {
42
+ if (customer?.paymentId) {
43
+ onSelectPaymentId(customer.paymentId);
44
+ }
45
+ }, [customer?.paymentId, onSelectPaymentId]);
46
+
47
+ const {
48
+ data: cards = [],
49
+ isFetching,
50
+ isLoading,
51
+ refetch,
52
+ } = useFetchSavedCards();
53
+
54
+ const onAddPress = () => {
55
+ onStartCardEntry(
56
+ (cardDetails) => {
57
+ saveCard({
58
+ sourceId: cardDetails.nonce,
59
+ idempotentKey: uuid.v4() as string,
60
+ });
61
+ },
62
+ () => {}
63
+ );
64
+ };
65
+
66
+ const label =
67
+ cards.length > 0 ? t('checkout.payAndPlaceOrder') : t('checkout.payByCard');
68
+
69
+ if (isLoading) {
70
+ return <ActivityIndicator />;
71
+ }
72
+
73
+ const onUseCard = () => {
74
+ if (cards.length === 0) {
75
+ // If no cards then initiate add card flow.
76
+ onStartCardEntry(
77
+ (cardDetails) => {
78
+ saveCard({
79
+ sourceId: cardDetails.nonce,
80
+ idempotentKey: uuid.v4() as string,
81
+ });
82
+ },
83
+ () => {}
84
+ );
85
+ } else if (!customer.paymentId) {
86
+ Alert.show({ title: 'Select a card' });
87
+ } else {
88
+ // Make payment
89
+ const selectedCard = cards.find(
90
+ (card: any) => card.linkedObjectId === customer.paymentId
91
+ );
92
+ if (selectedCard) {
93
+ onCheckout?.(selectedCard);
94
+ } else {
95
+ Alert.show({ title: 'Select a card' });
96
+ }
97
+ }
98
+ };
99
+
100
+ return (
101
+ <View flex={1}>
102
+ <View px="16" bg="background" flex={1}>
103
+ <LineLoader
104
+ isLoading={isFetching || disableCardLoading || updateCustomerLoading}
105
+ />
106
+ <FlatList
107
+ extraData={{ selectedPaymentId, disableCardLoading }}
108
+ refreshControl={
109
+ <RefreshControl refreshing={false} onRefresh={refetch} />
110
+ }
111
+ data={cards}
112
+ showsVerticalScrollIndicator={false}
113
+ renderItem={({ item: card, index }) => (
114
+ <CardRow
115
+ isDisabled={disableCardLoading}
116
+ isSelected={selectedPaymentId === card.linkedObjectId}
117
+ isSelectable={!!onCheckout}
118
+ key={index}
119
+ card={card}
120
+ onDelete={(id: string) => {
121
+ disableCard(id);
122
+ }}
123
+ onSelect={(linkedObjectId: string) => {
124
+ onSelectPaymentId(linkedObjectId);
125
+ updateCustomer({
126
+ paymentId: linkedObjectId,
127
+ addressId: customer.addressId,
128
+ squareCustomerId: customer.squareCustomerId,
129
+ });
130
+ }}
131
+ />
132
+ )}
133
+ ListHeaderComponent={
134
+ <>
135
+ {cards.length > 0 ? (
136
+ <Text mb="8" variant="titleMedium">
137
+ {t('checkout.paymentMethods')}
138
+ </Text>
139
+ ) : (
140
+ <Text variant="bodyLarge" color="outline">
141
+ {t('checkout.noSavedCards')}
142
+ </Text>
143
+ )}
144
+ </>
145
+ }
146
+ ListFooterComponent={
147
+ <View alignItems="flex-start">
148
+ <Button
149
+ pt={'16'}
150
+ loading={saveCardLoading}
151
+ onPress={onAddPress}
152
+ icon="plus"
153
+ mode="text"
154
+ >
155
+ {t('checkout.addCard')}
156
+ </Button>
157
+ </View>
158
+ }
159
+ />
160
+ </View>
161
+ {!!onCheckout && (
162
+ <View
163
+ bg="secondaryContainer"
164
+ height={84}
165
+ padding="16"
166
+ justifyContent="space-between"
167
+ flexDirection="row"
168
+ width="100%"
169
+ >
170
+ <View>
171
+ <Text variant="bodyLarge" color="onSurface">
172
+ {t('order.total')}
173
+ </Text>
174
+ <Text variant="titleLarge" color="onSurface">
175
+ {total}
176
+ </Text>
177
+ </View>
178
+ <Button
179
+ mode="contained"
180
+ height={40}
181
+ width={'auto'}
182
+ alignSelf="center"
183
+ bg="primary"
184
+ labelStyle={[
185
+ {
186
+ color: theme.colors.background,
187
+ },
188
+ ]}
189
+ onPress={onUseCard}
190
+ >
191
+ {label}
192
+ </Button>
193
+ </View>
194
+ )}
195
+ </View>
196
+ );
197
+ };
@@ -2,6 +2,11 @@ export const queryKeys = {
2
2
  BUSINESSES: 'BUSINESSES',
3
3
  TERMS_AND_CONDITIONS: 'TERMS_AND_CONDITIONS',
4
4
  TERMS_AND_CONDITIONS_URL: 'TERMS_AND_CONDITIONS_URL',
5
+ CARDS: 'CARDS',
6
+ CUSTOMER: 'CUSTOMER',
7
+ PROGRAM: 'PROGRAM',
8
+ LOYALTY: 'LOYALTY',
9
+ REWARDS: 'REWARDS',
5
10
  };
6
11
 
7
12
  export const DEFAULT_STALE_TIME = 60 * (60 * 1000); // 60 mins
@@ -0,0 +1,70 @@
1
+ export interface SaveCardRequest {
2
+ sourceId: string;
3
+ verificationToken?: string;
4
+ idempotentKey: string;
5
+ }
6
+
7
+ export interface ConnectSquareCustomerRequest {
8
+ uid: string;
9
+ businessId: string;
10
+ idempotentKey: string;
11
+ }
12
+
13
+ export interface Address {
14
+ addressLine1: string;
15
+ addressLine2: string;
16
+ // city: string;
17
+ // state: string;
18
+ // zip: string;
19
+ // country: string;
20
+ }
21
+
22
+ export interface CreateCustomerProfileProps {
23
+ address: Address | null;
24
+ }
25
+ export interface CustomerProfileProps {
26
+ addressId: string | null;
27
+ paymentId: string | null;
28
+ squareCustomerId: string | null;
29
+ }
30
+
31
+ export interface UpdateSquareLoyaltyCustomerRequest {
32
+ uid: string;
33
+ businessId: string;
34
+ }
35
+
36
+ interface DocumentProps {
37
+ created: string;
38
+ updated: string;
39
+ }
40
+
41
+ enum PaymentType {
42
+ card = 'card',
43
+ }
44
+ export interface CardDetailsProps {
45
+ bin: string;
46
+ cardBrand: string;
47
+ cardType: string;
48
+ enabled: boolean;
49
+ expMonth: number;
50
+ expYear: number;
51
+ fingerprint: string;
52
+ last4: string;
53
+ merchantId: string;
54
+ prepaidType: string;
55
+ version: number;
56
+ }
57
+
58
+ export interface CustomerPaymentProps {
59
+ type: PaymentType;
60
+ linkedObjectId: string;
61
+ provider: string;
62
+ }
63
+
64
+ export interface CustomerCardPayment
65
+ extends CustomerPaymentProps,
66
+ DocumentProps {
67
+ uid: string;
68
+ cardDetails: CardDetailsProps;
69
+ id: string;
70
+ }