@digilogiclabs/create-saas-app 2.11.0 → 2.12.1

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 (413) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/cli/index.js +1 -1
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/generators/template-generator.d.ts +0 -2
  6. package/dist/generators/template-generator.d.ts.map +1 -1
  7. package/dist/generators/template-generator.js +18 -17
  8. package/dist/generators/template-generator.js.map +1 -1
  9. package/dist/templates/mobile/base/template/App.tsx +7 -4
  10. package/dist/templates/mobile/base/template/app/checkout.tsx +5 -2
  11. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/_layout.tsx +6 -2
  12. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/billing.tsx +7 -3
  13. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/index.tsx +5 -2
  14. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/profile.tsx +7 -2
  15. package/dist/templates/mobile/ui-auth-payments/template/app/_layout.tsx +2 -4
  16. package/dist/templates/mobile/ui-auth-payments/template/app/auth/login.tsx +6 -3
  17. package/dist/templates/mobile/ui-auth-payments/template/app/auth/signup.tsx +6 -3
  18. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/_layout.tsx +6 -2
  19. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/billing.tsx +7 -3
  20. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/index.tsx +5 -2
  21. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/profile.tsx +7 -2
  22. package/dist/templates/mobile/ui-auth-payments-ai/template/app/_layout.tsx +2 -4
  23. package/dist/templates/mobile/ui-auth-payments-ai/template/app/auth/login.tsx +6 -3
  24. package/dist/templates/mobile/ui-auth-payments-ai/template/app/auth/signup.tsx +6 -3
  25. package/dist/templates/shared/admin/web/src/components/admin-nav.tsx +3 -3
  26. package/dist/templates/shared/auth/supabase/web/src/lib/auth-session.ts +36 -16
  27. package/dist/templates/shared/auth/supabase/web/src/middleware.ts +6 -0
  28. package/dist/templates/shared/config/web/next.config.mjs +0 -1
  29. package/dist/templates/shared/cookie-consent/web/components/cookie-consent.tsx +5 -5
  30. package/dist/templates/shared/design/web/src/components/ui/button.tsx +56 -0
  31. package/dist/templates/shared/email/web/src/lib/email/client.ts +1 -1
  32. package/dist/templates/shared/error-pages/web/src/app/error.tsx +13 -11
  33. package/dist/templates/shared/error-pages/web/src/app/global-error.tsx +2 -0
  34. package/dist/templates/shared/error-pages/web/src/app/not-found.tsx +6 -6
  35. package/dist/templates/shared/legal/web/src/app/(legal)/privacy/page.tsx +4 -4
  36. package/dist/templates/shared/legal/web/src/app/(legal)/terms/page.tsx +4 -4
  37. package/dist/templates/shared/loading/web/components/skeleton.tsx +4 -4
  38. package/dist/templates/shared/mock/web/.env.local +55 -0
  39. package/dist/templates/shared/mock/web/src/components/mock-auth-provider.tsx +72 -0
  40. package/dist/templates/shared/mock/web/src/components/mock-banner.tsx +29 -0
  41. package/dist/templates/shared/mock/web/src/lib/mock.ts +147 -0
  42. package/dist/templates/shared/payments/web/src/app/api/webhooks/stripe/route.ts +10 -4
  43. package/dist/templates/shared/redis/web/src/lib/redis.ts +1 -1
  44. package/dist/templates/web/ai-platform/template/package.json +0 -1
  45. package/dist/templates/web/ai-platform/template/src/app/chat/page.tsx +5 -2
  46. package/dist/templates/web/ai-platform/template/src/app/playground/page.tsx +5 -2
  47. package/dist/templates/web/ai-platform/template/src/components/providers/app-providers.tsx +2 -5
  48. package/dist/templates/web/base/template/eslint.config.mjs +14 -0
  49. package/dist/templates/web/base/template/src/app/auth/callback/route.ts +1 -1
  50. package/dist/templates/web/base/template/src/app/checkout/page.tsx +76 -103
  51. package/dist/templates/web/base/template/src/app/dashboard/page.tsx +145 -329
  52. package/dist/templates/web/base/template/src/app/layout.tsx +40 -38
  53. package/dist/templates/web/base/template/src/app/login/page.tsx +116 -66
  54. package/dist/templates/web/base/template/src/app/page.tsx +97 -193
  55. package/dist/templates/web/base/template/src/app/settings/page.tsx +154 -0
  56. package/dist/templates/web/base/template/src/app/signup/page.tsx +117 -66
  57. package/dist/templates/web/base/template/src/components/providers/app-providers.tsx +8 -3
  58. package/dist/templates/web/base/template/src/components/shared/header.tsx +229 -63
  59. package/dist/templates/web/iot-dashboard/template/package.json +0 -1
  60. package/dist/templates/web/iot-dashboard/template/src/components/providers/app-providers.tsx +2 -5
  61. package/dist/templates/web/marketplace/template/package.json +0 -1
  62. package/dist/templates/web/marketplace/template/src/components/providers/app-providers.tsx +2 -5
  63. package/dist/templates/web/micro-saas/template/package.json +0 -1
  64. package/dist/templates/web/micro-saas/template/src/components/providers/app-providers.tsx +2 -5
  65. package/dist/templates/web/ui-auth/template/eslint.config.mjs +14 -0
  66. package/dist/templates/web/ui-auth/template/src/app/checkout/page.tsx +3 -3
  67. package/dist/templates/web/ui-auth/template/src/app/dev-setup/page.tsx +81 -91
  68. package/dist/templates/web/ui-auth/template/src/app/layout.tsx +38 -36
  69. package/dist/templates/web/ui-auth/template/src/app/login/page.tsx +22 -45
  70. package/dist/templates/web/ui-auth/template/src/app/page.tsx +106 -306
  71. package/dist/templates/web/ui-auth/template/src/app/setup/page.tsx +387 -402
  72. package/dist/templates/web/ui-auth/template/src/app/signup/page.tsx +24 -47
  73. package/dist/templates/web/ui-auth/template/src/components/providers/app-providers.tsx +8 -3
  74. package/dist/templates/web/ui-auth/template/src/components/shared/header.tsx +229 -94
  75. package/dist/templates/web/ui-auth-ai/template/src/app/layout.tsx +38 -45
  76. package/dist/templates/web/ui-auth-ai/template/src/app/login/page.tsx +86 -0
  77. package/dist/templates/web/ui-auth-ai/template/src/app/page.tsx +107 -193
  78. package/dist/templates/web/ui-auth-ai/template/src/app/signup/page.tsx +105 -0
  79. package/dist/templates/web/ui-auth-ai/template/src/components/ai/audio-generator.tsx +144 -140
  80. package/dist/templates/web/ui-auth-ai/template/src/components/ai/video-generator.tsx +156 -157
  81. package/dist/templates/web/ui-auth-ai/template/src/components/auth/login-form.tsx +7 -3
  82. package/dist/templates/web/ui-auth-ai/template/src/components/providers/app-providers.tsx +25 -0
  83. package/dist/templates/web/ui-auth-ai/template/src/components/shared/footer.tsx +36 -0
  84. package/dist/templates/web/ui-auth-ai/template/src/components/shared/header.tsx +228 -0
  85. package/dist/templates/web/ui-auth-ai/template/src/components/ui/button.tsx +5 -5
  86. package/dist/templates/web/ui-auth-ai/template/src/components/ui/input.tsx +1 -1
  87. package/dist/templates/web/ui-auth-ai/template/src/components/ui/select.tsx +1 -1
  88. package/dist/templates/web/ui-auth-ai/template/src/components/ui/textarea.tsx +1 -1
  89. package/dist/templates/web/ui-auth-ai/template/src/components/ui/theme-toggle.tsx +34 -0
  90. package/dist/templates/web/ui-auth-ai/template/src/lib/supabase.ts +6 -4
  91. package/dist/templates/web/ui-auth-ai/template/src/providers/auth-provider.tsx +7 -5
  92. package/dist/templates/web/ui-auth-payments/template/src/app/billing/page.tsx +63 -192
  93. package/dist/templates/web/ui-auth-payments/template/src/app/checkout/page.tsx +104 -296
  94. package/dist/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +27 -27
  95. package/dist/templates/web/ui-auth-payments/template/src/app/dev-setup/page.tsx +70 -81
  96. package/dist/templates/web/ui-auth-payments/template/src/app/layout.tsx +38 -36
  97. package/dist/templates/web/ui-auth-payments/template/src/app/login/loading.tsx +9 -9
  98. package/dist/templates/web/ui-auth-payments/template/src/app/login/page.tsx +4 -104
  99. package/dist/templates/web/ui-auth-payments/template/src/app/page.tsx +69 -337
  100. package/dist/templates/web/ui-auth-payments/template/src/app/setup/page.tsx +55 -68
  101. package/dist/templates/web/ui-auth-payments/template/src/app/signup/loading.tsx +13 -13
  102. package/dist/templates/web/ui-auth-payments/template/src/app/signup/page.tsx +4 -123
  103. package/dist/templates/web/ui-auth-payments/template/src/components/client/auth-status.tsx +37 -52
  104. package/dist/templates/web/ui-auth-payments/template/src/components/client/login-form.tsx +49 -103
  105. package/dist/templates/web/ui-auth-payments/template/src/components/client/newsletter-signup.tsx +4 -4
  106. package/dist/templates/web/ui-auth-payments/template/src/components/client/signup-form.tsx +60 -140
  107. package/dist/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +25 -28
  108. package/dist/templates/web/ui-auth-payments/template/src/components/shared/header.tsx +229 -230
  109. package/dist/templates/web/ui-auth-payments/template/src/lib/actions/auth.ts +245 -245
  110. package/dist/templates/web/ui-auth-payments/template/src/lib/actions/index.ts +339 -339
  111. package/dist/templates/web/ui-auth-payments-ai/template/src/app/ai/page.tsx +305 -309
  112. package/dist/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +62 -312
  113. package/dist/templates/web/ui-auth-payments-ai/template/src/app/checkout/page.tsx +109 -125
  114. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +27 -27
  115. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dev-setup/page.tsx +68 -83
  116. package/dist/templates/web/ui-auth-payments-ai/template/src/app/layout.tsx +40 -38
  117. package/dist/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +20 -20
  118. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +140 -394
  119. package/dist/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +28 -27
  120. package/dist/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +51 -66
  121. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/auth-status.tsx +37 -52
  122. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +50 -79
  123. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +58 -111
  124. package/dist/templates/web/ui-auth-payments-ai/template/src/components/providers/app-providers.tsx +8 -3
  125. package/dist/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +229 -252
  126. package/dist/templates/web/ui-auth-payments-ai/template/src/lib/actions/auth.ts +245 -245
  127. package/dist/templates/web/ui-auth-payments-audio/template/src/app/billing/page.tsx +63 -192
  128. package/dist/templates/web/ui-auth-payments-audio/template/src/app/checkout/page.tsx +109 -125
  129. package/dist/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +27 -27
  130. package/dist/templates/web/ui-auth-payments-audio/template/src/app/layout.tsx +40 -38
  131. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +122 -385
  132. package/dist/templates/web/ui-auth-payments-audio/template/src/app/setup/page.tsx +340 -344
  133. package/dist/templates/web/ui-auth-payments-audio/template/src/components/client/auth-status.tsx +37 -52
  134. package/dist/templates/web/ui-auth-payments-audio/template/src/components/client/login-form.tsx +49 -103
  135. package/dist/templates/web/ui-auth-payments-audio/template/src/components/client/signup-form.tsx +60 -140
  136. package/dist/templates/web/ui-auth-payments-audio/template/src/components/providers/app-providers.tsx +8 -3
  137. package/dist/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +229 -252
  138. package/dist/templates/web/ui-auth-payments-audio/template/src/lib/actions/auth.ts +3 -3
  139. package/dist/templates/web/ui-auth-payments-video/template/src/app/billing/page.tsx +63 -192
  140. package/dist/templates/web/ui-auth-payments-video/template/src/app/checkout/page.tsx +109 -125
  141. package/dist/templates/web/ui-auth-payments-video/template/src/app/layout.tsx +38 -36
  142. package/dist/templates/web/ui-auth-payments-video/template/src/app/login/page.tsx +9 -109
  143. package/dist/templates/web/ui-auth-payments-video/template/src/app/page.tsx +132 -392
  144. package/dist/templates/web/ui-auth-payments-video/template/src/app/setup/page.tsx +346 -350
  145. package/dist/templates/web/ui-auth-payments-video/template/src/app/signup/page.tsx +9 -128
  146. package/dist/templates/web/ui-auth-payments-video/template/src/components/client/login-form.tsx +90 -0
  147. package/dist/templates/web/ui-auth-payments-video/template/src/components/client/signup-form.tsx +105 -0
  148. package/dist/templates/web/ui-auth-payments-video/template/src/components/providers/app-providers.tsx +8 -3
  149. package/dist/templates/web/ui-auth-payments-video/template/src/components/shared/header.tsx +229 -246
  150. package/dist/templates/web/ui-only/template/eslint.config.mjs +14 -0
  151. package/dist/templates/web/ui-only/template/src/app/checkout/page.tsx +2 -2
  152. package/dist/templates/web/ui-only/template/src/app/login/page.tsx +69 -63
  153. package/dist/templates/web/ui-only/template/src/app/page.tsx +69 -91
  154. package/dist/templates/web/ui-only/template/src/app/signup/page.tsx +94 -79
  155. package/dist/templates/web/ui-only/template/src/components/providers/app-providers.tsx +1 -6
  156. package/dist/templates/web/ui-only/template/src/components/shared/header.tsx +90 -53
  157. package/dist/templates/web/ui-package-test/template/package.json +19 -23
  158. package/dist/templates/web/ui-package-test/template/postcss.config.mjs +8 -0
  159. package/dist/templates/web/ui-package-test/template/src/app/globals.css +88 -0
  160. package/dist/templates/web/ui-package-test/template/src/app/layout.tsx +27 -0
  161. package/dist/templates/web/ui-package-test/template/src/app/page.tsx +46 -106
  162. package/package.json +1 -1
  163. package/src/templates/mobile/base/template/App.tsx +7 -4
  164. package/src/templates/mobile/base/template/app/checkout.tsx +5 -2
  165. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/_layout.tsx +6 -2
  166. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/billing.tsx +7 -3
  167. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/index.tsx +5 -2
  168. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/profile.tsx +7 -2
  169. package/src/templates/mobile/ui-auth-payments/template/app/_layout.tsx +2 -4
  170. package/src/templates/mobile/ui-auth-payments/template/app/auth/login.tsx +6 -3
  171. package/src/templates/mobile/ui-auth-payments/template/app/auth/signup.tsx +6 -3
  172. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/_layout.tsx +6 -2
  173. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/billing.tsx +7 -3
  174. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/index.tsx +5 -2
  175. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/profile.tsx +7 -2
  176. package/src/templates/mobile/ui-auth-payments-ai/template/app/_layout.tsx +2 -4
  177. package/src/templates/mobile/ui-auth-payments-ai/template/app/auth/login.tsx +6 -3
  178. package/src/templates/mobile/ui-auth-payments-ai/template/app/auth/signup.tsx +6 -3
  179. package/src/templates/shared/admin/web/src/components/admin-nav.tsx +3 -3
  180. package/src/templates/shared/auth/supabase/web/src/lib/auth-session.ts +36 -16
  181. package/src/templates/shared/auth/supabase/web/src/middleware.ts +6 -0
  182. package/src/templates/shared/config/web/next.config.mjs +0 -1
  183. package/src/templates/shared/cookie-consent/web/components/cookie-consent.tsx +5 -5
  184. package/src/templates/shared/design/web/src/components/ui/button.tsx +56 -0
  185. package/src/templates/shared/email/web/src/lib/email/client.ts +1 -1
  186. package/src/templates/shared/error-pages/web/src/app/error.tsx +13 -11
  187. package/src/templates/shared/error-pages/web/src/app/global-error.tsx +2 -0
  188. package/src/templates/shared/error-pages/web/src/app/not-found.tsx +6 -6
  189. package/src/templates/shared/legal/web/src/app/(legal)/privacy/page.tsx +4 -4
  190. package/src/templates/shared/legal/web/src/app/(legal)/terms/page.tsx +4 -4
  191. package/src/templates/shared/loading/web/components/skeleton.tsx +4 -4
  192. package/src/templates/shared/mock/web/.env.local +55 -0
  193. package/src/templates/shared/mock/web/src/components/mock-auth-provider.tsx +72 -0
  194. package/src/templates/shared/mock/web/src/components/mock-banner.tsx +29 -0
  195. package/src/templates/shared/mock/web/src/lib/mock.ts +147 -0
  196. package/src/templates/shared/payments/web/src/app/api/webhooks/stripe/route.ts +10 -4
  197. package/src/templates/shared/redis/web/src/lib/redis.ts +1 -1
  198. package/src/templates/web/ai-platform/template/package.json +0 -1
  199. package/src/templates/web/ai-platform/template/src/app/chat/page.tsx +5 -2
  200. package/src/templates/web/ai-platform/template/src/app/playground/page.tsx +5 -2
  201. package/src/templates/web/ai-platform/template/src/components/providers/app-providers.tsx +2 -5
  202. package/src/templates/web/base/template/eslint.config.mjs +14 -0
  203. package/src/templates/web/base/template/src/app/auth/callback/route.ts +1 -1
  204. package/src/templates/web/base/template/src/app/checkout/page.tsx +76 -103
  205. package/src/templates/web/base/template/src/app/dashboard/page.tsx +145 -329
  206. package/src/templates/web/base/template/src/app/layout.tsx +40 -38
  207. package/src/templates/web/base/template/src/app/login/page.tsx +116 -66
  208. package/src/templates/web/base/template/src/app/page.tsx +97 -193
  209. package/src/templates/web/base/template/src/app/settings/page.tsx +154 -0
  210. package/src/templates/web/base/template/src/app/signup/page.tsx +117 -66
  211. package/src/templates/web/base/template/src/components/providers/app-providers.tsx +8 -3
  212. package/src/templates/web/base/template/src/components/shared/header.tsx +229 -63
  213. package/src/templates/web/iot-dashboard/template/package.json +0 -1
  214. package/src/templates/web/iot-dashboard/template/src/components/providers/app-providers.tsx +2 -5
  215. package/src/templates/web/marketplace/template/package.json +0 -1
  216. package/src/templates/web/marketplace/template/src/components/providers/app-providers.tsx +2 -5
  217. package/src/templates/web/micro-saas/template/package.json +0 -1
  218. package/src/templates/web/micro-saas/template/src/components/providers/app-providers.tsx +2 -5
  219. package/src/templates/web/ui-auth/template/eslint.config.mjs +14 -0
  220. package/src/templates/web/ui-auth/template/src/app/checkout/page.tsx +3 -3
  221. package/src/templates/web/ui-auth/template/src/app/dev-setup/page.tsx +81 -91
  222. package/src/templates/web/ui-auth/template/src/app/layout.tsx +38 -36
  223. package/src/templates/web/ui-auth/template/src/app/login/page.tsx +22 -45
  224. package/src/templates/web/ui-auth/template/src/app/page.tsx +106 -306
  225. package/src/templates/web/ui-auth/template/src/app/setup/page.tsx +387 -402
  226. package/src/templates/web/ui-auth/template/src/app/signup/page.tsx +24 -47
  227. package/src/templates/web/ui-auth/template/src/components/providers/app-providers.tsx +8 -3
  228. package/src/templates/web/ui-auth/template/src/components/shared/header.tsx +229 -94
  229. package/src/templates/web/ui-auth-ai/template/src/app/layout.tsx +38 -45
  230. package/src/templates/web/ui-auth-ai/template/src/app/login/page.tsx +86 -0
  231. package/src/templates/web/ui-auth-ai/template/src/app/page.tsx +107 -193
  232. package/src/templates/web/ui-auth-ai/template/src/app/signup/page.tsx +105 -0
  233. package/src/templates/web/ui-auth-ai/template/src/components/ai/audio-generator.tsx +144 -140
  234. package/src/templates/web/ui-auth-ai/template/src/components/ai/video-generator.tsx +156 -157
  235. package/src/templates/web/ui-auth-ai/template/src/components/auth/login-form.tsx +7 -3
  236. package/src/templates/web/ui-auth-ai/template/src/components/providers/app-providers.tsx +25 -0
  237. package/src/templates/web/ui-auth-ai/template/src/components/shared/footer.tsx +36 -0
  238. package/src/templates/web/ui-auth-ai/template/src/components/shared/header.tsx +228 -0
  239. package/src/templates/web/ui-auth-ai/template/src/components/ui/button.tsx +5 -5
  240. package/src/templates/web/ui-auth-ai/template/src/components/ui/input.tsx +1 -1
  241. package/src/templates/web/ui-auth-ai/template/src/components/ui/select.tsx +1 -1
  242. package/src/templates/web/ui-auth-ai/template/src/components/ui/textarea.tsx +1 -1
  243. package/src/templates/web/ui-auth-ai/template/src/components/ui/theme-toggle.tsx +34 -0
  244. package/src/templates/web/ui-auth-ai/template/src/lib/supabase.ts +6 -4
  245. package/src/templates/web/ui-auth-ai/template/src/providers/auth-provider.tsx +7 -5
  246. package/src/templates/web/ui-auth-payments/template/src/app/billing/page.tsx +63 -192
  247. package/src/templates/web/ui-auth-payments/template/src/app/checkout/page.tsx +104 -296
  248. package/src/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +27 -27
  249. package/src/templates/web/ui-auth-payments/template/src/app/dev-setup/page.tsx +70 -81
  250. package/src/templates/web/ui-auth-payments/template/src/app/layout.tsx +38 -36
  251. package/src/templates/web/ui-auth-payments/template/src/app/login/loading.tsx +9 -9
  252. package/src/templates/web/ui-auth-payments/template/src/app/login/page.tsx +4 -104
  253. package/src/templates/web/ui-auth-payments/template/src/app/page.tsx +69 -337
  254. package/src/templates/web/ui-auth-payments/template/src/app/setup/page.tsx +55 -68
  255. package/src/templates/web/ui-auth-payments/template/src/app/signup/loading.tsx +13 -13
  256. package/src/templates/web/ui-auth-payments/template/src/app/signup/page.tsx +4 -123
  257. package/src/templates/web/ui-auth-payments/template/src/components/client/auth-status.tsx +37 -52
  258. package/src/templates/web/ui-auth-payments/template/src/components/client/login-form.tsx +49 -103
  259. package/src/templates/web/ui-auth-payments/template/src/components/client/newsletter-signup.tsx +4 -4
  260. package/src/templates/web/ui-auth-payments/template/src/components/client/signup-form.tsx +60 -140
  261. package/src/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +25 -28
  262. package/src/templates/web/ui-auth-payments/template/src/components/shared/header.tsx +229 -230
  263. package/src/templates/web/ui-auth-payments/template/src/lib/actions/auth.ts +245 -245
  264. package/src/templates/web/ui-auth-payments/template/src/lib/actions/index.ts +339 -339
  265. package/src/templates/web/ui-auth-payments-ai/template/src/app/ai/page.tsx +305 -309
  266. package/src/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +62 -312
  267. package/src/templates/web/ui-auth-payments-ai/template/src/app/checkout/page.tsx +109 -125
  268. package/src/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +27 -27
  269. package/src/templates/web/ui-auth-payments-ai/template/src/app/dev-setup/page.tsx +68 -83
  270. package/src/templates/web/ui-auth-payments-ai/template/src/app/layout.tsx +40 -38
  271. package/src/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +20 -20
  272. package/src/templates/web/ui-auth-payments-ai/template/src/app/page.tsx +140 -394
  273. package/src/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +28 -27
  274. package/src/templates/web/ui-auth-payments-ai/template/src/app/setup/page.tsx +51 -66
  275. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/auth-status.tsx +37 -52
  276. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +50 -79
  277. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +58 -111
  278. package/src/templates/web/ui-auth-payments-ai/template/src/components/providers/app-providers.tsx +8 -3
  279. package/src/templates/web/ui-auth-payments-ai/template/src/components/shared/header.tsx +229 -252
  280. package/src/templates/web/ui-auth-payments-ai/template/src/lib/actions/auth.ts +245 -245
  281. package/src/templates/web/ui-auth-payments-audio/template/src/app/billing/page.tsx +63 -192
  282. package/src/templates/web/ui-auth-payments-audio/template/src/app/checkout/page.tsx +109 -125
  283. package/src/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +27 -27
  284. package/src/templates/web/ui-auth-payments-audio/template/src/app/layout.tsx +40 -38
  285. package/src/templates/web/ui-auth-payments-audio/template/src/app/page.tsx +122 -385
  286. package/src/templates/web/ui-auth-payments-audio/template/src/app/setup/page.tsx +340 -344
  287. package/src/templates/web/ui-auth-payments-audio/template/src/components/client/auth-status.tsx +37 -52
  288. package/src/templates/web/ui-auth-payments-audio/template/src/components/client/login-form.tsx +49 -103
  289. package/src/templates/web/ui-auth-payments-audio/template/src/components/client/signup-form.tsx +60 -140
  290. package/src/templates/web/ui-auth-payments-audio/template/src/components/providers/app-providers.tsx +8 -3
  291. package/src/templates/web/ui-auth-payments-audio/template/src/components/shared/header.tsx +229 -252
  292. package/src/templates/web/ui-auth-payments-audio/template/src/lib/actions/auth.ts +3 -3
  293. package/src/templates/web/ui-auth-payments-video/template/src/app/billing/page.tsx +63 -192
  294. package/src/templates/web/ui-auth-payments-video/template/src/app/checkout/page.tsx +109 -125
  295. package/src/templates/web/ui-auth-payments-video/template/src/app/layout.tsx +38 -36
  296. package/src/templates/web/ui-auth-payments-video/template/src/app/login/page.tsx +9 -109
  297. package/src/templates/web/ui-auth-payments-video/template/src/app/page.tsx +132 -392
  298. package/src/templates/web/ui-auth-payments-video/template/src/app/setup/page.tsx +346 -350
  299. package/src/templates/web/ui-auth-payments-video/template/src/app/signup/page.tsx +9 -128
  300. package/src/templates/web/ui-auth-payments-video/template/src/components/client/login-form.tsx +90 -0
  301. package/src/templates/web/ui-auth-payments-video/template/src/components/client/signup-form.tsx +105 -0
  302. package/src/templates/web/ui-auth-payments-video/template/src/components/providers/app-providers.tsx +8 -3
  303. package/src/templates/web/ui-auth-payments-video/template/src/components/shared/header.tsx +229 -246
  304. package/src/templates/web/ui-only/template/eslint.config.mjs +14 -0
  305. package/src/templates/web/ui-only/template/src/app/checkout/page.tsx +2 -2
  306. package/src/templates/web/ui-only/template/src/app/login/page.tsx +69 -63
  307. package/src/templates/web/ui-only/template/src/app/page.tsx +69 -91
  308. package/src/templates/web/ui-only/template/src/app/signup/page.tsx +94 -79
  309. package/src/templates/web/ui-only/template/src/components/providers/app-providers.tsx +1 -6
  310. package/src/templates/web/ui-only/template/src/components/shared/header.tsx +90 -53
  311. package/src/templates/web/ui-package-test/template/package.json +19 -23
  312. package/src/templates/web/ui-package-test/template/postcss.config.mjs +8 -0
  313. package/src/templates/web/ui-package-test/template/src/app/globals.css +88 -0
  314. package/src/templates/web/ui-package-test/template/src/app/layout.tsx +27 -0
  315. package/src/templates/web/ui-package-test/template/src/app/page.tsx +46 -106
  316. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/README.md +0 -655
  317. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/app/(tabs)/ai.tsx +0 -683
  318. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/app/_layout.tsx +0 -124
  319. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/app.json +0 -74
  320. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/babel.config.js +0 -25
  321. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/docs/MOBILE-SETUP.md +0 -787
  322. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/eas.json +0 -25
  323. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/expo-env.d.ts +0 -3
  324. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +0 -346
  325. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/jest-setup.ts +0 -37
  326. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/lib/rag/config.ts +0 -180
  327. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/metro.config.js +0 -11
  328. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/package.json +0 -122
  329. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +0 -599
  330. package/dist/templates/mobile/ui-auth-payments-ai-rag/template/tsconfig.json +0 -32
  331. package/dist/templates/web/base/template/.eslintrc.js +0 -8
  332. package/dist/templates/web/base/template/src/components/__tests__/example.test.tsx +0 -49
  333. package/dist/templates/web/base/template/src/test/setup.ts +0 -74
  334. package/dist/templates/web/base/template/vitest.config.ts +0 -17
  335. package/dist/templates/web/ui-auth/template/.eslintrc.js +0 -8
  336. package/dist/templates/web/ui-auth/template/src/components/__tests__/example.test.tsx +0 -49
  337. package/dist/templates/web/ui-auth/template/src/test/setup.ts +0 -74
  338. package/dist/templates/web/ui-auth/template/vitest.config.ts +0 -17
  339. package/dist/templates/web/ui-auth-payments/template/src/components/__tests__/example.test.tsx +0 -49
  340. package/dist/templates/web/ui-auth-payments/template/src/test/setup.ts +0 -74
  341. package/dist/templates/web/ui-auth-payments/template/vitest.config.ts +0 -17
  342. package/dist/templates/web/ui-auth-payments-ai/template/src/components/__tests__/example.test.tsx +0 -49
  343. package/dist/templates/web/ui-auth-payments-ai/template/src/test/setup.ts +0 -74
  344. package/dist/templates/web/ui-auth-payments-ai/template/vitest.config.ts +0 -17
  345. package/dist/templates/web/ui-auth-payments-ai-rag/template/README.md +0 -434
  346. package/dist/templates/web/ui-auth-payments-ai-rag/template/components/rag/KnowledgeManager.tsx +0 -642
  347. package/dist/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGAnalytics.tsx +0 -466
  348. package/dist/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGChatInterface.tsx +0 -393
  349. package/dist/templates/web/ui-auth-payments-ai-rag/template/docs/GETTING-STARTED.md +0 -457
  350. package/dist/templates/web/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +0 -478
  351. package/dist/templates/web/ui-auth-payments-ai-rag/template/lib/rag/config.ts +0 -250
  352. package/dist/templates/web/ui-auth-payments-ai-rag/template/package.json +0 -73
  353. package/dist/templates/web/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +0 -622
  354. package/dist/templates/web/ui-auth-payments-ai-rag/template/src/app/ai/page.tsx +0 -396
  355. package/dist/templates/web/ui-auth-payments-audio/template/src/components/__tests__/example.test.tsx +0 -49
  356. package/dist/templates/web/ui-auth-payments-audio/template/src/test/setup.ts +0 -74
  357. package/dist/templates/web/ui-auth-payments-audio/template/vitest.config.ts +0 -17
  358. package/dist/templates/web/ui-auth-payments-video/template/src/components/__tests__/example.test.tsx +0 -49
  359. package/dist/templates/web/ui-auth-payments-video/template/src/test/setup.ts +0 -74
  360. package/dist/templates/web/ui-auth-payments-video/template/vitest.config.ts +0 -17
  361. package/dist/templates/web/ui-only/template/.eslintrc.js +0 -8
  362. package/dist/templates/web/ui-only/template/src/components/__tests__/example.test.tsx +0 -49
  363. package/dist/templates/web/ui-only/template/src/test/setup.ts +0 -74
  364. package/dist/templates/web/ui-only/template/vitest.config.ts +0 -17
  365. package/src/templates/mobile/ui-auth-payments-ai-rag/template/README.md +0 -655
  366. package/src/templates/mobile/ui-auth-payments-ai-rag/template/app/(tabs)/ai.tsx +0 -683
  367. package/src/templates/mobile/ui-auth-payments-ai-rag/template/app/_layout.tsx +0 -124
  368. package/src/templates/mobile/ui-auth-payments-ai-rag/template/app.json +0 -74
  369. package/src/templates/mobile/ui-auth-payments-ai-rag/template/babel.config.js +0 -25
  370. package/src/templates/mobile/ui-auth-payments-ai-rag/template/docs/MOBILE-SETUP.md +0 -787
  371. package/src/templates/mobile/ui-auth-payments-ai-rag/template/eas.json +0 -25
  372. package/src/templates/mobile/ui-auth-payments-ai-rag/template/expo-env.d.ts +0 -3
  373. package/src/templates/mobile/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +0 -346
  374. package/src/templates/mobile/ui-auth-payments-ai-rag/template/jest-setup.ts +0 -37
  375. package/src/templates/mobile/ui-auth-payments-ai-rag/template/lib/rag/config.ts +0 -180
  376. package/src/templates/mobile/ui-auth-payments-ai-rag/template/metro.config.js +0 -11
  377. package/src/templates/mobile/ui-auth-payments-ai-rag/template/package.json +0 -122
  378. package/src/templates/mobile/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +0 -599
  379. package/src/templates/mobile/ui-auth-payments-ai-rag/template/tsconfig.json +0 -32
  380. package/src/templates/web/base/template/.eslintrc.js +0 -8
  381. package/src/templates/web/base/template/src/components/__tests__/example.test.tsx +0 -49
  382. package/src/templates/web/base/template/src/test/setup.ts +0 -74
  383. package/src/templates/web/base/template/vitest.config.ts +0 -17
  384. package/src/templates/web/ui-auth/template/.eslintrc.js +0 -8
  385. package/src/templates/web/ui-auth/template/src/components/__tests__/example.test.tsx +0 -49
  386. package/src/templates/web/ui-auth/template/src/test/setup.ts +0 -74
  387. package/src/templates/web/ui-auth/template/vitest.config.ts +0 -17
  388. package/src/templates/web/ui-auth-payments/template/src/components/__tests__/example.test.tsx +0 -49
  389. package/src/templates/web/ui-auth-payments/template/src/test/setup.ts +0 -74
  390. package/src/templates/web/ui-auth-payments/template/vitest.config.ts +0 -17
  391. package/src/templates/web/ui-auth-payments-ai/template/src/components/__tests__/example.test.tsx +0 -49
  392. package/src/templates/web/ui-auth-payments-ai/template/src/test/setup.ts +0 -74
  393. package/src/templates/web/ui-auth-payments-ai/template/vitest.config.ts +0 -17
  394. package/src/templates/web/ui-auth-payments-ai-rag/template/README.md +0 -434
  395. package/src/templates/web/ui-auth-payments-ai-rag/template/components/rag/KnowledgeManager.tsx +0 -642
  396. package/src/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGAnalytics.tsx +0 -466
  397. package/src/templates/web/ui-auth-payments-ai-rag/template/components/rag/RAGChatInterface.tsx +0 -393
  398. package/src/templates/web/ui-auth-payments-ai-rag/template/docs/GETTING-STARTED.md +0 -457
  399. package/src/templates/web/ui-auth-payments-ai-rag/template/hooks/useRAGSystem.ts +0 -478
  400. package/src/templates/web/ui-auth-payments-ai-rag/template/lib/rag/config.ts +0 -250
  401. package/src/templates/web/ui-auth-payments-ai-rag/template/package.json +0 -73
  402. package/src/templates/web/ui-auth-payments-ai-rag/template/scripts/setup-rag.js +0 -622
  403. package/src/templates/web/ui-auth-payments-ai-rag/template/src/app/ai/page.tsx +0 -396
  404. package/src/templates/web/ui-auth-payments-audio/template/src/components/__tests__/example.test.tsx +0 -49
  405. package/src/templates/web/ui-auth-payments-audio/template/src/test/setup.ts +0 -74
  406. package/src/templates/web/ui-auth-payments-audio/template/vitest.config.ts +0 -17
  407. package/src/templates/web/ui-auth-payments-video/template/src/components/__tests__/example.test.tsx +0 -49
  408. package/src/templates/web/ui-auth-payments-video/template/src/test/setup.ts +0 -74
  409. package/src/templates/web/ui-auth-payments-video/template/vitest.config.ts +0 -17
  410. package/src/templates/web/ui-only/template/.eslintrc.js +0 -8
  411. package/src/templates/web/ui-only/template/src/components/__tests__/example.test.tsx +0 -49
  412. package/src/templates/web/ui-only/template/src/test/setup.ts +0 -74
  413. package/src/templates/web/ui-only/template/vitest.config.ts +0 -17
@@ -1,340 +1,340 @@
1
- 'use server'
2
-
3
- import { after } from 'next/server'
4
- import { revalidateTag, revalidatePath } from 'next/cache'
5
- import { getCurrentUser } from '@/lib/auth-server'
6
- import { z } from 'zod'
7
-
8
- // Common response type
9
- export type ActionResponse<T = any> = {
10
- success: boolean
11
- data?: T
12
- error?: string
13
- fieldErrors?: Record<string, string[]>
14
- }
15
-
16
- /**
17
- * Example server action for contact form
18
- */
19
- export async function submitContactForm(prevState: any, formData: FormData): Promise<ActionResponse> {
20
- try {
21
- const contactSchema = z.object({
22
- name: z.string().min(2, 'Name must be at least 2 characters'),
23
- email: z.string().email('Invalid email address'),
24
- subject: z.string().min(5, 'Subject must be at least 5 characters'),
25
- message: z.string().min(10, 'Message must be at least 10 characters'),
26
- })
27
-
28
- const rawData = {
29
- name: formData.get('name') as string,
30
- email: formData.get('email') as string,
31
- subject: formData.get('subject') as string,
32
- message: formData.get('message') as string,
33
- }
34
-
35
- const validationResult = contactSchema.safeParse(rawData)
36
-
37
- if (!validationResult.success) {
38
- return {
39
- success: false,
40
- error: 'Please check your input',
41
- fieldErrors: validationResult.error.formErrors.fieldErrors,
42
- }
43
- }
44
-
45
- const { name, email, subject, message } = validationResult.data
46
-
47
- // Process contact form submission
48
- // This could involve:
49
- // - Sending email to admin
50
- // - Saving to database
51
- // - Sending auto-reply to user
52
-
53
- // Use after() for non-blocking operations (Next.js 15.3 feature)
54
- after(async () => {
55
- // Send notification email to admin (non-blocking)
56
- console.log('Sending notification email for contact form submission')
57
-
58
- // Log analytics event (non-blocking)
59
- console.log('Logging contact form submission analytics')
60
-
61
- // Update dashboard statistics (non-blocking)
62
- console.log('Updating contact form statistics')
63
- })
64
-
65
- return {
66
- success: true,
67
- data: { message: 'Thank you for your message. We\'ll get back to you soon!' }
68
- }
69
- } catch (error) {
70
- console.error('Contact form error:', error)
71
- return {
72
- success: false,
73
- error: 'An unexpected error occurred. Please try again.',
74
- }
75
- }
76
- }
77
-
78
- /**
79
- * Example server action for newsletter signup
80
- */
81
- export async function subscribeToNewsletter(prevState: any, formData: FormData): Promise<ActionResponse> {
82
- try {
83
- const email = formData.get('email') as string
84
-
85
- const emailSchema = z.string().email('Invalid email address')
86
- const validationResult = emailSchema.safeParse(email)
87
-
88
- if (!validationResult.success) {
89
- return {
90
- success: false,
91
- error: 'Please enter a valid email address',
92
- }
93
- }
94
-
95
- // Add to newsletter list
96
- // This could involve:
97
- // - Adding to email service provider (Mailchimp, ConvertKit, etc.)
98
- // - Saving to database
99
- // - Sending welcome email
100
-
101
- after(async () => {
102
- // Send welcome email (non-blocking)
103
- console.log(`Sending welcome email to ${email}`)
104
-
105
- // Add to email marketing platform (non-blocking)
106
- console.log(`Adding ${email} to newsletter list`)
107
-
108
- // Track conversion (non-blocking)
109
- console.log('Tracking newsletter signup conversion')
110
- })
111
-
112
- return {
113
- success: true,
114
- data: { message: 'Successfully subscribed to newsletter!' }
115
- }
116
- } catch (error) {
117
- console.error('Newsletter subscription error:', error)
118
- return {
119
- success: false,
120
- error: 'An unexpected error occurred. Please try again.',
121
- }
122
- }
123
- }
124
-
125
- /**
126
- * Example authenticated server action
127
- */
128
- export async function createPost(prevState: any, formData: FormData): Promise<ActionResponse> {
129
- try {
130
- // Require authentication
131
- const user = await getCurrentUser()
132
- if (!user) {
133
- return {
134
- success: false,
135
- error: 'Authentication required',
136
- }
137
- }
138
-
139
- const postSchema = z.object({
140
- title: z.string().min(3, 'Title must be at least 3 characters'),
141
- content: z.string().min(10, 'Content must be at least 10 characters'),
142
- published: z.boolean().default(false),
143
- })
144
-
145
- const rawData = {
146
- title: formData.get('title') as string,
147
- content: formData.get('content') as string,
148
- published: formData.get('published') === 'true',
149
- }
150
-
151
- const validationResult = postSchema.safeParse(rawData)
152
-
153
- if (!validationResult.success) {
154
- return {
155
- success: false,
156
- error: 'Please check your input',
157
- fieldErrors: validationResult.error.formErrors.fieldErrors,
158
- }
159
- }
160
-
161
- const { title, content, published } = validationResult.data
162
-
163
- // Create post in database
164
- const post = {
165
- id: Math.random().toString(36).substr(2, 9),
166
- title,
167
- content,
168
- published,
169
- authorId: user.id,
170
- createdAt: new Date().toISOString(),
171
- }
172
-
173
- // Revalidate relevant paths and tags
174
- revalidateTag('posts')
175
- revalidatePath('/posts')
176
- if (published) {
177
- revalidatePath('/')
178
- }
179
-
180
- // Non-blocking operations
181
- after(async () => {
182
- // Send notifications to subscribers (non-blocking)
183
- if (published) {
184
- console.log('Notifying subscribers of new post')
185
- }
186
-
187
- // Update search index (non-blocking)
188
- console.log('Updating search index')
189
-
190
- // Track content creation analytics (non-blocking)
191
- console.log('Tracking post creation analytics')
192
- })
193
-
194
- return {
195
- success: true,
196
- data: { post, message: published ? 'Post published successfully!' : 'Post saved as draft!' }
197
- }
198
- } catch (error) {
199
- console.error('Create post error:', error)
200
- return {
201
- success: false,
202
- error: 'An unexpected error occurred. Please try again.',
203
- }
204
- }
205
- }
206
-
207
- /**
208
- * Example action for updating user preferences
209
- */
210
- export async function updatePreferences(prevState: any, formData: FormData): Promise<ActionResponse> {
211
- try {
212
- const user = await getCurrentUser()
213
- if (!user) {
214
- return {
215
- success: false,
216
- error: 'Authentication required',
217
- }
218
- }
219
-
220
- const preferencesSchema = z.object({
221
- emailNotifications: z.boolean().default(true),
222
- pushNotifications: z.boolean().default(false),
223
- marketingEmails: z.boolean().default(false),
224
- theme: z.enum(['light', 'dark', 'system']).default('system'),
225
- })
226
-
227
- const rawData = {
228
- emailNotifications: formData.get('emailNotifications') === 'true',
229
- pushNotifications: formData.get('pushNotifications') === 'true',
230
- marketingEmails: formData.get('marketingEmails') === 'true',
231
- theme: formData.get('theme') as 'light' | 'dark' | 'system' | null || 'system',
232
- }
233
-
234
- const validationResult = preferencesSchema.safeParse(rawData)
235
-
236
- if (!validationResult.success) {
237
- return {
238
- success: false,
239
- error: 'Please check your input',
240
- fieldErrors: validationResult.error.formErrors.fieldErrors,
241
- }
242
- }
243
-
244
- const preferences = validationResult.data
245
-
246
- // Update user preferences in database
247
- // This would typically involve a database update
248
-
249
- after(async () => {
250
- // Update notification service settings (non-blocking)
251
- console.log('Updating notification service settings')
252
-
253
- // Log preference changes for analytics (non-blocking)
254
- console.log('Logging preference changes')
255
- })
256
-
257
- return {
258
- success: true,
259
- data: { preferences, message: 'Preferences updated successfully!' }
260
- }
261
- } catch (error) {
262
- console.error('Update preferences error:', error)
263
- return {
264
- success: false,
265
- error: 'An unexpected error occurred. Please try again.',
266
- }
267
- }
268
- }
269
-
270
- /**
271
- * Example action with file upload
272
- */
273
- export async function uploadAvatar(prevState: any, formData: FormData): Promise<ActionResponse> {
274
- try {
275
- const user = await getCurrentUser()
276
- if (!user) {
277
- return {
278
- success: false,
279
- error: 'Authentication required',
280
- }
281
- }
282
-
283
- const file = formData.get('avatar') as File
284
-
285
- if (!file || file.size === 0) {
286
- return {
287
- success: false,
288
- error: 'Please select a file to upload',
289
- }
290
- }
291
-
292
- // Validate file type and size
293
- const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
294
- const maxSize = 5 * 1024 * 1024 // 5MB
295
-
296
- if (!allowedTypes.includes(file.type)) {
297
- return {
298
- success: false,
299
- error: 'Please upload a valid image file (JPEG, PNG, GIF, or WebP)',
300
- }
301
- }
302
-
303
- if (file.size > maxSize) {
304
- return {
305
- success: false,
306
- error: 'File size must be less than 5MB',
307
- }
308
- }
309
-
310
- // Process file upload
311
- // This would typically involve:
312
- // - Uploading to cloud storage (AWS S3, Cloudinary, etc.)
313
- // - Resizing/optimizing the image
314
- // - Updating user record in database
315
-
316
- const avatarUrl = `https://example.com/avatars/${user.id}-${Date.now()}.${file.type.split('/')[1]}`
317
-
318
- after(async () => {
319
- // Generate different image sizes (non-blocking)
320
- console.log('Generating avatar thumbnails')
321
-
322
- // Update CDN cache (non-blocking)
323
- console.log('Updating CDN cache')
324
-
325
- // Log upload event (non-blocking)
326
- console.log('Logging avatar upload event')
327
- })
328
-
329
- return {
330
- success: true,
331
- data: { avatarUrl, message: 'Avatar uploaded successfully!' }
332
- }
333
- } catch (error) {
334
- console.error('Upload avatar error:', error)
335
- return {
336
- success: false,
337
- error: 'An unexpected error occurred. Please try again.',
338
- }
339
- }
1
+ 'use server'
2
+
3
+ import { after } from 'next/server'
4
+ import { revalidateTag, revalidatePath } from 'next/cache'
5
+ import { getCurrentUser } from '@/lib/auth-server'
6
+ import { z } from 'zod'
7
+
8
+ // Common response type
9
+ export type ActionResponse<T = any> = {
10
+ success: boolean
11
+ data?: T
12
+ error?: string
13
+ fieldErrors?: Record<string, string[]>
14
+ }
15
+
16
+ /**
17
+ * Example server action for contact form
18
+ */
19
+ export async function submitContactForm(prevState: any, formData: FormData): Promise<ActionResponse> {
20
+ try {
21
+ const contactSchema = z.object({
22
+ name: z.string().min(2, 'Name must be at least 2 characters'),
23
+ email: z.string().email('Invalid email address'),
24
+ subject: z.string().min(5, 'Subject must be at least 5 characters'),
25
+ message: z.string().min(10, 'Message must be at least 10 characters'),
26
+ })
27
+
28
+ const rawData = {
29
+ name: formData.get('name') as string,
30
+ email: formData.get('email') as string,
31
+ subject: formData.get('subject') as string,
32
+ message: formData.get('message') as string,
33
+ }
34
+
35
+ const validationResult = contactSchema.safeParse(rawData)
36
+
37
+ if (!validationResult.success) {
38
+ return {
39
+ success: false,
40
+ error: 'Please check your input',
41
+ fieldErrors: validationResult.error.flatten().fieldErrors,
42
+ }
43
+ }
44
+
45
+ const { name, email, subject, message } = validationResult.data
46
+
47
+ // Process contact form submission
48
+ // This could involve:
49
+ // - Sending email to admin
50
+ // - Saving to database
51
+ // - Sending auto-reply to user
52
+
53
+ // Use after() for non-blocking operations (Next.js 15.3 feature)
54
+ after(async () => {
55
+ // Send notification email to admin (non-blocking)
56
+ console.log('Sending notification email for contact form submission')
57
+
58
+ // Log analytics event (non-blocking)
59
+ console.log('Logging contact form submission analytics')
60
+
61
+ // Update dashboard statistics (non-blocking)
62
+ console.log('Updating contact form statistics')
63
+ })
64
+
65
+ return {
66
+ success: true,
67
+ data: { message: 'Thank you for your message. We\'ll get back to you soon!' }
68
+ }
69
+ } catch (error) {
70
+ console.error('Contact form error:', error)
71
+ return {
72
+ success: false,
73
+ error: 'An unexpected error occurred. Please try again.',
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Example server action for newsletter signup
80
+ */
81
+ export async function subscribeToNewsletter(prevState: any, formData: FormData): Promise<ActionResponse> {
82
+ try {
83
+ const email = formData.get('email') as string
84
+
85
+ const emailSchema = z.string().email('Invalid email address')
86
+ const validationResult = emailSchema.safeParse(email)
87
+
88
+ if (!validationResult.success) {
89
+ return {
90
+ success: false,
91
+ error: 'Please enter a valid email address',
92
+ }
93
+ }
94
+
95
+ // Add to newsletter list
96
+ // This could involve:
97
+ // - Adding to email service provider (Mailchimp, ConvertKit, etc.)
98
+ // - Saving to database
99
+ // - Sending welcome email
100
+
101
+ after(async () => {
102
+ // Send welcome email (non-blocking)
103
+ console.log(`Sending welcome email to ${email}`)
104
+
105
+ // Add to email marketing platform (non-blocking)
106
+ console.log(`Adding ${email} to newsletter list`)
107
+
108
+ // Track conversion (non-blocking)
109
+ console.log('Tracking newsletter signup conversion')
110
+ })
111
+
112
+ return {
113
+ success: true,
114
+ data: { message: 'Successfully subscribed to newsletter!' }
115
+ }
116
+ } catch (error) {
117
+ console.error('Newsletter subscription error:', error)
118
+ return {
119
+ success: false,
120
+ error: 'An unexpected error occurred. Please try again.',
121
+ }
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Example authenticated server action
127
+ */
128
+ export async function createPost(prevState: any, formData: FormData): Promise<ActionResponse> {
129
+ try {
130
+ // Require authentication
131
+ const user = await getCurrentUser()
132
+ if (!user) {
133
+ return {
134
+ success: false,
135
+ error: 'Authentication required',
136
+ }
137
+ }
138
+
139
+ const postSchema = z.object({
140
+ title: z.string().min(3, 'Title must be at least 3 characters'),
141
+ content: z.string().min(10, 'Content must be at least 10 characters'),
142
+ published: z.boolean().default(false),
143
+ })
144
+
145
+ const rawData = {
146
+ title: formData.get('title') as string,
147
+ content: formData.get('content') as string,
148
+ published: formData.get('published') === 'true',
149
+ }
150
+
151
+ const validationResult = postSchema.safeParse(rawData)
152
+
153
+ if (!validationResult.success) {
154
+ return {
155
+ success: false,
156
+ error: 'Please check your input',
157
+ fieldErrors: validationResult.error.flatten().fieldErrors,
158
+ }
159
+ }
160
+
161
+ const { title, content, published } = validationResult.data
162
+
163
+ // Create post in database
164
+ const post = {
165
+ id: Math.random().toString(36).substr(2, 9),
166
+ title,
167
+ content,
168
+ published,
169
+ authorId: user.id,
170
+ createdAt: new Date().toISOString(),
171
+ }
172
+
173
+ // Revalidate relevant paths and tags
174
+ revalidateTag('posts')
175
+ revalidatePath('/posts')
176
+ if (published) {
177
+ revalidatePath('/')
178
+ }
179
+
180
+ // Non-blocking operations
181
+ after(async () => {
182
+ // Send notifications to subscribers (non-blocking)
183
+ if (published) {
184
+ console.log('Notifying subscribers of new post')
185
+ }
186
+
187
+ // Update search index (non-blocking)
188
+ console.log('Updating search index')
189
+
190
+ // Track content creation analytics (non-blocking)
191
+ console.log('Tracking post creation analytics')
192
+ })
193
+
194
+ return {
195
+ success: true,
196
+ data: { post, message: published ? 'Post published successfully!' : 'Post saved as draft!' }
197
+ }
198
+ } catch (error) {
199
+ console.error('Create post error:', error)
200
+ return {
201
+ success: false,
202
+ error: 'An unexpected error occurred. Please try again.',
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Example action for updating user preferences
209
+ */
210
+ export async function updatePreferences(prevState: any, formData: FormData): Promise<ActionResponse> {
211
+ try {
212
+ const user = await getCurrentUser()
213
+ if (!user) {
214
+ return {
215
+ success: false,
216
+ error: 'Authentication required',
217
+ }
218
+ }
219
+
220
+ const preferencesSchema = z.object({
221
+ emailNotifications: z.boolean().default(true),
222
+ pushNotifications: z.boolean().default(false),
223
+ marketingEmails: z.boolean().default(false),
224
+ theme: z.enum(['light', 'dark', 'system']).default('system'),
225
+ })
226
+
227
+ const rawData = {
228
+ emailNotifications: formData.get('emailNotifications') === 'true',
229
+ pushNotifications: formData.get('pushNotifications') === 'true',
230
+ marketingEmails: formData.get('marketingEmails') === 'true',
231
+ theme: formData.get('theme') as 'light' | 'dark' | 'system' | null || 'system',
232
+ }
233
+
234
+ const validationResult = preferencesSchema.safeParse(rawData)
235
+
236
+ if (!validationResult.success) {
237
+ return {
238
+ success: false,
239
+ error: 'Please check your input',
240
+ fieldErrors: validationResult.error.flatten().fieldErrors,
241
+ }
242
+ }
243
+
244
+ const preferences = validationResult.data
245
+
246
+ // Update user preferences in database
247
+ // This would typically involve a database update
248
+
249
+ after(async () => {
250
+ // Update notification service settings (non-blocking)
251
+ console.log('Updating notification service settings')
252
+
253
+ // Log preference changes for analytics (non-blocking)
254
+ console.log('Logging preference changes')
255
+ })
256
+
257
+ return {
258
+ success: true,
259
+ data: { preferences, message: 'Preferences updated successfully!' }
260
+ }
261
+ } catch (error) {
262
+ console.error('Update preferences error:', error)
263
+ return {
264
+ success: false,
265
+ error: 'An unexpected error occurred. Please try again.',
266
+ }
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Example action with file upload
272
+ */
273
+ export async function uploadAvatar(prevState: any, formData: FormData): Promise<ActionResponse> {
274
+ try {
275
+ const user = await getCurrentUser()
276
+ if (!user) {
277
+ return {
278
+ success: false,
279
+ error: 'Authentication required',
280
+ }
281
+ }
282
+
283
+ const file = formData.get('avatar') as File
284
+
285
+ if (!file || file.size === 0) {
286
+ return {
287
+ success: false,
288
+ error: 'Please select a file to upload',
289
+ }
290
+ }
291
+
292
+ // Validate file type and size
293
+ const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
294
+ const maxSize = 5 * 1024 * 1024 // 5MB
295
+
296
+ if (!allowedTypes.includes(file.type)) {
297
+ return {
298
+ success: false,
299
+ error: 'Please upload a valid image file (JPEG, PNG, GIF, or WebP)',
300
+ }
301
+ }
302
+
303
+ if (file.size > maxSize) {
304
+ return {
305
+ success: false,
306
+ error: 'File size must be less than 5MB',
307
+ }
308
+ }
309
+
310
+ // Process file upload
311
+ // This would typically involve:
312
+ // - Uploading to cloud storage (AWS S3, Cloudinary, etc.)
313
+ // - Resizing/optimizing the image
314
+ // - Updating user record in database
315
+
316
+ const avatarUrl = `https://example.com/avatars/${user.id}-${Date.now()}.${file.type.split('/')[1]}`
317
+
318
+ after(async () => {
319
+ // Generate different image sizes (non-blocking)
320
+ console.log('Generating avatar thumbnails')
321
+
322
+ // Update CDN cache (non-blocking)
323
+ console.log('Updating CDN cache')
324
+
325
+ // Log upload event (non-blocking)
326
+ console.log('Logging avatar upload event')
327
+ })
328
+
329
+ return {
330
+ success: true,
331
+ data: { avatarUrl, message: 'Avatar uploaded successfully!' }
332
+ }
333
+ } catch (error) {
334
+ console.error('Upload avatar error:', error)
335
+ return {
336
+ success: false,
337
+ error: 'An unexpected error occurred. Please try again.',
338
+ }
339
+ }
340
340
  }