@digilogiclabs/create-saas-app 1.5.3 → 1.6.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 (56) hide show
  1. package/CHANGELOG.md +109 -49
  2. package/bin/index.js +1 -1
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/templates/mobile/base/template/App.tsx +113 -23
  5. package/dist/templates/mobile/base/template/package.json +41 -38
  6. package/dist/templates/web/base/template/package.json +2 -2
  7. package/dist/templates/web/base/template/src/app/checkout/page.tsx +99 -8
  8. package/dist/templates/web/base/template/src/app/dashboard/page.tsx +309 -0
  9. package/dist/templates/web/base/template/src/app/globals.css +97 -0
  10. package/dist/templates/web/base/template/src/app/login/page.tsx +36 -8
  11. package/dist/templates/web/base/template/src/app/page.tsx +123 -83
  12. package/dist/templates/web/base/template/src/app/signup/page.tsx +36 -8
  13. package/dist/templates/web/base/template/src/components/shared/header.tsx +49 -30
  14. package/dist/templates/web/ui-auth/template/package.json +3 -3
  15. package/dist/templates/web/ui-auth/template/src/app/page.tsx +203 -61
  16. package/dist/templates/web/ui-auth-payments/template/package.json +3 -3
  17. package/dist/templates/web/ui-auth-payments/template/src/app/checkout/page.tsx +253 -87
  18. package/dist/templates/web/ui-auth-payments/template/src/app/globals.css +129 -0
  19. package/dist/templates/web/ui-auth-payments/template/src/app/page.tsx +246 -74
  20. package/dist/templates/web/ui-auth-payments/template/src/components/shared/header.tsx +106 -40
  21. package/dist/templates/web/ui-auth-payments-audio/template/package.json +3 -3
  22. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +221 -82
  23. package/dist/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +132 -40
  24. package/dist/templates/web/ui-auth-payments-video/template/package.json +3 -3
  25. package/dist/templates/web/ui-auth-payments-video/template/src/app/globals.css +146 -0
  26. package/dist/templates/web/ui-auth-payments-video/template/src/app/page.tsx +259 -85
  27. package/dist/templates/web/ui-auth-payments-video/template/src/components/shared/header.tsx +133 -41
  28. package/dist/templates/web/ui-only/template/package.json +1 -1
  29. package/package.json +106 -106
  30. package/src/templates/mobile/base/template/App.tsx +113 -23
  31. package/src/templates/mobile/base/template/package.json +41 -38
  32. package/src/templates/web/base/template/package.json +2 -2
  33. package/src/templates/web/base/template/src/app/checkout/page.tsx +99 -8
  34. package/src/templates/web/base/template/src/app/dashboard/page.tsx +309 -0
  35. package/src/templates/web/base/template/src/app/globals.css +97 -0
  36. package/src/templates/web/base/template/src/app/login/page.tsx +36 -8
  37. package/src/templates/web/base/template/src/app/page.tsx +123 -83
  38. package/src/templates/web/base/template/src/app/signup/page.tsx +36 -8
  39. package/src/templates/web/base/template/src/components/shared/header.tsx +49 -30
  40. package/src/templates/web/ui-auth/template/package.json +3 -3
  41. package/src/templates/web/ui-auth/template/src/app/page.tsx +203 -61
  42. package/src/templates/web/ui-auth-payments/template/package.json +3 -3
  43. package/src/templates/web/ui-auth-payments/template/src/app/checkout/page.tsx +253 -87
  44. package/src/templates/web/ui-auth-payments/template/src/app/globals.css +129 -0
  45. package/src/templates/web/ui-auth-payments/template/src/app/page.tsx +246 -74
  46. package/src/templates/web/ui-auth-payments/template/src/components/shared/header.tsx +106 -40
  47. package/src/templates/web/ui-auth-payments-audio/template/package.json +3 -3
  48. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +221 -82
  49. package/src/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +132 -40
  50. package/src/templates/web/ui-auth-payments-video/template/package.json +3 -3
  51. package/src/templates/web/ui-auth-payments-video/template/src/app/globals.css +146 -0
  52. package/src/templates/web/ui-auth-payments-video/template/src/app/page.tsx +259 -85
  53. package/src/templates/web/ui-auth-payments-video/template/src/components/shared/header.tsx +133 -41
  54. package/src/templates/web/ui-only/template/package.json +1 -1
  55. package/dist/index.js +0 -1173
  56. package/dist/index.js.map +0 -1
@@ -3,9 +3,20 @@
3
3
  import React from 'react';
4
4
  import { useStripe } from '@digilogiclabs/saas-factory-payments';
5
5
  import { Button } from '@/components/ui/button';
6
+ import {
7
+ PageTransition,
8
+ MobileContainer,
9
+ TouchInput,
10
+ MobileForm,
11
+ SwipeableCard,
12
+ NetworkAwareContent,
13
+ useNetworkInfo
14
+ } from '@digilogiclabs/saas-factory-ui';
15
+ import { CreditCard, Zap } from 'lucide-react';
6
16
 
7
17
  export default function CheckoutPage() {
8
18
  const { handleCheckout } = useStripe();
19
+ const networkInfo = useNetworkInfo();
9
20
 
10
21
  const onCheckout = async () => {
11
22
  await handleCheckout({
@@ -15,14 +26,94 @@ export default function CheckoutPage() {
15
26
  };
16
27
 
17
28
  return (
18
- <div className="flex items-center justify-center min-h-screen bg-gray-100">
19
- <div className="p-8 bg-white rounded-lg shadow-md">
20
- <h1 className="text-2xl font-bold mb-4">Checkout</h1>
21
- <p className="mb-6">Click the button below to proceed to payment.</p>
22
- <Button onClick={onCheckout}>
23
- Proceed to Checkout
24
- </Button>
29
+ <PageTransition type="slide" direction="up" duration={350}>
30
+ <div className="flex items-center justify-center min-h-screen bg-gray-100">
31
+ <MobileContainer className="w-full max-w-md">
32
+ <NetworkAwareContent
33
+ showOnSlow={
34
+ <div className="p-6 bg-white rounded-lg shadow-md">
35
+ <div className="flex items-center gap-2 mb-4">
36
+ <CreditCard className="h-6 w-6 text-blue-600" />
37
+ <h1 className="text-xl font-bold">Checkout</h1>
38
+ </div>
39
+ <p className="mb-6 text-gray-600">
40
+ Simplified checkout for slower connections.
41
+ </p>
42
+ <Button
43
+ onClick={onCheckout}
44
+ className="w-full"
45
+ size="lg"
46
+ >
47
+ Proceed to Checkout
48
+ </Button>
49
+ </div>
50
+ }
51
+ >
52
+ <SwipeableCard
53
+ leftActions={[
54
+ {
55
+ id: 'back',
56
+ label: 'Back',
57
+ onAction: () => window.history.back(),
58
+ color: 'gray'
59
+ }
60
+ ]}
61
+ rightActions={[
62
+ {
63
+ id: 'proceed',
64
+ label: 'Pay Now',
65
+ onAction: onCheckout,
66
+ color: 'green'
67
+ }
68
+ ]}
69
+ threshold={60}
70
+ hapticFeedback={true}
71
+ showActionLabels={true}
72
+ >
73
+ <div className="p-8 bg-white rounded-lg shadow-md">
74
+ <div className="flex items-center gap-3 mb-6">
75
+ <div className="p-3 bg-blue-100 rounded-full">
76
+ <Zap className="h-6 w-6 text-blue-600" />
77
+ </div>
78
+ <div>
79
+ <h1 className="text-2xl font-bold">Premium Checkout</h1>
80
+ <p className="text-sm text-gray-500">
81
+ {networkInfo?.effectiveType && `${networkInfo.effectiveType.toUpperCase()} connection`}
82
+ </p>
83
+ </div>
84
+ </div>
85
+
86
+ <div className="space-y-4 mb-6">
87
+ <div className="p-4 bg-blue-50 rounded-lg">
88
+ <h3 className="font-semibold text-blue-900">Pro Plan</h3>
89
+ <p className="text-blue-700">$29/month • All features included</p>
90
+ </div>
91
+
92
+ <div className="text-sm text-gray-600">
93
+ <p>✓ Touch-optimized checkout experience</p>
94
+ <p>✓ Network-aware performance</p>
95
+ <p>✓ Secure payment processing</p>
96
+ </div>
97
+ </div>
98
+
99
+ <div className="space-y-3">
100
+ <Button
101
+ onClick={onCheckout}
102
+ className="w-full"
103
+ size="lg"
104
+ >
105
+ Proceed to Checkout
106
+ </Button>
107
+
108
+ <p className="text-xs text-center text-gray-500">
109
+ Swipe left to go back • Swipe right to pay now
110
+ </p>
111
+ </div>
112
+ </div>
113
+ </SwipeableCard>
114
+ </NetworkAwareContent>
115
+ </MobileContainer>
25
116
  </div>
26
- </div>
117
+ </PageTransition>
27
118
  );
28
119
  }
@@ -0,0 +1,309 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+ import { useAuth } from '@digilogiclabs/saas-factory-auth';
5
+ import { Button } from '@/components/ui/button';
6
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
7
+ import {
8
+ PageTransition,
9
+ MobileContainer,
10
+ ResponsiveGrid,
11
+ PullToRefresh,
12
+ LazyImage,
13
+ VirtualScrollList,
14
+ SwipeableCard,
15
+ NetworkAwareContent,
16
+ OfflineWrapper,
17
+ useNetworkInfo,
18
+ useOfflineState
19
+ } from '@digilogiclabs/saas-factory-ui';
20
+ import {
21
+ BarChart3,
22
+ Users,
23
+ DollarSign,
24
+ TrendingUp,
25
+ Settings,
26
+ Archive,
27
+ Star,
28
+ Trash2,
29
+ Wifi,
30
+ WifiOff
31
+ } from 'lucide-react';
32
+
33
+ // Mock data for demonstration
34
+ const mockActivityData = Array.from({ length: 50 }, (_, i) => ({
35
+ id: i + 1,
36
+ title: `Activity ${i + 1}`,
37
+ description: `This is a sample activity item #${i + 1}`,
38
+ timestamp: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString(),
39
+ type: ['user', 'sale', 'system'][Math.floor(Math.random() * 3)],
40
+ avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${i}`
41
+ }));
42
+
43
+ export default function DashboardPage() {
44
+ const { user } = useAuth();
45
+ const networkInfo = useNetworkInfo();
46
+ const isOnline = useOfflineState();
47
+ const [activityData, setActivityData] = useState(mockActivityData);
48
+ const [isRefreshing, setIsRefreshing] = useState(false);
49
+
50
+ const handleRefresh = async () => {
51
+ setIsRefreshing(true);
52
+ // Simulate API call
53
+ await new Promise(resolve => setTimeout(resolve, 1500));
54
+ setIsRefreshing(false);
55
+ };
56
+
57
+ const handleArchive = (id: number) => {
58
+ setActivityData(prev => prev.filter(item => item.id !== id));
59
+ };
60
+
61
+ const handleStar = (id: number) => {
62
+ console.log('Starred item:', id);
63
+ };
64
+
65
+ const handleDelete = (id: number) => {
66
+ setActivityData(prev => prev.filter(item => item.id !== id));
67
+ };
68
+
69
+ const stats = [
70
+ {
71
+ title: 'Total Users',
72
+ value: '2,543',
73
+ change: '+12%',
74
+ icon: Users,
75
+ color: 'blue'
76
+ },
77
+ {
78
+ title: 'Revenue',
79
+ value: '$12,456',
80
+ change: '+8%',
81
+ icon: DollarSign,
82
+ color: 'green'
83
+ },
84
+ {
85
+ title: 'Growth',
86
+ value: '23.5%',
87
+ change: '+2.1%',
88
+ icon: TrendingUp,
89
+ color: 'purple'
90
+ },
91
+ {
92
+ title: 'Analytics',
93
+ value: '1,234',
94
+ change: '+5%',
95
+ icon: BarChart3,
96
+ color: 'orange'
97
+ }
98
+ ];
99
+
100
+ return (
101
+ <PageTransition type="slide" direction="horizontal" duration={300}>
102
+ <OfflineWrapper
103
+ cacheStrategy="stale-while-revalidate"
104
+ showOfflineIndicator={true}
105
+ backgroundSync={true}
106
+ >
107
+ <PullToRefresh
108
+ onRefresh={handleRefresh}
109
+ threshold={80}
110
+ loadingIndicator="spinner"
111
+ hapticOnTrigger={true}
112
+ networkAware={true}
113
+ >
114
+ <div className="min-h-screen bg-gray-50">
115
+ <MobileContainer className="py-6">
116
+ {/* Header */}
117
+ <div className="mb-6">
118
+ <div className="flex items-center justify-between">
119
+ <div>
120
+ <h1 className="text-2xl font-bold text-gray-900">
121
+ Welcome back, {user?.email?.split('@')[0]}
122
+ </h1>
123
+ <p className="text-gray-600 flex items-center gap-2">
124
+ {isOnline ? (
125
+ <>
126
+ <Wifi className="h-4 w-4 text-green-600" />
127
+ <span>Online</span>
128
+ </>
129
+ ) : (
130
+ <>
131
+ <WifiOff className="h-4 w-4 text-red-600" />
132
+ <span>Offline</span>
133
+ </>
134
+ )}
135
+ {networkInfo?.effectiveType && (
136
+ <span className="text-xs bg-gray-200 px-2 py-1 rounded">
137
+ {networkInfo.effectiveType.toUpperCase()}
138
+ </span>
139
+ )}
140
+ </p>
141
+ </div>
142
+ <Button variant="outline" size="icon">
143
+ <Settings className="h-4 w-4" />
144
+ </Button>
145
+ </div>
146
+ </div>
147
+
148
+ {/* Stats Grid */}
149
+ <NetworkAwareContent
150
+ showOnSlow={
151
+ <ResponsiveGrid columns={{ base: 2, md: 2 }} gap="sm" className="mb-6">
152
+ {stats.slice(0, 2).map((stat, index) => (
153
+ <Card key={index}>
154
+ <CardContent className="p-4">
155
+ <div className="flex items-center gap-2">
156
+ <stat.icon className={`h-5 w-5 text-${stat.color}-600`} />
157
+ <div>
158
+ <p className="text-sm font-medium text-gray-600">{stat.title}</p>
159
+ <p className="text-lg font-bold">{stat.value}</p>
160
+ </div>
161
+ </div>
162
+ </CardContent>
163
+ </Card>
164
+ ))}
165
+ </ResponsiveGrid>
166
+ }
167
+ >
168
+ <ResponsiveGrid columns={{ base: 2, md: 4 }} gap="md" className="mb-6">
169
+ {stats.map((stat, index) => (
170
+ <Card key={index}>
171
+ <CardContent className="p-4">
172
+ <div className="flex items-center justify-between mb-2">
173
+ <stat.icon className={`h-5 w-5 text-${stat.color}-600`} />
174
+ <span className="text-sm text-green-600 font-medium">
175
+ {stat.change}
176
+ </span>
177
+ </div>
178
+ <div>
179
+ <p className="text-sm font-medium text-gray-600">{stat.title}</p>
180
+ <p className="text-2xl font-bold">{stat.value}</p>
181
+ </div>
182
+ </CardContent>
183
+ </Card>
184
+ ))}
185
+ </ResponsiveGrid>
186
+ </NetworkAwareContent>
187
+
188
+ {/* Activity Feed */}
189
+ <Card className="mb-6">
190
+ <CardHeader>
191
+ <CardTitle className="flex items-center gap-2">
192
+ <BarChart3 className="h-5 w-5" />
193
+ Recent Activity
194
+ </CardTitle>
195
+ <CardDescription>
196
+ Swipe left on items to archive or star them
197
+ </CardDescription>
198
+ </CardHeader>
199
+ <CardContent className="p-0">
200
+ <VirtualScrollList
201
+ items={activityData}
202
+ itemHeight={80}
203
+ containerHeight={400}
204
+ bufferSize={5}
205
+ renderItem={(item) => (
206
+ <SwipeableCard
207
+ key={item.id}
208
+ leftActions={[
209
+ {
210
+ id: 'archive',
211
+ label: 'Archive',
212
+ onAction: () => handleArchive(item.id),
213
+ color: 'blue',
214
+ icon: Archive
215
+ },
216
+ {
217
+ id: 'star',
218
+ label: 'Star',
219
+ onAction: () => handleStar(item.id),
220
+ color: 'yellow',
221
+ icon: Star
222
+ }
223
+ ]}
224
+ rightActions={[
225
+ {
226
+ id: 'delete',
227
+ label: 'Delete',
228
+ onAction: () => handleDelete(item.id),
229
+ color: 'red',
230
+ icon: Trash2
231
+ }
232
+ ]}
233
+ threshold={50}
234
+ hapticFeedback={true}
235
+ showActionLabels={true}
236
+ >
237
+ <div className="flex items-center gap-3 p-4 border-b">
238
+ <LazyImage
239
+ src={item.avatar}
240
+ alt={`Activity ${item.id}`}
241
+ className="w-10 h-10 rounded-full"
242
+ placeholder="skeleton"
243
+ webpSupport={true}
244
+ mobileOptimization={{
245
+ quality: 80,
246
+ format: "webp"
247
+ }}
248
+ />
249
+ <div className="flex-1 min-w-0">
250
+ <h4 className="font-medium text-gray-900 truncate">
251
+ {item.title}
252
+ </h4>
253
+ <p className="text-sm text-gray-600 truncate">
254
+ {item.description}
255
+ </p>
256
+ <p className="text-xs text-gray-400">
257
+ {new Date(item.timestamp).toLocaleDateString()}
258
+ </p>
259
+ </div>
260
+ <div className={`px-2 py-1 rounded-full text-xs ${
261
+ item.type === 'user' ? 'bg-blue-100 text-blue-800' :
262
+ item.type === 'sale' ? 'bg-green-100 text-green-800' :
263
+ 'bg-gray-100 text-gray-800'
264
+ }`}>
265
+ {item.type}
266
+ </div>
267
+ </div>
268
+ </SwipeableCard>
269
+ )}
270
+ onEndReached={() => {
271
+ console.log('Loading more items...');
272
+ }}
273
+ mobileOptimized={true}
274
+ />
275
+ </CardContent>
276
+ </Card>
277
+
278
+ {/* Quick Actions */}
279
+ <Card>
280
+ <CardHeader>
281
+ <CardTitle>Quick Actions</CardTitle>
282
+ <CardDescription>
283
+ Common tasks and shortcuts
284
+ </CardDescription>
285
+ </CardHeader>
286
+ <CardContent>
287
+ <ResponsiveGrid columns={{ base: 2, md: 3 }} gap="sm">
288
+ <Button variant="outline" className="h-20 flex flex-col gap-2">
289
+ <Users className="h-5 w-5" />
290
+ <span className="text-xs">Manage Users</span>
291
+ </Button>
292
+ <Button variant="outline" className="h-20 flex flex-col gap-2">
293
+ <DollarSign className="h-5 w-5" />
294
+ <span className="text-xs">View Revenue</span>
295
+ </Button>
296
+ <Button variant="outline" className="h-20 flex flex-col gap-2">
297
+ <BarChart3 className="h-5 w-5" />
298
+ <span className="text-xs">Analytics</span>
299
+ </Button>
300
+ </ResponsiveGrid>
301
+ </CardContent>
302
+ </Card>
303
+ </MobileContainer>
304
+ </div>
305
+ </PullToRefresh>
306
+ </OfflineWrapper>
307
+ </PageTransition>
308
+ );
309
+ }
@@ -2,6 +2,9 @@
2
2
  @tailwind components;
3
3
  @tailwind utilities;
4
4
 
5
+ /* Import SaaS Factory UI styles */
6
+ @import '@digilogiclabs/saas-factory-ui/styles.css';
7
+
5
8
  @layer base {
6
9
  :root {
7
10
  --background: 0 0% 100%;
@@ -53,8 +56,102 @@
53
56
  * {
54
57
  @apply border-border;
55
58
  }
59
+
56
60
  body {
57
61
  @apply bg-background text-foreground;
58
62
  }
59
63
  }
60
64
 
65
+ /* Mobile-first optimizations */
66
+ @media (max-width: 768px) {
67
+ .mobile-optimized {
68
+ touch-action: manipulation;
69
+ -webkit-tap-highlight-color: transparent;
70
+ }
71
+
72
+ /* Better touch targets */
73
+ button,
74
+ a,
75
+ input,
76
+ select,
77
+ textarea {
78
+ min-height: 44px;
79
+ min-width: 44px;
80
+ }
81
+
82
+ /* Smooth scrolling for mobile */
83
+ html {
84
+ scroll-behavior: smooth;
85
+ -webkit-overflow-scrolling: touch;
86
+ }
87
+ }
88
+
89
+ /* Network-aware styles */
90
+ @media (prefers-reduced-data: reduce) {
91
+ .high-bandwidth-content {
92
+ display: none;
93
+ }
94
+ }
95
+
96
+ /* Reduced motion preferences */
97
+ @media (prefers-reduced-motion: reduce) {
98
+ *,
99
+ *::before,
100
+ *::after {
101
+ animation-duration: 0.01ms !important;
102
+ animation-iteration-count: 1 !important;
103
+ transition-duration: 0.01ms !important;
104
+ }
105
+ }
106
+
107
+ /* Custom animations for mobile interactions */
108
+ @keyframes haptic-feedback {
109
+ 0% { transform: scale(1); }
110
+ 50% { transform: scale(0.95); }
111
+ 100% { transform: scale(1); }
112
+ }
113
+
114
+ .haptic-feedback {
115
+ animation: haptic-feedback 0.1s ease-in-out;
116
+ }
117
+
118
+ /* Offline indicator styles */
119
+ .offline-indicator {
120
+ position: fixed;
121
+ top: 0;
122
+ left: 0;
123
+ right: 0;
124
+ background: #f59e0b;
125
+ color: white;
126
+ text-align: center;
127
+ padding: 8px;
128
+ font-size: 14px;
129
+ z-index: 9999;
130
+ }
131
+
132
+ /* Loading states */
133
+ .loading-skeleton {
134
+ background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
135
+ background-size: 200% 100%;
136
+ animation: loading 1.5s infinite;
137
+ }
138
+
139
+ @keyframes loading {
140
+ 0% {
141
+ background-position: 200% 0;
142
+ }
143
+ 100% {
144
+ background-position: -200% 0;
145
+ }
146
+ }
147
+
148
+ /* Progressive image loading */
149
+ .progressive-image {
150
+ filter: blur(5px);
151
+ transition: filter 0.3s;
152
+ }
153
+
154
+ .progressive-image.loaded {
155
+ filter: blur(0);
156
+ }
157
+
@@ -1,6 +1,12 @@
1
1
  'use client';
2
2
 
3
- import { LoginForm } from '@digilogiclabs/saas-factory-ui';
3
+ import {
4
+ LoginForm,
5
+ PageTransition,
6
+ MobileContainer,
7
+ NetworkAwareContent,
8
+ OfflineWrapper
9
+ } from '@digilogiclabs/saas-factory-ui';
4
10
  import { AuthProvider } from '@digilogiclabs/saas-factory-auth';
5
11
  import { createBrowserClient } from '@supabase/ssr';
6
12
  import React from 'react';
@@ -28,12 +34,34 @@ export default function LoginPage() {
28
34
  };
29
35
 
30
36
  return (
31
- <div className="flex items-center justify-center min-h-screen bg-gray-100">
32
- <LoginForm
33
- onSubmit={handleLogin}
34
- onGoogleSignIn={handleGoogleLogin}
35
- authProvider={AuthProvider.SUPABASE}
36
- />
37
- </div>
37
+ <PageTransition type="slide" direction="horizontal" duration={300}>
38
+ <OfflineWrapper
39
+ cacheStrategy="network-first"
40
+ showOfflineIndicator={true}
41
+ >
42
+ <NetworkAwareContent
43
+ showOnOffline={
44
+ <div className="flex items-center justify-center min-h-screen bg-gray-100">
45
+ <div className="text-center p-6">
46
+ <h2 className="text-xl font-semibold mb-2">You're offline</h2>
47
+ <p className="text-gray-600">Please check your connection to sign in.</p>
48
+ </div>
49
+ </div>
50
+ }
51
+ >
52
+ <div className="flex items-center justify-center min-h-screen bg-gray-100">
53
+ <MobileContainer className="w-full max-w-md">
54
+ <LoginForm
55
+ onSubmit={handleLogin}
56
+ onGoogleSignIn={handleGoogleLogin}
57
+ authProvider={AuthProvider.SUPABASE}
58
+ mobileOptimized={true}
59
+ touchFriendly={true}
60
+ />
61
+ </MobileContainer>
62
+ </div>
63
+ </NetworkAwareContent>
64
+ </OfflineWrapper>
65
+ </PageTransition>
38
66
  );
39
67
  }