@digilogiclabs/create-saas-app 2.8.0 → 2.9.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 (94) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/generators/template-generator.js +8 -8
  3. package/dist/generators/template-generator.js.map +1 -1
  4. package/dist/templates/shared/quality/web/src/__tests__/accessibility.test.tsx +3 -3
  5. package/dist/templates/web/ai-platform/template/src/app/page.tsx +207 -207
  6. package/dist/templates/web/base/template/package.json +1 -3
  7. package/dist/templates/web/base/template/src/app/auth/callback/route.ts +32 -18
  8. package/dist/templates/web/base/template/src/app/dashboard/page.tsx +6 -43
  9. package/dist/templates/web/base/template/src/app/globals.css +158 -157
  10. package/dist/templates/web/base/template/src/app/page.tsx +2 -2
  11. package/dist/templates/web/ui-auth/template/src/app/dev-setup/page.tsx +800 -800
  12. package/dist/templates/web/ui-auth/template/src/app/globals.css +96 -95
  13. package/dist/templates/web/ui-auth/template/src/app/login/page.tsx +109 -109
  14. package/dist/templates/web/ui-auth/template/src/app/page.tsx +4 -3
  15. package/dist/templates/web/ui-auth/template/src/app/signup/page.tsx +128 -128
  16. package/dist/templates/web/ui-auth-ai/template/src/app/globals.css +35 -40
  17. package/dist/templates/web/ui-auth-ai/template/src/app/layout.tsx +1 -0
  18. package/dist/templates/web/ui-auth-payments/template/src/app/checkout/page.tsx +3 -3
  19. package/dist/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +10 -49
  20. package/dist/templates/web/ui-auth-payments/template/src/app/dev-setup/page.tsx +800 -800
  21. package/dist/templates/web/ui-auth-payments/template/src/app/globals.css +212 -211
  22. package/dist/templates/web/ui-auth-payments/template/src/app/login/page.tsx +109 -109
  23. package/dist/templates/web/ui-auth-payments/template/src/app/page.tsx +350 -350
  24. package/dist/templates/web/ui-auth-payments/template/src/app/setup/page.tsx +506 -506
  25. package/dist/templates/web/ui-auth-payments/template/src/app/signup/page.tsx +128 -128
  26. package/dist/templates/web/ui-auth-payments/template/src/components/client/login-form.tsx +143 -143
  27. package/dist/templates/web/ui-auth-payments/template/src/components/client/signup-form.tsx +184 -184
  28. package/dist/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +143 -233
  29. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +10 -50
  30. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dev-setup/page.tsx +800 -800
  31. package/dist/templates/web/ui-auth-payments-ai/template/src/app/globals.css +97 -96
  32. package/dist/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +325 -364
  33. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +1 -1
  34. package/dist/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +389 -532
  35. package/dist/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +644 -644
  36. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +119 -163
  37. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +158 -201
  38. package/dist/templates/web/ui-auth-payments-ai-rag/template/package.json +1 -2
  39. package/dist/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +10 -51
  40. package/dist/templates/web/ui-auth-payments-audio/template/src/app/globals.css +97 -96
  41. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +402 -403
  42. package/dist/templates/web/ui-auth-payments-audio/template/src/components/client/login-form.tsx +143 -143
  43. package/dist/templates/web/ui-auth-payments-audio/template/src/components/client/signup-form.tsx +184 -184
  44. package/dist/templates/web/ui-auth-payments-video/template/src/app/globals.css +229 -228
  45. package/dist/templates/web/ui-auth-payments-video/template/src/app/login/page.tsx +1 -1
  46. package/dist/templates/web/ui-auth-payments-video/template/src/app/page.tsx +4 -7
  47. package/dist/templates/web/ui-auth-payments-video/template/src/app/signup/page.tsx +1 -1
  48. package/dist/templates/web/ui-only/template/src/app/globals.css +43 -42
  49. package/package.json +1 -1
  50. package/src/templates/shared/quality/web/src/__tests__/accessibility.test.tsx +3 -3
  51. package/src/templates/web/ai-platform/template/src/app/page.tsx +207 -207
  52. package/src/templates/web/base/template/package.json +1 -3
  53. package/src/templates/web/base/template/src/app/auth/callback/route.ts +32 -18
  54. package/src/templates/web/base/template/src/app/dashboard/page.tsx +6 -43
  55. package/src/templates/web/base/template/src/app/globals.css +158 -157
  56. package/src/templates/web/base/template/src/app/page.tsx +2 -2
  57. package/src/templates/web/ui-auth/template/src/app/dev-setup/page.tsx +800 -800
  58. package/src/templates/web/ui-auth/template/src/app/globals.css +96 -95
  59. package/src/templates/web/ui-auth/template/src/app/login/page.tsx +109 -109
  60. package/src/templates/web/ui-auth/template/src/app/page.tsx +4 -3
  61. package/src/templates/web/ui-auth/template/src/app/signup/page.tsx +128 -128
  62. package/src/templates/web/ui-auth-ai/template/src/app/globals.css +35 -40
  63. package/src/templates/web/ui-auth-ai/template/src/app/layout.tsx +1 -0
  64. package/src/templates/web/ui-auth-payments/template/src/app/checkout/page.tsx +3 -3
  65. package/src/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +10 -49
  66. package/src/templates/web/ui-auth-payments/template/src/app/dev-setup/page.tsx +800 -800
  67. package/src/templates/web/ui-auth-payments/template/src/app/globals.css +212 -211
  68. package/src/templates/web/ui-auth-payments/template/src/app/login/page.tsx +109 -109
  69. package/src/templates/web/ui-auth-payments/template/src/app/page.tsx +350 -350
  70. package/src/templates/web/ui-auth-payments/template/src/app/setup/page.tsx +506 -506
  71. package/src/templates/web/ui-auth-payments/template/src/app/signup/page.tsx +128 -128
  72. package/src/templates/web/ui-auth-payments/template/src/components/client/login-form.tsx +143 -143
  73. package/src/templates/web/ui-auth-payments/template/src/components/client/signup-form.tsx +184 -184
  74. package/src/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +143 -233
  75. package/src/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +10 -50
  76. package/src/templates/web/ui-auth-payments-ai/template/src/app/dev-setup/page.tsx +800 -800
  77. package/src/templates/web/ui-auth-payments-ai/template/src/app/globals.css +97 -96
  78. package/src/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +325 -364
  79. package/src/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +1 -1
  80. package/src/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +389 -532
  81. package/src/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +644 -644
  82. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +119 -163
  83. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +158 -201
  84. package/src/templates/web/ui-auth-payments-ai-rag/template/package.json +1 -2
  85. package/src/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +10 -51
  86. package/src/templates/web/ui-auth-payments-audio/template/src/app/globals.css +97 -96
  87. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +402 -403
  88. package/src/templates/web/ui-auth-payments-audio/template/src/components/client/login-form.tsx +143 -143
  89. package/src/templates/web/ui-auth-payments-audio/template/src/components/client/signup-form.tsx +184 -184
  90. package/src/templates/web/ui-auth-payments-video/template/src/app/globals.css +229 -228
  91. package/src/templates/web/ui-auth-payments-video/template/src/app/login/page.tsx +1 -1
  92. package/src/templates/web/ui-auth-payments-video/template/src/app/page.tsx +4 -7
  93. package/src/templates/web/ui-auth-payments-video/template/src/app/signup/page.tsx +1 -1
  94. package/src/templates/web/ui-only/template/src/app/globals.css +43 -42
@@ -1,507 +1,507 @@
1
- 'use client'
2
-
3
- import {
4
- Card,
5
- Button,
6
- PageTransition,
7
- MobileContainer,
8
- ResponsiveGrid,
9
- useAnimationTokens,
10
- useGlassmorphism
11
- } from '@digilogiclabs/saas-factory-ui'
12
- import {
13
- ArrowLeft,
14
- CheckCircle,
15
- AlertCircle,
16
- ExternalLink,
17
- Copy,
18
- Database,
19
- CreditCard,
20
- Shield,
21
- Key,
22
- Settings,
23
- BookOpen,
24
- Zap,
25
- Code2,
26
- FileText
27
- } from 'lucide-react'
28
- import Link from 'next/link'
29
- import { useState } from 'react'
30
-
31
- interface ServiceConfig {
32
- name: string
33
- status: 'required' | 'optional' | 'configured'
34
- icon: any
35
- description: string
36
- setupSteps: Array<{
37
- title: string
38
- description: string
39
- code?: string
40
- link?: string
41
- }>
42
- envVars: Array<{
43
- name: string
44
- description: string
45
- example: string
46
- required: boolean
47
- }>
48
- }
49
-
50
- export default function SetupPage() {
51
- const animations = useAnimationTokens()
52
- const glass = useGlassmorphism()
53
- const [copiedVar, setCopiedVar] = useState<string | null>(null)
54
-
55
- const projectName = "{{projectName}}"
56
- const templateName = "SaaS Platform with Payments"
57
- const templateDescription = "UI + Authentication + Payments with Stripe"
58
-
59
- const services: ServiceConfig[] = [
60
- {
61
- name: "Supabase (Database & Auth)",
62
- status: 'required',
63
- icon: Database,
64
- description: "PostgreSQL database with built-in authentication, real-time subscriptions, and edge functions.",
65
- setupSteps: [
66
- {
67
- title: "Create Supabase Project",
68
- description: "Sign up at supabase.com and create a new project",
69
- link: "https://supabase.com/dashboard"
70
- },
71
- {
72
- title: "Get API Keys",
73
- description: "Go to Settings → API to find your project URL and anon key"
74
- },
75
- {
76
- title: "Configure Authentication",
77
- description: "Enable email/password auth in Authentication → Settings"
78
- },
79
- {
80
- title: "Set up Database Tables",
81
- description: "Create tables for user profiles, subscriptions, and usage tracking",
82
- code: `-- User profiles table
83
- CREATE TABLE profiles (
84
- id UUID REFERENCES auth.users(id) PRIMARY KEY,
85
- email TEXT,
86
- full_name TEXT,
87
- avatar_url TEXT,
88
- stripe_customer_id TEXT,
89
- subscription_status TEXT DEFAULT 'inactive',
90
- subscription_id TEXT,
91
- created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
92
- );
93
-
94
- -- Subscriptions table
95
- CREATE TABLE subscriptions (
96
- id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
97
- user_id UUID REFERENCES profiles(id),
98
- stripe_subscription_id TEXT UNIQUE,
99
- status TEXT NOT NULL,
100
- price_id TEXT,
101
- quantity INTEGER DEFAULT 1,
102
- current_period_start TIMESTAMP WITH TIME ZONE,
103
- current_period_end TIMESTAMP WITH TIME ZONE,
104
- created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
105
- );
106
-
107
- -- Enable RLS
108
- ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
109
- ALTER TABLE subscriptions ENABLE ROW LEVEL SECURITY;
110
-
111
- -- RLS Policies
112
- CREATE POLICY "Users can view own profile" ON profiles FOR SELECT USING (auth.uid() = id);
113
- CREATE POLICY "Users can update own profile" ON profiles FOR UPDATE USING (auth.uid() = id);
114
- CREATE POLICY "Users can view own subscriptions" ON subscriptions FOR ALL USING (auth.uid() = user_id);`
115
- }
116
- ],
117
- envVars: [
118
- {
119
- name: "NEXT_PUBLIC_SUPABASE_URL",
120
- description: "Your Supabase project URL",
121
- example: "https://your-project.supabase.co",
122
- required: true
123
- },
124
- {
125
- name: "NEXT_PUBLIC_SUPABASE_ANON_KEY",
126
- description: "Your Supabase anonymous key",
127
- example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
128
- required: true
129
- },
130
- {
131
- name: "SUPABASE_SERVICE_ROLE_KEY",
132
- description: "Service role key for server-side operations (optional)",
133
- example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
134
- required: false
135
- }
136
- ]
137
- },
138
- {
139
- name: "Stripe (Payments)",
140
- status: 'required',
141
- icon: CreditCard,
142
- description: "Payment processing for subscriptions, one-time payments, and billing management.",
143
- setupSteps: [
144
- {
145
- title: "Create Stripe Account",
146
- description: "Sign up at stripe.com and complete account verification",
147
- link: "https://dashboard.stripe.com/register"
148
- },
149
- {
150
- title: "Get API Keys",
151
- description: "Go to Developers → API keys to find your publishable and secret keys"
152
- },
153
- {
154
- title: "Set up Products & Pricing",
155
- description: "Create products and pricing plans in the Stripe dashboard"
156
- },
157
- {
158
- title: "Configure Webhooks",
159
- description: "Set up webhooks to handle payment events",
160
- code: `// Add to your API route: /api/webhooks/stripe
161
- const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET!
162
-
163
- const sig = headers.get('stripe-signature')!
164
- const payload = await request.text()
165
-
166
- try {
167
- const event = stripe.webhooks.constructEvent(payload, sig, endpointSecret)
168
-
169
- switch (event.type) {
170
- case 'customer.subscription.created':
171
- case 'customer.subscription.updated':
172
- case 'customer.subscription.deleted':
173
- const subscription = event.data.object
174
- // Update user subscription status in Supabase
175
- await supabase
176
- .from('subscriptions')
177
- .upsert({
178
- stripe_subscription_id: subscription.id,
179
- status: subscription.status,
180
- user_id: subscription.metadata.user_id
181
- })
182
- break
183
- case 'invoice.payment_succeeded':
184
- // Handle successful payments
185
- break
186
- }
187
- } catch (err) {
188
- console.error('Webhook signature verification failed:', err)
189
- return new Response('Webhook Error', { status: 400 })
190
- }`
191
- }
192
- ],
193
- envVars: [
194
- {
195
- name: "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY",
196
- description: "Your Stripe publishable key",
197
- example: "pk_test_51234567890abcdef...",
198
- required: true
199
- },
200
- {
201
- name: "STRIPE_SECRET_KEY",
202
- description: "Your Stripe secret key",
203
- example: "sk_test_51234567890abcdef...",
204
- required: true
205
- },
206
- {
207
- name: "STRIPE_WEBHOOK_SECRET",
208
- description: "Webhook endpoint secret for event verification",
209
- example: "whsec_1234567890abcdef...",
210
- required: true
211
- }
212
- ]
213
- }
214
- ]
215
-
216
- const allEnvVars = services.flatMap(service => service.envVars)
217
-
218
- const copyToClipboard = async (text: string, varName: string) => {
219
- await navigator.clipboard.writeText(text)
220
- setCopiedVar(varName)
221
- setTimeout(() => setCopiedVar(null), 2000)
222
- }
223
-
224
- const getStatusColor = (status: ServiceConfig['status']) => {
225
- switch (status) {
226
- case 'required': return 'text-red-400'
227
- case 'optional': return 'text-yellow-400'
228
- case 'configured': return 'text-green-400'
229
- default: return 'text-gray-400'
230
- }
231
- }
232
-
233
- const getStatusIcon = (status: ServiceConfig['status']) => {
234
- switch (status) {
235
- case 'required': return AlertCircle
236
- case 'optional': return Settings
237
- case 'configured': return CheckCircle
238
- default: return AlertCircle
239
- }
240
- }
241
-
242
- return (
243
- <PageTransition type="slide" direction="up" duration={300}>
244
- <main className={`min-h-screen ${glass.background.primary} relative overflow-hidden`}>
245
- <div className={`absolute inset-0 ${glass.background.accent} opacity-30`} />
246
- <div className="relative z-10">
247
- <MobileContainer className="py-8">
248
- {/* Header */}
249
- <div className="flex items-center justify-between mb-8">
250
- <div className="flex items-center gap-4">
251
- <Link href="/" className={`${glass.card} ${glass.border} p-2 rounded-xl ${animations.hover.scale}`}>
252
- <ArrowLeft className="w-5 h-5" />
253
- </Link>
254
- <div>
255
- <h1 className="text-2xl font-bold">Setup Guide</h1>
256
- <p className="text-gray-600 dark:text-gray-300">{templateName}</p>
257
- </div>
258
- </div>
259
- <div className={`${glass.card} ${glass.border} px-4 py-2 rounded-xl`}>
260
- <span className="text-sm font-medium">{projectName}</span>
261
- </div>
262
- </div>
263
-
264
- {/* Template Overview */}
265
- <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mb-8`}>
266
- <div className="flex items-center gap-4 mb-4">
267
- <div className={`w-12 h-12 rounded-xl bg-gradient-to-r from-green-500 to-blue-500 flex items-center justify-center`}>
268
- <CreditCard className="w-6 h-6 text-white" />
269
- </div>
270
- <div>
271
- <h2 className="text-xl font-semibold">{templateName}</h2>
272
- <p className="text-gray-600 dark:text-gray-300">{templateDescription}</p>
273
- </div>
274
- </div>
275
- <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6">
276
- <div className="text-center p-4 rounded-xl bg-blue-500/10">
277
- <Shield className="w-8 h-8 text-blue-400 mx-auto mb-2" />
278
- <div className="font-medium">Authentication</div>
279
- <div className="text-sm text-gray-600 dark:text-gray-300">Secure user management</div>
280
- </div>
281
- <div className="text-center p-4 rounded-xl bg-green-500/10">
282
- <CreditCard className="w-8 h-8 text-green-400 mx-auto mb-2" />
283
- <div className="font-medium">Payments</div>
284
- <div className="text-sm text-gray-600 dark:text-gray-300">Stripe integration</div>
285
- </div>
286
- <div className="text-center p-4 rounded-xl bg-purple-500/10">
287
- <Code2 className="w-8 h-8 text-purple-400 mx-auto mb-2" />
288
- <div className="font-medium">Modern UI</div>
289
- <div className="text-sm text-gray-600 dark:text-gray-300">Beautiful components</div>
290
- </div>
291
- </div>
292
- </div>
293
-
294
- {/* Quick Start */}
295
- <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mb-8`}>
296
- <h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
297
- <Zap className="w-5 h-5 text-yellow-400" />
298
- Quick Start
299
- </h3>
300
- <div className="space-y-3 text-sm">
301
- <div className="flex items-center gap-3">
302
- <CheckCircle className="w-5 h-5 text-green-400" />
303
- <span>1. Set up your environment variables (see below)</span>
304
- </div>
305
- <div className="flex items-center gap-3">
306
- <CheckCircle className="w-5 h-5 text-green-400" />
307
- <span>2. Configure Supabase database and authentication</span>
308
- </div>
309
- <div className="flex items-center gap-3">
310
- <CheckCircle className="w-5 h-5 text-green-400" />
311
- <span>3. Set up Stripe for payment processing</span>
312
- </div>
313
- <div className="flex items-center gap-3">
314
- <CheckCircle className="w-5 h-5 text-green-400" />
315
- <span>4. Run <code className="px-2 py-1 bg-gray-800 rounded text-green-400">npm run dev</code> to start developing</span>
316
- </div>
317
- </div>
318
- </div>
319
-
320
- {/* Environment Variables */}
321
- <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mb-8`}>
322
- <h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
323
- <Key className="w-5 h-5 text-blue-400" />
324
- Environment Variables
325
- </h3>
326
- <p className="text-sm text-gray-600 dark:text-gray-300 mb-4">
327
- Copy these to your <code className="px-2 py-1 bg-gray-800 rounded">.env.local</code> file:
328
- </p>
329
- <div className="bg-gray-900 rounded-xl p-4 overflow-x-auto">
330
- <pre className="text-sm text-green-400">
331
- {allEnvVars.map(envVar => (
332
- `${envVar.name}=${envVar.example}${envVar.required ? ' # Required' : ' # Optional'}`
333
- )).join('\n')}
334
- </pre>
335
- <button
336
- onClick={() => copyToClipboard(
337
- allEnvVars.map(envVar => `${envVar.name}=${envVar.example}`).join('\n'),
338
- 'all-env-vars'
339
- )}
340
- className="mt-3 flex items-center gap-2 text-xs text-gray-400 hover:text-white transition-colors"
341
- >
342
- <Copy className="w-4 h-4" />
343
- {copiedVar === 'all-env-vars' ? 'Copied!' : 'Copy all environment variables'}
344
- </button>
345
- </div>
346
- </div>
347
-
348
- {/* Services Configuration */}
349
- <div className="space-y-6">
350
- <h3 className="text-lg font-semibold flex items-center gap-2">
351
- <Settings className="w-5 h-5 text-gray-400" />
352
- Service Configuration
353
- </h3>
354
-
355
- {services.map((service, index) => {
356
- const StatusIcon = getStatusIcon(service.status)
357
- const ServiceIcon = service.icon
358
-
359
- return (
360
- <div key={service.name} className={`${glass.card} ${glass.border} rounded-2xl p-6`}>
361
- <div className="flex items-start justify-between mb-4">
362
- <div className="flex items-center gap-3">
363
- <div className={`w-10 h-10 rounded-xl bg-gray-800 flex items-center justify-center`}>
364
- <ServiceIcon className="w-5 h-5 text-white" />
365
- </div>
366
- <div>
367
- <h4 className="text-lg font-semibold flex items-center gap-2">
368
- {service.name}
369
- <StatusIcon className={`w-4 h-4 ${getStatusColor(service.status)}`} />
370
- </h4>
371
- <p className="text-sm text-gray-600 dark:text-gray-300">{service.description}</p>
372
- </div>
373
- </div>
374
- <span className={`px-3 py-1 rounded-full text-xs font-medium ${
375
- service.status === 'required' ? 'bg-red-500/20 text-red-400' :
376
- service.status === 'optional' ? 'bg-yellow-500/20 text-yellow-400' :
377
- 'bg-green-500/20 text-green-400'
378
- }`}>
379
- {service.status}
380
- </span>
381
- </div>
382
-
383
- {/* Setup Steps */}
384
- <div className="mb-6">
385
- <h5 className="font-semibold mb-3">Setup Steps:</h5>
386
- <div className="space-y-3">
387
- {service.setupSteps.map((step, stepIndex) => (
388
- <div key={stepIndex} className="flex gap-3">
389
- <div className="w-6 h-6 rounded-full bg-blue-500 text-white text-xs flex items-center justify-center flex-shrink-0 mt-0.5">
390
- {stepIndex + 1}
391
- </div>
392
- <div className="flex-1">
393
- <h6 className="font-medium">{step.title}</h6>
394
- <p className="text-sm text-gray-600 dark:text-gray-300">{step.description}</p>
395
- {step.link && (
396
- <a
397
- href={step.link}
398
- target="_blank"
399
- rel="noopener noreferrer"
400
- className="inline-flex items-center gap-1 text-sm text-blue-400 hover:text-blue-300 mt-1"
401
- >
402
- Open Dashboard <ExternalLink className="w-3 h-3" />
403
- </a>
404
- )}
405
- {step.code && (
406
- <details className="mt-2">
407
- <summary className="text-sm text-blue-400 cursor-pointer hover:text-blue-300">
408
- Show code example
409
- </summary>
410
- <pre className="bg-gray-900 rounded-lg p-3 mt-2 text-xs overflow-x-auto">
411
- <code className="text-green-400">{step.code}</code>
412
- </pre>
413
- </details>
414
- )}
415
- </div>
416
- </div>
417
- ))}
418
- </div>
419
- </div>
420
-
421
- {/* Environment Variables for this service */}
422
- <div>
423
- <h5 className="font-semibold mb-3">Environment Variables:</h5>
424
- <div className="space-y-2">
425
- {service.envVars.map((envVar, envIndex) => (
426
- <div key={envIndex} className="bg-gray-800/50 rounded-lg p-3">
427
- <div className="flex items-center justify-between mb-1">
428
- <code className="text-blue-400 font-mono text-sm">{envVar.name}</code>
429
- <div className="flex items-center gap-2">
430
- <span className={`px-2 py-1 rounded text-xs ${
431
- envVar.required ? 'bg-red-500/20 text-red-400' : 'bg-gray-500/20 text-gray-400'
432
- }`}>
433
- {envVar.required ? 'Required' : 'Optional'}
434
- </span>
435
- <button
436
- onClick={() => copyToClipboard(`${envVar.name}=${envVar.example}`, envVar.name)}
437
- className="p-1 hover:bg-gray-700 rounded transition-colors"
438
- >
439
- <Copy className="w-3 h-3" />
440
- </button>
441
- </div>
442
- </div>
443
- <p className="text-xs text-gray-400 mb-2">{envVar.description}</p>
444
- <code className="text-xs text-gray-500 font-mono">{envVar.example}</code>
445
- {copiedVar === envVar.name && (
446
- <span className="text-xs text-green-400 ml-2">Copied!</span>
447
- )}
448
- </div>
449
- ))}
450
- </div>
451
- </div>
452
- </div>
453
- )
454
- })}
455
- </div>
456
-
457
- {/* Additional Resources */}
458
- <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mt-8`}>
459
- <h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
460
- <BookOpen className="w-5 h-5 text-green-400" />
461
- Additional Resources
462
- </h3>
463
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
464
- <a
465
- href="https://docs.digilogiclabs.com"
466
- className={`${glass.card} ${glass.border} p-4 rounded-xl ${animations.hover.scale} block`}
467
- >
468
- <FileText className="w-8 h-8 text-blue-400 mb-2" />
469
- <h4 className="font-medium">Documentation</h4>
470
- <p className="text-sm text-gray-600 dark:text-gray-300">Complete guides and API reference</p>
471
- </a>
472
- <a
473
- href="https://github.com/digilogiclabs/examples"
474
- className={`${glass.card} ${glass.border} p-4 rounded-xl ${animations.hover.scale} block`}
475
- >
476
- <Code2 className="w-8 h-8 text-purple-400 mb-2" />
477
- <h4 className="font-medium">Examples</h4>
478
- <p className="text-sm text-gray-600 dark:text-gray-300">Sample projects and code snippets</p>
479
- </a>
480
- </div>
481
- </div>
482
-
483
- {/* Support */}
484
- <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mt-8 text-center`}>
485
- <h3 className="text-lg font-semibold mb-4">Need Help?</h3>
486
- <p className="text-gray-600 dark:text-gray-300 mb-4">
487
- Our community and support team are here to help you get started.
488
- </p>
489
- <div className="flex justify-center gap-4">
490
- <Button variant="outline" size="sm" asChild>
491
- <a href="https://discord.gg/digilogiclabs" target="_blank" rel="noopener noreferrer">
492
- Join Discord
493
- </a>
494
- </Button>
495
- <Button size="sm" asChild>
496
- <a href="https://docs.digilogiclabs.com/support" target="_blank" rel="noopener noreferrer">
497
- Get Support
498
- </a>
499
- </Button>
500
- </div>
501
- </div>
502
- </MobileContainer>
503
- </div>
504
- </main>
505
- </PageTransition>
506
- )
1
+ 'use client'
2
+
3
+ import {
4
+ Card,
5
+ Button,
6
+ PageTransition,
7
+ MobileContainer,
8
+ ResponsiveGrid,
9
+ useAnimationTokens,
10
+ useGlassmorphism
11
+ } from '@digilogiclabs/saas-factory-ui'
12
+ import {
13
+ ArrowLeft,
14
+ CheckCircle,
15
+ AlertCircle,
16
+ ExternalLink,
17
+ Copy,
18
+ Database,
19
+ CreditCard,
20
+ Shield,
21
+ Key,
22
+ Settings,
23
+ BookOpen,
24
+ Zap,
25
+ Code2,
26
+ FileText
27
+ } from 'lucide-react'
28
+ import Link from 'next/link'
29
+ import { useState } from 'react'
30
+
31
+ interface ServiceConfig {
32
+ name: string
33
+ status: 'required' | 'optional' | 'configured'
34
+ icon: any
35
+ description: string
36
+ setupSteps: Array<{
37
+ title: string
38
+ description: string
39
+ code?: string
40
+ link?: string
41
+ }>
42
+ envVars: Array<{
43
+ name: string
44
+ description: string
45
+ example: string
46
+ required: boolean
47
+ }>
48
+ }
49
+
50
+ export default function SetupPage() {
51
+ const animations = useAnimationTokens()
52
+ const glass = useGlassmorphism()
53
+ const [copiedVar, setCopiedVar] = useState<string | null>(null)
54
+
55
+ const projectName = "{{projectName}}"
56
+ const templateName = "SaaS Platform with Payments"
57
+ const templateDescription = "UI + Authentication + Payments with Stripe"
58
+
59
+ const services: ServiceConfig[] = [
60
+ {
61
+ name: "Supabase (Database & Auth)",
62
+ status: 'required',
63
+ icon: Database,
64
+ description: "PostgreSQL database with built-in authentication, real-time subscriptions, and edge functions.",
65
+ setupSteps: [
66
+ {
67
+ title: "Create Supabase Project",
68
+ description: "Sign up at supabase.com and create a new project",
69
+ link: "https://supabase.com/dashboard"
70
+ },
71
+ {
72
+ title: "Get API Keys",
73
+ description: "Go to Settings → API to find your project URL and anon key"
74
+ },
75
+ {
76
+ title: "Configure Authentication",
77
+ description: "Enable email/password auth in Authentication → Settings"
78
+ },
79
+ {
80
+ title: "Set up Database Tables",
81
+ description: "Create tables for user profiles, subscriptions, and usage tracking",
82
+ code: `-- User profiles table
83
+ CREATE TABLE profiles (
84
+ id UUID REFERENCES auth.users(id) PRIMARY KEY,
85
+ email TEXT,
86
+ full_name TEXT,
87
+ avatar_url TEXT,
88
+ stripe_customer_id TEXT,
89
+ subscription_status TEXT DEFAULT 'inactive',
90
+ subscription_id TEXT,
91
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
92
+ );
93
+
94
+ -- Subscriptions table
95
+ CREATE TABLE subscriptions (
96
+ id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
97
+ user_id UUID REFERENCES profiles(id),
98
+ stripe_subscription_id TEXT UNIQUE,
99
+ status TEXT NOT NULL,
100
+ price_id TEXT,
101
+ quantity INTEGER DEFAULT 1,
102
+ current_period_start TIMESTAMP WITH TIME ZONE,
103
+ current_period_end TIMESTAMP WITH TIME ZONE,
104
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
105
+ );
106
+
107
+ -- Enable RLS
108
+ ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
109
+ ALTER TABLE subscriptions ENABLE ROW LEVEL SECURITY;
110
+
111
+ -- RLS Policies
112
+ CREATE POLICY "Users can view own profile" ON profiles FOR SELECT USING (auth.uid() = id);
113
+ CREATE POLICY "Users can update own profile" ON profiles FOR UPDATE USING (auth.uid() = id);
114
+ CREATE POLICY "Users can view own subscriptions" ON subscriptions FOR ALL USING (auth.uid() = user_id);`
115
+ }
116
+ ],
117
+ envVars: [
118
+ {
119
+ name: "NEXT_PUBLIC_SUPABASE_URL",
120
+ description: "Your Supabase project URL",
121
+ example: "https://your-project.supabase.co",
122
+ required: true
123
+ },
124
+ {
125
+ name: "NEXT_PUBLIC_SUPABASE_ANON_KEY",
126
+ description: "Your Supabase anonymous key",
127
+ example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
128
+ required: true
129
+ },
130
+ {
131
+ name: "SUPABASE_SERVICE_ROLE_KEY",
132
+ description: "Service role key for server-side operations (optional)",
133
+ example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
134
+ required: false
135
+ }
136
+ ]
137
+ },
138
+ {
139
+ name: "Stripe (Payments)",
140
+ status: 'required',
141
+ icon: <CreditCard className="w-4 h-4" />,
142
+ description: "Payment processing for subscriptions, one-time payments, and billing management.",
143
+ setupSteps: [
144
+ {
145
+ title: "Create Stripe Account",
146
+ description: "Sign up at stripe.com and complete account verification",
147
+ link: "https://dashboard.stripe.com/register"
148
+ },
149
+ {
150
+ title: "Get API Keys",
151
+ description: "Go to Developers → API keys to find your publishable and secret keys"
152
+ },
153
+ {
154
+ title: "Set up Products & Pricing",
155
+ description: "Create products and pricing plans in the Stripe dashboard"
156
+ },
157
+ {
158
+ title: "Configure Webhooks",
159
+ description: "Set up webhooks to handle payment events",
160
+ code: `// Add to your API route: /api/webhooks/stripe
161
+ const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET!
162
+
163
+ const sig = headers.get('stripe-signature')!
164
+ const payload = await request.text()
165
+
166
+ try {
167
+ const event = stripe.webhooks.constructEvent(payload, sig, endpointSecret)
168
+
169
+ switch (event.type) {
170
+ case 'customer.subscription.created':
171
+ case 'customer.subscription.updated':
172
+ case 'customer.subscription.deleted':
173
+ const subscription = event.data.object
174
+ // Update user subscription status in Supabase
175
+ await supabase
176
+ .from('subscriptions')
177
+ .upsert({
178
+ stripe_subscription_id: subscription.id,
179
+ status: subscription.status,
180
+ user_id: subscription.metadata.user_id
181
+ })
182
+ break
183
+ case 'invoice.payment_succeeded':
184
+ // Handle successful payments
185
+ break
186
+ }
187
+ } catch (err) {
188
+ console.error('Webhook signature verification failed:', err)
189
+ return new Response('Webhook Error', { status: 400 })
190
+ }`
191
+ }
192
+ ],
193
+ envVars: [
194
+ {
195
+ name: "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY",
196
+ description: "Your Stripe publishable key",
197
+ example: "pk_test_51234567890abcdef...",
198
+ required: true
199
+ },
200
+ {
201
+ name: "STRIPE_SECRET_KEY",
202
+ description: "Your Stripe secret key",
203
+ example: "sk_test_51234567890abcdef...",
204
+ required: true
205
+ },
206
+ {
207
+ name: "STRIPE_WEBHOOK_SECRET",
208
+ description: "Webhook endpoint secret for event verification",
209
+ example: "whsec_1234567890abcdef...",
210
+ required: true
211
+ }
212
+ ]
213
+ }
214
+ ]
215
+
216
+ const allEnvVars = services.flatMap(service => service.envVars)
217
+
218
+ const copyToClipboard = async (text: string, varName: string) => {
219
+ await navigator.clipboard.writeText(text)
220
+ setCopiedVar(varName)
221
+ setTimeout(() => setCopiedVar(null), 2000)
222
+ }
223
+
224
+ const getStatusColor = (status: ServiceConfig['status']) => {
225
+ switch (status) {
226
+ case 'required': return 'text-red-400'
227
+ case 'optional': return 'text-yellow-400'
228
+ case 'configured': return 'text-green-400'
229
+ default: return 'text-gray-400'
230
+ }
231
+ }
232
+
233
+ const getStatusIcon = (status: ServiceConfig['status']) => {
234
+ switch (status) {
235
+ case 'required': return AlertCircle
236
+ case 'optional': return Settings
237
+ case 'configured': return CheckCircle
238
+ default: return AlertCircle
239
+ }
240
+ }
241
+
242
+ return (
243
+ <PageTransition type="slide" direction="up" duration={300}>
244
+ <main className={`min-h-screen ${glass.background.primary} relative overflow-hidden`}>
245
+ <div className={`absolute inset-0 ${glass.background.accent} opacity-30`} />
246
+ <div className="relative z-10">
247
+ <MobileContainer className="py-8">
248
+ {/* Header */}
249
+ <div className="flex items-center justify-between mb-8">
250
+ <div className="flex items-center gap-4">
251
+ <Link href="/" className={`${glass.card} ${glass.border} p-2 rounded-xl ${animations.hover.scale}`}>
252
+ <ArrowLeft className="w-5 h-5" />
253
+ </Link>
254
+ <div>
255
+ <h1 className="text-2xl font-bold">Setup Guide</h1>
256
+ <p className="text-gray-600 dark:text-gray-300">{templateName}</p>
257
+ </div>
258
+ </div>
259
+ <div className={`${glass.card} ${glass.border} px-4 py-2 rounded-xl`}>
260
+ <span className="text-sm font-medium">{projectName}</span>
261
+ </div>
262
+ </div>
263
+
264
+ {/* Template Overview */}
265
+ <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mb-8`}>
266
+ <div className="flex items-center gap-4 mb-4">
267
+ <div className={`w-12 h-12 rounded-xl bg-gradient-to-r from-green-500 to-blue-500 flex items-center justify-center`}>
268
+ <CreditCard className="w-6 h-6 text-white" />
269
+ </div>
270
+ <div>
271
+ <h2 className="text-xl font-semibold">{templateName}</h2>
272
+ <p className="text-gray-600 dark:text-gray-300">{templateDescription}</p>
273
+ </div>
274
+ </div>
275
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6">
276
+ <div className="text-center p-4 rounded-xl bg-blue-500/10">
277
+ <Shield className="w-8 h-8 text-blue-400 mx-auto mb-2" />
278
+ <div className="font-medium">Authentication</div>
279
+ <div className="text-sm text-gray-600 dark:text-gray-300">Secure user management</div>
280
+ </div>
281
+ <div className="text-center p-4 rounded-xl bg-green-500/10">
282
+ <CreditCard className="w-8 h-8 text-green-400 mx-auto mb-2" />
283
+ <div className="font-medium">Payments</div>
284
+ <div className="text-sm text-gray-600 dark:text-gray-300">Stripe integration</div>
285
+ </div>
286
+ <div className="text-center p-4 rounded-xl bg-purple-500/10">
287
+ <Code2 className="w-8 h-8 text-purple-400 mx-auto mb-2" />
288
+ <div className="font-medium">Modern UI</div>
289
+ <div className="text-sm text-gray-600 dark:text-gray-300">Beautiful components</div>
290
+ </div>
291
+ </div>
292
+ </div>
293
+
294
+ {/* Quick Start */}
295
+ <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mb-8`}>
296
+ <h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
297
+ <Zap className="w-5 h-5 text-yellow-400" />
298
+ Quick Start
299
+ </h3>
300
+ <div className="space-y-3 text-sm">
301
+ <div className="flex items-center gap-3">
302
+ <CheckCircle className="w-5 h-5 text-green-400" />
303
+ <span>1. Set up your environment variables (see below)</span>
304
+ </div>
305
+ <div className="flex items-center gap-3">
306
+ <CheckCircle className="w-5 h-5 text-green-400" />
307
+ <span>2. Configure Supabase database and authentication</span>
308
+ </div>
309
+ <div className="flex items-center gap-3">
310
+ <CheckCircle className="w-5 h-5 text-green-400" />
311
+ <span>3. Set up Stripe for payment processing</span>
312
+ </div>
313
+ <div className="flex items-center gap-3">
314
+ <CheckCircle className="w-5 h-5 text-green-400" />
315
+ <span>4. Run <code className="px-2 py-1 bg-gray-800 rounded text-green-400">npm run dev</code> to start developing</span>
316
+ </div>
317
+ </div>
318
+ </div>
319
+
320
+ {/* Environment Variables */}
321
+ <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mb-8`}>
322
+ <h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
323
+ <Key className="w-5 h-5 text-blue-400" />
324
+ Environment Variables
325
+ </h3>
326
+ <p className="text-sm text-gray-600 dark:text-gray-300 mb-4">
327
+ Copy these to your <code className="px-2 py-1 bg-gray-800 rounded">.env.local</code> file:
328
+ </p>
329
+ <div className="bg-gray-900 rounded-xl p-4 overflow-x-auto">
330
+ <pre className="text-sm text-green-400">
331
+ {allEnvVars.map(envVar => (
332
+ `${envVar.name}=${envVar.example}${envVar.required ? ' # Required' : ' # Optional'}`
333
+ )).join('\n')}
334
+ </pre>
335
+ <button
336
+ onClick={() => copyToClipboard(
337
+ allEnvVars.map(envVar => `${envVar.name}=${envVar.example}`).join('\n'),
338
+ 'all-env-vars'
339
+ )}
340
+ className="mt-3 flex items-center gap-2 text-xs text-gray-400 hover:text-white transition-colors"
341
+ >
342
+ <Copy className="w-4 h-4" />
343
+ {copiedVar === 'all-env-vars' ? 'Copied!' : 'Copy all environment variables'}
344
+ </button>
345
+ </div>
346
+ </div>
347
+
348
+ {/* Services Configuration */}
349
+ <div className="space-y-6">
350
+ <h3 className="text-lg font-semibold flex items-center gap-2">
351
+ <Settings className="w-5 h-5 text-gray-400" />
352
+ Service Configuration
353
+ </h3>
354
+
355
+ {services.map((service, index) => {
356
+ const StatusIcon = getStatusIcon(service.status)
357
+ const ServiceIcon = service.icon
358
+
359
+ return (
360
+ <div key={service.name} className={`${glass.card} ${glass.border} rounded-2xl p-6`}>
361
+ <div className="flex items-start justify-between mb-4">
362
+ <div className="flex items-center gap-3">
363
+ <div className={`w-10 h-10 rounded-xl bg-gray-800 flex items-center justify-center`}>
364
+ <ServiceIcon className="w-5 h-5 text-white" />
365
+ </div>
366
+ <div>
367
+ <h4 className="text-lg font-semibold flex items-center gap-2">
368
+ {service.name}
369
+ <StatusIcon className={`w-4 h-4 ${getStatusColor(service.status)}`} />
370
+ </h4>
371
+ <p className="text-sm text-gray-600 dark:text-gray-300">{service.description}</p>
372
+ </div>
373
+ </div>
374
+ <span className={`px-3 py-1 rounded-full text-xs font-medium ${
375
+ service.status === 'required' ? 'bg-red-500/20 text-red-400' :
376
+ service.status === 'optional' ? 'bg-yellow-500/20 text-yellow-400' :
377
+ 'bg-green-500/20 text-green-400'
378
+ }`}>
379
+ {service.status}
380
+ </span>
381
+ </div>
382
+
383
+ {/* Setup Steps */}
384
+ <div className="mb-6">
385
+ <h5 className="font-semibold mb-3">Setup Steps:</h5>
386
+ <div className="space-y-3">
387
+ {service.setupSteps.map((step, stepIndex) => (
388
+ <div key={stepIndex} className="flex gap-3">
389
+ <div className="w-6 h-6 rounded-full bg-blue-500 text-white text-xs flex items-center justify-center flex-shrink-0 mt-0.5">
390
+ {stepIndex + 1}
391
+ </div>
392
+ <div className="flex-1">
393
+ <h6 className="font-medium">{step.title}</h6>
394
+ <p className="text-sm text-gray-600 dark:text-gray-300">{step.description}</p>
395
+ {step.link && (
396
+ <a
397
+ href={step.link}
398
+ target="_blank"
399
+ rel="noopener noreferrer"
400
+ className="inline-flex items-center gap-1 text-sm text-blue-400 hover:text-blue-300 mt-1"
401
+ >
402
+ Open Dashboard <ExternalLink className="w-3 h-3" />
403
+ </a>
404
+ )}
405
+ {step.code && (
406
+ <details className="mt-2">
407
+ <summary className="text-sm text-blue-400 cursor-pointer hover:text-blue-300">
408
+ Show code example
409
+ </summary>
410
+ <pre className="bg-gray-900 rounded-lg p-3 mt-2 text-xs overflow-x-auto">
411
+ <code className="text-green-400">{step.code}</code>
412
+ </pre>
413
+ </details>
414
+ )}
415
+ </div>
416
+ </div>
417
+ ))}
418
+ </div>
419
+ </div>
420
+
421
+ {/* Environment Variables for this service */}
422
+ <div>
423
+ <h5 className="font-semibold mb-3">Environment Variables:</h5>
424
+ <div className="space-y-2">
425
+ {service.envVars.map((envVar, envIndex) => (
426
+ <div key={envIndex} className="bg-gray-800/50 rounded-lg p-3">
427
+ <div className="flex items-center justify-between mb-1">
428
+ <code className="text-blue-400 font-mono text-sm">{envVar.name}</code>
429
+ <div className="flex items-center gap-2">
430
+ <span className={`px-2 py-1 rounded text-xs ${
431
+ envVar.required ? 'bg-red-500/20 text-red-400' : 'bg-gray-500/20 text-gray-400'
432
+ }`}>
433
+ {envVar.required ? 'Required' : 'Optional'}
434
+ </span>
435
+ <button
436
+ onClick={() => copyToClipboard(`${envVar.name}=${envVar.example}`, envVar.name)}
437
+ className="p-1 hover:bg-gray-700 rounded transition-colors"
438
+ >
439
+ <Copy className="w-3 h-3" />
440
+ </button>
441
+ </div>
442
+ </div>
443
+ <p className="text-xs text-gray-400 mb-2">{envVar.description}</p>
444
+ <code className="text-xs text-gray-500 font-mono">{envVar.example}</code>
445
+ {copiedVar === envVar.name && (
446
+ <span className="text-xs text-green-400 ml-2">Copied!</span>
447
+ )}
448
+ </div>
449
+ ))}
450
+ </div>
451
+ </div>
452
+ </div>
453
+ )
454
+ })}
455
+ </div>
456
+
457
+ {/* Additional Resources */}
458
+ <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mt-8`}>
459
+ <h3 className="text-lg font-semibold mb-4 flex items-center gap-2">
460
+ <BookOpen className="w-5 h-5 text-green-400" />
461
+ Additional Resources
462
+ </h3>
463
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
464
+ <a
465
+ href="https://docs.digilogiclabs.com"
466
+ className={`${glass.card} ${glass.border} p-4 rounded-xl ${animations.hover.scale} block`}
467
+ >
468
+ <FileText className="w-8 h-8 text-blue-400 mb-2" />
469
+ <h4 className="font-medium">Documentation</h4>
470
+ <p className="text-sm text-gray-600 dark:text-gray-300">Complete guides and API reference</p>
471
+ </a>
472
+ <a
473
+ href="https://github.com/digilogiclabs/examples"
474
+ className={`${glass.card} ${glass.border} p-4 rounded-xl ${animations.hover.scale} block`}
475
+ >
476
+ <Code2 className="w-8 h-8 text-purple-400 mb-2" />
477
+ <h4 className="font-medium">Examples</h4>
478
+ <p className="text-sm text-gray-600 dark:text-gray-300">Sample projects and code snippets</p>
479
+ </a>
480
+ </div>
481
+ </div>
482
+
483
+ {/* Support */}
484
+ <div className={`${glass.card} ${glass.border} rounded-2xl p-6 mt-8 text-center`}>
485
+ <h3 className="text-lg font-semibold mb-4">Need Help?</h3>
486
+ <p className="text-gray-600 dark:text-gray-300 mb-4">
487
+ Our community and support team are here to help you get started.
488
+ </p>
489
+ <div className="flex justify-center gap-4">
490
+ <Button variant="outline" size="sm" asChild>
491
+ <a href="https://discord.gg/digilogiclabs" target="_blank" rel="noopener noreferrer">
492
+ Join Discord
493
+ </a>
494
+ </Button>
495
+ <Button size="sm" asChild>
496
+ <a href="https://docs.digilogiclabs.com/support" target="_blank" rel="noopener noreferrer">
497
+ Get Support
498
+ </a>
499
+ </Button>
500
+ </div>
501
+ </div>
502
+ </MobileContainer>
503
+ </div>
504
+ </main>
505
+ </PageTransition>
506
+ )
507
507
  }