create-gufran-expo-app 2.0.4 → 2.0.5

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 (41) hide show
  1. package/package.json +3 -3
  2. package/template/src/navigation/AuthStack.tsx +6 -25
  3. package/template/src/navigation/MainStack.tsx +0 -148
  4. package/template/src/navigation/RootNavigator.tsx +4 -26
  5. package/template/src/navigation/index.ts +0 -1
  6. package/template/src/navigation/navigationRef.ts +1 -1
  7. package/template/src/screens/HomeScreen.tsx +3 -215
  8. package/template/src/screens/auth/LoginScreen.tsx +13 -13
  9. package/template/src/screens/auth/index.ts +1 -6
  10. package/template/src/screens/index.ts +0 -35
  11. package/template/src/services/api.ts +5 -5
  12. package/template/src/services/authService.ts +3 -299
  13. package/template/src/services/mainServices.ts +19 -1914
  14. package/template/src/types/navigation.ts +5 -155
  15. package/template/src/utils/index.ts +5 -8
  16. package/template/src/navigation/MiddleStack.tsx +0 -35
  17. package/template/src/screens/auth/AddMamber.tsx +0 -428
  18. package/template/src/screens/auth/ForgotPasswordScreen.tsx +0 -176
  19. package/template/src/screens/auth/OTPVerifyScreen.tsx +0 -359
  20. package/template/src/screens/auth/RegisterScreen.tsx +0 -430
  21. package/template/src/screens/auth/SuccessScreen.tsx +0 -201
  22. package/template/src/screens/chat/ChatScreen.tsx +0 -1819
  23. package/template/src/screens/chat/ChatThreadsScreen.tsx +0 -360
  24. package/template/src/screens/chat/ReportMessageScreen.tsx +0 -238
  25. package/template/src/screens/clubs/Announcements.tsx +0 -426
  26. package/template/src/screens/clubs/BuyRaffleTicketsScreen.tsx +0 -568
  27. package/template/src/screens/clubs/ClubDeteils.tsx +0 -497
  28. package/template/src/screens/clubs/JoinClub.tsx +0 -841
  29. package/template/src/screens/events/EventScreen.tsx +0 -460
  30. package/template/src/screens/raffles/MyReferralMembersScreen.tsx +0 -758
  31. package/template/src/screens/raffles/RaffleDetailsScreen.tsx +0 -762
  32. package/template/src/screens/raffles/RafflesScreen.tsx +0 -495
  33. package/template/src/screens/raffles/SetRaffleReminderScreen.tsx +0 -390
  34. package/template/src/screens/teams/JoinTeamScreen.tsx +0 -464
  35. package/template/src/screens/teams/MyTeamDetailsScreen.tsx +0 -979
  36. package/template/src/screens/teams/MyTeamScreen.tsx +0 -568
  37. package/template/src/screens/teams/PendingRequestsScreen.tsx +0 -426
  38. package/template/src/screens/volunteerOpportunities/SetReminderScreen.tsx +0 -631
  39. package/template/src/screens/volunteerOpportunities/VolunteerOpportunitiesDetailsScreen.tsx +0 -1049
  40. package/template/src/screens/volunteerOpportunities/VolunteerOpportunitiesScreen.tsx +0 -608
  41. package/template/src/utils/ClubSearchManager.ts +0 -222
@@ -1,758 +0,0 @@
1
- import React, { useMemo, useCallback, useState, useRef } from 'react';
2
- import {
3
- View,
4
- Text,
5
- StyleSheet,
6
- StatusBar,
7
- Platform,
8
- TouchableOpacity,
9
- Image,
10
- FlatList,
11
- ListRenderItem,
12
- Share,
13
- ActivityIndicator,
14
- RefreshControl,
15
- Modal,
16
- Animated,
17
- Dimensions,
18
- PanResponder,
19
- } from 'react-native';
20
- import { MyReferralMembersScreenProps } from '@navigation';
21
- import { theme } from '@constants';
22
- import { moderateScale } from '@utils/scaling';
23
- import { Fonts } from '@constants/Fonts';
24
- import SVG from '@assets/icons';
25
- import { SafeAreaView } from 'react-native-safe-area-context';
26
- import { Button } from '@components/common';
27
- import { useInfiniteReferrerMemberSales, ReferrerMember, mainService } from '@services/mainServices';
28
-
29
-
30
- export const MyReferralMembersScreen: React.FC<MyReferralMembersScreenProps> = ({ navigation, route }) => {
31
- const { selectedClub, selectedMember: initialSelectedMember, raffleId, raffleTitle } = route?.params ?? {};
32
-
33
- const memberId = initialSelectedMember?.id;
34
- const pageSize = 10;
35
-
36
- // Fetch referral members with pagination
37
- const {
38
- data,
39
- isLoading,
40
- isError,
41
- error,
42
- fetchNextPage,
43
- hasNextPage,
44
- isFetchingNextPage,
45
- refetch,
46
- isRefetching,
47
- } = useInfiniteReferrerMemberSales(raffleId, memberId, pageSize);
48
-
49
- // Modal state
50
- const [ticketModalVisible, setTicketModalVisible] = useState(false);
51
- const [ticketDetailsLoading, setTicketDetailsLoading] = useState(false);
52
- const [ticketNumbers, setTicketNumbers] = useState<any>([]);
53
- const translateY = useRef(new Animated.Value(0)).current;
54
- const screenHeight = Dimensions.get('window').height;
55
- const bottomSheetHeight = screenHeight * 0.5; // 50% of screen height
56
-
57
-
58
- // Flatten paginated data
59
- const referralMembers = useMemo(() => {
60
- if (!data?.pages) return [];
61
-
62
- return data.pages.flatMap((page) => {
63
- // Access the correct nested structure: data.data.data.salesList
64
- const responseData = page?.data?.data;
65
-
66
- if (responseData && typeof responseData === 'object') {
67
- // Check for nested data.data.salesList structure
68
- if ('data' in responseData && responseData.data && typeof responseData.data === 'object') {
69
- const nestedData = responseData.data as any;
70
- if ('salesList' in nestedData && Array.isArray(nestedData.salesList)) {
71
- return nestedData.salesList;
72
- }
73
- }
74
- // Direct salesList
75
- if ('salesList' in responseData && Array.isArray(responseData.salesList)) {
76
- return responseData.salesList;
77
- }
78
- // Fallback to other possible structures
79
- if ('members' in responseData && Array.isArray(responseData.members)) {
80
- return responseData.members;
81
- } else if ('referralMembers' in responseData && Array.isArray(responseData.referralMembers)) {
82
- return responseData.referralMembers;
83
- } else if (Array.isArray(responseData)) {
84
- return responseData;
85
- }
86
- } else if (Array.isArray(page?.data?.data)) {
87
- return page.data.data;
88
- }
89
-
90
- return [];
91
- });
92
- }, [data]);
93
-
94
- // Calculate total sales from API response
95
- const totalSales = useMemo(() => {
96
- if (!data?.pages?.[0]) return 0;
97
-
98
- const firstPage = data.pages[0];
99
- const responseData = firstPage?.data?.data;
100
-
101
- // Try to get totalPurchasedTicketCount from nested data structure
102
- if (responseData && typeof responseData === 'object') {
103
- if ('data' in responseData && responseData.data && typeof responseData.data === 'object') {
104
- const nestedData = responseData.data as any;
105
- if (typeof nestedData.totalPurchasedTicketCount === 'number') {
106
- return nestedData.totalPurchasedTicketCount;
107
- }
108
- }
109
- // Try direct totalPurchasedTicketCount
110
- if ('totalPurchasedTicketCount' in responseData && typeof responseData.totalPurchasedTicketCount === 'number') {
111
- return responseData.totalPurchasedTicketCount;
112
- }
113
- }
114
-
115
- // Fallback: calculate from member data
116
- return referralMembers.reduce((sum, member) => {
117
- const tickets = member.purchasedTicketCount ?? member.ticketCount ?? member.ticketsSold ?? member.totalTickets ?? 0;
118
- return sum + tickets;
119
- }, 0);
120
- }, [data, referralMembers]);
121
-
122
- const handleReferToFriends = async () => {
123
- try {
124
- const response = await mainService.getReferralCode({
125
- raffleId: raffleId || 0,
126
- memberId: memberId || 0,
127
- });
128
-
129
- const responseData = response?.data?.data;
130
- const referralCode = responseData?.referralCode || '';
131
- const clubCode = responseData?.clubCode || '';
132
- const clubName = responseData?.clubName || 'ClubYakka';
133
-
134
- const appLink = '(App Link)';
135
- const shareMessage =
136
- `Join the *${raffleTitle}* raffle on ClubYakka app!
137
-
138
- Use my referral code: *${referralCode}* when buying tickets
139
-
140
- Steps to buy:
141
- 1. Ensure you have ${clubName} club already joined or if not, find it with club code: #${clubCode} to join it
142
- 2. Continue as desired member in Club Dashboard
143
- 3. Click Raffle section and find raffle: *${raffleTitle}*
144
- 4. When buying raffle tickets, apply my code: *${referralCode}*
145
- 5. Purchase raffle tickets and WIN!
146
-
147
- Click the link to open the app ${appLink}`;
148
-
149
- Share.share({
150
- message: shareMessage,
151
- title: `${clubName} Raffle on ClubYakka`
152
- });
153
- } catch (error) {
154
- console.error('Failed to get referral code:', error);
155
- }
156
- };
157
-
158
- // Handle load more for pagination
159
- const handleLoadMore = useCallback(() => {
160
- if (hasNextPage && !isFetchingNextPage) {
161
- fetchNextPage();
162
- }
163
- }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
164
-
165
- // Handle pull to refresh
166
- const handleRefresh = useCallback(() => {
167
- refetch();
168
- }, [refetch]);
169
-
170
- // Bottom sheet animation functions
171
- const showBottomSheet = () => {
172
- setTicketModalVisible(true);
173
- Animated.spring(translateY, {
174
- toValue: 0,
175
- useNativeDriver: true,
176
- tension: 100,
177
- friction: 8,
178
- }).start();
179
- };
180
-
181
- const hideBottomSheet = () => {
182
- Animated.timing(translateY, {
183
- toValue: bottomSheetHeight,
184
- duration: 300,
185
- useNativeDriver: true,
186
- }).start(() => {
187
- setTicketModalVisible(false);
188
- translateY.setValue(bottomSheetHeight);
189
- setTicketNumbers([]);
190
- });
191
- };
192
-
193
- // PanResponder for swipe gestures
194
- const panResponder = useRef(
195
- PanResponder.create({
196
- onMoveShouldSetPanResponder: (_, gestureState) => {
197
- return Math.abs(gestureState.dy) > 5;
198
- },
199
- onPanResponderGrant: () => {
200
- translateY.setOffset((translateY as any)._value);
201
- translateY.setValue(0);
202
- },
203
- onPanResponderMove: (_, gestureState) => {
204
- // Only allow downward movement
205
- if (gestureState.dy > 0) {
206
- translateY.setValue(gestureState.dy);
207
- }
208
- },
209
- onPanResponderRelease: (_, gestureState) => {
210
- translateY.flattenOffset();
211
-
212
- // If swiped down more than 100px or with high velocity, close the modal
213
- if (gestureState.dy > 100 || gestureState.vy > 0.5) {
214
- hideBottomSheet();
215
- } else {
216
- // Snap back to original position
217
- Animated.spring(translateY, {
218
- toValue: 0,
219
- useNativeDriver: true,
220
- tension: 100,
221
- friction: 8,
222
- }).start();
223
- }
224
- },
225
- })
226
- ).current;
227
-
228
- // Handle ticket badge press
229
- const handleTicketPress = async (member: ReferrerMember) => {
230
- try {
231
- setTicketDetailsLoading(true);
232
-
233
- const response = await mainService.getTicketDetails({
234
- raffleId: raffleId || 0,
235
- memberId: member?.memberId || 0,
236
- purchasedMemberId: member.memberId || member.id || 0,
237
- });
238
- console.log("data===>>>", JSON.stringify(response));
239
-
240
-
241
- if (response?.data?.data) {
242
- setTicketNumbers(response?.data?.data || []);
243
- showBottomSheet();
244
- }
245
- } catch (error) {
246
- console.error('Failed to fetch ticket details:', error);
247
- } finally {
248
- setTicketDetailsLoading(false);
249
- }
250
- };
251
-
252
-
253
- // Render individual member item
254
- const renderMemberItem: ListRenderItem<ReferrerMember> = ({ item }) => {
255
- const displayName = item.memberName || item.name || 'Unknown';
256
- const profileImg = item.profileImage || item.profileImageUrl;
257
- const tickets = item.purchasedTicketCount ?? item.ticketCount ?? item.ticketsSold ?? item.totalTickets ?? 0;
258
-
259
- return (
260
- <View style={styles.memberRow}>
261
- <View style={styles.memberInfo}>
262
- <View style={styles.memberAvatar}>
263
- {profileImg ? (
264
- <Image source={{ uri: profileImg }} style={styles.avatarImage} resizeMode="cover" />
265
- ) : (
266
- <View style={styles.avatarPlaceholder}>
267
- <SVG.UsersIcon width={moderateScale(24)} height={moderateScale(24)} />
268
- </View>
269
- )}
270
- </View>
271
- <Text style={styles.memberName}>{displayName}</Text>
272
- </View>
273
- <TouchableOpacity
274
- style={styles.ticketBadge}
275
- onPress={() => handleTicketPress(item)}
276
- disabled={ticketDetailsLoading}
277
- >
278
- {ticketDetailsLoading ? (
279
- <ActivityIndicator size="small" color={theme.colors.blue} />
280
- ) : (
281
- <Text style={styles.ticketCount}>{tickets} Ticket{tickets !== 1 ? 's' : ''}</Text>
282
- )}
283
- </TouchableOpacity>
284
- </View>
285
- );
286
- };
287
-
288
- // Render footer loader
289
- const renderFooter = () => {
290
- if (!isFetchingNextPage) return null;
291
- return (
292
- <View style={styles.footerLoader}>
293
- <ActivityIndicator size="small" color={theme.colors.blue} />
294
- </View>
295
- );
296
- };
297
-
298
- // Render empty state
299
- const renderEmptyComponent = () => {
300
- if (isLoading) {
301
- return (
302
- <View style={styles.emptyContainer}>
303
- <ActivityIndicator size="large" color={theme.colors.blue} />
304
- <Text style={styles.emptyText}>Loading referral members...</Text>
305
- </View>
306
- );
307
- }
308
-
309
- if (isError) {
310
- return (
311
- <View style={styles.emptyContainer}>
312
- <Text style={styles.errorText}>Failed to load referral members</Text>
313
- <Text style={styles.errorSubText}>{error?.message || 'Please try again'}</Text>
314
- <TouchableOpacity onPress={handleRefresh} style={styles.retryButton}>
315
- <Text style={styles.retryButtonText}>Retry</Text>
316
- </TouchableOpacity>
317
- </View>
318
- );
319
- }
320
-
321
- return (
322
- <View style={styles.emptyContainer}>
323
- <Text style={styles.emptyText}>No referral members found</Text>
324
- <Text style={styles.emptySubText}>Start referring friends to see them here</Text>
325
- </View>
326
- );
327
- };
328
-
329
- return (
330
-
331
- console.log("hhhh", ticketNumbers),
332
-
333
- <View style={styles.container}>
334
- <StatusBar
335
- barStyle="light-content"
336
- backgroundColor={theme.colors.blue}
337
- translucent={Platform.OS === 'android' ? true : false}
338
- />
339
- {Platform.OS === 'ios' && <View style={styles.statusBarBackground} />}
340
- <SafeAreaView style={styles.header}>
341
- <View style={styles.headerTopRow}>
342
- <TouchableOpacity onPress={() => navigation.goBack()}>
343
- <SVG.arrowLeft_white width={moderateScale(25)} height={moderateScale(25)} />
344
- </TouchableOpacity>
345
- <View style={styles.clubInfoWrapper}>
346
- <View style={styles.userConSty}>
347
- {!!selectedClub?.clubImage ? (
348
- <Image source={{ uri: selectedClub?.clubImage }} style={styles.userDetailsSty} resizeMode="cover" />
349
- ) : (
350
- <View style={styles.placeholderLogoHeader}>
351
- <SVG.UsersIcon width={moderateScale(20)} height={moderateScale(20)} />
352
- </View>
353
- )}
354
- </View>
355
- <Text style={styles.userNameSty}>{selectedClub?.clubName || 'Unknown Club'}</Text>
356
- </View>
357
- </View>
358
- <View style={styles.titleWrapper}>
359
- <Text style={styles.headerTitle}>My Referral Members Sales</Text>
360
- </View>
361
- <View style={styles.addMemberContainer} />
362
- <View style={styles.content}>
363
- <View style={{ paddingHorizontal: theme.spacing.lg }}>
364
-
365
- <View style={styles.headerCard}>
366
- <Text style={styles.totalSalesLabel}>Total Sales</Text>
367
- <View style={styles.totalSalesBadge}>
368
- <Text style={styles.totalSalesCount}>{totalSales}</Text>
369
- </View>
370
- </View>
371
- <View style={{ height: moderateScale(500) }}>
372
- <FlatList
373
- data={referralMembers}
374
- keyExtractor={(item, index) => item.id?.toString() || item.memberId?.toString() || index.toString()}
375
- renderItem={renderMemberItem}
376
- contentContainerStyle={styles.listContent}
377
- showsVerticalScrollIndicator={false}
378
- onEndReached={handleLoadMore}
379
- onEndReachedThreshold={0.3}
380
- ListFooterComponent={renderFooter}
381
- ListEmptyComponent={renderEmptyComponent}
382
- refreshControl={
383
- <RefreshControl
384
- refreshing={isRefetching}
385
- onRefresh={handleRefresh}
386
- tintColor={theme.colors.blue}
387
- colors={[theme.colors.blue]}
388
- />
389
- }
390
- />
391
- </View>
392
- <Button
393
- title="Refer to More Friends"
394
- onPress={handleReferToFriends}
395
- variant="outline"
396
- textStyle={styles.referButtonText}
397
- style={styles.referButton}
398
- size="medium"
399
- />
400
- </View>
401
- </View>
402
- </SafeAreaView>
403
-
404
- {/* Ticket Details Modal */}
405
- <Modal
406
- visible={ticketModalVisible}
407
- animationType="fade"
408
- transparent={true}
409
- onRequestClose={hideBottomSheet}
410
- >
411
- <View style={styles.modalOverlay}>
412
- <TouchableOpacity
413
- style={styles.modalBackdrop}
414
- activeOpacity={1}
415
- onPress={hideBottomSheet}
416
- />
417
- <Animated.View
418
- style={[
419
- styles.modalContainer,
420
- {
421
- transform: [{ translateY }],
422
- },
423
- ]}
424
- >
425
- <View style={styles.dragHandle} {...panResponder.panHandlers} />
426
- <View style={styles.modalHeader}>
427
- <Text style={styles.modalTitle}>Ticket Details</Text>
428
- </View>
429
- <FlatList
430
- data={ticketNumbers}
431
- keyExtractor={(item, index) => `ticket-${item}-${index}`}
432
- contentContainerStyle={styles.ticketListContent}
433
- showsVerticalScrollIndicator={false}
434
- renderItem={({ item }) => (
435
- <View style={styles.ticketNumberBadge}>
436
- <Text style={styles.ticketNumberText}>{item?.ticketNumber}</Text>
437
- </View>
438
- )}
439
- ListEmptyComponent={() => (
440
- <View style={styles.emptyTicketContainer}>
441
- <Text style={styles.emptyTicketText}>No tickets found</Text>
442
- </View>
443
- )}
444
- />
445
- </Animated.View>
446
- </View>
447
- </Modal>
448
- </View>
449
- );
450
- };
451
-
452
- const styles = StyleSheet.create({
453
- container: {
454
- flex: 1,
455
- backgroundColor: theme.colors.blue,
456
- },
457
- statusBarBackground: {
458
- position: 'absolute',
459
- top: 0,
460
- left: 0,
461
- right: 0,
462
- height: Platform.OS === 'ios' ? 44 : 0,
463
- backgroundColor: theme.colors.blue,
464
- zIndex: 1000,
465
- },
466
- header: {
467
- flex: 1,
468
- backgroundColor: theme.colors.blue,
469
- },
470
- userConSty: {
471
- marginHorizontal: moderateScale(10),
472
- width: moderateScale(30),
473
- height: moderateScale(30),
474
- borderRadius: moderateScale(15),
475
- borderWidth: 1.5,
476
- borderColor: theme.colors.imageBorder,
477
- backgroundColor: theme.colors.background,
478
- alignItems: 'center',
479
- justifyContent: 'center',
480
- },
481
- headerTopRow: {
482
- flexDirection: 'row',
483
- alignItems: 'center',
484
- paddingHorizontal: theme.spacing.lg,
485
- },
486
- clubInfoWrapper: {
487
- flexDirection: 'row',
488
- alignItems: 'center',
489
- },
490
- headerTitle: {
491
- marginTop: moderateScale(10),
492
- fontFamily: Fonts.outfitMedium,
493
- fontSize: moderateScale(22),
494
- color: theme.colors.white,
495
- },
496
- titleWrapper: {
497
- paddingHorizontal: theme.spacing.lg,
498
- },
499
- content: {
500
- flex: 1,
501
- backgroundColor: theme.colors.background,
502
- paddingTop: theme.spacing.md,
503
- borderTopLeftRadius: moderateScale(30),
504
- borderTopRightRadius: moderateScale(30),
505
- },
506
- userDetailsSty: {
507
- width: moderateScale(30),
508
- height: moderateScale(30),
509
- borderRadius: moderateScale(15),
510
- },
511
- placeholderLogoHeader: {
512
- width: moderateScale(20),
513
- height: moderateScale(20),
514
- borderRadius: moderateScale(10),
515
- alignItems: 'center',
516
- justifyContent: 'center',
517
- },
518
- userNameSty: {
519
- marginTop: moderateScale(5),
520
- color: theme.colors.white,
521
- fontFamily: Fonts.outfitMedium,
522
- fontSize: moderateScale(15),
523
- },
524
- addMemberContainer: {
525
- backgroundColor: theme.colors.blue,
526
- paddingHorizontal: theme.spacing.lg,
527
- paddingBottom: theme.spacing.md,
528
- },
529
- listContent: {
530
- paddingTop: theme.spacing.md,
531
- paddingBottom: theme.spacing.xl,
532
- },
533
- // Header card with total sales
534
- headerCard: {
535
- backgroundColor: theme.colors.lightLavenderGray,
536
- borderRadius: theme.borderRadius.lg,
537
- paddingHorizontal: theme.spacing.lg,
538
- paddingVertical: theme.spacing.sm,
539
- flexDirection: 'row',
540
- justifyContent: 'space-between',
541
- alignItems: 'center',
542
- marginBottom: theme.spacing.xs
543
- },
544
- totalSalesLabel: {
545
- fontFamily: Fonts.outfitMedium,
546
- fontSize: theme.typography.fontSize.md,
547
- color: theme.colors.blue,
548
- },
549
- totalSalesBadge: {
550
- width: moderateScale(25),
551
- height: moderateScale(25),
552
- borderRadius: moderateScale(12.5),
553
- backgroundColor: theme.colors.appleGreen,
554
- alignItems: 'center',
555
- justifyContent: 'center',
556
- },
557
- totalSalesCount: {
558
- fontFamily: Fonts.outfitMedium,
559
- fontSize: theme.typography.fontSize.xs,
560
- color: theme.colors.blue,
561
- },
562
- // Member row
563
- memberRow: {
564
- flexDirection: 'row',
565
- alignItems: 'center',
566
- justifyContent: 'space-between',
567
- backgroundColor: theme.colors.background,
568
- paddingVertical: moderateScale(10),
569
- borderBottomWidth: 0.5,
570
- borderBottomColor: theme.colors.border,
571
- },
572
- memberInfo: {
573
- flexDirection: 'row',
574
- alignItems: 'center',
575
- flex: 1,
576
- },
577
- memberAvatar: {
578
- width: moderateScale(45),
579
- height: moderateScale(45),
580
- borderRadius: moderateScale(22.5),
581
- marginRight: theme.spacing.md,
582
- overflow: 'hidden',
583
- },
584
- avatarImage: {
585
- width: '100%',
586
- height: '100%',
587
- resizeMode: 'cover',
588
- },
589
- avatarPlaceholder: {
590
- width: '100%',
591
- height: '100%',
592
- backgroundColor: theme.colors.surface,
593
- alignItems: 'center',
594
- justifyContent: 'center',
595
- },
596
- memberName: {
597
- fontFamily: Fonts.outfitRegular,
598
- fontSize: moderateScale(16),
599
- color: theme.colors.text,
600
- },
601
- ticketBadge: {
602
- paddingHorizontal: theme.spacing.sm,
603
- paddingVertical: theme.spacing.xs,
604
- },
605
- ticketCount: {
606
- fontFamily: Fonts.outfitMedium,
607
- fontSize: moderateScale(14),
608
- color: theme.colors.blue,
609
- },
610
- // Footer
611
- footerContainer: {
612
- paddingHorizontal: theme.spacing.lg,
613
- paddingTop: theme.spacing.lg,
614
- paddingBottom: theme.spacing.md,
615
- },
616
- referButton: {
617
- borderColor: theme.colors.blue,
618
- backgroundColor: 'transparent',
619
- marginTop: theme.spacing.sm,
620
- },
621
- referButtonText: {
622
- color: theme.colors.blue,
623
- fontFamily: Fonts.outfitMedium,
624
- },
625
- // Loading and error states
626
- footerLoader: {
627
- paddingVertical: theme.spacing.md,
628
- alignItems: 'center',
629
- justifyContent: 'center',
630
- },
631
- emptyContainer: {
632
- flex: 1,
633
- alignItems: 'center',
634
- justifyContent: 'center',
635
- paddingVertical: moderateScale(60),
636
- paddingHorizontal: theme.spacing.xl,
637
- },
638
- emptyText: {
639
- fontFamily: Fonts.outfitMedium,
640
- fontSize: moderateScale(16),
641
- color: theme.colors.text,
642
- textAlign: 'center',
643
- marginBottom: theme.spacing.xs,
644
- },
645
- emptySubText: {
646
- fontFamily: Fonts.outfitRegular,
647
- fontSize: moderateScale(14),
648
- color: theme.colors.textSecondary,
649
- textAlign: 'center',
650
- },
651
- errorText: {
652
- fontFamily: Fonts.outfitMedium,
653
- fontSize: moderateScale(16),
654
- color: theme.colors.error,
655
- textAlign: 'center',
656
- marginBottom: theme.spacing.xs,
657
- },
658
- errorSubText: {
659
- fontFamily: Fonts.outfitRegular,
660
- fontSize: moderateScale(14),
661
- color: theme.colors.textSecondary,
662
- textAlign: 'center',
663
- marginBottom: theme.spacing.md,
664
- },
665
- retryButton: {
666
- paddingHorizontal: theme.spacing.lg,
667
- paddingVertical: theme.spacing.sm,
668
- backgroundColor: theme.colors.blue,
669
- borderRadius: theme.borderRadius.md,
670
- marginTop: theme.spacing.sm,
671
- },
672
- retryButtonText: {
673
- fontFamily: Fonts.outfitMedium,
674
- fontSize: moderateScale(14),
675
- color: theme.colors.white,
676
- },
677
- // Modal styles
678
- modalOverlay: {
679
- flex: 1,
680
- justifyContent: 'flex-end',
681
- },
682
- modalBackdrop: {
683
- position: 'absolute',
684
- top: 0,
685
- left: 0,
686
- right: 0,
687
- bottom: 0,
688
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
689
- },
690
- modalContainer: {
691
- backgroundColor: theme.colors.white,
692
- borderTopLeftRadius: moderateScale(20),
693
- borderTopRightRadius: moderateScale(20),
694
- paddingHorizontal: theme.spacing.lg,
695
- paddingTop: theme.spacing.sm,
696
- paddingBottom: theme.spacing.xl,
697
- height: '60%',
698
- maxHeight: '60%',
699
- },
700
- dragHandle: {
701
- width: moderateScale(40),
702
- height: moderateScale(4),
703
- backgroundColor: theme.colors.border,
704
- borderRadius: moderateScale(2),
705
- alignSelf: 'center',
706
- marginBottom: theme.spacing.sm,
707
- },
708
- modalHeader: {
709
- paddingVertical: theme.spacing.md,
710
- borderBottomColor: theme.colors.border,
711
- },
712
- modalTitle: {
713
- fontFamily: Fonts.outfitSemiBold,
714
- fontSize: moderateScale(18),
715
- color: theme.colors.text,
716
- },
717
- modalSubtitle: {
718
- fontFamily: Fonts.outfitRegular,
719
- fontSize: moderateScale(14),
720
- color: theme.colors.textSecondary,
721
- textAlign: 'center',
722
- marginTop: theme.spacing.xs,
723
- },
724
- ticketListContent: {
725
- paddingVertical: theme.spacing.sm,
726
- },
727
- ticketNumberBadge: {
728
- flex: 1,
729
- margin: moderateScale(5),
730
- paddingVertical: moderateScale(12),
731
- paddingHorizontal: moderateScale(8),
732
- backgroundColor: theme.colors.lightLavenderGray,
733
- borderRadius: theme.borderRadius.md,
734
- alignItems: 'center',
735
- justifyContent: 'center',
736
- minWidth: moderateScale(90),
737
- },
738
- ticketNumberText: {
739
- fontFamily: Fonts.outfitMedium,
740
- fontSize: moderateScale(16),
741
- color: theme.colors.blue,
742
- },
743
- emptyTicketContainer: {
744
- flex: 1,
745
- alignItems: 'center',
746
- justifyContent: 'center',
747
- paddingVertical: moderateScale(40),
748
- },
749
- emptyTicketText: {
750
- fontFamily: Fonts.outfitMedium,
751
- fontSize: moderateScale(14),
752
- color: theme.colors.textSecondary,
753
- textAlign: 'center',
754
- },
755
- closeButton: {
756
- marginTop: theme.spacing.md,
757
- },
758
- });