@digilogiclabs/create-saas-app 1.10.6 → 1.12.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 (204) hide show
  1. package/README.md +331 -350
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cli/commands/create.js +2 -2
  4. package/dist/cli/commands/create.js.map +1 -1
  5. package/dist/generators/template-generator.d.ts.map +1 -1
  6. package/dist/generators/template-generator.js +14 -2
  7. package/dist/generators/template-generator.js.map +1 -1
  8. package/dist/templates/web/ui-auth/template/.claude +21 -0
  9. package/dist/templates/web/ui-auth/template/context.md +105 -0
  10. package/dist/templates/web/ui-auth/template/src/app/dev-setup/page.tsx +801 -0
  11. package/dist/templates/web/ui-auth/template/src/app/setup/page.tsx +403 -0
  12. package/dist/templates/web/ui-auth-payments/template/src/app/dev-setup/page.tsx +801 -0
  13. package/dist/templates/web/ui-auth-payments/template/src/app/setup/page.tsx +507 -0
  14. package/dist/templates/web/ui-auth-payments/template/src/components/shared/header.tsx +127 -32
  15. package/dist/templates/web/ui-auth-payments-ai/template/.claude +21 -0
  16. package/dist/templates/web/ui-auth-payments-ai/template/.env.example +15 -0
  17. package/dist/templates/web/ui-auth-payments-ai/template/README.md +207 -0
  18. package/dist/templates/web/ui-auth-payments-ai/template/context.md +169 -0
  19. package/dist/templates/web/ui-auth-payments-ai/template/middleware.ts +68 -0
  20. package/dist/templates/web/ui-auth-payments-ai/template/next.config.js +12 -0
  21. package/dist/templates/web/ui-auth-payments-ai/template/package-lock.json +12241 -0
  22. package/dist/templates/web/ui-auth-payments-ai/template/package.json +55 -0
  23. package/dist/templates/web/ui-auth-payments-ai/template/postcss.config.js +7 -0
  24. package/dist/templates/web/ui-auth-payments-ai/template/src/app/ai/page.tsx +310 -0
  25. package/dist/templates/web/ui-auth-payments-ai/template/src/app/api/ai/audio/route.ts +56 -0
  26. package/dist/templates/web/ui-auth-payments-ai/template/src/app/api/ai/chat/route.ts +49 -0
  27. package/dist/templates/web/ui-auth-payments-ai/template/src/app/api/ai/text/route.ts +64 -0
  28. package/dist/templates/web/ui-auth-payments-ai/template/src/app/api/ai/video/route.ts +73 -0
  29. package/dist/templates/web/ui-auth-payments-ai/template/src/app/auth/callback/route.ts +12 -0
  30. package/dist/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +211 -0
  31. package/dist/templates/web/ui-auth-payments-ai/template/src/app/checkout/page.tsx +142 -0
  32. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dashboard/layout.tsx +22 -0
  33. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +183 -0
  34. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dev-setup/page.tsx +801 -0
  35. package/dist/templates/web/ui-auth-payments-ai/template/src/app/error.tsx +67 -0
  36. package/dist/templates/web/ui-auth-payments-ai/template/src/app/globals.css +43 -0
  37. package/dist/templates/web/ui-auth-payments-ai/template/src/app/layout.tsx +35 -0
  38. package/dist/templates/web/ui-auth-payments-ai/template/src/app/loading.tsx +20 -0
  39. package/dist/templates/web/ui-auth-payments-ai/template/src/app/login/page.tsx +6 -0
  40. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +380 -0
  41. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.backup +391 -0
  42. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.bak +391 -0
  43. package/dist/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +640 -0
  44. package/dist/templates/web/ui-auth-payments-ai/template/src/app/signup/page.tsx +6 -0
  45. package/dist/templates/web/ui-auth-payments-ai/template/src/components/__tests__/example.test.tsx +49 -0
  46. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/auth-status.tsx +52 -0
  47. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +144 -0
  48. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +185 -0
  49. package/dist/templates/web/ui-auth-payments-ai/template/src/components/providers/app-providers.tsx +36 -0
  50. package/dist/templates/web/ui-auth-payments-ai/template/src/components/providers/theme-provider.tsx +96 -0
  51. package/dist/templates/web/ui-auth-payments-ai/template/src/components/shared/footer.tsx +36 -0
  52. package/dist/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +246 -0
  53. package/dist/templates/web/ui-auth-payments-ai/template/src/components/ui/badge.tsx +36 -0
  54. package/dist/templates/web/ui-auth-payments-ai/template/src/components/ui/theme-toggle.tsx +34 -0
  55. package/dist/templates/web/ui-auth-payments-ai/template/src/lib/actions/auth.ts +246 -0
  56. package/dist/templates/web/ui-auth-payments-ai/template/src/lib/actions/index.ts +14 -0
  57. package/dist/templates/web/ui-auth-payments-ai/template/src/lib/auth-server.ts +177 -0
  58. package/dist/templates/web/ui-auth-payments-ai/template/src/lib/env.ts +49 -0
  59. package/dist/templates/web/ui-auth-payments-ai/template/src/lib/utils.ts +140 -0
  60. package/dist/templates/web/ui-auth-payments-ai/template/src/test/setup.ts +79 -0
  61. package/dist/templates/web/ui-auth-payments-ai/template/tailwind.config.js +77 -0
  62. package/dist/templates/web/ui-auth-payments-ai/template/tsconfig.json +33 -0
  63. package/dist/templates/web/ui-auth-payments-ai/template/tsconfig.tsbuildinfo +1 -0
  64. package/dist/templates/web/ui-auth-payments-ai/template/vitest.config.ts +17 -0
  65. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +28 -20
  66. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.backup +391 -0
  67. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.bak +391 -0
  68. package/dist/templates/web/ui-auth-payments-audio/template/src/app/setup/page.tsx +345 -0
  69. package/dist/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +122 -37
  70. package/dist/templates/web/ui-auth-payments-video/template/src/app/setup/page.tsx +351 -0
  71. package/dist/templates/web/ui-auth-payments-video/template/src/components/shared/header.tsx +122 -37
  72. package/package.json +1 -1
  73. package/src/templates/web/ui-auth/template/.claude +21 -0
  74. package/src/templates/web/ui-auth/template/context.md +105 -0
  75. package/src/templates/web/ui-auth/template/src/app/dev-setup/page.tsx +801 -0
  76. package/src/templates/web/ui-auth/template/src/app/setup/page.tsx +403 -0
  77. package/src/templates/web/ui-auth-payments/template/src/app/dev-setup/page.tsx +801 -0
  78. package/src/templates/web/ui-auth-payments/template/src/app/setup/page.tsx +507 -0
  79. package/src/templates/web/ui-auth-payments/template/src/components/shared/header.tsx +127 -32
  80. package/src/templates/web/ui-auth-payments-ai/template/.claude +21 -0
  81. package/src/templates/web/ui-auth-payments-ai/template/.env.example +15 -0
  82. package/src/templates/web/ui-auth-payments-ai/template/README.md +207 -0
  83. package/src/templates/web/ui-auth-payments-ai/template/context.md +169 -0
  84. package/src/templates/web/ui-auth-payments-ai/template/middleware.ts +68 -0
  85. package/src/templates/web/ui-auth-payments-ai/template/next.config.js +12 -0
  86. package/src/templates/web/ui-auth-payments-ai/template/package-lock.json +12241 -0
  87. package/src/templates/web/ui-auth-payments-ai/template/package.json +55 -0
  88. package/src/templates/web/ui-auth-payments-ai/template/postcss.config.js +7 -0
  89. package/src/templates/web/ui-auth-payments-ai/template/src/app/ai/page.tsx +310 -0
  90. package/src/templates/web/ui-auth-payments-ai/template/src/app/api/ai/audio/route.ts +56 -0
  91. package/src/templates/web/ui-auth-payments-ai/template/src/app/api/ai/chat/route.ts +49 -0
  92. package/src/templates/web/ui-auth-payments-ai/template/src/app/api/ai/text/route.ts +64 -0
  93. package/src/templates/web/ui-auth-payments-ai/template/src/app/api/ai/video/route.ts +73 -0
  94. package/src/templates/web/ui-auth-payments-ai/template/src/app/auth/callback/route.ts +12 -0
  95. package/src/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +211 -0
  96. package/src/templates/web/ui-auth-payments-ai/template/src/app/checkout/page.tsx +142 -0
  97. package/src/templates/web/ui-auth-payments-ai/template/src/app/dashboard/layout.tsx +22 -0
  98. package/src/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +183 -0
  99. package/src/templates/web/ui-auth-payments-ai/template/src/app/dev-setup/page.tsx +801 -0
  100. package/src/templates/web/ui-auth-payments-ai/template/src/app/error.tsx +67 -0
  101. package/src/templates/web/ui-auth-payments-ai/template/src/app/globals.css +43 -0
  102. package/src/templates/web/ui-auth-payments-ai/template/src/app/layout.tsx +35 -0
  103. package/src/templates/web/ui-auth-payments-ai/template/src/app/loading.tsx +20 -0
  104. package/src/templates/web/ui-auth-payments-ai/template/src/app/login/page.tsx +6 -0
  105. package/src/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +380 -0
  106. package/src/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.backup +391 -0
  107. package/src/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.bak +391 -0
  108. package/src/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +640 -0
  109. package/src/templates/web/ui-auth-payments-ai/template/src/app/signup/page.tsx +6 -0
  110. package/src/templates/web/ui-auth-payments-ai/template/src/components/__tests__/example.test.tsx +49 -0
  111. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/auth-status.tsx +52 -0
  112. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +144 -0
  113. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +185 -0
  114. package/src/templates/web/ui-auth-payments-ai/template/src/components/providers/app-providers.tsx +36 -0
  115. package/src/templates/web/ui-auth-payments-ai/template/src/components/providers/theme-provider.tsx +96 -0
  116. package/src/templates/web/ui-auth-payments-ai/template/src/components/shared/footer.tsx +36 -0
  117. package/src/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +246 -0
  118. package/src/templates/web/ui-auth-payments-ai/template/src/components/ui/badge.tsx +36 -0
  119. package/src/templates/web/ui-auth-payments-ai/template/src/components/ui/theme-toggle.tsx +34 -0
  120. package/src/templates/web/ui-auth-payments-ai/template/src/lib/actions/auth.ts +246 -0
  121. package/src/templates/web/ui-auth-payments-ai/template/src/lib/actions/index.ts +14 -0
  122. package/src/templates/web/ui-auth-payments-ai/template/src/lib/auth-server.ts +177 -0
  123. package/src/templates/web/ui-auth-payments-ai/template/src/lib/env.ts +49 -0
  124. package/src/templates/web/ui-auth-payments-ai/template/src/lib/utils.ts +140 -0
  125. package/src/templates/web/ui-auth-payments-ai/template/src/test/setup.ts +79 -0
  126. package/src/templates/web/ui-auth-payments-ai/template/tailwind.config.js +77 -0
  127. package/src/templates/web/ui-auth-payments-ai/template/tsconfig.json +33 -0
  128. package/src/templates/web/ui-auth-payments-ai/template/tsconfig.tsbuildinfo +1 -0
  129. package/src/templates/web/ui-auth-payments-ai/template/vitest.config.ts +17 -0
  130. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +28 -20
  131. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.backup +391 -0
  132. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.bak +391 -0
  133. package/src/templates/web/ui-auth-payments-audio/template/src/app/setup/page.tsx +345 -0
  134. package/src/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +122 -37
  135. package/src/templates/web/ui-auth-payments-video/template/src/app/setup/page.tsx +351 -0
  136. package/src/templates/web/ui-auth-payments-video/template/src/components/shared/header.tsx +122 -37
  137. package/dist/cli/commands/add.d.ts +0 -6
  138. package/dist/cli/commands/add.d.ts.map +0 -1
  139. package/dist/cli/commands/add.js +0 -39
  140. package/dist/cli/commands/add.js.map +0 -1
  141. package/dist/cli/commands/index.d.ts +0 -4
  142. package/dist/cli/commands/index.d.ts.map +0 -1
  143. package/dist/cli/commands/index.js +0 -20
  144. package/dist/cli/commands/index.js.map +0 -1
  145. package/dist/cli/commands/update.d.ts +0 -6
  146. package/dist/cli/commands/update.d.ts.map +0 -1
  147. package/dist/cli/commands/update.js +0 -68
  148. package/dist/cli/commands/update.js.map +0 -1
  149. package/dist/cli/index.d.ts +0 -4
  150. package/dist/cli/index.d.ts.map +0 -1
  151. package/dist/cli/index.js +0 -61
  152. package/dist/cli/index.js.map +0 -1
  153. package/dist/cli/prompts/index.d.ts +0 -2
  154. package/dist/cli/prompts/index.d.ts.map +0 -1
  155. package/dist/cli/prompts/index.js +0 -18
  156. package/dist/cli/prompts/index.js.map +0 -1
  157. package/dist/cli/prompts/project-setup.d.ts +0 -5
  158. package/dist/cli/prompts/project-setup.d.ts.map +0 -1
  159. package/dist/cli/prompts/project-setup.js +0 -251
  160. package/dist/cli/prompts/project-setup.js.map +0 -1
  161. package/dist/cli/utils/git.d.ts +0 -9
  162. package/dist/cli/utils/git.d.ts.map +0 -1
  163. package/dist/cli/utils/git.js +0 -77
  164. package/dist/cli/utils/git.js.map +0 -1
  165. package/dist/cli/utils/index.d.ts +0 -5
  166. package/dist/cli/utils/index.d.ts.map +0 -1
  167. package/dist/cli/utils/index.js +0 -21
  168. package/dist/cli/utils/index.js.map +0 -1
  169. package/dist/cli/utils/logger.d.ts +0 -16
  170. package/dist/cli/utils/logger.d.ts.map +0 -1
  171. package/dist/cli/utils/logger.js +0 -55
  172. package/dist/cli/utils/logger.js.map +0 -1
  173. package/dist/cli/utils/package-manager.d.ts +0 -8
  174. package/dist/cli/utils/package-manager.d.ts.map +0 -1
  175. package/dist/cli/utils/package-manager.js +0 -92
  176. package/dist/cli/utils/package-manager.js.map +0 -1
  177. package/dist/cli/utils/spinner.d.ts +0 -7
  178. package/dist/cli/utils/spinner.d.ts.map +0 -1
  179. package/dist/cli/utils/spinner.js +0 -48
  180. package/dist/cli/utils/spinner.js.map +0 -1
  181. package/dist/cli/validators/dependencies.d.ts +0 -15
  182. package/dist/cli/validators/dependencies.d.ts.map +0 -1
  183. package/dist/cli/validators/dependencies.js +0 -108
  184. package/dist/cli/validators/dependencies.js.map +0 -1
  185. package/dist/cli/validators/index.d.ts +0 -3
  186. package/dist/cli/validators/index.d.ts.map +0 -1
  187. package/dist/cli/validators/index.js +0 -19
  188. package/dist/cli/validators/index.js.map +0 -1
  189. package/dist/cli/validators/project-name.d.ts +0 -5
  190. package/dist/cli/validators/project-name.d.ts.map +0 -1
  191. package/dist/cli/validators/project-name.js +0 -151
  192. package/dist/cli/validators/project-name.js.map +0 -1
  193. package/dist/generators/file-processor.d.ts +0 -28
  194. package/dist/generators/file-processor.d.ts.map +0 -1
  195. package/dist/generators/file-processor.js +0 -224
  196. package/dist/generators/file-processor.js.map +0 -1
  197. package/dist/generators/index.d.ts +0 -4
  198. package/dist/generators/index.d.ts.map +0 -1
  199. package/dist/generators/index.js +0 -20
  200. package/dist/generators/index.js.map +0 -1
  201. package/dist/generators/package-installer.d.ts +0 -29
  202. package/dist/generators/package-installer.d.ts.map +0 -1
  203. package/dist/generators/package-installer.js +0 -167
  204. package/dist/generators/package-installer.js.map +0 -1
@@ -0,0 +1,246 @@
1
+ 'use client';
2
+
3
+ import React, { useState } from 'react';
4
+ import Link from 'next/link';
5
+ import { LogOut, CreditCard, User, Settings, Home, Music, Headphones, Menu, X, Info } from 'lucide-react';
6
+ import { useAuth } from '@digilogiclabs/saas-factory-auth';
7
+ import {
8
+ ResponsiveHeader,
9
+ MobileNavigation,
10
+ HamburgerIcon,
11
+ useNetworkInfo,
12
+ useOfflineState
13
+ } from '@digilogiclabs/saas-factory-ui';
14
+ import { ThemeToggle } from '@/components/ui/theme-toggle';
15
+
16
+ export function Header() {
17
+ const { user, signOut } = useAuth();
18
+ const networkInfo = useNetworkInfo();
19
+ const isOnline = useOfflineState();
20
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
21
+
22
+ const projectName = "{{titleCaseName}}";
23
+
24
+ const handleSignOut = async () => {
25
+ try {
26
+ await signOut();
27
+ } catch (error) {
28
+ console.error('Sign out error:', error);
29
+ }
30
+ };
31
+
32
+ const navigationItems = [
33
+ {
34
+ label: 'Home',
35
+ href: '/',
36
+ icon: Home,
37
+ protected: false
38
+ },
39
+ {
40
+ label: 'AI Dashboard',
41
+ href: '/ai',
42
+ icon: User,
43
+ protected: true
44
+ },
45
+ {
46
+ label: 'Dashboard',
47
+ href: '/dashboard',
48
+ icon: User,
49
+ protected: true
50
+ },
51
+ {
52
+ label: 'Billing',
53
+ href: '/billing',
54
+ icon: CreditCard,
55
+ protected: true
56
+ },
57
+ {
58
+ label: 'Checkout',
59
+ href: '/checkout',
60
+ icon: CreditCard,
61
+ protected: false
62
+ },
63
+ {
64
+ label: 'Setup Guide',
65
+ href: '/setup',
66
+ icon: Info,
67
+ protected: false
68
+ },
69
+ {
70
+ label: 'Settings',
71
+ href: '/settings',
72
+ icon: Settings,
73
+ protected: true
74
+ }
75
+ ];
76
+
77
+ const authActions = user ? [
78
+ {
79
+ label: 'Sign Out',
80
+ icon: LogOut,
81
+ onClick: handleSignOut,
82
+ variant: 'ghost' as const
83
+ }
84
+ ] : [
85
+ {
86
+ label: 'Login',
87
+ href: '/login',
88
+ variant: 'ghost' as const
89
+ },
90
+ {
91
+ label: 'Sign Up',
92
+ href: '/signup',
93
+ variant: 'default' as const
94
+ }
95
+ ];
96
+
97
+ // Filter navigation items based on user authentication
98
+ const visibleNavItems = navigationItems.filter(item => !item.protected || user);
99
+
100
+ return (
101
+ <>
102
+ {/* Network Status Banner */}
103
+ {!isOnline && (
104
+ <div className="bg-red-500 text-white text-center py-2 text-sm animate-pulse">
105
+ <span>🎵 Offline - Playing cached audio only</span>
106
+ </div>
107
+ )}
108
+
109
+ {/* Audio Quality Banner */}
110
+ {isOnline && networkInfo?.effectiveType === '2g' && (
111
+ <div className="bg-yellow-500 text-white text-center py-2 text-sm">
112
+ <div className="animate-marquee whitespace-nowrap">
113
+ 🎶 Slow connection - Audio quality optimized for better streaming • Lower bitrate enabled • Cached tracks prioritized
114
+ </div>
115
+ </div>
116
+ )}
117
+
118
+ {/* High Quality Audio Banner */}
119
+ {isOnline && (networkInfo?.effectiveType === '4g' || networkInfo?.effectiveType === '5g') && (
120
+ <div className="bg-green-500 text-white text-center py-2 text-sm">
121
+ <div className="animate-marquee whitespace-nowrap">
122
+ 🎧 High-speed connection detected - Premium audio quality enabled • Lossless streaming available • Instant playback ready
123
+ </div>
124
+ </div>
125
+ )}
126
+
127
+ {/* Responsive Header */}
128
+ <header className="bg-white dark:bg-gray-800 shadow-md border-b">
129
+ <div className="container mx-auto px-4">
130
+ <div className="flex justify-between items-center h-16">
131
+ {/* Logo */}
132
+ <Link href="/" className="text-2xl font-bold text-gray-900 dark:text-white flex items-center gap-2">
133
+ <Music className="w-6 h-6" />
134
+ {projectName}
135
+ </Link>
136
+
137
+ {/* Desktop Navigation */}
138
+ <nav className="hidden md:flex items-center gap-6">
139
+ {visibleNavItems.map((item) => (
140
+ <Link
141
+ key={item.href}
142
+ href={item.href}
143
+ className="flex items-center gap-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white transition-colors"
144
+ >
145
+ <item.icon className="w-4 h-4" />
146
+ {item.label}
147
+ </Link>
148
+ ))}
149
+
150
+ {/* Auth Actions */}
151
+ <div className="flex items-center gap-2 ml-4 pl-4 border-l border-gray-200 dark:border-gray-600">
152
+ <ThemeToggle />
153
+ {user ? (
154
+ <button
155
+ onClick={handleSignOut}
156
+ className="flex items-center gap-2 px-3 py-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white transition-colors"
157
+ >
158
+ <LogOut className="w-4 h-4" />
159
+ Sign Out
160
+ </button>
161
+ ) : (
162
+ <div className="flex items-center gap-2">
163
+ <Link
164
+ href="/login"
165
+ className="text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white transition-colors"
166
+ >
167
+ Login
168
+ </Link>
169
+ <Link
170
+ href="/signup"
171
+ className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
172
+ >
173
+ Sign Up
174
+ </Link>
175
+ </div>
176
+ )}
177
+ </div>
178
+ </nav>
179
+
180
+ {/* Mobile Menu Button */}
181
+ <button
182
+ onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
183
+ className="md:hidden p-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
184
+ >
185
+ {mobileMenuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
186
+ </button>
187
+ </div>
188
+
189
+ {/* Mobile Menu */}
190
+ {mobileMenuOpen && (
191
+ <div className="md:hidden border-t border-gray-200 dark:border-gray-600 py-4">
192
+ <nav className="flex flex-col space-y-3">
193
+ {visibleNavItems.map((item) => (
194
+ <Link
195
+ key={item.href}
196
+ href={item.href}
197
+ onClick={() => setMobileMenuOpen(false)}
198
+ className="flex items-center gap-3 px-3 py-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors"
199
+ >
200
+ <item.icon className="w-4 h-4" />
201
+ {item.label}
202
+ </Link>
203
+ ))}
204
+
205
+ {/* Mobile Auth Actions */}
206
+ <div className="flex items-center gap-3 px-3 pt-3 border-t border-gray-200 dark:border-gray-600">
207
+ <ThemeToggle />
208
+ {user ? (
209
+ <button
210
+ onClick={() => {
211
+ handleSignOut();
212
+ setMobileMenuOpen(false);
213
+ }}
214
+ className="flex items-center gap-2 px-3 py-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors"
215
+ >
216
+ <LogOut className="w-4 h-4" />
217
+ Sign Out
218
+ </button>
219
+ ) : (
220
+ <div className="flex flex-col gap-2 w-full">
221
+ <Link
222
+ href="/login"
223
+ onClick={() => setMobileMenuOpen(false)}
224
+ className="text-center py-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors"
225
+ >
226
+ Login
227
+ </Link>
228
+ <Link
229
+ href="/signup"
230
+ onClick={() => setMobileMenuOpen(false)}
231
+ className="text-center py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
232
+ >
233
+ Sign Up
234
+ </Link>
235
+ </div>
236
+ )}
237
+ </div>
238
+ </nav>
239
+ </div>
240
+ )}
241
+ </div>
242
+ </header>
243
+ </>
244
+ );
245
+ }
246
+
@@ -0,0 +1,36 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const badgeVariants = cva(
6
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default:
11
+ "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
12
+ secondary:
13
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
14
+ destructive:
15
+ "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
16
+ outline: "text-foreground",
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ variant: "default",
21
+ },
22
+ }
23
+ )
24
+
25
+ export interface BadgeProps
26
+ extends React.HTMLAttributes<HTMLDivElement>,
27
+ VariantProps<typeof badgeVariants> {}
28
+
29
+ function Badge({ className, variant, ...props }: BadgeProps) {
30
+ return (
31
+ <div className={cn(badgeVariants({ variant }), className)} {...props} />
32
+ )
33
+ }
34
+
35
+ export { Badge, badgeVariants }
36
+
@@ -0,0 +1,34 @@
1
+ 'use client'
2
+
3
+ import * as React from "react"
4
+ import { Moon, Sun } from "lucide-react"
5
+ import { useTheme } from "next-themes"
6
+
7
+ import { Button } from "@digilogiclabs/saas-factory-ui"
8
+
9
+ export function ThemeToggle() {
10
+ const { theme, setTheme } = useTheme()
11
+
12
+ const toggleTheme = () => {
13
+ if (theme === 'light') {
14
+ setTheme('dark')
15
+ } else if (theme === 'dark') {
16
+ setTheme('system')
17
+ } else {
18
+ setTheme('light')
19
+ }
20
+ }
21
+
22
+ return (
23
+ <Button
24
+ variant="outline"
25
+ size="icon"
26
+ onClick={toggleTheme}
27
+ className="h-9 w-9"
28
+ >
29
+ <Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
30
+ <Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
31
+ <span className="sr-only">Toggle theme</span>
32
+ </Button>
33
+ )
34
+ }
@@ -0,0 +1,246 @@
1
+ 'use server'
2
+
3
+ import { redirect } from 'next/navigation'
4
+ import { cookies } from 'next/headers'
5
+ import { z } from 'zod'
6
+
7
+ // Schema for form validation
8
+ const signInSchema = z.object({
9
+ email: z.string().email('Invalid email address'),
10
+ password: z.string().min(6, 'Password must be at least 6 characters'),
11
+ })
12
+
13
+ const signUpSchema = z.object({
14
+ email: z.string().email('Invalid email address'),
15
+ password: z.string().min(6, 'Password must be at least 6 characters'),
16
+ confirmPassword: z.string(),
17
+ name: z.string().min(2, 'Name must be at least 2 characters').optional(),
18
+ }).refine((data) => data.password === data.confirmPassword, {
19
+ message: "Passwords don't match",
20
+ path: ["confirmPassword"],
21
+ })
22
+
23
+ // Response types
24
+ type ActionResult = {
25
+ success: boolean
26
+ error?: string
27
+ fieldErrors?: Record<string, string[]>
28
+ }
29
+
30
+ /**
31
+ * Server action for signing in
32
+ * This works alongside the client-side @digilogiclabs/saas-factory-auth
33
+ */
34
+ export async function signInAction(prevState: any, formData: FormData): Promise<ActionResult> {
35
+ try {
36
+ const rawData = {
37
+ email: formData.get('email') as string,
38
+ password: formData.get('password') as string,
39
+ }
40
+
41
+ // Validate form data
42
+ const validationResult = signInSchema.safeParse(rawData)
43
+
44
+ if (!validationResult.success) {
45
+ return {
46
+ success: false,
47
+ error: 'Please check your input',
48
+ fieldErrors: validationResult.error.formErrors.fieldErrors,
49
+ }
50
+ }
51
+
52
+ const { email, password } = validationResult.data
53
+
54
+ // Note: The actual authentication is handled by the client-side library
55
+ // This server action is mainly for form validation and server-side processing
56
+ // You might want to add additional server-side logic here like:
57
+ // - Rate limiting
58
+ // - Logging
59
+ // - Analytics
60
+
61
+ // For now, we'll return success and let the client handle the actual auth
62
+ return {
63
+ success: true,
64
+ }
65
+ } catch (error) {
66
+ console.error('Sign in error:', error)
67
+ return {
68
+ success: false,
69
+ error: 'An unexpected error occurred. Please try again.',
70
+ }
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Server action for signing up
76
+ */
77
+ export async function signUpAction(prevState: any, formData: FormData): Promise<ActionResult> {
78
+ try {
79
+ const rawData = {
80
+ email: formData.get('email') as string,
81
+ password: formData.get('password') as string,
82
+ confirmPassword: formData.get('confirmPassword') as string,
83
+ name: formData.get('name') as string,
84
+ }
85
+
86
+ // Validate form data
87
+ const validationResult = signUpSchema.safeParse(rawData)
88
+
89
+ if (!validationResult.success) {
90
+ return {
91
+ success: false,
92
+ error: 'Please check your input',
93
+ fieldErrors: validationResult.error.formErrors.fieldErrors,
94
+ }
95
+ }
96
+
97
+ const { email, password, name } = validationResult.data
98
+
99
+ // Additional server-side processing can go here
100
+ // - User existence check
101
+ // - Welcome email preparation
102
+ // - User analytics setup
103
+
104
+ return {
105
+ success: true,
106
+ }
107
+ } catch (error) {
108
+ console.error('Sign up error:', error)
109
+ return {
110
+ success: false,
111
+ error: 'An unexpected error occurred. Please try again.',
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Server action for signing out
118
+ */
119
+ export async function signOutAction(): Promise<void> {
120
+ try {
121
+ const cookieStore = await cookies()
122
+
123
+ // Clear auth cookies (adjust cookie names based on the auth library)
124
+ cookieStore.delete('saas-factory-auth-token')
125
+ cookieStore.delete('saas-factory-auth-user')
126
+
127
+ // Additional cleanup can go here
128
+ // - Clear session data
129
+ // - Log sign out event
130
+ // - Clear cache
131
+
132
+ } catch (error) {
133
+ console.error('Sign out error:', error)
134
+ }
135
+
136
+ redirect('/')
137
+ }
138
+
139
+ /**
140
+ * Server action for OAuth redirect handling
141
+ */
142
+ export async function handleOAuthCallback(provider: string, code: string): Promise<ActionResult> {
143
+ try {
144
+ // This would handle OAuth callback processing
145
+ // For now, we'll delegate to the client-side library
146
+
147
+ return {
148
+ success: true,
149
+ }
150
+ } catch (error) {
151
+ console.error('OAuth callback error:', error)
152
+ return {
153
+ success: false,
154
+ error: 'Authentication failed. Please try again.',
155
+ }
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Server action for password reset request
161
+ */
162
+ export async function requestPasswordReset(prevState: any, formData: FormData): Promise<ActionResult> {
163
+ try {
164
+ const email = formData.get('email') as string
165
+
166
+ if (!email) {
167
+ return {
168
+ success: false,
169
+ error: 'Email is required',
170
+ }
171
+ }
172
+
173
+ const emailSchema = z.string().email()
174
+ const validationResult = emailSchema.safeParse(email)
175
+
176
+ if (!validationResult.success) {
177
+ return {
178
+ success: false,
179
+ error: 'Please enter a valid email address',
180
+ }
181
+ }
182
+
183
+ // Password reset logic would go here
184
+ // - Generate reset token
185
+ // - Send reset email
186
+ // - Log reset request
187
+
188
+ return {
189
+ success: true,
190
+ }
191
+ } catch (error) {
192
+ console.error('Password reset error:', error)
193
+ return {
194
+ success: false,
195
+ error: 'An unexpected error occurred. Please try again.',
196
+ }
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Server action for updating user profile
202
+ */
203
+ export async function updateProfileAction(prevState: any, formData: FormData): Promise<ActionResult> {
204
+ try {
205
+ // This would require authentication check
206
+ const cookieStore = await cookies()
207
+ const authToken = cookieStore.get('saas-factory-auth-token')?.value
208
+
209
+ if (!authToken) {
210
+ redirect('/login')
211
+ }
212
+
213
+ const name = formData.get('name') as string
214
+ const email = formData.get('email') as string
215
+
216
+ const updateSchema = z.object({
217
+ name: z.string().min(2, 'Name must be at least 2 characters').optional(),
218
+ email: z.string().email('Invalid email address').optional(),
219
+ })
220
+
221
+ const validationResult = updateSchema.safeParse({ name, email })
222
+
223
+ if (!validationResult.success) {
224
+ return {
225
+ success: false,
226
+ error: 'Please check your input',
227
+ fieldErrors: validationResult.error.formErrors.fieldErrors,
228
+ }
229
+ }
230
+
231
+ // Profile update logic would go here
232
+ // - Update user in database
233
+ // - Update auth cookies
234
+ // - Send confirmation email if email changed
235
+
236
+ return {
237
+ success: true,
238
+ }
239
+ } catch (error) {
240
+ console.error('Profile update error:', error)
241
+ return {
242
+ success: false,
243
+ error: 'An unexpected error occurred. Please try again.',
244
+ }
245
+ }
246
+ }
@@ -0,0 +1,14 @@
1
+ // Re-export all server actions for easier imports
2
+ export {
3
+ signInAction,
4
+ signUpAction,
5
+ signOutAction,
6
+ handleOAuthCallback,
7
+ requestPasswordReset,
8
+ updateProfileAction,
9
+ } from './auth'
10
+
11
+ // Add other action exports here as needed
12
+ // export * from './posts'
13
+ // export * from './profile'
14
+ // export * from './settings'