@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,676 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { View, Text, StyleSheet, ScrollView, RefreshControl, Dimensions, Animated } from 'react-native';
3
+ import { useAuth } from '@digilogiclabs/saas-factory-auth/native';
4
+ import { LinearGradient } from 'expo-linear-gradient';
5
+ import { BlurView } from 'expo-blur';
6
+ import * as Haptics from 'expo-haptics';
7
+
8
+ // UI Components - Updated for v0.22.0
9
+ import {
10
+ NativeCard as Card,
11
+ NativeMobileContainer as MobileContainer,
12
+ NativeButton as Button,
13
+ NativeProgressRing as ProgressRing,
14
+ NativeChart as Chart,
15
+ NativeStatCard as StatCard,
16
+ PageTransition,
17
+ NetworkAwareContent,
18
+ NativeMobileHero as MobileHero,
19
+ VirtualScrollList,
20
+ LazyImage,
21
+ ProgressiveImage,
22
+ SwipeableCard,
23
+ NativeTour,
24
+ NativeFeatureHighlight,
25
+ NativeTooltip,
26
+ PullToRefresh,
27
+ useNetworkInfo,
28
+ useOfflineState,
29
+ useTheme
30
+ } from '@digilogiclabs/saas-factory-ui/native';
31
+
32
+ // Icons
33
+ import {
34
+ TrendingUp,
35
+ ShoppingBag,
36
+ CreditCard,
37
+ Users,
38
+ Bell,
39
+ Plus,
40
+ ArrowRight
41
+ } from 'react-native-heroicons/outline';
42
+
43
+ const { width } = Dimensions.get('window');
44
+
45
+ interface DashboardData {
46
+ stats: {
47
+ totalOrders: number;
48
+ totalRevenue: number;
49
+ activeUsers: number;
50
+ conversionRate: number;
51
+ };
52
+ recentActivity: Array<{
53
+ id: string;
54
+ type: 'order' | 'user' | 'payment';
55
+ message: string;
56
+ timestamp: string;
57
+ }>;
58
+ chartData: Array<{
59
+ date: string;
60
+ revenue: number;
61
+ orders: number;
62
+ }>;
63
+ }
64
+
65
+ export default function HomeScreen() {
66
+ const { user } = useAuth();
67
+ const { colors, isDark } = useTheme();
68
+ const [data, setData] = useState<DashboardData | null>(null);
69
+ const [loading, setLoading] = useState(true);
70
+ const [refreshing, setRefreshing] = useState(false);
71
+ const [showTour, setShowTour] = useState(false);
72
+ const networkInfo = useNetworkInfo();
73
+ const isOnline = useOfflineState();
74
+
75
+ // Animation values
76
+ const fadeAnim = useState(new Animated.Value(0))[0];
77
+ const slideAnim = useState(new Animated.Value(50))[0];
78
+
79
+ // Tour configuration for new users
80
+ const tourSteps = [
81
+ {
82
+ target: 'stats-section',
83
+ title: 'Your Business Stats',
84
+ content: 'Track key metrics like orders, revenue, and user growth at a glance.',
85
+ placement: 'bottom'
86
+ },
87
+ {
88
+ target: 'chart-section',
89
+ title: 'Performance Charts',
90
+ content: 'Visualize your business trends with interactive charts and analytics.',
91
+ placement: 'top'
92
+ },
93
+ {
94
+ target: 'activity-section',
95
+ title: 'Recent Activity',
96
+ content: 'Stay updated with real-time notifications about orders, users, and payments.',
97
+ placement: 'top'
98
+ }
99
+ ];
100
+
101
+ const fetchDashboardData = async (isRefresh = false) => {
102
+ try {
103
+ if (isRefresh) setRefreshing(true);
104
+
105
+ // Simulate API call
106
+ await new Promise(resolve => setTimeout(resolve, 1000));
107
+
108
+ const mockData: DashboardData = {
109
+ stats: {
110
+ totalOrders: 156,
111
+ totalRevenue: 12450,
112
+ activeUsers: 1249,
113
+ conversionRate: 3.2
114
+ },
115
+ recentActivity: [
116
+ {
117
+ id: '1',
118
+ type: 'order',
119
+ message: 'New order #1234 received',
120
+ timestamp: '2 minutes ago'
121
+ },
122
+ {
123
+ id: '2',
124
+ type: 'user',
125
+ message: 'New user registered',
126
+ timestamp: '5 minutes ago'
127
+ },
128
+ {
129
+ id: '3',
130
+ type: 'payment',
131
+ message: 'Payment of $299 processed',
132
+ timestamp: '10 minutes ago'
133
+ }
134
+ ],
135
+ chartData: [
136
+ { date: 'Mon', revenue: 1200, orders: 15 },
137
+ { date: 'Tue', revenue: 1800, orders: 22 },
138
+ { date: 'Wed', revenue: 2100, orders: 28 },
139
+ { date: 'Thu', revenue: 1600, orders: 18 },
140
+ { date: 'Fri', revenue: 2400, orders: 32 },
141
+ { date: 'Sat', revenue: 2800, orders: 38 },
142
+ { date: 'Sun', revenue: 1900, orders: 25 }
143
+ ]
144
+ };
145
+
146
+ setData(mockData);
147
+ } catch (error) {
148
+ console.error('Failed to fetch dashboard data:', error);
149
+ } finally {
150
+ setLoading(false);
151
+ setRefreshing(false);
152
+ }
153
+ };
154
+
155
+ useEffect(() => {
156
+ fetchDashboardData();
157
+
158
+ // Check if user is new and should see the tour
159
+ const checkForTour = async () => {
160
+ // In a real app, check AsyncStorage or user preferences
161
+ const hasSeenTour = false; // Replace with actual storage check
162
+ if (!hasSeenTour) {
163
+ setTimeout(() => setShowTour(true), 1500);
164
+ }
165
+ };
166
+
167
+ // Entrance animations
168
+ Animated.parallel([
169
+ Animated.timing(fadeAnim, {
170
+ toValue: 1,
171
+ duration: 800,
172
+ useNativeDriver: true,
173
+ }),
174
+ Animated.timing(slideAnim, {
175
+ toValue: 0,
176
+ duration: 600,
177
+ useNativeDriver: true,
178
+ }),
179
+ ]).start();
180
+
181
+ checkForTour();
182
+ }, []);
183
+
184
+ const onRefresh = async () => {
185
+ await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
186
+ fetchDashboardData(true);
187
+ };
188
+
189
+ if (loading && !data) {
190
+ return (
191
+ <MobileContainer style={styles.container}>
192
+ <View style={styles.loadingContainer}>
193
+ <Text style={styles.loadingText}>Loading dashboard...</Text>
194
+ </View>
195
+ </MobileContainer>
196
+ );
197
+ }
198
+
199
+ return (
200
+ <PageTransition type="fade">
201
+ <View style={styles.container}>
202
+ {/* Dynamic gradient background */}
203
+ <LinearGradient
204
+ colors={
205
+ isDark
206
+ ? ['#0F172A', '#1E293B', '#334155']
207
+ : ['#F8FAFC', '#E2E8F0', '#CBD5E1']
208
+ }
209
+ style={styles.gradientBackground}
210
+ />
211
+
212
+ {/* Animated background elements */}
213
+ <View style={styles.backgroundElements}>
214
+ <Animated.View
215
+ style={[
216
+ styles.floatingElement,
217
+ {
218
+ opacity: fadeAnim,
219
+ transform: [
220
+ { translateY: slideAnim },
221
+ { scale: fadeAnim }
222
+ ]
223
+ }
224
+ ]}
225
+ >
226
+ <LinearGradient
227
+ colors={[colors.primary + '40', colors.secondary + '20']}
228
+ style={[styles.gradientCircle, styles.circle1]}
229
+ />
230
+ </Animated.View>
231
+
232
+ <Animated.View
233
+ style={[
234
+ styles.floatingElement,
235
+ {
236
+ opacity: fadeAnim.interpolate({
237
+ inputRange: [0, 1],
238
+ outputRange: [0, 0.6]
239
+ }),
240
+ transform: [
241
+ { translateY: slideAnim },
242
+ { scale: fadeAnim }
243
+ ]
244
+ }
245
+ ]}
246
+ >
247
+ <LinearGradient
248
+ colors={[colors.accent + '30', colors.primary + '10']}
249
+ style={[styles.gradientCircle, styles.circle2]}
250
+ />
251
+ </Animated.View>
252
+ </View>
253
+
254
+ <ScrollView
255
+ style={styles.scrollView}
256
+ contentContainerStyle={styles.scrollContent}
257
+ showsVerticalScrollIndicator={false}
258
+ refreshControl={
259
+ <RefreshControl
260
+ refreshing={refreshing}
261
+ onRefresh={onRefresh}
262
+ tintColor={colors.primary}
263
+ colors={[colors.primary]}
264
+ />
265
+ }
266
+ >
267
+ <Animated.View
268
+ style={[
269
+ styles.content,
270
+ {
271
+ opacity: fadeAnim,
272
+ transform: [{ translateY: slideAnim }]
273
+ }
274
+ ]}
275
+ >
276
+ {/* Hero Section */}
277
+ <MobileHero
278
+ badge={{
279
+ text: "🚀 Dashboard",
280
+ variant: "secondary" as const,
281
+ }}
282
+ title={{
283
+ text: `Welcome back, ${user?.name || user?.email?.split('@')[0] || 'User'}!`,
284
+ size: "lg" as const
285
+ }}
286
+ description="Here's your business overview and key metrics for today."
287
+ actions={[
288
+ {
289
+ label: "View Analytics",
290
+ variant: "default",
291
+ size: "md",
292
+ onPress: () => {/* Navigate to analytics */}
293
+ },
294
+ {
295
+ label: "Add Order",
296
+ variant: "outline",
297
+ size: "md",
298
+ onPress: () => {/* Navigate to new order */}
299
+ }
300
+ ]}
301
+ className="mb-8"
302
+ />
303
+
304
+ {/* Network Status (when offline) */}
305
+ {!isOnline && (
306
+ <BlurView intensity={80} style={styles.offlineCard}>
307
+ <LinearGradient
308
+ colors={['rgba(251, 191, 36, 0.1)', 'rgba(245, 158, 11, 0.05)']}
309
+ style={styles.gradientOverlay}
310
+ />
311
+ <Text style={styles.offlineText}>
312
+ 🔴 You're offline. Some features may be limited.
313
+ </Text>
314
+ </BlurView>
315
+ )}
316
+
317
+ {/* Quick Stats */}
318
+ <NetworkAwareContent
319
+ showOnSlow={
320
+ <View style={styles.statsGrid}>
321
+ <StatCard
322
+ title="Orders"
323
+ value={data?.stats.totalOrders.toString() || '0'}
324
+ icon={<ShoppingBag width={24} height={24} color="#3b82f6" />}
325
+ change="+12%"
326
+ changeType="positive"
327
+ style={styles.statCard}
328
+ />
329
+ <StatCard
330
+ title="Revenue"
331
+ value={`$${data?.stats.totalRevenue.toLocaleString() || '0'}`}
332
+ icon={<CreditCard width={24} height={24} color="#10b981" />}
333
+ change="+8%"
334
+ changeType="positive"
335
+ style={styles.statCard}
336
+ />
337
+ </View>
338
+ }
339
+ >
340
+ <View style={styles.statsGrid}>
341
+ <StatCard
342
+ title="Orders"
343
+ value={data?.stats.totalOrders.toString() || '0'}
344
+ icon={<ShoppingBag width={24} height={24} color="#3b82f6" />}
345
+ change="+12%"
346
+ changeType="positive"
347
+ style={styles.statCard}
348
+ />
349
+ <StatCard
350
+ title="Revenue"
351
+ value={`$${data?.stats.totalRevenue.toLocaleString() || '0'}`}
352
+ icon={<CreditCard width={24} height={24} color="#10b981" />}
353
+ change="+8%"
354
+ changeType="positive"
355
+ style={styles.statCard}
356
+ />
357
+ <StatCard
358
+ title="Users"
359
+ value={data?.stats.activeUsers.toLocaleString() || '0'}
360
+ icon={<Users width={24} height={24} color="#f59e0b" />}
361
+ change="+15%"
362
+ changeType="positive"
363
+ style={styles.statCard}
364
+ />
365
+ <StatCard
366
+ title="Conversion"
367
+ value={`${data?.stats.conversionRate || '0'}%`}
368
+ icon={<TrendingUp width={24} height={24} color="#ef4444" />}
369
+ change="+2.1%"
370
+ changeType="positive"
371
+ style={styles.statCard}
372
+ />
373
+ </View>
374
+ </NetworkAwareContent>
375
+
376
+ {/* Chart Section */}
377
+ <Card style={styles.chartCard}>
378
+ <View style={styles.cardHeader}>
379
+ <Text style={styles.cardTitle}>Revenue This Week</Text>
380
+ <Button variant="ghost" size="sm">
381
+ View All
382
+ </Button>
383
+ </View>
384
+ <Chart
385
+ data={data?.chartData || []}
386
+ type="line"
387
+ xKey="date"
388
+ yKey="revenue"
389
+ height={200}
390
+ style={styles.chart}
391
+ />
392
+ </Card>
393
+
394
+ {/* Quick Actions */}
395
+ <Card style={styles.actionsCard}>
396
+ <Text style={styles.cardTitle}>Quick Actions</Text>
397
+ <View style={styles.actionsGrid}>
398
+ <Button
399
+ variant="outline"
400
+ style={styles.actionButton}
401
+ onPress={() => {/* Navigate to add product */}}
402
+ >
403
+ <Plus width={20} height={20} />
404
+ <Text style={styles.actionButtonText}>Add Product</Text>
405
+ </Button>
406
+ <Button
407
+ variant="outline"
408
+ style={styles.actionButton}
409
+ onPress={() => {/* Navigate to orders */}}
410
+ >
411
+ <ShoppingBag width={20} height={20} />
412
+ <Text style={styles.actionButtonText}>View Orders</Text>
413
+ </Button>
414
+ <Button
415
+ variant="outline"
416
+ style={styles.actionButton}
417
+ onPress={() => {/* Navigate to analytics */}}
418
+ >
419
+ <TrendingUp width={20} height={20} />
420
+ <Text style={styles.actionButtonText}>Analytics</Text>
421
+ </Button>
422
+ </View>
423
+ </Card>
424
+
425
+ {/* Recent Activity */}
426
+ <Card style={styles.activityCard}>
427
+ <View style={styles.cardHeader}>
428
+ <Text style={styles.cardTitle}>Recent Activity</Text>
429
+ <Button
430
+ variant="ghost"
431
+ size="sm"
432
+ onPress={() => {/* Navigate to full activity */}}
433
+ >
434
+ <ArrowRight width={16} height={16} />
435
+ </Button>
436
+ </View>
437
+ <View style={styles.activityList}>
438
+ {data?.recentActivity.map((activity) => (
439
+ <View key={activity.id} style={styles.activityItem}>
440
+ <View style={[
441
+ styles.activityIcon,
442
+ { backgroundColor:
443
+ activity.type === 'order' ? '#dbeafe' :
444
+ activity.type === 'user' ? '#dcfce7' : '#fef3c7'
445
+ }
446
+ ]}>
447
+ {activity.type === 'order' && <ShoppingBag width={16} height={16} color="#3b82f6" />}
448
+ {activity.type === 'user' && <Users width={16} height={16} color="#10b981" />}
449
+ {activity.type === 'payment' && <CreditCard width={16} height={16} color="#f59e0b" />}
450
+ </View>
451
+ <View style={styles.activityContent}>
452
+ <Text style={styles.activityMessage}>{activity.message}</Text>
453
+ <Text style={styles.activityTime}>{activity.timestamp}</Text>
454
+ </View>
455
+ </View>
456
+ ))}
457
+ </View>
458
+ </Card>
459
+ </Animated.View>
460
+ </ScrollView>
461
+
462
+ {/* Native Tour Overlay */}
463
+ {showTour && (
464
+ <NativeTour
465
+ steps={tourSteps}
466
+ isActive={showTour}
467
+ onComplete={() => {
468
+ setShowTour(false);
469
+ Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
470
+ }}
471
+ onSkip={() => {
472
+ setShowTour(false);
473
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
474
+ }}
475
+ maskColor="rgba(0, 0, 0, 0.7)"
476
+ borderRadius={12}
477
+ enableHaptics={true}
478
+ showStepNumber={true}
479
+ showProgress={true}
480
+ animated={true}
481
+ />
482
+ )}
483
+ </View>
484
+ </PageTransition>
485
+ );
486
+ }
487
+
488
+ const styles = StyleSheet.create({
489
+ container: {
490
+ flex: 1,
491
+ },
492
+ gradientBackground: {
493
+ position: 'absolute',
494
+ left: 0,
495
+ right: 0,
496
+ top: 0,
497
+ bottom: 0,
498
+ },
499
+ backgroundElements: {
500
+ position: 'absolute',
501
+ width: '100%',
502
+ height: '100%',
503
+ },
504
+ floatingElement: {
505
+ position: 'absolute',
506
+ },
507
+ gradientCircle: {
508
+ borderRadius: 150,
509
+ },
510
+ circle1: {
511
+ width: 300,
512
+ height: 300,
513
+ top: -100,
514
+ right: -150,
515
+ },
516
+ circle2: {
517
+ width: 200,
518
+ height: 200,
519
+ bottom: 100,
520
+ left: -100,
521
+ },
522
+ scrollView: {
523
+ flex: 1,
524
+ },
525
+ scrollContent: {
526
+ paddingBottom: 120, // Account for floating tab bar
527
+ },
528
+ content: {
529
+ paddingHorizontal: 20,
530
+ paddingTop: 20,
531
+ },
532
+ loadingContainer: {
533
+ flex: 1,
534
+ justifyContent: 'center',
535
+ alignItems: 'center',
536
+ },
537
+ loadingText: {
538
+ fontSize: 16,
539
+ color: '#64748b',
540
+ },
541
+ header: {
542
+ flexDirection: 'row',
543
+ justifyContent: 'space-between',
544
+ alignItems: 'center',
545
+ marginBottom: 24,
546
+ },
547
+ welcomeSection: {
548
+ flex: 1,
549
+ },
550
+ greeting: {
551
+ fontSize: 16,
552
+ color: '#64748b',
553
+ },
554
+ userName: {
555
+ fontSize: 24,
556
+ fontWeight: 'bold',
557
+ color: '#1e293b',
558
+ marginTop: 4,
559
+ },
560
+ notificationButton: {
561
+ width: 44,
562
+ height: 44,
563
+ },
564
+ offlineCard: {
565
+ padding: 20,
566
+ marginBottom: 20,
567
+ marginHorizontal: 20,
568
+ borderRadius: 16,
569
+ overflow: 'hidden',
570
+ borderWidth: 1,
571
+ borderColor: 'rgba(245, 158, 11, 0.2)',
572
+ },
573
+ gradientOverlay: {
574
+ position: 'absolute',
575
+ left: 0,
576
+ right: 0,
577
+ top: 0,
578
+ bottom: 0,
579
+ },
580
+ offlineText: {
581
+ color: '#92400e',
582
+ textAlign: 'center',
583
+ fontWeight: '600',
584
+ fontSize: 16,
585
+ },
586
+ chartCard: {
587
+ padding: 20,
588
+ marginBottom: 20,
589
+ marginHorizontal: 20,
590
+ borderRadius: 20,
591
+ overflow: 'hidden',
592
+ borderWidth: 1,
593
+ borderColor: 'rgba(255, 255, 255, 0.2)',
594
+ },
595
+ statsGrid: {
596
+ flexDirection: 'row',
597
+ flexWrap: 'wrap',
598
+ marginHorizontal: -8,
599
+ marginBottom: 24,
600
+ },
601
+ statCard: {
602
+ width: (width - 48) / 2, // Account for container padding and gaps
603
+ marginHorizontal: 8,
604
+ marginBottom: 16,
605
+ },
606
+ chartCard: {
607
+ padding: 16,
608
+ marginBottom: 16,
609
+ },
610
+ cardHeader: {
611
+ flexDirection: 'row',
612
+ justifyContent: 'space-between',
613
+ alignItems: 'center',
614
+ marginBottom: 16,
615
+ },
616
+ cardTitle: {
617
+ fontSize: 18,
618
+ fontWeight: '600',
619
+ color: '#1e293b',
620
+ },
621
+ chart: {
622
+ marginTop: 8,
623
+ },
624
+ actionsCard: {
625
+ padding: 16,
626
+ marginBottom: 16,
627
+ },
628
+ actionsGrid: {
629
+ flexDirection: 'row',
630
+ justifyContent: 'space-between',
631
+ marginTop: 16,
632
+ gap: 12,
633
+ },
634
+ actionButton: {
635
+ flex: 1,
636
+ flexDirection: 'column',
637
+ alignItems: 'center',
638
+ paddingVertical: 16,
639
+ gap: 8,
640
+ },
641
+ actionButtonText: {
642
+ fontSize: 14,
643
+ fontWeight: '500',
644
+ },
645
+ activityCard: {
646
+ padding: 16,
647
+ },
648
+ activityList: {
649
+ gap: 16,
650
+ },
651
+ activityItem: {
652
+ flexDirection: 'row',
653
+ alignItems: 'center',
654
+ gap: 12,
655
+ },
656
+ activityIcon: {
657
+ width: 32,
658
+ height: 32,
659
+ borderRadius: 16,
660
+ alignItems: 'center',
661
+ justifyContent: 'center',
662
+ },
663
+ activityContent: {
664
+ flex: 1,
665
+ },
666
+ activityMessage: {
667
+ fontSize: 14,
668
+ fontWeight: '500',
669
+ color: '#1e293b',
670
+ },
671
+ activityTime: {
672
+ fontSize: 12,
673
+ color: '#64748b',
674
+ marginTop: 2,
675
+ },
676
+ });