@digilogiclabs/create-saas-app 2.3.0 → 2.4.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/generators/template-generator.js +4 -4
- package/dist/templates/mobile/base/template/package.json +1 -1
- package/dist/templates/mobile/ui-auth-payments/template/package.json +1 -1
- package/dist/templates/mobile/ui-auth-payments-ai/template/package.json +1 -1
- package/dist/templates/mobile/ui-auth-payments-ai-rag/template/package.json +1 -1
- package/dist/templates/web/ai-platform/template/package.json +2 -2
- package/dist/templates/web/ai-platform/template/src/app/error.tsx +75 -0
- package/dist/templates/web/ai-platform/template/src/app/loading.tsx +71 -0
- package/dist/templates/web/ai-platform/template/src/app/page.tsx +24 -20
- package/dist/templates/web/base/template/package.json +2 -2
- package/dist/templates/web/iot-dashboard/template/package.json +2 -2
- package/dist/templates/web/iot-dashboard/template/src/app/dashboard/page.tsx +6 -11
- package/dist/templates/web/iot-dashboard/template/src/app/error.tsx +75 -0
- package/dist/templates/web/iot-dashboard/template/src/app/loading.tsx +78 -0
- package/dist/templates/web/iot-dashboard/template/src/app/page.tsx +6 -8
- package/dist/templates/web/marketplace/template/package.json +2 -2
- package/dist/templates/web/marketplace/template/src/app/error.tsx +75 -0
- package/dist/templates/web/marketplace/template/src/app/loading.tsx +57 -0
- package/dist/templates/web/marketplace/template/src/app/page.tsx +13 -11
- package/dist/templates/web/micro-saas/template/package.json +2 -2
- package/dist/templates/web/micro-saas/template/src/app/error.tsx +75 -0
- package/dist/templates/web/micro-saas/template/src/app/loading.tsx +39 -0
- package/dist/templates/web/ui-auth/template/package.json +2 -2
- package/dist/templates/web/ui-auth-ai/template/package.json +1 -1
- package/dist/templates/web/ui-auth-payments/template/package.json +2 -2
- package/dist/templates/web/ui-auth-payments-ai/template/package.json +2 -2
- package/dist/templates/web/ui-auth-payments-ai-rag/template/package.json +1 -1
- package/dist/templates/web/ui-auth-payments-audio/template/package.json +1 -1
- package/dist/templates/web/ui-auth-payments-video/template/package.json +1 -1
- package/dist/templates/web/ui-only/template/package.json +1 -1
- package/dist/templates/web/ui-package-test/template/package.json +1 -1
- package/package.json +1 -1
- package/src/templates/mobile/base/template/package.json +1 -1
- package/src/templates/mobile/ui-auth-payments/template/package.json +1 -1
- package/src/templates/mobile/ui-auth-payments-ai/template/package.json +1 -1
- package/src/templates/mobile/ui-auth-payments-ai-rag/template/package.json +1 -1
- package/src/templates/web/ai-platform/template/package.json +2 -2
- package/src/templates/web/ai-platform/template/src/app/error.tsx +75 -0
- package/src/templates/web/ai-platform/template/src/app/loading.tsx +71 -0
- package/src/templates/web/ai-platform/template/src/app/page.tsx +24 -20
- package/src/templates/web/base/template/package.json +2 -2
- package/src/templates/web/iot-dashboard/template/package.json +2 -2
- package/src/templates/web/iot-dashboard/template/src/app/dashboard/page.tsx +6 -11
- package/src/templates/web/iot-dashboard/template/src/app/error.tsx +75 -0
- package/src/templates/web/iot-dashboard/template/src/app/loading.tsx +78 -0
- package/src/templates/web/iot-dashboard/template/src/app/page.tsx +6 -8
- package/src/templates/web/marketplace/template/package.json +2 -2
- package/src/templates/web/marketplace/template/src/app/error.tsx +75 -0
- package/src/templates/web/marketplace/template/src/app/loading.tsx +57 -0
- package/src/templates/web/marketplace/template/src/app/page.tsx +13 -11
- package/src/templates/web/micro-saas/template/package.json +2 -2
- package/src/templates/web/micro-saas/template/src/app/error.tsx +75 -0
- package/src/templates/web/micro-saas/template/src/app/loading.tsx +39 -0
- package/src/templates/web/ui-auth/template/package.json +2 -2
- package/src/templates/web/ui-auth-ai/template/package.json +1 -1
- package/src/templates/web/ui-auth-payments/template/package.json +2 -2
- package/src/templates/web/ui-auth-payments-ai/template/package.json +2 -2
- package/src/templates/web/ui-auth-payments-ai-rag/template/package.json +1 -1
- package/src/templates/web/ui-auth-payments-audio/template/package.json +1 -1
- package/src/templates/web/ui-auth-payments-video/template/package.json +1 -1
- package/src/templates/web/ui-only/template/package.json +1 -1
- package/src/templates/web/ui-package-test/template/package.json +1 -1
|
@@ -119,9 +119,9 @@ class TemplateGenerator {
|
|
|
119
119
|
generatedDate,
|
|
120
120
|
generatorVersion: '2.0.0',
|
|
121
121
|
// DLL package versions
|
|
122
|
-
platformCoreVersion: dependencies['@digilogiclabs/platform-core']?.replace('^', '') || '1.
|
|
122
|
+
platformCoreVersion: dependencies['@digilogiclabs/platform-core']?.replace('^', '') || '1.13.0',
|
|
123
123
|
appSdkVersion: dependencies['@digilogiclabs/app-sdk']?.replace('^', '') || '1.0.0',
|
|
124
|
-
uiVersion: dependencies['@digilogiclabs/saas-factory-ui']?.replace('^', '') || '1.0
|
|
124
|
+
uiVersion: dependencies['@digilogiclabs/saas-factory-ui']?.replace('^', '') || '1.4.0',
|
|
125
125
|
authVersion: dependencies['@digilogiclabs/saas-factory-auth']?.replace('^', '') || '1.0.0',
|
|
126
126
|
paymentsVersion: dependencies['@digilogiclabs/saas-factory-payments']?.replace('^', '') || '1.0.0',
|
|
127
127
|
aiVersion: dependencies['@digilogiclabs/saas-factory-ai']?.replace('^', '') || '1.0.0',
|
|
@@ -139,7 +139,7 @@ class TemplateGenerator {
|
|
|
139
139
|
// ═══════════════════════════════════════════════════════════════
|
|
140
140
|
// Platform Core - Always included for all tiers (infrastructure abstraction)
|
|
141
141
|
if (features.platformCore) {
|
|
142
|
-
baseDeps['@digilogiclabs/platform-core'] = '^1.
|
|
142
|
+
baseDeps['@digilogiclabs/platform-core'] = '^1.13.0';
|
|
143
143
|
}
|
|
144
144
|
// App SDK - Always included for React apps (unified hooks)
|
|
145
145
|
if (features.appSdk && (this.config.platform === 'web' || this.config.platform === 'both')) {
|
|
@@ -160,7 +160,7 @@ class TemplateGenerator {
|
|
|
160
160
|
'ai-platform',
|
|
161
161
|
'iot-dashboard',
|
|
162
162
|
].includes(this.config.template)) {
|
|
163
|
-
baseDeps['@digilogiclabs/saas-factory-ui'] = '^1.
|
|
163
|
+
baseDeps['@digilogiclabs/saas-factory-ui'] = '^1.4.0';
|
|
164
164
|
}
|
|
165
165
|
// Auth package (tier: micro+)
|
|
166
166
|
if (features.auth && this.config.template !== 'base' && this.config.template !== 'ui-only') {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"react-native-screens": "~3.22.0",
|
|
23
23
|
"react-native-safe-area-context": "4.6.3",
|
|
24
24
|
"react-native-gesture-handler": "~2.12.0",
|
|
25
|
-
"@digilogiclabs/saas-factory-ui": "^
|
|
25
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
26
26
|
"@digilogiclabs/saas-factory-auth": "^1.0.5",
|
|
27
27
|
"@digilogiclabs/saas-factory-payments": "^1.2.7",
|
|
28
28
|
"firebase": "^10.0.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"react-native-gesture-handler": "~2.14.0",
|
|
36
36
|
"react-native-reanimated": "~3.6.2",
|
|
37
37
|
|
|
38
|
-
"@digilogiclabs/saas-factory-ui": "^
|
|
38
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
39
39
|
"@digilogiclabs/saas-factory-auth": "^1.0.5",
|
|
40
40
|
"@digilogiclabs/saas-factory-payments": "^1.2.7",
|
|
41
41
|
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"react-native-gesture-handler": "~2.14.0",
|
|
36
36
|
"react-native-reanimated": "~3.6.2",
|
|
37
37
|
|
|
38
|
-
"@digilogiclabs/saas-factory-ui": "^
|
|
38
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
39
39
|
"@digilogiclabs/saas-factory-auth": "^1.0.5",
|
|
40
40
|
"@digilogiclabs/saas-factory-payments": "^1.2.7",
|
|
41
41
|
"@digilogiclabs/saas-factory-ai": "^4.0.2",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"react-native-gesture-handler": "~2.14.0",
|
|
39
39
|
"react-native-reanimated": "~3.6.2",
|
|
40
40
|
|
|
41
|
-
"@digilogiclabs/saas-factory-ui": "^
|
|
41
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
42
42
|
"@digilogiclabs/saas-factory-auth": "^1.0.5",
|
|
43
43
|
"@digilogiclabs/saas-factory-payments": "^1.2.7",
|
|
44
44
|
"@digilogiclabs/saas-factory-ai": "^4.0.2",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"next": "^15.0.0",
|
|
17
17
|
"react": "^19.0.0",
|
|
18
18
|
"react-dom": "^19.0.0",
|
|
19
|
-
"@digilogiclabs/platform-core": "^1.
|
|
19
|
+
"@digilogiclabs/platform-core": "^1.13.0",
|
|
20
20
|
"@digilogiclabs/app-sdk": "^1.0.0",
|
|
21
21
|
"@digilogiclabs/saas-factory-auth": "^1.0.7",
|
|
22
22
|
"@digilogiclabs/saas-factory-payments": "^1.2.9",
|
|
23
23
|
"@digilogiclabs/saas-factory-ai": "^1.0.0",
|
|
24
|
-
"@digilogiclabs/saas-factory-ui": "^1.0
|
|
24
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
25
25
|
"ai": "^3.4.0",
|
|
26
26
|
"@ai-sdk/openai": "^0.0.70",
|
|
27
27
|
"@ai-sdk/anthropic": "^0.0.57",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useEffect } from 'react'
|
|
4
|
+
import { Button, Card } from '@digilogiclabs/saas-factory-ui'
|
|
5
|
+
import { AlertTriangle, RefreshCw, Home } from 'lucide-react'
|
|
6
|
+
import Link from 'next/link'
|
|
7
|
+
|
|
8
|
+
interface ErrorProps {
|
|
9
|
+
error: Error & { digest?: string }
|
|
10
|
+
reset: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function Error({ error, reset }: ErrorProps) {
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
console.error('Application error:', error)
|
|
16
|
+
}, [error])
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 flex items-center justify-center p-4">
|
|
20
|
+
<Card className="p-8 max-w-lg w-full bg-white/5 border-white/10 backdrop-blur-sm">
|
|
21
|
+
<div className="flex flex-col items-center space-y-6 text-center">
|
|
22
|
+
<div className="w-16 h-16 bg-red-500/20 rounded-full flex items-center justify-center">
|
|
23
|
+
<AlertTriangle className="w-8 h-8 text-red-400" />
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div>
|
|
27
|
+
<h1 className="text-2xl font-bold text-white mb-2">
|
|
28
|
+
Something went wrong!
|
|
29
|
+
</h1>
|
|
30
|
+
<p className="text-gray-400 mb-4">
|
|
31
|
+
We encountered an unexpected error. This has been logged and our team will look into it.
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
{process.env.NODE_ENV === 'development' && (
|
|
35
|
+
<details className="mt-4 text-left">
|
|
36
|
+
<summary className="cursor-pointer text-sm text-gray-500 hover:text-gray-300">
|
|
37
|
+
Error details (development only)
|
|
38
|
+
</summary>
|
|
39
|
+
<div className="mt-2 p-3 bg-black/30 rounded text-xs font-mono text-gray-400 overflow-auto max-h-40">
|
|
40
|
+
<div className="mb-2">
|
|
41
|
+
<strong className="text-gray-300">Message:</strong> {error.message}
|
|
42
|
+
</div>
|
|
43
|
+
{error.digest && (
|
|
44
|
+
<div className="mb-2">
|
|
45
|
+
<strong className="text-gray-300">Digest:</strong> {error.digest}
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
{error.stack && (
|
|
49
|
+
<div>
|
|
50
|
+
<strong className="text-gray-300">Stack:</strong>
|
|
51
|
+
<pre className="whitespace-pre-wrap mt-1">{error.stack}</pre>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
</div>
|
|
55
|
+
</details>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className="flex flex-col sm:flex-row gap-3 w-full">
|
|
60
|
+
<Button onClick={reset} className="flex-1 bg-purple-600 hover:bg-purple-700" size="lg">
|
|
61
|
+
<RefreshCw className="w-4 h-4 mr-2" />
|
|
62
|
+
Try again
|
|
63
|
+
</Button>
|
|
64
|
+
<Link href="/" className="flex-1">
|
|
65
|
+
<Button variant="outline" className="w-full border-white/20 text-white hover:bg-white/10" size="lg">
|
|
66
|
+
<Home className="w-4 h-4 mr-2" />
|
|
67
|
+
Go home
|
|
68
|
+
</Button>
|
|
69
|
+
</Link>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</Card>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Card, SkeletonText } from '@digilogiclabs/saas-factory-ui'
|
|
2
|
+
|
|
3
|
+
export default function Loading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900">
|
|
6
|
+
{/* Header skeleton */}
|
|
7
|
+
<div className="border-b border-white/10 bg-black/20 backdrop-blur-sm px-4 py-4">
|
|
8
|
+
<div className="max-w-7xl mx-auto flex items-center justify-between">
|
|
9
|
+
<SkeletonText className="h-8 w-48 bg-white/10" />
|
|
10
|
+
<div className="flex gap-6">
|
|
11
|
+
<SkeletonText className="h-4 w-16 bg-white/10" />
|
|
12
|
+
<SkeletonText className="h-4 w-20 bg-white/10" />
|
|
13
|
+
<SkeletonText className="h-4 w-12 bg-white/10" />
|
|
14
|
+
</div>
|
|
15
|
+
<div className="flex gap-2">
|
|
16
|
+
<SkeletonText className="h-8 w-20 bg-white/10" />
|
|
17
|
+
<SkeletonText className="h-8 w-24 bg-white/10" />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div className="max-w-7xl mx-auto px-4 py-16">
|
|
23
|
+
{/* Hero skeleton */}
|
|
24
|
+
<div className="text-center mb-20">
|
|
25
|
+
<SkeletonText className="h-6 w-40 mx-auto mb-6 bg-purple-500/20" />
|
|
26
|
+
<SkeletonText className="h-16 w-80 mx-auto mb-6 bg-white/10" />
|
|
27
|
+
<SkeletonText className="h-6 w-96 mx-auto mb-8 bg-white/10" />
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
{/* Feature cards skeleton */}
|
|
31
|
+
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6 mb-20">
|
|
32
|
+
{Array.from({ length: 4 }).map((_, i) => (
|
|
33
|
+
<Card key={i} className="p-6 bg-white/5 border-white/10">
|
|
34
|
+
<div className="animate-pulse">
|
|
35
|
+
<SkeletonText className="h-12 w-12 mb-4 bg-white/10 rounded-lg" />
|
|
36
|
+
<SkeletonText className="h-5 w-24 mb-2 bg-white/10" />
|
|
37
|
+
<SkeletonText className="h-4 w-full bg-white/10" />
|
|
38
|
+
</div>
|
|
39
|
+
</Card>
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
{/* Models skeleton */}
|
|
44
|
+
<div className="mb-20">
|
|
45
|
+
<SkeletonText className="h-8 w-48 mb-8 bg-white/10" />
|
|
46
|
+
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
47
|
+
{Array.from({ length: 4 }).map((_, i) => (
|
|
48
|
+
<Card key={i} className="p-4 bg-white/5 border-white/10">
|
|
49
|
+
<div className="animate-pulse">
|
|
50
|
+
<SkeletonText className="h-5 w-20 mb-2 bg-white/10" />
|
|
51
|
+
<SkeletonText className="h-4 w-16 bg-white/10" />
|
|
52
|
+
</div>
|
|
53
|
+
</Card>
|
|
54
|
+
))}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
{/* Loading indicator */}
|
|
59
|
+
<div className="flex justify-center">
|
|
60
|
+
<div className="flex items-center gap-3 text-gray-400">
|
|
61
|
+
<div className="relative">
|
|
62
|
+
<div className="w-8 h-8 border-4 border-white/10 rounded-full"></div>
|
|
63
|
+
<div className="absolute top-0 left-0 w-8 h-8 border-4 border-purple-500 border-t-transparent rounded-full animate-spin"></div>
|
|
64
|
+
</div>
|
|
65
|
+
<p className="text-sm">Loading AI platform...</p>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { Button, Card } from '@digilogiclabs/saas-factory-ui'
|
|
3
|
+
import { Button, Card, PremiumCard, PremiumCardContent, GradientBorderCard } from '@digilogiclabs/saas-factory-ui'
|
|
4
4
|
import { useAuth } from '@digilogiclabs/app-sdk'
|
|
5
5
|
import { Bot, Sparkles, Zap, MessageSquare, Code, Brain, ArrowRight, User, LogOut } from 'lucide-react'
|
|
6
6
|
import Link from 'next/link'
|
|
@@ -140,13 +140,15 @@ export default function Home() {
|
|
|
140
140
|
{/* Features */}
|
|
141
141
|
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6 mb-20">
|
|
142
142
|
{FEATURES.map((feature) => (
|
|
143
|
-
<
|
|
144
|
-
<
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
<PremiumCard key={feature.title} variant="glass" className="bg-white/5 border-white/10 backdrop-blur-sm">
|
|
144
|
+
<PremiumCardContent className="p-6">
|
|
145
|
+
<div className={`w-12 h-12 rounded-lg flex items-center justify-center mb-4 bg-${feature.color}-500/20`}>
|
|
146
|
+
<feature.icon className={`w-6 h-6 text-${feature.color}-400`} />
|
|
147
|
+
</div>
|
|
148
|
+
<h3 className="text-lg font-semibold text-white mb-2">{feature.title}</h3>
|
|
149
|
+
<p className="text-gray-400 text-sm">{feature.description}</p>
|
|
150
|
+
</PremiumCardContent>
|
|
151
|
+
</PremiumCard>
|
|
150
152
|
))}
|
|
151
153
|
</div>
|
|
152
154
|
|
|
@@ -185,18 +187,20 @@ export default function Home() {
|
|
|
185
187
|
</div>
|
|
186
188
|
|
|
187
189
|
{/* CTA */}
|
|
188
|
-
<
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
<
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
190
|
+
<GradientBorderCard gradientColors="from-purple-500 via-pink-500 to-purple-500" borderWidth={2}>
|
|
191
|
+
<div className="text-center py-6">
|
|
192
|
+
<h2 className="text-3xl font-bold text-white mb-4">Ready to Build?</h2>
|
|
193
|
+
<p className="text-gray-400 mb-8 max-w-md mx-auto">
|
|
194
|
+
Start building AI-powered applications today. Free tier available.
|
|
195
|
+
</p>
|
|
196
|
+
<Link href="/signup">
|
|
197
|
+
<Button size="lg" className="bg-purple-600 hover:bg-purple-700">
|
|
198
|
+
Get Started Free
|
|
199
|
+
<ArrowRight className="w-5 h-5 ml-2" />
|
|
200
|
+
</Button>
|
|
201
|
+
</Link>
|
|
202
|
+
</div>
|
|
203
|
+
</GradientBorderCard>
|
|
200
204
|
</div>
|
|
201
205
|
</main>
|
|
202
206
|
)
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"next": "^15.0.0",
|
|
18
18
|
"react": "^19.0.0",
|
|
19
19
|
"react-dom": "^19.0.0",
|
|
20
|
-
"@digilogiclabs/platform-core": "^1.
|
|
21
|
-
"@digilogiclabs/saas-factory-ui": "^
|
|
20
|
+
"@digilogiclabs/platform-core": "^1.13.0",
|
|
21
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
22
22
|
"@digilogiclabs/saas-factory-auth": "^1.0.6",
|
|
23
23
|
"@digilogiclabs/saas-factory-payments": "^1.2.8",
|
|
24
24
|
"tailwindcss": "^3.3.0",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"next": "^15.0.0",
|
|
17
17
|
"react": "^19.0.0",
|
|
18
18
|
"react-dom": "^19.0.0",
|
|
19
|
-
"@digilogiclabs/platform-core": "^1.
|
|
19
|
+
"@digilogiclabs/platform-core": "^1.13.0",
|
|
20
20
|
"@digilogiclabs/app-sdk": "^1.0.0",
|
|
21
21
|
"@digilogiclabs/saas-factory-auth": "^1.0.7",
|
|
22
|
-
"@digilogiclabs/saas-factory-ui": "^1.0
|
|
22
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
23
23
|
"tailwindcss": "^4.0.0",
|
|
24
24
|
"clsx": "^2.0.0",
|
|
25
25
|
"class-variance-authority": "^0.7.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect } from 'react'
|
|
4
|
-
import { Button, Card } from '@digilogiclabs/saas-factory-ui'
|
|
4
|
+
import { Button, Card, PulseIndicator } from '@digilogiclabs/saas-factory-ui'
|
|
5
5
|
import { Cpu, Activity, Signal, Bell, AlertTriangle, CheckCircle, Clock, ThermometerSun, Gauge, Wifi, Plus } from 'lucide-react'
|
|
6
6
|
import Link from 'next/link'
|
|
7
7
|
|
|
@@ -202,16 +202,11 @@ export default function DashboardPage() {
|
|
|
202
202
|
</td>
|
|
203
203
|
<td className="py-3 px-4 text-slate-600 dark:text-slate-400">{device.type}</td>
|
|
204
204
|
<td className="py-3 px-4">
|
|
205
|
-
<
|
|
206
|
-
device.status === 'online'
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
<span className={`w-1.5 h-1.5 rounded-full mr-1.5 ${
|
|
211
|
-
device.status === 'online' ? 'bg-green-500' : 'bg-red-500'
|
|
212
|
-
}`} />
|
|
213
|
-
{device.status}
|
|
214
|
-
</span>
|
|
205
|
+
<PulseIndicator
|
|
206
|
+
status={device.status === 'online' ? 'success' : 'error'}
|
|
207
|
+
label={device.status}
|
|
208
|
+
size="sm"
|
|
209
|
+
/>
|
|
215
210
|
</td>
|
|
216
211
|
<td className="py-3 px-4 text-slate-600 dark:text-slate-400 flex items-center">
|
|
217
212
|
<Clock className="w-3 h-3 mr-1" />
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useEffect } from 'react'
|
|
4
|
+
import { Button, Card } from '@digilogiclabs/saas-factory-ui'
|
|
5
|
+
import { AlertTriangle, RefreshCw, Home } from 'lucide-react'
|
|
6
|
+
import Link from 'next/link'
|
|
7
|
+
|
|
8
|
+
interface ErrorProps {
|
|
9
|
+
error: Error & { digest?: string }
|
|
10
|
+
reset: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function Error({ error, reset }: ErrorProps) {
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
console.error('Application error:', error)
|
|
16
|
+
}, [error])
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="min-h-screen bg-gradient-to-br from-red-50 to-orange-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center p-4">
|
|
20
|
+
<Card className="p-8 max-w-lg w-full">
|
|
21
|
+
<div className="flex flex-col items-center space-y-6 text-center">
|
|
22
|
+
<div className="w-16 h-16 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center">
|
|
23
|
+
<AlertTriangle className="w-8 h-8 text-red-600 dark:text-red-400" />
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div>
|
|
27
|
+
<h1 className="text-2xl font-bold text-slate-900 dark:text-white mb-2">
|
|
28
|
+
Something went wrong!
|
|
29
|
+
</h1>
|
|
30
|
+
<p className="text-slate-600 dark:text-slate-300 mb-4">
|
|
31
|
+
We encountered an unexpected error. This has been logged and our team will look into it.
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
{process.env.NODE_ENV === 'development' && (
|
|
35
|
+
<details className="mt-4 text-left">
|
|
36
|
+
<summary className="cursor-pointer text-sm text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200">
|
|
37
|
+
Error details (development only)
|
|
38
|
+
</summary>
|
|
39
|
+
<div className="mt-2 p-3 bg-slate-100 dark:bg-slate-800 rounded text-xs font-mono text-slate-700 dark:text-slate-300 overflow-auto max-h-40">
|
|
40
|
+
<div className="mb-2">
|
|
41
|
+
<strong>Message:</strong> {error.message}
|
|
42
|
+
</div>
|
|
43
|
+
{error.digest && (
|
|
44
|
+
<div className="mb-2">
|
|
45
|
+
<strong>Digest:</strong> {error.digest}
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
{error.stack && (
|
|
49
|
+
<div>
|
|
50
|
+
<strong>Stack:</strong>
|
|
51
|
+
<pre className="whitespace-pre-wrap mt-1">{error.stack}</pre>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
</div>
|
|
55
|
+
</details>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className="flex flex-col sm:flex-row gap-3 w-full">
|
|
60
|
+
<Button onClick={reset} className="flex-1 bg-emerald-600 hover:bg-emerald-700" size="lg">
|
|
61
|
+
<RefreshCw className="w-4 h-4 mr-2" />
|
|
62
|
+
Try again
|
|
63
|
+
</Button>
|
|
64
|
+
<Link href="/" className="flex-1">
|
|
65
|
+
<Button variant="outline" className="w-full" size="lg">
|
|
66
|
+
<Home className="w-4 h-4 mr-2" />
|
|
67
|
+
Go home
|
|
68
|
+
</Button>
|
|
69
|
+
</Link>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</Card>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Card, SkeletonText } from '@digilogiclabs/saas-factory-ui'
|
|
2
|
+
|
|
3
|
+
export default function Loading() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="min-h-screen bg-slate-50 dark:bg-slate-900">
|
|
6
|
+
{/* Header skeleton */}
|
|
7
|
+
<div className="bg-white dark:bg-slate-800 border-b border-slate-200 dark:border-slate-700 px-4 py-4">
|
|
8
|
+
<div className="max-w-7xl mx-auto flex items-center justify-between">
|
|
9
|
+
<div className="flex items-center gap-2">
|
|
10
|
+
<SkeletonText className="h-8 w-8 rounded-lg" />
|
|
11
|
+
<SkeletonText className="h-8 w-48" />
|
|
12
|
+
</div>
|
|
13
|
+
<div className="flex gap-6">
|
|
14
|
+
<SkeletonText className="h-4 w-16" />
|
|
15
|
+
<SkeletonText className="h-4 w-20" />
|
|
16
|
+
<SkeletonText className="h-4 w-12" />
|
|
17
|
+
</div>
|
|
18
|
+
<div className="flex gap-2">
|
|
19
|
+
<SkeletonText className="h-8 w-20" />
|
|
20
|
+
<SkeletonText className="h-8 w-24" />
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div className="max-w-7xl mx-auto px-4 py-16">
|
|
26
|
+
{/* Hero skeleton */}
|
|
27
|
+
<div className="text-center mb-16">
|
|
28
|
+
<SkeletonText className="h-6 w-48 mx-auto mb-6" />
|
|
29
|
+
<SkeletonText className="h-12 w-96 mx-auto mb-6" />
|
|
30
|
+
<SkeletonText className="h-6 w-[32rem] mx-auto mb-8" />
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
{/* Device cards skeleton */}
|
|
34
|
+
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-4 mb-16">
|
|
35
|
+
{Array.from({ length: 4 }).map((_, i) => (
|
|
36
|
+
<Card key={i} className="p-6">
|
|
37
|
+
<div className="animate-pulse">
|
|
38
|
+
<div className="flex items-center justify-between mb-3">
|
|
39
|
+
<SkeletonText className="h-10 w-10 rounded-lg" />
|
|
40
|
+
<SkeletonText className="h-5 w-20 rounded-full" />
|
|
41
|
+
</div>
|
|
42
|
+
<SkeletonText className="h-5 w-32 mb-2" />
|
|
43
|
+
<SkeletonText className="h-8 w-12" />
|
|
44
|
+
</div>
|
|
45
|
+
</Card>
|
|
46
|
+
))}
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
{/* Features skeleton */}
|
|
50
|
+
<div className="mb-16">
|
|
51
|
+
<SkeletonText className="h-8 w-64 mx-auto mb-12" />
|
|
52
|
+
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
53
|
+
{Array.from({ length: 4 }).map((_, i) => (
|
|
54
|
+
<Card key={i} className="p-6">
|
|
55
|
+
<div className="animate-pulse text-center">
|
|
56
|
+
<SkeletonText className="h-12 w-12 mx-auto mb-4 rounded-lg" />
|
|
57
|
+
<SkeletonText className="h-5 w-32 mx-auto mb-2" />
|
|
58
|
+
<SkeletonText className="h-4 w-full" />
|
|
59
|
+
</div>
|
|
60
|
+
</Card>
|
|
61
|
+
))}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
{/* Loading indicator */}
|
|
66
|
+
<div className="flex justify-center">
|
|
67
|
+
<div className="flex items-center gap-3">
|
|
68
|
+
<div className="relative">
|
|
69
|
+
<div className="w-8 h-8 border-4 border-slate-200 dark:border-slate-700 rounded-full"></div>
|
|
70
|
+
<div className="absolute top-0 left-0 w-8 h-8 border-4 border-emerald-600 border-t-transparent rounded-full animate-spin"></div>
|
|
71
|
+
</div>
|
|
72
|
+
<p className="text-sm text-slate-600 dark:text-slate-300">Loading IoT dashboard...</p>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { Button, Card } from '@digilogiclabs/saas-factory-ui'
|
|
3
|
+
import { Button, Card, PulseIndicator } from '@digilogiclabs/saas-factory-ui'
|
|
4
4
|
import { useAuth } from '@digilogiclabs/app-sdk'
|
|
5
5
|
import { Cpu, Activity, Signal, Bell, Settings, ArrowRight, User, LogOut, Wifi, ThermometerSun, Gauge, Shield } from 'lucide-react'
|
|
6
6
|
import Link from 'next/link'
|
|
@@ -140,13 +140,11 @@ export default function Home() {
|
|
|
140
140
|
<div className="w-10 h-10 bg-emerald-100 dark:bg-emerald-900/30 rounded-lg flex items-center justify-center">
|
|
141
141
|
<device.icon className="w-5 h-5 text-emerald-600" />
|
|
142
142
|
</div>
|
|
143
|
-
<
|
|
144
|
-
device.status === 'online'
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
{device.status === 'online' ? 'All Online' : 'Partial'}
|
|
149
|
-
</span>
|
|
143
|
+
<PulseIndicator
|
|
144
|
+
status={device.status === 'online' ? 'success' : 'loading'}
|
|
145
|
+
label={device.status === 'online' ? 'All Online' : 'Partial'}
|
|
146
|
+
size="sm"
|
|
147
|
+
/>
|
|
150
148
|
</div>
|
|
151
149
|
<h3 className="font-semibold text-slate-900 dark:text-white">{device.name}</h3>
|
|
152
150
|
<p className="text-2xl font-bold text-emerald-600">{device.count}</p>
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"next": "^15.0.0",
|
|
17
17
|
"react": "^19.0.0",
|
|
18
18
|
"react-dom": "^19.0.0",
|
|
19
|
-
"@digilogiclabs/platform-core": "^1.
|
|
19
|
+
"@digilogiclabs/platform-core": "^1.13.0",
|
|
20
20
|
"@digilogiclabs/app-sdk": "^1.0.0",
|
|
21
21
|
"@digilogiclabs/saas-factory-auth": "^1.0.7",
|
|
22
22
|
"@digilogiclabs/saas-factory-payments": "^1.2.9",
|
|
23
|
-
"@digilogiclabs/saas-factory-ui": "^1.0
|
|
23
|
+
"@digilogiclabs/saas-factory-ui": "^1.4.0",
|
|
24
24
|
"stripe": "^16.12.0",
|
|
25
25
|
"@stripe/react-stripe-js": "^2.8.0",
|
|
26
26
|
"@stripe/stripe-js": "^4.10.0",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useEffect } from 'react'
|
|
4
|
+
import { Button, Card } from '@digilogiclabs/saas-factory-ui'
|
|
5
|
+
import { AlertTriangle, RefreshCw, Home } from 'lucide-react'
|
|
6
|
+
import Link from 'next/link'
|
|
7
|
+
|
|
8
|
+
interface ErrorProps {
|
|
9
|
+
error: Error & { digest?: string }
|
|
10
|
+
reset: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function Error({ error, reset }: ErrorProps) {
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
console.error('Application error:', error)
|
|
16
|
+
}, [error])
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="min-h-screen bg-gradient-to-br from-red-50 to-orange-100 dark:from-gray-900 dark:to-gray-800 flex items-center justify-center p-4">
|
|
20
|
+
<Card className="p-8 max-w-lg w-full">
|
|
21
|
+
<div className="flex flex-col items-center space-y-6 text-center">
|
|
22
|
+
<div className="w-16 h-16 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center">
|
|
23
|
+
<AlertTriangle className="w-8 h-8 text-red-600 dark:text-red-400" />
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div>
|
|
27
|
+
<h1 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
|
|
28
|
+
Something went wrong!
|
|
29
|
+
</h1>
|
|
30
|
+
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
|
31
|
+
We encountered an unexpected error. This has been logged and our team will look into it.
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
{process.env.NODE_ENV === 'development' && (
|
|
35
|
+
<details className="mt-4 text-left">
|
|
36
|
+
<summary className="cursor-pointer text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
|
37
|
+
Error details (development only)
|
|
38
|
+
</summary>
|
|
39
|
+
<div className="mt-2 p-3 bg-gray-100 dark:bg-gray-800 rounded text-xs font-mono text-gray-700 dark:text-gray-300 overflow-auto max-h-40">
|
|
40
|
+
<div className="mb-2">
|
|
41
|
+
<strong>Message:</strong> {error.message}
|
|
42
|
+
</div>
|
|
43
|
+
{error.digest && (
|
|
44
|
+
<div className="mb-2">
|
|
45
|
+
<strong>Digest:</strong> {error.digest}
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
{error.stack && (
|
|
49
|
+
<div>
|
|
50
|
+
<strong>Stack:</strong>
|
|
51
|
+
<pre className="whitespace-pre-wrap mt-1">{error.stack}</pre>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
</div>
|
|
55
|
+
</details>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className="flex flex-col sm:flex-row gap-3 w-full">
|
|
60
|
+
<Button onClick={reset} className="flex-1" size="lg">
|
|
61
|
+
<RefreshCw className="w-4 h-4 mr-2" />
|
|
62
|
+
Try again
|
|
63
|
+
</Button>
|
|
64
|
+
<Link href="/" className="flex-1">
|
|
65
|
+
<Button variant="outline" className="w-full" size="lg">
|
|
66
|
+
<Home className="w-4 h-4 mr-2" />
|
|
67
|
+
Go home
|
|
68
|
+
</Button>
|
|
69
|
+
</Link>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</Card>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|