@digilogiclabs/create-saas-app 1.12.0 → 1.14.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/README.md +104 -36
- package/dist/.tsbuildinfo +1 -1
- package/dist/cli/commands/add.d.ts +6 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +39 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/index.d.ts +4 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +20 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/update.d.ts +6 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +68 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +61 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts/index.d.ts +2 -0
- package/dist/cli/prompts/index.d.ts.map +1 -0
- package/dist/cli/prompts/index.js +18 -0
- package/dist/cli/prompts/index.js.map +1 -0
- package/dist/cli/prompts/project-setup.d.ts +5 -0
- package/dist/cli/prompts/project-setup.d.ts.map +1 -0
- package/dist/cli/prompts/project-setup.js +251 -0
- package/dist/cli/prompts/project-setup.js.map +1 -0
- package/dist/cli/utils/git.d.ts +9 -0
- package/dist/cli/utils/git.d.ts.map +1 -0
- package/dist/cli/utils/git.js +77 -0
- package/dist/cli/utils/git.js.map +1 -0
- package/dist/cli/utils/index.d.ts +5 -0
- package/dist/cli/utils/index.d.ts.map +1 -0
- package/dist/cli/utils/index.js +21 -0
- package/dist/cli/utils/index.js.map +1 -0
- package/dist/cli/utils/logger.d.ts +16 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/cli/utils/logger.js +55 -0
- package/dist/cli/utils/logger.js.map +1 -0
- package/dist/cli/utils/package-manager.d.ts +8 -0
- package/dist/cli/utils/package-manager.d.ts.map +1 -0
- package/dist/cli/utils/package-manager.js +92 -0
- package/dist/cli/utils/package-manager.js.map +1 -0
- package/dist/cli/utils/spinner.d.ts +7 -0
- package/dist/cli/utils/spinner.d.ts.map +1 -0
- package/dist/cli/utils/spinner.js +48 -0
- package/dist/cli/utils/spinner.js.map +1 -0
- package/dist/cli/validators/dependencies.d.ts +15 -0
- package/dist/cli/validators/dependencies.d.ts.map +1 -0
- package/dist/cli/validators/dependencies.js +108 -0
- package/dist/cli/validators/dependencies.js.map +1 -0
- package/dist/cli/validators/index.d.ts +3 -0
- package/dist/cli/validators/index.d.ts.map +1 -0
- package/dist/cli/validators/index.js +19 -0
- package/dist/cli/validators/index.js.map +1 -0
- package/dist/cli/validators/project-name.d.ts +5 -0
- package/dist/cli/validators/project-name.d.ts.map +1 -0
- package/dist/cli/validators/project-name.js +151 -0
- package/dist/cli/validators/project-name.js.map +1 -0
- package/dist/generators/file-processor.d.ts +28 -0
- package/dist/generators/file-processor.d.ts.map +1 -0
- package/dist/generators/file-processor.js +224 -0
- package/dist/generators/file-processor.js.map +1 -0
- package/dist/generators/index.d.ts +4 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +20 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/package-installer.d.ts +29 -0
- package/dist/generators/package-installer.d.ts.map +1 -0
- package/dist/generators/package-installer.js +167 -0
- package/dist/generators/package-installer.js.map +1 -0
- package/dist/templates/web/ui-auth/template/package.json +2 -2
- package/dist/templates/web/ui-auth/template/src/app/globals.css +53 -0
- package/dist/templates/web/ui-auth/template/src/app/page.tsx +14 -1
- package/dist/templates/web/ui-auth-payments/template/package.json +3 -3
- package/dist/templates/web/ui-auth-payments/template/src/app/globals.css +40 -0
- package/dist/templates/web/ui-auth-payments/template/src/app/page.tsx +14 -1
- package/dist/templates/web/ui-auth-payments-ai/template/.env.example +7 -0
- package/dist/templates/web/ui-auth-payments-ai/template/package.json +6 -6
- package/dist/templates/web/ui-auth-payments-ai/template/src/app/globals.css +53 -0
- package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +75 -61
- package/dist/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +19 -14
- package/dist/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +18 -11
- package/dist/templates/web/ui-auth-payments-ai/template/src/lib/supabase/server.ts +72 -0
- package/dist/templates/web/ui-auth-payments-audio/template/package.json +3 -3
- package/dist/templates/web/ui-auth-payments-audio/template/src/app/globals.css +53 -0
- package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +23 -13
- package/dist/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +18 -11
- package/dist/templates/web/ui-auth-payments-video/template/package.json +3 -3
- package/dist/templates/web/ui-auth-payments-video/template/src/app/globals.css +40 -0
- package/dist/templates/web/ui-auth-payments-video/template/src/app/page.tsx +14 -1
- package/package.json +1 -1
- package/src/templates/web/ui-auth/template/package.json +2 -2
- package/src/templates/web/ui-auth/template/src/app/globals.css +53 -0
- package/src/templates/web/ui-auth/template/src/app/page.tsx +14 -1
- package/src/templates/web/ui-auth-payments/template/package.json +3 -3
- package/src/templates/web/ui-auth-payments/template/src/app/globals.css +40 -0
- package/src/templates/web/ui-auth-payments/template/src/app/page.tsx +14 -1
- package/src/templates/web/ui-auth-payments-ai/template/.env.example +7 -0
- package/src/templates/web/ui-auth-payments-ai/template/package.json +6 -6
- package/src/templates/web/ui-auth-payments-ai/template/src/app/globals.css +53 -0
- package/src/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +75 -61
- package/src/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +19 -14
- package/src/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +18 -11
- package/src/templates/web/ui-auth-payments-ai/template/src/lib/supabase/server.ts +72 -0
- package/src/templates/web/ui-auth-payments-audio/template/package.json +3 -3
- package/src/templates/web/ui-auth-payments-audio/template/src/app/globals.css +53 -0
- package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +23 -13
- package/src/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +18 -11
- package/src/templates/web/ui-auth-payments-video/template/package.json +3 -3
- package/src/templates/web/ui-auth-payments-video/template/src/app/globals.css +40 -0
- package/src/templates/web/ui-auth-payments-video/template/src/app/page.tsx +14 -1
|
@@ -13,3 +13,10 @@ NEXT_PUBLIC_FIREBASE_PROJECT_ID=
|
|
|
13
13
|
# Payments
|
|
14
14
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
|
|
15
15
|
STRIPE_SECRET_KEY=
|
|
16
|
+
|
|
17
|
+
# AI Configuration (Client-side accessible)
|
|
18
|
+
NEXT_PUBLIC_OPENAI_API_KEY=your_openai_key_here
|
|
19
|
+
NEXT_PUBLIC_ANTHROPIC_API_KEY=your_anthropic_key_here
|
|
20
|
+
NEXT_PUBLIC_GOOGLE_AI_API_KEY=your_google_key_here
|
|
21
|
+
NEXT_PUBLIC_ELEVENLABS_API_KEY=your_elevenlabs_key_here
|
|
22
|
+
NEXT_PUBLIC_REPLICATE_API_TOKEN=your_replicate_token_here
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
"next": "^15.0.0",
|
|
18
18
|
"react": "^19.0.0",
|
|
19
19
|
"react-dom": "^19.0.0",
|
|
20
|
-
"@digilogiclabs/saas-factory-ui": "^0.18.
|
|
21
|
-
"@digilogiclabs/saas-factory-auth": "^1.0.
|
|
22
|
-
"@digilogiclabs/saas-factory-payments": "^1.
|
|
23
|
-
"@digilogiclabs/saas-factory-ai": "^1.
|
|
24
|
-
"@digilogiclabs/saas-factory-ai-types": "^1.0.0",
|
|
20
|
+
"@digilogiclabs/saas-factory-ui": "^0.18.4",
|
|
21
|
+
"@digilogiclabs/saas-factory-auth": "^1.0.1",
|
|
22
|
+
"@digilogiclabs/saas-factory-payments": "^1.1.0",
|
|
23
|
+
"@digilogiclabs/saas-factory-ai": "^3.1.1",
|
|
25
24
|
"stripe": "^14.0.0",
|
|
26
25
|
"tailwindcss": "^3.3.0",
|
|
27
26
|
"autoprefixer": "^10.4.16",
|
|
@@ -47,7 +46,8 @@
|
|
|
47
46
|
"@testing-library/react": "^16.0.0",
|
|
48
47
|
"@testing-library/jest-dom": "^6.0.0",
|
|
49
48
|
"@testing-library/user-event": "^14.0.0",
|
|
50
|
-
"jsdom": "^24.0.0"
|
|
49
|
+
"jsdom": "^24.0.0",
|
|
50
|
+
"@digilogiclabs/saas-factory-ai-types": "^3.0.0"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=18.0.0"
|
|
@@ -41,3 +41,56 @@
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/* Custom animations for enhanced visual effects */
|
|
45
|
+
@keyframes slide-down {
|
|
46
|
+
from {
|
|
47
|
+
opacity: 0;
|
|
48
|
+
transform: translateY(-10px);
|
|
49
|
+
}
|
|
50
|
+
to {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
transform: translateY(0);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@keyframes fade-in-up {
|
|
57
|
+
from {
|
|
58
|
+
opacity: 0;
|
|
59
|
+
transform: translateY(10px);
|
|
60
|
+
}
|
|
61
|
+
to {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
transform: translateY(0);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@keyframes marquee {
|
|
68
|
+
0% {
|
|
69
|
+
transform: translateX(100%);
|
|
70
|
+
}
|
|
71
|
+
100% {
|
|
72
|
+
transform: translateX(-100%);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.animate-slide-down {
|
|
77
|
+
animation: slide-down 0.6s ease-out;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.animate-fade-in-up {
|
|
81
|
+
animation: fade-in-up 0.6s ease-out;
|
|
82
|
+
animation-fill-mode: both;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.animate-marquee {
|
|
86
|
+
animation: marquee 20s linear infinite;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.animation-delay-2000 {
|
|
90
|
+
animation-delay: 2s;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.animation-delay-4000 {
|
|
94
|
+
animation-delay: 4s;
|
|
95
|
+
}
|
|
96
|
+
|
|
@@ -36,7 +36,18 @@ import {
|
|
|
36
36
|
FileText
|
|
37
37
|
} from 'lucide-react'
|
|
38
38
|
import { useAuth } from '@digilogiclabs/saas-factory-auth'
|
|
39
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
AIProvider,
|
|
41
|
+
AIChat,
|
|
42
|
+
AITextGenerator,
|
|
43
|
+
AIAudioGenerator,
|
|
44
|
+
AIVideoGenerator,
|
|
45
|
+
AISetupStatus,
|
|
46
|
+
getAIConfigFromEnv,
|
|
47
|
+
validateAIConfig,
|
|
48
|
+
type ChatMessage,
|
|
49
|
+
type QuickStartOptions
|
|
50
|
+
} from '@digilogiclabs/saas-factory-ai'
|
|
40
51
|
import Link from 'next/link'
|
|
41
52
|
import { useState } from 'react'
|
|
42
53
|
|
|
@@ -49,7 +60,7 @@ export default function Home() {
|
|
|
49
60
|
|
|
50
61
|
// Modern design tokens
|
|
51
62
|
const animations = useAnimationTokens()
|
|
52
|
-
const glass = useGlassmorphism()
|
|
63
|
+
const glass = useGlassmorphism({ intensity: 'medium', border: true, accent: true })
|
|
53
64
|
|
|
54
65
|
const projectName = "{{projectName}}"
|
|
55
66
|
const projectDescription = "{{description}}"
|
|
@@ -118,75 +129,63 @@ export default function Home() {
|
|
|
118
129
|
}
|
|
119
130
|
]
|
|
120
131
|
|
|
121
|
-
const
|
|
122
|
-
const aiConfig = {
|
|
123
|
-
apiKey: process.env.NEXT_PUBLIC_AI_API_KEY || '',
|
|
124
|
-
provider: 'openai' as const,
|
|
125
|
-
model: 'gpt-4'
|
|
126
|
-
}
|
|
132
|
+
const aiConfig = getAIConfigFromEnv()
|
|
127
133
|
|
|
134
|
+
const renderAITool = () => {
|
|
128
135
|
switch (activeAITool) {
|
|
129
136
|
case 'chat':
|
|
130
137
|
return (
|
|
131
138
|
<div className={`${glass.card} ${glass.border} rounded-2xl p-6 h-96`}>
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
/>
|
|
140
|
-
</AIProvider>
|
|
139
|
+
<AIChat
|
|
140
|
+
placeholder="Ask me anything..."
|
|
141
|
+
showTypingIndicator={true}
|
|
142
|
+
enableFileUpload={true}
|
|
143
|
+
maxMessages={50}
|
|
144
|
+
className="h-full"
|
|
145
|
+
/>
|
|
141
146
|
</div>
|
|
142
147
|
)
|
|
143
148
|
case 'text':
|
|
144
149
|
return (
|
|
145
150
|
<div className={`${glass.card} ${glass.border} rounded-2xl p-6`}>
|
|
146
|
-
<
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
/>
|
|
160
|
-
</AIProvider>
|
|
151
|
+
<AITextGenerator
|
|
152
|
+
placeholder="Describe what you want to generate..."
|
|
153
|
+
maxLength={2000}
|
|
154
|
+
showWordCount={true}
|
|
155
|
+
templates={[
|
|
156
|
+
'Blog post',
|
|
157
|
+
'Product description',
|
|
158
|
+
'Email',
|
|
159
|
+
'Social media post',
|
|
160
|
+
'Technical documentation'
|
|
161
|
+
]}
|
|
162
|
+
className="min-h-64"
|
|
163
|
+
/>
|
|
161
164
|
</div>
|
|
162
165
|
)
|
|
163
166
|
case 'audio':
|
|
164
167
|
return (
|
|
165
168
|
<div className={`${glass.card} ${glass.border} rounded-2xl p-6`}>
|
|
166
|
-
<
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
/>
|
|
174
|
-
</AIProvider>
|
|
169
|
+
<AIAudioGenerator
|
|
170
|
+
placeholder="Describe the audio you want to create..."
|
|
171
|
+
supportedFormats={['mp3', 'wav', 'ogg']}
|
|
172
|
+
maxDuration={300}
|
|
173
|
+
showWaveform={true}
|
|
174
|
+
className="min-h-64"
|
|
175
|
+
/>
|
|
175
176
|
</div>
|
|
176
177
|
)
|
|
177
178
|
case 'video':
|
|
178
179
|
return (
|
|
179
180
|
<div className={`${glass.card} ${glass.border} rounded-2xl p-6`}>
|
|
180
|
-
<
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
/>
|
|
189
|
-
</AIProvider>
|
|
181
|
+
<AIVideoGenerator
|
|
182
|
+
placeholder="Describe the video you want to create..."
|
|
183
|
+
supportedFormats={['mp4', 'webm']}
|
|
184
|
+
maxDuration={60}
|
|
185
|
+
resolution="1080p"
|
|
186
|
+
showPreview={true}
|
|
187
|
+
className="min-h-64"
|
|
188
|
+
/>
|
|
190
189
|
</div>
|
|
191
190
|
)
|
|
192
191
|
default:
|
|
@@ -195,12 +194,13 @@ export default function Home() {
|
|
|
195
194
|
}
|
|
196
195
|
|
|
197
196
|
return (
|
|
198
|
-
<
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
197
|
+
<AIProvider config={aiConfig}>
|
|
198
|
+
<PageTransition type="fade" duration={300}>
|
|
199
|
+
<OfflineWrapper
|
|
200
|
+
cacheStrategy="stale-while-revalidate"
|
|
201
|
+
showOfflineIndicator={true}
|
|
202
|
+
backgroundSync={true}
|
|
203
|
+
>
|
|
204
204
|
<PullToRefresh
|
|
205
205
|
onRefresh={handleRefresh}
|
|
206
206
|
threshold={80}
|
|
@@ -208,11 +208,24 @@ export default function Home() {
|
|
|
208
208
|
hapticOnTrigger={true}
|
|
209
209
|
networkAware={true}
|
|
210
210
|
>
|
|
211
|
-
<main className=
|
|
212
|
-
{/*
|
|
213
|
-
<div className=
|
|
211
|
+
<main className="min-h-screen relative overflow-hidden bg-background">
|
|
212
|
+
{/* Theme-aware gradient background */}
|
|
213
|
+
<div className="absolute inset-0 bg-gradient-to-br from-primary/10 via-background to-secondary/10 dark:from-primary/20 dark:via-background dark:to-secondary/20" />
|
|
214
|
+
<div className="absolute inset-0 bg-gradient-to-tr from-accent/5 via-transparent to-primary/5 dark:from-accent/10 dark:via-transparent dark:to-primary/10" />
|
|
215
|
+
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,_var(--tw-gradient-stops))] from-primary/15 via-transparent to-transparent dark:from-primary/25 dark:via-transparent dark:to-transparent" />
|
|
216
|
+
{/* Animated background particles - theme aware */}
|
|
217
|
+
<div className="absolute inset-0 opacity-30 dark:opacity-20">
|
|
218
|
+
<div className="absolute top-1/4 left-1/4 w-72 h-72 bg-primary/40 rounded-full mix-blend-multiply filter blur-3xl animate-pulse dark:bg-primary/60"></div>
|
|
219
|
+
<div className="absolute top-3/4 right-1/4 w-72 h-72 bg-secondary/40 rounded-full mix-blend-multiply filter blur-3xl animate-pulse animation-delay-2000 dark:bg-secondary/60"></div>
|
|
220
|
+
<div className="absolute top-1/2 left-1/2 w-72 h-72 bg-accent/40 rounded-full mix-blend-multiply filter blur-3xl animate-pulse animation-delay-4000 dark:bg-accent/60"></div>
|
|
221
|
+
</div>
|
|
222
|
+
{/* Subtle overlay for depth */}
|
|
223
|
+
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-background/5 to-background/20" />
|
|
214
224
|
<div className="relative z-10">
|
|
215
225
|
<MobileContainer className="py-8">
|
|
226
|
+
{/* AI Configuration Status */}
|
|
227
|
+
<AISetupStatus className="mb-6" />
|
|
228
|
+
|
|
216
229
|
{/* Simple Auth Status */}
|
|
217
230
|
{user && (
|
|
218
231
|
<div className="flex justify-end mb-8">
|
|
@@ -286,7 +299,7 @@ export default function Home() {
|
|
|
286
299
|
`}
|
|
287
300
|
>
|
|
288
301
|
<div className={`mx-auto w-12 h-12 rounded-xl flex items-center justify-center mb-3 ${
|
|
289
|
-
isActive ? 'bg-white/20' :
|
|
302
|
+
isActive ? 'bg-white/20' : glass.accent
|
|
290
303
|
}`}>
|
|
291
304
|
<Icon className={`h-6 w-6 ${isActive ? 'text-white' : `text-${tool.color}-400`}`} />
|
|
292
305
|
</div>
|
|
@@ -376,5 +389,6 @@ export default function Home() {
|
|
|
376
389
|
</PullToRefresh>
|
|
377
390
|
</OfflineWrapper>
|
|
378
391
|
</PageTransition>
|
|
392
|
+
</AIProvider>
|
|
379
393
|
)
|
|
380
394
|
}
|
|
@@ -53,6 +53,11 @@ interface ServiceConfig {
|
|
|
53
53
|
export default function SetupPage() {
|
|
54
54
|
const animations = useAnimationTokens()
|
|
55
55
|
const glass = useGlassmorphism()
|
|
56
|
+
|
|
57
|
+
// Static glassmorphism classes to avoid template literal corruption
|
|
58
|
+
const glassCard = "bg-white/10 backdrop-blur-lg border border-white/20"
|
|
59
|
+
const glassCardRounded = "bg-white/10 backdrop-blur-lg border border-white/20 rounded-2xl"
|
|
60
|
+
const glassBackground = "bg-gradient-to-br from-purple-900/20 via-blue-900/20 to-teal-900/20"
|
|
56
61
|
const [copiedVar, setCopiedVar] = useState<string | null>(null)
|
|
57
62
|
|
|
58
63
|
const projectName = "{{projectName}}"
|
|
@@ -340,14 +345,14 @@ const response = await openai.chat.completions.create({
|
|
|
340
345
|
|
|
341
346
|
return (
|
|
342
347
|
<PageTransition type="slide" direction="up" duration={300}>
|
|
343
|
-
<main className={`min-h-screen ${
|
|
344
|
-
<div className=
|
|
348
|
+
<main className={`min-h-screen ${glassBackground} relative overflow-hidden`}>
|
|
349
|
+
<div className="absolute inset-0 bg-gradient-to-tr from-purple-500/10 to-blue-500/10 opacity-30" />
|
|
345
350
|
<div className="relative z-10">
|
|
346
351
|
<MobileContainer className="py-8">
|
|
347
352
|
{/* Header */}
|
|
348
353
|
<div className="flex items-center justify-between mb-8">
|
|
349
354
|
<div className="flex items-center gap-4">
|
|
350
|
-
<Link href="/" className={`${
|
|
355
|
+
<Link href="/" className={`${glassCard} p-2 rounded-xl ${animations.hover.scale}`}>
|
|
351
356
|
<ArrowLeft className="w-5 h-5" />
|
|
352
357
|
</Link>
|
|
353
358
|
<div>
|
|
@@ -355,13 +360,13 @@ const response = await openai.chat.completions.create({
|
|
|
355
360
|
<p className="text-gray-600 dark:text-gray-300">{templateName}</p>
|
|
356
361
|
</div>
|
|
357
362
|
</div>
|
|
358
|
-
<div className={`${
|
|
363
|
+
<div className={`${glassCard} px-4 py-2 rounded-xl`}>
|
|
359
364
|
<span className="text-sm font-medium">{projectName}</span>
|
|
360
365
|
</div>
|
|
361
366
|
</div>
|
|
362
367
|
|
|
363
368
|
{/* Template Overview */}
|
|
364
|
-
<div className={`${
|
|
369
|
+
<div className={`${glassCardRounded} p-6 mb-8`}>
|
|
365
370
|
<div className="flex items-center gap-4 mb-4">
|
|
366
371
|
<div className={`w-12 h-12 rounded-xl bg-gradient-to-r from-purple-500 to-pink-500 flex items-center justify-center`}>
|
|
367
372
|
<Zap className="w-6 h-6 text-white" />
|
|
@@ -392,7 +397,7 @@ const response = await openai.chat.completions.create({
|
|
|
392
397
|
</div>
|
|
393
398
|
|
|
394
399
|
{/* Quick Start */}
|
|
395
|
-
<div className={`${
|
|
400
|
+
<div className={`${glassCardRounded} p-6 mb-8`}>
|
|
396
401
|
<h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
397
402
|
<Zap className="w-5 h-5 text-yellow-400" />
|
|
398
403
|
Quick Start
|
|
@@ -422,7 +427,7 @@ const response = await openai.chat.completions.create({
|
|
|
422
427
|
</div>
|
|
423
428
|
|
|
424
429
|
{/* Environment Variables */}
|
|
425
|
-
<div className={`${
|
|
430
|
+
<div className={`${glassCardRounded} p-6 mb-8`}>
|
|
426
431
|
<h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
427
432
|
<Key className="w-5 h-5 text-blue-400" />
|
|
428
433
|
Environment Variables
|
|
@@ -461,7 +466,7 @@ const response = await openai.chat.completions.create({
|
|
|
461
466
|
const ServiceIcon = service.icon
|
|
462
467
|
|
|
463
468
|
return (
|
|
464
|
-
<div key={service.name} className={`${
|
|
469
|
+
<div key={service.name} className={`${glassCardRounded} p-6`}>
|
|
465
470
|
<div className="flex items-start justify-between mb-4">
|
|
466
471
|
<div className="flex items-center gap-3">
|
|
467
472
|
<div className={`w-10 h-10 rounded-xl bg-gray-800 flex items-center justify-center`}>
|
|
@@ -559,7 +564,7 @@ const response = await openai.chat.completions.create({
|
|
|
559
564
|
</div>
|
|
560
565
|
|
|
561
566
|
{/* Next Steps */}
|
|
562
|
-
<div className={`${
|
|
567
|
+
<div className={`${glassCardRounded} p-6 mt-8`}>
|
|
563
568
|
<h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
564
569
|
<Zap className="w-5 h-5 text-yellow-400" />
|
|
565
570
|
Next Steps
|
|
@@ -570,7 +575,7 @@ const response = await openai.chat.completions.create({
|
|
|
570
575
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
571
576
|
<Link
|
|
572
577
|
href="/dev-setup"
|
|
573
|
-
className={`${
|
|
578
|
+
className={`${glassCard} p-4 rounded-xl ${animations.hover.scale} block`}
|
|
574
579
|
>
|
|
575
580
|
<Code2 className="w-8 h-8 text-purple-400 mb-2" />
|
|
576
581
|
<h4 className="font-medium">Development & Deployment</h4>
|
|
@@ -578,7 +583,7 @@ const response = await openai.chat.completions.create({
|
|
|
578
583
|
</Link>
|
|
579
584
|
<Link
|
|
580
585
|
href="/"
|
|
581
|
-
className={`${
|
|
586
|
+
className={`${glassCard} p-4 rounded-xl ${animations.hover.scale} block`}
|
|
582
587
|
>
|
|
583
588
|
<Zap className="w-8 h-8 text-blue-400 mb-2" />
|
|
584
589
|
<h4 className="font-medium">Start Building</h4>
|
|
@@ -588,7 +593,7 @@ const response = await openai.chat.completions.create({
|
|
|
588
593
|
</div>
|
|
589
594
|
|
|
590
595
|
{/* Additional Resources */}
|
|
591
|
-
<div className={`${
|
|
596
|
+
<div className={`${glassCardRounded} p-6 mt-8`}>
|
|
592
597
|
<h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
593
598
|
<BookOpen className="w-5 h-5 text-green-400" />
|
|
594
599
|
Additional Resources
|
|
@@ -596,7 +601,7 @@ const response = await openai.chat.completions.create({
|
|
|
596
601
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
597
602
|
<a
|
|
598
603
|
href="https://docs.digilogiclabs.com"
|
|
599
|
-
className={`${
|
|
604
|
+
className={`${glassCard} p-4 rounded-xl ${animations.hover.scale} block`}
|
|
600
605
|
>
|
|
601
606
|
<FileText className="w-8 h-8 text-blue-400 mb-2" />
|
|
602
607
|
<h4 className="font-medium">Documentation</h4>
|
|
@@ -604,7 +609,7 @@ const response = await openai.chat.completions.create({
|
|
|
604
609
|
</a>
|
|
605
610
|
<a
|
|
606
611
|
href="https://github.com/digilogiclabs/examples"
|
|
607
|
-
className={`${
|
|
612
|
+
className={`${glassCard} p-4 rounded-xl ${animations.hover.scale} block`}
|
|
608
613
|
>
|
|
609
614
|
<Code2 className="w-8 h-8 text-purple-400 mb-2" />
|
|
610
615
|
<h4 className="font-medium">Examples</h4>
|
|
@@ -124,26 +124,33 @@ export function Header() {
|
|
|
124
124
|
</div>
|
|
125
125
|
)}
|
|
126
126
|
|
|
127
|
-
{/* Responsive Header */}
|
|
128
|
-
<header className="bg-
|
|
129
|
-
<div className="
|
|
127
|
+
{/* Responsive Header with theme-aware gradient */}
|
|
128
|
+
<header className="bg-background/90 backdrop-blur-md shadow-lg border-b border-border/20 transition-all duration-300 animate-slide-down">
|
|
129
|
+
<div className="absolute inset-0 bg-gradient-to-r from-primary/10 via-transparent to-secondary/10"></div>
|
|
130
|
+
<div className="container mx-auto px-4 relative">
|
|
130
131
|
<div className="flex justify-between items-center h-16">
|
|
131
|
-
{/* Logo */}
|
|
132
|
-
<Link href="/" className="text-2xl font-bold text-
|
|
133
|
-
<Music className="w-6 h-6" />
|
|
134
|
-
|
|
132
|
+
{/* Logo with animation */}
|
|
133
|
+
<Link href="/" className="text-2xl font-bold text-foreground flex items-center gap-2 transition-all duration-300 hover:scale-105">
|
|
134
|
+
<Music className="w-6 h-6 transition-transform duration-300 hover:rotate-12 text-primary" />
|
|
135
|
+
<span className="bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent transition-all duration-300">
|
|
136
|
+
{projectName}
|
|
137
|
+
</span>
|
|
135
138
|
</Link>
|
|
136
139
|
|
|
137
140
|
{/* Desktop Navigation */}
|
|
138
141
|
<nav className="hidden md:flex items-center gap-6">
|
|
139
|
-
{visibleNavItems.map((item) => (
|
|
142
|
+
{visibleNavItems.map((item, index) => (
|
|
140
143
|
<Link
|
|
141
144
|
key={item.href}
|
|
142
145
|
href={item.href}
|
|
143
|
-
className="flex items-center gap-2 text-
|
|
146
|
+
className="group flex items-center gap-2 text-muted-foreground hover:text-primary transition-all duration-300 relative px-3 py-2 rounded-lg hover:bg-gradient-to-r hover:from-primary/10 hover:to-secondary/10 animate-fade-in-up"
|
|
147
|
+
style={{ animationDelay: `${index * 100}ms` }}
|
|
144
148
|
>
|
|
145
|
-
<item.icon className="w-4 h-4" />
|
|
146
|
-
|
|
149
|
+
<item.icon className="w-4 h-4 transition-transform duration-300 group-hover:scale-110 group-hover:rotate-3" />
|
|
150
|
+
<span className="relative">
|
|
151
|
+
{item.label}
|
|
152
|
+
<span className="absolute -bottom-1 left-0 h-0.5 w-0 bg-gradient-to-r from-primary to-secondary transition-all duration-300 group-hover:w-full"></span>
|
|
153
|
+
</span>
|
|
147
154
|
</Link>
|
|
148
155
|
))}
|
|
149
156
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createServerClient } from '@supabase/ssr'
|
|
2
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
3
|
+
|
|
4
|
+
export function createSupabaseServerClient(request: NextRequest) {
|
|
5
|
+
let response = NextResponse.next({
|
|
6
|
+
request: {
|
|
7
|
+
headers: request.headers,
|
|
8
|
+
},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const supabase = createServerClient(
|
|
12
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
13
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
14
|
+
{
|
|
15
|
+
cookies: {
|
|
16
|
+
get(name: string) {
|
|
17
|
+
return request.cookies.get(name)?.value
|
|
18
|
+
},
|
|
19
|
+
set(name: string, value: string, options: any) {
|
|
20
|
+
request.cookies.set({
|
|
21
|
+
name,
|
|
22
|
+
value,
|
|
23
|
+
...options,
|
|
24
|
+
})
|
|
25
|
+
response = NextResponse.next({
|
|
26
|
+
request: {
|
|
27
|
+
headers: request.headers,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
response.cookies.set({
|
|
31
|
+
name,
|
|
32
|
+
value,
|
|
33
|
+
...options,
|
|
34
|
+
})
|
|
35
|
+
},
|
|
36
|
+
remove(name: string, options: any) {
|
|
37
|
+
request.cookies.set({
|
|
38
|
+
name,
|
|
39
|
+
value: '',
|
|
40
|
+
...options,
|
|
41
|
+
})
|
|
42
|
+
response = NextResponse.next({
|
|
43
|
+
request: {
|
|
44
|
+
headers: request.headers,
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
response.cookies.set({
|
|
48
|
+
name,
|
|
49
|
+
value: '',
|
|
50
|
+
...options,
|
|
51
|
+
})
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return { supabase, response }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function createSupabaseServerComponentClient() {
|
|
61
|
+
return createServerClient(
|
|
62
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
63
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
64
|
+
{
|
|
65
|
+
cookies: {
|
|
66
|
+
get(name: string) {
|
|
67
|
+
return require('next/headers').cookies().get(name)?.value
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"next": "^15.0.0",
|
|
18
18
|
"react": "^19.0.0",
|
|
19
19
|
"react-dom": "^19.0.0",
|
|
20
|
-
"@digilogiclabs/saas-factory-ui": "^0.18.
|
|
21
|
-
"@digilogiclabs/saas-factory-auth": "^1.0.
|
|
22
|
-
"@digilogiclabs/saas-factory-payments": "^1.
|
|
20
|
+
"@digilogiclabs/saas-factory-ui": "^0.18.4",
|
|
21
|
+
"@digilogiclabs/saas-factory-auth": "^1.0.1",
|
|
22
|
+
"@digilogiclabs/saas-factory-payments": "^1.1.0",
|
|
23
23
|
"stripe": "^14.0.0",
|
|
24
24
|
"tailwindcss": "^3.3.0",
|
|
25
25
|
"autoprefixer": "^10.4.16",
|
|
@@ -41,3 +41,56 @@
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
/* Custom animations for enhanced visual effects */
|
|
45
|
+
@keyframes slide-down {
|
|
46
|
+
from {
|
|
47
|
+
opacity: 0;
|
|
48
|
+
transform: translateY(-10px);
|
|
49
|
+
}
|
|
50
|
+
to {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
transform: translateY(0);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@keyframes fade-in-up {
|
|
57
|
+
from {
|
|
58
|
+
opacity: 0;
|
|
59
|
+
transform: translateY(10px);
|
|
60
|
+
}
|
|
61
|
+
to {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
transform: translateY(0);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@keyframes marquee {
|
|
68
|
+
0% {
|
|
69
|
+
transform: translateX(100%);
|
|
70
|
+
}
|
|
71
|
+
100% {
|
|
72
|
+
transform: translateX(-100%);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.animate-slide-down {
|
|
77
|
+
animation: slide-down 0.6s ease-out;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.animate-fade-in-up {
|
|
81
|
+
animation: fade-in-up 0.6s ease-out;
|
|
82
|
+
animation-fill-mode: both;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.animate-marquee {
|
|
86
|
+
animation: marquee 20s linear infinite;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.animation-delay-2000 {
|
|
90
|
+
animation-delay: 2s;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.animation-delay-4000 {
|
|
94
|
+
animation-delay: 4s;
|
|
95
|
+
}
|
|
96
|
+
|