@digilogiclabs/create-saas-app 1.14.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +134 -29
  2. package/bin/index.js +1 -1
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/cli/prompts/project-setup.d.ts.map +1 -1
  5. package/dist/cli/prompts/project-setup.js +45 -12
  6. package/dist/cli/prompts/project-setup.js.map +1 -1
  7. package/dist/generators/template-generator.d.ts.map +1 -1
  8. package/dist/generators/template-generator.js +27 -4
  9. package/dist/generators/template-generator.js.map +1 -1
  10. package/dist/templates/mobile/ui-auth-payments/template/.env.example +20 -0
  11. package/dist/templates/mobile/ui-auth-payments/template/README.md +218 -0
  12. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/_layout.tsx +153 -0
  13. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/analytics.tsx +668 -0
  14. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/billing.tsx +743 -0
  15. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/index.tsx +676 -0
  16. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/orders.tsx +402 -0
  17. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/profile.tsx +580 -0
  18. package/dist/templates/mobile/ui-auth-payments/template/app/_layout.tsx +125 -0
  19. package/dist/templates/mobile/ui-auth-payments/template/app/auth/login.tsx +246 -0
  20. package/dist/templates/mobile/ui-auth-payments/template/app/auth/signup.tsx +362 -0
  21. package/dist/templates/mobile/ui-auth-payments/template/app/onboarding/index.tsx +193 -0
  22. package/dist/templates/mobile/ui-auth-payments/template/app/tour/index.tsx +272 -0
  23. package/dist/templates/mobile/ui-auth-payments/template/app.json +93 -0
  24. package/dist/templates/mobile/ui-auth-payments/template/babel.config.js +23 -0
  25. package/dist/templates/mobile/ui-auth-payments/template/eas.json +45 -0
  26. package/dist/templates/mobile/ui-auth-payments/template/expo-env.d.ts +3 -0
  27. package/dist/templates/mobile/ui-auth-payments/template/jest-setup.ts +74 -0
  28. package/dist/templates/mobile/ui-auth-payments/template/metro.config.js +11 -0
  29. package/dist/templates/mobile/ui-auth-payments/template/package.json +106 -0
  30. package/dist/templates/mobile/ui-auth-payments/template/tsconfig.json +31 -0
  31. package/dist/templates/web/base/template/src/app/dashboard/page.tsx +62 -20
  32. package/dist/templates/web/ui-auth/template/package.json +1 -1
  33. package/dist/templates/web/ui-auth-payments/template/package.json +1 -1
  34. package/dist/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +69 -17
  35. package/dist/templates/web/ui-auth-payments-ai/template/package.json +1 -1
  36. package/dist/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +218 -7
  37. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +62 -9
  38. package/dist/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +364 -0
  39. package/dist/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +532 -0
  40. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +70 -51
  41. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +76 -60
  42. package/dist/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +1 -1
  43. package/dist/templates/web/ui-auth-payments-audio/template/package.json +1 -1
  44. package/dist/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +71 -17
  45. package/dist/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +1 -1
  46. package/dist/templates/web/ui-auth-payments-video/template/package.json +1 -1
  47. package/package.json +1 -1
  48. package/src/templates/mobile/ui-auth-payments/template/.env.example +20 -0
  49. package/src/templates/mobile/ui-auth-payments/template/README.md +218 -0
  50. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/_layout.tsx +153 -0
  51. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/analytics.tsx +668 -0
  52. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/billing.tsx +743 -0
  53. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/index.tsx +676 -0
  54. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/orders.tsx +402 -0
  55. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/profile.tsx +580 -0
  56. package/src/templates/mobile/ui-auth-payments/template/app/_layout.tsx +125 -0
  57. package/src/templates/mobile/ui-auth-payments/template/app/auth/login.tsx +246 -0
  58. package/src/templates/mobile/ui-auth-payments/template/app/auth/signup.tsx +362 -0
  59. package/src/templates/mobile/ui-auth-payments/template/app/onboarding/index.tsx +193 -0
  60. package/src/templates/mobile/ui-auth-payments/template/app/tour/index.tsx +272 -0
  61. package/src/templates/mobile/ui-auth-payments/template/app.json +93 -0
  62. package/src/templates/mobile/ui-auth-payments/template/babel.config.js +23 -0
  63. package/src/templates/mobile/ui-auth-payments/template/eas.json +45 -0
  64. package/src/templates/mobile/ui-auth-payments/template/expo-env.d.ts +3 -0
  65. package/src/templates/mobile/ui-auth-payments/template/jest-setup.ts +74 -0
  66. package/src/templates/mobile/ui-auth-payments/template/metro.config.js +11 -0
  67. package/src/templates/mobile/ui-auth-payments/template/package.json +106 -0
  68. package/src/templates/mobile/ui-auth-payments/template/tsconfig.json +31 -0
  69. package/src/templates/web/base/template/src/app/dashboard/page.tsx +62 -20
  70. package/src/templates/web/ui-auth/template/package.json +1 -1
  71. package/src/templates/web/ui-auth-payments/template/package.json +1 -1
  72. package/src/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +69 -17
  73. package/src/templates/web/ui-auth-payments-ai/template/package.json +1 -1
  74. package/src/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +218 -7
  75. package/src/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +62 -9
  76. package/src/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +364 -0
  77. package/src/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +532 -0
  78. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +70 -51
  79. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +76 -60
  80. package/src/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +1 -1
  81. package/src/templates/web/ui-auth-payments-audio/template/package.json +1 -1
  82. package/src/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +71 -17
  83. package/src/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +1 -1
  84. package/src/templates/web/ui-auth-payments-video/template/package.json +1 -1
@@ -0,0 +1,580 @@
1
+ import React, { useState } from 'react';
2
+ import { View, Text, StyleSheet, ScrollView, Alert, RefreshControl, Animated } from 'react-native';
3
+ import { router } from 'expo-router';
4
+ import { useAuth } from '@digilogiclabs/saas-factory-auth/native';
5
+ import { LinearGradient } from 'expo-linear-gradient';
6
+ import { BlurView } from 'expo-blur';
7
+ import * as Haptics from 'expo-haptics';
8
+
9
+ // UI Components - Updated for v0.22.0
10
+ import {
11
+ NativeCard as Card,
12
+ NativeMobileContainer as MobileContainer,
13
+ NativeButton as Button,
14
+ NativeAvatar as Avatar,
15
+ NativeListItem as ListItem,
16
+ PageTransition,
17
+ NativeSwitch as Switch,
18
+ LazyImage,
19
+ ProgressiveImage,
20
+ PullToRefresh,
21
+ NativeMobileHero as MobileHero,
22
+ NativeFeatureHighlight,
23
+ useTheme
24
+ } from '@digilogiclabs/saas-factory-ui/native';
25
+
26
+ // Icons
27
+ import {
28
+ User,
29
+ Settings,
30
+ Bell,
31
+ Shield,
32
+ HelpCircle,
33
+ LogOut,
34
+ ChevronRight,
35
+ Camera,
36
+ Mail,
37
+ Phone,
38
+ MapPin,
39
+ Calendar
40
+ } from 'react-native-heroicons/outline';
41
+
42
+ export default function ProfileScreen() {
43
+ const { user, signOut, updateProfile } = useAuth();
44
+ const { theme, isDark } = useTheme();
45
+ const [notificationsEnabled, setNotificationsEnabled] = useState(true);
46
+ const [emailUpdates, setEmailUpdates] = useState(true);
47
+ const [loading, setLoading] = useState(false);
48
+ const [refreshing, setRefreshing] = useState(false);
49
+
50
+ // Animation values
51
+ const fadeAnim = useState(new Animated.Value(0))[0];
52
+ const slideAnim = useState(new Animated.Value(50))[0];
53
+
54
+ const handleSignOut = () => {
55
+ Alert.alert(
56
+ 'Sign Out',
57
+ 'Are you sure you want to sign out?',
58
+ [
59
+ { text: 'Cancel', style: 'cancel' },
60
+ {
61
+ text: 'Sign Out',
62
+ style: 'destructive',
63
+ onPress: async () => {
64
+ try {
65
+ await signOut();
66
+ router.replace('/auth/login');
67
+ } catch (error: any) {
68
+ Alert.alert('Error', error.message);
69
+ }
70
+ }
71
+ }
72
+ ]
73
+ );
74
+ };
75
+
76
+ const handleEditProfile = () => {
77
+ router.push('/profile/edit');
78
+ };
79
+
80
+ const handleChangeAvatar = () => {
81
+ Alert.alert(
82
+ 'Change Profile Photo',
83
+ 'Choose an option',
84
+ [
85
+ { text: 'Camera', onPress: () => {/* Open camera */} },
86
+ { text: 'Photo Library', onPress: () => {/* Open library */} },
87
+ { text: 'Cancel', style: 'cancel' }
88
+ ]
89
+ );
90
+ };
91
+
92
+ const menuItems = [
93
+ {
94
+ id: 'edit-profile',
95
+ title: 'Edit Profile',
96
+ icon: <User width={20} height={20} color="#64748b" />,
97
+ onPress: handleEditProfile
98
+ },
99
+ {
100
+ id: 'settings',
101
+ title: 'Settings',
102
+ icon: <Settings width={20} height={20} color="#64748b" />,
103
+ onPress: () => router.push('/settings')
104
+ },
105
+ {
106
+ id: 'billing',
107
+ title: 'Billing & Payments',
108
+ icon: <Settings width={20} height={20} color="#64748b" />,
109
+ onPress: () => router.push('/billing')
110
+ },
111
+ {
112
+ id: 'security',
113
+ title: 'Security & Privacy',
114
+ icon: <Shield width={20} height={20} color="#64748b" />,
115
+ onPress: () => router.push('/profile/security')
116
+ },
117
+ {
118
+ id: 'help',
119
+ title: 'Help & Support',
120
+ icon: <HelpCircle width={20} height={20} color="#64748b" />,
121
+ onPress: () => router.push('/profile/help')
122
+ }
123
+ ];
124
+
125
+ const onRefresh = async () => {
126
+ setRefreshing(true);
127
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
128
+ // Simulate refresh
129
+ await new Promise(resolve => setTimeout(resolve, 1500));
130
+ setRefreshing(false);
131
+ };
132
+
133
+ React.useEffect(() => {
134
+ // Entrance animations
135
+ Animated.parallel([
136
+ Animated.timing(fadeAnim, {
137
+ toValue: 1,
138
+ duration: 600,
139
+ useNativeDriver: true,
140
+ }),
141
+ Animated.spring(slideAnim, {
142
+ toValue: 0,
143
+ tension: 50,
144
+ friction: 8,
145
+ useNativeDriver: true,
146
+ }),
147
+ ]).start();
148
+ }, []);
149
+
150
+ return (
151
+ <PageTransition type="fade">
152
+ <View style={styles.mainContainer}>
153
+ {/* Enhanced gradient background with floating elements */}
154
+ <LinearGradient
155
+ colors={isDark
156
+ ? ['#0F172A', '#1E293B', '#334155']
157
+ : ['#F8FAFC', '#E2E8F0', '#CBD5E1']
158
+ }
159
+ style={styles.gradientBackground}
160
+ />
161
+
162
+ {/* Floating animated elements */}
163
+ <Animated.View style={[styles.floatingElement, styles.element1, {
164
+ opacity: fadeAnim,
165
+ transform: [{ translateY: slideAnim }]
166
+ }]}>
167
+ <LinearGradient
168
+ colors={['rgba(99, 102, 241, 0.3)', 'rgba(79, 70, 229, 0.3)']}
169
+ style={styles.gradientOrb}
170
+ />
171
+ </Animated.View>
172
+
173
+ <PullToRefresh
174
+ onRefresh={onRefresh}
175
+ refreshing={refreshing}
176
+ >
177
+ <ScrollView
178
+ style={styles.scrollView}
179
+ showsVerticalScrollIndicator={false}
180
+ refreshControl={
181
+ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
182
+ }
183
+ >
184
+ <MobileContainer style={styles.container}>
185
+ {/* Hero Section */}
186
+ <Animated.View style={{
187
+ opacity: fadeAnim,
188
+ transform: [{ translateY: slideAnim }]
189
+ }}>
190
+ <MobileHero
191
+ badge={{
192
+ text: "👤 Your Profile",
193
+ variant: "secondary"
194
+ }}
195
+ title={{
196
+ text: "Account Settings",
197
+ size: "lg"
198
+ }}
199
+ description="Manage your account, preferences, and security settings."
200
+ className="text-center mb-6"
201
+ />
202
+ </Animated.View>
203
+
204
+ {/* Enhanced Profile Header with Glass Effect */}
205
+ <Animated.View style={{
206
+ opacity: fadeAnim,
207
+ transform: [{ translateY: slideAnim }]
208
+ }}>
209
+ <BlurView intensity={30} style={styles.profileCardBlur}>
210
+ <Card style={styles.profileCard}>
211
+ <View style={styles.profileHeader}>
212
+ <View style={styles.avatarContainer}>
213
+ <NativeFeatureHighlight
214
+ target="profile-avatar"
215
+ title="Profile Photo"
216
+ content="Tap to change your profile photo"
217
+ placement="bottom"
218
+ >
219
+ {user?.avatar ? (
220
+ <ProgressiveImage
221
+ source={{ uri: user.avatar }}
222
+ placeholder={{ uri: 'https://via.placeholder.com/100x100/e2e8f0/64748b?text=Loading...' }}
223
+ style={styles.profileImage}
224
+ resizeMode="cover"
225
+ fadeDuration={300}
226
+ loadingIndicator={true}
227
+ />
228
+ ) : (
229
+ <Avatar
230
+ initials={user?.name?.charAt(0) || user?.email?.charAt(0) || 'U'}
231
+ size="xl"
232
+ style={styles.avatar}
233
+ />
234
+ )}
235
+ </NativeFeatureHighlight>
236
+ <Button
237
+ variant="outline"
238
+ size="sm"
239
+ style={styles.cameraButton}
240
+ onPress={handleChangeAvatar}
241
+ >
242
+ <Camera width={16} height={16} />
243
+ </Button>
244
+ </View>
245
+
246
+ <View style={styles.profileInfo}>
247
+ <Text style={styles.userName}>
248
+ {user?.name || 'User Name'}
249
+ </Text>
250
+ <Text style={styles.userEmail}>
251
+ {user?.email || 'user@example.com'}
252
+ </Text>
253
+
254
+ {/* User Details */}
255
+ <View style={styles.userDetails}>
256
+ {user?.phone && (
257
+ <View style={styles.detailItem}>
258
+ <Phone width={14} height={14} color="#64748b" />
259
+ <Text style={styles.detailText}>{user.phone}</Text>
260
+ </View>
261
+ )}
262
+ {user?.location && (
263
+ <View style={styles.detailItem}>
264
+ <MapPin width={14} height={14} color="#64748b" />
265
+ <Text style={styles.detailText}>{user.location}</Text>
266
+ </View>
267
+ )}
268
+ <View style={styles.detailItem}>
269
+ <Calendar width={14} height={14} color="#64748b" />
270
+ <Text style={styles.detailText}>
271
+ Joined {new Date(user?.created_at || Date.now()).toLocaleDateString()}
272
+ </Text>
273
+ </View>
274
+ </View>
275
+ </View>
276
+ </View>
277
+
278
+ <Button
279
+ variant="outline"
280
+ style={styles.editButton}
281
+ onPress={handleEditProfile}
282
+ >
283
+ Edit Profile
284
+ </Button>
285
+ </Card>
286
+ </BlurView>
287
+ </Animated.View>
288
+
289
+ {/* Enhanced Menu Items with Glass Effects */}
290
+ <Animated.View style={{
291
+ opacity: fadeAnim,
292
+ transform: [{ translateY: slideAnim }]
293
+ }}>
294
+ {menuItems.map((item, index) => (
295
+ <BlurView key={item.id} intensity={25} style={[styles.menuItemBlur, { marginBottom: 12 }]}>
296
+ <ListItem
297
+ leftIcon={item.icon}
298
+ title={item.title}
299
+ rightIcon={<ChevronRight width={16} height={16} color="#94a3b8" />}
300
+ onPress={item.onPress}
301
+ style={styles.menuItem}
302
+ />
303
+ </BlurView>
304
+ ))}
305
+ </Animated.View>
306
+
307
+ {/* Enhanced Preferences with Glass Effect */}
308
+ <Animated.View style={{
309
+ opacity: fadeAnim,
310
+ transform: [{ translateY: slideAnim }]
311
+ }}>
312
+ <BlurView intensity={25} style={styles.preferencesBlur}>
313
+ <Card style={styles.preferencesCard}>
314
+ <Text style={styles.sectionTitle}>Preferences</Text>
315
+
316
+ <View style={styles.preferenceItem}>
317
+ <View style={styles.preferenceInfo}>
318
+ <Bell width={20} height={20} color="#64748b" />
319
+ <View>
320
+ <Text style={styles.preferenceTitle}>Push Notifications</Text>
321
+ <Text style={styles.preferenceDescription}>
322
+ Get notified about orders and updates
323
+ </Text>
324
+ </View>
325
+ </View>
326
+ <Switch
327
+ value={notificationsEnabled}
328
+ onValueChange={setNotificationsEnabled}
329
+ />
330
+ </View>
331
+
332
+ <View style={styles.preferenceItem}>
333
+ <View style={styles.preferenceInfo}>
334
+ <Mail width={20} height={20} color="#64748b" />
335
+ <View>
336
+ <Text style={styles.preferenceTitle}>Email Updates</Text>
337
+ <Text style={styles.preferenceDescription}>
338
+ Receive promotional emails and newsletters
339
+ </Text>
340
+ </View>
341
+ </View>
342
+ <Switch
343
+ value={emailUpdates}
344
+ onValueChange={setEmailUpdates}
345
+ />
346
+ </View>
347
+ </Card>
348
+ </BlurView>
349
+ </Animated.View>
350
+
351
+ {/* Enhanced Sign Out with Glass Effect */}
352
+ <Animated.View style={{
353
+ opacity: fadeAnim,
354
+ transform: [{ translateY: slideAnim }]
355
+ }}>
356
+ <BlurView intensity={20} style={styles.signOutBlur}>
357
+ <Card style={styles.actionsCard}>
358
+ <ListItem
359
+ leftIcon={<LogOut width={20} height={20} color="#ef4444" />}
360
+ title="Sign Out"
361
+ titleStyle={styles.signOutText}
362
+ onPress={handleSignOut}
363
+ style={styles.signOutItem}
364
+ />
365
+ </Card>
366
+ </BlurView>
367
+ </Animated.View>
368
+
369
+ {/* App Info */}
370
+ <View style={styles.appInfo}>
371
+ <Text style={styles.appInfoText}>{{titleCaseName}} v1.0.0</Text>
372
+ <Text style={styles.appInfoText}>Made with ❤️ by Your Team</Text>
373
+ </View>
374
+ </MobileContainer>
375
+ </ScrollView>
376
+ </PullToRefresh>
377
+ </View>
378
+ </PageTransition>
379
+ );
380
+ }
381
+
382
+ const styles = StyleSheet.create({
383
+ mainContainer: {
384
+ flex: 1,
385
+ backgroundColor: 'transparent',
386
+ },
387
+ gradientBackground: {
388
+ position: 'absolute',
389
+ left: 0,
390
+ right: 0,
391
+ top: 0,
392
+ bottom: 0,
393
+ },
394
+ floatingElement: {
395
+ position: 'absolute',
396
+ borderRadius: 100,
397
+ },
398
+ element1: {
399
+ top: 200,
400
+ right: 20,
401
+ width: 120,
402
+ height: 120,
403
+ },
404
+ gradientOrb: {
405
+ flex: 1,
406
+ borderRadius: 100,
407
+ },
408
+ scrollView: {
409
+ flex: 1,
410
+ backgroundColor: 'transparent',
411
+ },
412
+ container: {
413
+ padding: 16,
414
+ paddingBottom: 100,
415
+ },
416
+ profileCardBlur: {
417
+ borderRadius: 20,
418
+ overflow: 'hidden',
419
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
420
+ marginBottom: 16,
421
+ },
422
+ profileCard: {
423
+ padding: 20,
424
+ backgroundColor: 'transparent',
425
+ shadowOpacity: 0,
426
+ elevation: 0,
427
+ },
428
+ profileHeader: {
429
+ alignItems: 'center',
430
+ marginBottom: 20,
431
+ },
432
+ avatarContainer: {
433
+ position: 'relative',
434
+ marginBottom: 16,
435
+ },
436
+ avatar: {
437
+ marginBottom: 0,
438
+ },
439
+ cameraButton: {
440
+ position: 'absolute',
441
+ bottom: 0,
442
+ right: 0,
443
+ width: 32,
444
+ height: 32,
445
+ borderRadius: 16,
446
+ padding: 0,
447
+ alignItems: 'center',
448
+ justifyContent: 'center',
449
+ },
450
+ profileInfo: {
451
+ alignItems: 'center',
452
+ },
453
+ userName: {
454
+ fontSize: 24,
455
+ fontWeight: 'bold',
456
+ color: '#1e293b',
457
+ marginBottom: 4,
458
+ },
459
+ userEmail: {
460
+ fontSize: 16,
461
+ color: '#64748b',
462
+ marginBottom: 12,
463
+ },
464
+ userDetails: {
465
+ alignItems: 'center',
466
+ gap: 6,
467
+ },
468
+ detailItem: {
469
+ flexDirection: 'row',
470
+ alignItems: 'center',
471
+ gap: 6,
472
+ },
473
+ detailText: {
474
+ fontSize: 14,
475
+ color: '#64748b',
476
+ },
477
+ editButton: {
478
+ marginTop: 8,
479
+ },
480
+ profileImage: {
481
+ width: 100,
482
+ height: 100,
483
+ borderRadius: 50,
484
+ },
485
+ menuItemBlur: {
486
+ borderRadius: 16,
487
+ overflow: 'hidden',
488
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
489
+ },
490
+ preferencesBlur: {
491
+ borderRadius: 20,
492
+ overflow: 'hidden',
493
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
494
+ marginBottom: 16,
495
+ },
496
+ preferencesCard: {
497
+ padding: 20,
498
+ backgroundColor: 'transparent',
499
+ shadowOpacity: 0,
500
+ elevation: 0,
501
+ },
502
+ signOutBlur: {
503
+ borderRadius: 16,
504
+ overflow: 'hidden',
505
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
506
+ marginBottom: 16,
507
+ },
508
+ sectionTitle: {
509
+ fontSize: 16,
510
+ fontWeight: '600',
511
+ color: '#1e293b',
512
+ marginBottom: 16,
513
+ },
514
+ preferenceItem: {
515
+ flexDirection: 'row',
516
+ justifyContent: 'space-between',
517
+ alignItems: 'center',
518
+ paddingVertical: 12,
519
+ borderBottomWidth: 1,
520
+ borderBottomColor: '#f1f5f9',
521
+ },
522
+ preferenceInfo: {
523
+ flex: 1,
524
+ flexDirection: 'row',
525
+ alignItems: 'center',
526
+ gap: 12,
527
+ },
528
+ preferenceTitle: {
529
+ fontSize: 16,
530
+ fontWeight: '500',
531
+ color: '#1e293b',
532
+ marginBottom: 2,
533
+ },
534
+ preferenceDescription: {
535
+ fontSize: 14,
536
+ color: '#64748b',
537
+ },
538
+ menuCard: {
539
+ marginBottom: 16,
540
+ overflow: 'hidden',
541
+ },
542
+ menuItem: {
543
+ paddingVertical: 16,
544
+ paddingHorizontal: 16,
545
+ borderBottomWidth: 1,
546
+ borderBottomColor: '#f1f5f9',
547
+ },
548
+ lastMenuItem: {
549
+ borderBottomWidth: 0,
550
+ },
551
+ actionsCard: {
552
+ padding: 16,
553
+ backgroundColor: 'transparent',
554
+ shadowOpacity: 0,
555
+ elevation: 0,
556
+ },
557
+ menuItem: {
558
+ paddingVertical: 16,
559
+ paddingHorizontal: 16,
560
+ backgroundColor: 'transparent',
561
+ borderBottomWidth: 0,
562
+ },
563
+ signOutItem: {
564
+ paddingVertical: 12,
565
+ paddingHorizontal: 0,
566
+ },
567
+ signOutText: {
568
+ color: '#ef4444',
569
+ fontWeight: '500',
570
+ },
571
+ appInfo: {
572
+ alignItems: 'center',
573
+ paddingVertical: 16,
574
+ gap: 4,
575
+ },
576
+ appInfoText: {
577
+ fontSize: 12,
578
+ color: '#94a3b8',
579
+ },
580
+ });
@@ -0,0 +1,125 @@
1
+ import { useEffect } from 'react';
2
+ import { useFonts } from 'expo-font';
3
+ import { SplashScreen, Stack } from 'expo-router';
4
+ import { SafeAreaProvider } from 'react-native-safe-area-context';
5
+ import { StatusBar } from 'expo-status-bar';
6
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
7
+ import { StripeProvider } from '@stripe/stripe-react-native';
8
+
9
+ // UI Library Providers
10
+ import {
11
+ NativeThemeProvider as ThemeProvider,
12
+ OfflineWrapper,
13
+ NetworkAwareContent,
14
+ NativeHapticsProvider as HapticsProvider,
15
+ AppShell
16
+ } from '@digilogiclabs/saas-factory-ui/native';
17
+
18
+ // Auth Provider
19
+ import { AuthProvider } from '@digilogiclabs/saas-factory-auth/native';
20
+
21
+ // Prevent the splash screen from auto-hiding before asset loading is complete
22
+ SplashScreen.preventAutoHideAsync();
23
+
24
+ export default function RootLayout() {
25
+ const [loaded, error] = useFonts({
26
+ // Add your custom fonts here
27
+ });
28
+
29
+ // Expo Router uses Error Boundaries to catch errors in the navigation tree
30
+ useEffect(() => {
31
+ if (error) throw error;
32
+ }, [error]);
33
+
34
+ useEffect(() => {
35
+ if (loaded) {
36
+ SplashScreen.hideAsync();
37
+ }
38
+ }, [loaded]);
39
+
40
+ if (!loaded) {
41
+ return null;
42
+ }
43
+
44
+ return (
45
+ <GestureHandlerRootView style={{ flex: 1 }}>
46
+ <SafeAreaProvider>
47
+ <ThemeProvider>
48
+ <HapticsProvider>
49
+ <OfflineWrapper
50
+ cacheStrategy="stale-while-revalidate"
51
+ showOfflineIndicator={true}
52
+ backgroundSync={true}
53
+ >
54
+ <NetworkAwareContent>
55
+ <AuthProvider
56
+ supabaseUrl={process.env.EXPO_PUBLIC_SUPABASE_URL!}
57
+ supabaseAnonKey={process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!}
58
+ >
59
+ <StripeProvider
60
+ publishableKey={process.env.EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY!}
61
+ merchantIdentifier="merchant.com.{{packageName}}.app"
62
+ >
63
+ <AppShell
64
+ navigationMode="tabs"
65
+ showHeader={true}
66
+ headerConfig={{
67
+ title: "{{titleCaseName}}",
68
+ showBackButton: false,
69
+ showProfileButton: true
70
+ }}
71
+ >
72
+ <Stack
73
+ screenOptions={{
74
+ headerShown: false,
75
+ animation: 'slide_from_right',
76
+ animationTypeForReplace: 'push'
77
+ }}
78
+ >
79
+ <Stack.Screen
80
+ name="(tabs)"
81
+ options={{ headerShown: false }}
82
+ />
83
+ <Stack.Screen
84
+ name="auth"
85
+ options={{
86
+ presentation: 'modal',
87
+ headerShown: false
88
+ }}
89
+ />
90
+ <Stack.Screen
91
+ name="onboarding"
92
+ options={{
93
+ presentation: 'fullScreenModal',
94
+ headerShown: false
95
+ }}
96
+ />
97
+ <Stack.Screen
98
+ name="profile"
99
+ options={{
100
+ presentation: 'card',
101
+ headerShown: true,
102
+ title: 'Profile'
103
+ }}
104
+ />
105
+ <Stack.Screen
106
+ name="settings"
107
+ options={{
108
+ presentation: 'card',
109
+ headerShown: true,
110
+ title: 'Settings'
111
+ }}
112
+ />
113
+ </Stack>
114
+ </AppShell>
115
+ <StatusBar style="auto" />
116
+ </StripeProvider>
117
+ </AuthProvider>
118
+ </NetworkAwareContent>
119
+ </OfflineWrapper>
120
+ </HapticsProvider>
121
+ </ThemeProvider>
122
+ </SafeAreaProvider>
123
+ </GestureHandlerRootView>
124
+ );
125
+ }