wexts 3.0.1 → 4.0.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 (276) hide show
  1. package/README.md +49 -346
  2. package/bin/wexts.cjs +2 -0
  3. package/dist/chunk-2KAQYLVN.js +0 -0
  4. package/dist/chunk-2KAQYLVN.js.map +1 -1
  5. package/dist/{chunk-O42L6HOX.js → chunk-2LJVUMXW.js} +79 -93
  6. package/dist/chunk-2LJVUMXW.js.map +1 -0
  7. package/dist/chunk-7QKLIVRF.js +94 -0
  8. package/dist/chunk-7QKLIVRF.js.map +1 -0
  9. package/dist/{chunk-FCEZDH42.mjs → chunk-7WULUGLH.mjs} +5 -3
  10. package/dist/chunk-7WULUGLH.mjs.map +1 -0
  11. package/dist/{chunk-WF65EDRZ.js → chunk-BG56B4DE.js} +20 -2
  12. package/dist/chunk-BG56B4DE.js.map +1 -0
  13. package/dist/chunk-CLM5PNSG.mjs +496 -0
  14. package/dist/chunk-CLM5PNSG.mjs.map +1 -0
  15. package/dist/chunk-DNLGCKTT.js +31 -0
  16. package/dist/chunk-DNLGCKTT.js.map +1 -0
  17. package/dist/{chunk-VNNVLQLJ.mjs → chunk-JHOVXH3X.mjs} +2 -2
  18. package/dist/chunk-JHOVXH3X.mjs.map +1 -0
  19. package/dist/chunk-MXINIFPC.js +105 -0
  20. package/dist/chunk-MXINIFPC.js.map +1 -0
  21. package/dist/chunk-SE32ZPOZ.js +496 -0
  22. package/dist/chunk-SE32ZPOZ.js.map +1 -0
  23. package/dist/{chunk-STTOPUZ2.mjs → chunk-UAL54DVV.mjs} +21 -3
  24. package/dist/chunk-UAL54DVV.mjs.map +1 -0
  25. package/dist/{chunk-3OM7CHCA.js → chunk-WCKSKU3C.js} +1 -1
  26. package/dist/chunk-WCKSKU3C.js.map +1 -0
  27. package/dist/chunk-WU6FW77M.mjs +105 -0
  28. package/dist/chunk-WU6FW77M.mjs.map +1 -0
  29. package/dist/chunk-XE4OXN2W.js +0 -0
  30. package/dist/chunk-XE4OXN2W.js.map +1 -1
  31. package/dist/chunk-YBM3IJEA.mjs +94 -0
  32. package/dist/chunk-YBM3IJEA.mjs.map +1 -0
  33. package/dist/{chunk-KXYLEUSW.mjs → chunk-YN6WIWNQ.mjs} +69 -83
  34. package/dist/chunk-YN6WIWNQ.mjs.map +1 -0
  35. package/dist/chunk-YSLEF5C5.mjs +0 -0
  36. package/dist/chunk-YSLEF5C5.mjs.map +0 -0
  37. package/dist/chunk-ZX7QIN24.mjs +31 -0
  38. package/dist/chunk-ZX7QIN24.mjs.map +1 -0
  39. package/dist/cli/index.d.mts +10 -0
  40. package/dist/cli/index.d.ts +10 -0
  41. package/dist/cli/index.js +292 -292
  42. package/dist/cli/index.js.map +1 -1
  43. package/dist/cli/index.mjs +294 -293
  44. package/dist/cli/index.mjs.map +1 -1
  45. package/dist/client/index.d.mts +10 -1
  46. package/dist/client/index.d.ts +10 -1
  47. package/dist/client/index.js +4 -2
  48. package/dist/client/index.js.map +1 -1
  49. package/dist/client/index.mjs +6 -4
  50. package/dist/client/index.mjs.map +0 -0
  51. package/dist/codegen/index.d.mts +2 -1
  52. package/dist/codegen/index.d.ts +2 -1
  53. package/dist/codegen/index.js +5 -3
  54. package/dist/codegen/index.js.map +1 -1
  55. package/dist/codegen/index.mjs +7 -5
  56. package/dist/codegen/index.mjs.map +0 -0
  57. package/dist/decorators-BT1FFqN0.d.mts +29 -0
  58. package/dist/decorators-DvS58PqC.d.ts +29 -0
  59. package/dist/dev-server/index.d.mts +1 -1
  60. package/dist/dev-server/index.d.ts +1 -1
  61. package/dist/dev-server/index.js +3 -3
  62. package/dist/dev-server/index.js.map +1 -1
  63. package/dist/dev-server/index.mjs +3 -3
  64. package/dist/dev-server/index.mjs.map +0 -0
  65. package/dist/{index-SjUaHgFr.d.ts → index-7QeQEf37.d.ts} +27 -10
  66. package/dist/{index-tFGPFVfQ.d.mts → index-7RvU-jGE.d.mts} +0 -1
  67. package/dist/{index-tFGPFVfQ.d.ts → index-7RvU-jGE.d.ts} +0 -1
  68. package/dist/{index-SjUaHgFr.d.mts → index-8nzxy0NN.d.mts} +27 -10
  69. package/dist/index-Co5ZsLqq.d.ts +58 -0
  70. package/dist/index-D94W1__r.d.mts +58 -0
  71. package/dist/index-DQmyVp6F.d.mts +27 -0
  72. package/dist/index-KL_1BrQb.d.ts +27 -0
  73. package/dist/index.d.mts +17 -6
  74. package/dist/index.d.ts +17 -6
  75. package/dist/index.js +57 -30
  76. package/dist/index.js.map +1 -1
  77. package/dist/index.mjs +48 -21
  78. package/dist/index.mjs.map +1 -1
  79. package/dist/nest/index.d.mts +3 -1
  80. package/dist/nest/index.d.ts +3 -1
  81. package/dist/nest/index.js +20 -2
  82. package/dist/nest/index.js.map +1 -1
  83. package/dist/nest/index.mjs +21 -3
  84. package/dist/nest/index.mjs.map +0 -0
  85. package/dist/next/index.d.mts +7 -2
  86. package/dist/next/index.d.ts +7 -2
  87. package/dist/next/index.js +72 -5
  88. package/dist/next/index.js.map +1 -1
  89. package/dist/next/index.mjs +70 -4
  90. package/dist/next/index.mjs.map +1 -1
  91. package/dist/rpc/index.d.mts +2 -0
  92. package/dist/rpc/index.d.ts +2 -0
  93. package/dist/rpc/index.js +23 -0
  94. package/dist/rpc/index.js.map +1 -0
  95. package/dist/rpc/index.mjs +23 -0
  96. package/dist/{chunk-7NSRDJ5C.mjs.map → rpc/index.mjs.map} +0 -0
  97. package/dist/runtime/index.d.mts +55 -0
  98. package/dist/runtime/index.d.ts +55 -0
  99. package/dist/runtime/index.js +213 -0
  100. package/dist/runtime/index.js.map +1 -0
  101. package/dist/runtime/index.mjs +213 -0
  102. package/dist/runtime/index.mjs.map +1 -0
  103. package/dist/types/index.d.mts +0 -0
  104. package/dist/types/index.d.ts +0 -0
  105. package/dist/types/index.js +0 -0
  106. package/dist/types/index.js.map +1 -1
  107. package/dist/types/index.mjs +1 -1
  108. package/dist/types/index.mjs.map +0 -0
  109. package/dist/types-7d_fC-C3.d.mts +32 -0
  110. package/dist/types-7d_fC-C3.d.ts +32 -0
  111. package/dist/vercel-builder/index.d.mts +58 -0
  112. package/dist/vercel-builder/index.d.ts +58 -0
  113. package/dist/vercel-builder/index.js +330 -0
  114. package/dist/vercel-builder/index.js.map +1 -0
  115. package/dist/vercel-builder/index.mjs +330 -0
  116. package/dist/vercel-builder/index.mjs.map +1 -0
  117. package/package.json +37 -16
  118. package/templates/.dockerignore +43 -43
  119. package/templates/.env.example +0 -0
  120. package/templates/Dockerfile +60 -60
  121. package/templates/Procfile +1 -1
  122. package/templates/README.md +67 -58
  123. package/templates/api-sdk.ts +115 -115
  124. package/templates/docker-compose.yml +34 -34
  125. package/templates/nestjs-api/.env.example +0 -0
  126. package/templates/nestjs-api/README.md +87 -79
  127. package/templates/nestjs-api/nest-cli.json +6 -6
  128. package/templates/nestjs-api/package-lock.json +5623 -5623
  129. package/templates/nestjs-api/package.json +40 -40
  130. package/templates/nestjs-api/prisma/dev.db +0 -0
  131. package/templates/nestjs-api/prisma/migrations/20251123205437_init/migration.sql +0 -0
  132. package/templates/nestjs-api/prisma/migrations/migration_lock.toml +0 -0
  133. package/templates/nestjs-api/prisma/schema.prisma +29 -29
  134. package/templates/nestjs-api/src/app.module.ts +17 -17
  135. package/templates/nestjs-api/src/auth/auth.controller.ts +27 -27
  136. package/templates/nestjs-api/src/auth/auth.module.ts +37 -29
  137. package/templates/nestjs-api/src/auth/auth.service.ts +86 -86
  138. package/templates/nestjs-api/src/auth/dto/auth.dto.ts +22 -22
  139. package/templates/nestjs-api/src/auth/guards/jwt-auth.guard.ts +5 -5
  140. package/templates/nestjs-api/src/auth/strategies/jwt.strategy.ts +27 -19
  141. package/templates/nestjs-api/src/main.ts +32 -32
  142. package/templates/nestjs-api/src/prisma/prisma.module.ts +9 -9
  143. package/templates/nestjs-api/src/prisma/prisma.service.ts +14 -14
  144. package/templates/nestjs-api/src/todos/dto/todo.dto.ts +24 -24
  145. package/templates/nestjs-api/src/todos/todos.controller.ts +39 -39
  146. package/templates/nestjs-api/src/todos/todos.module.ts +11 -11
  147. package/templates/nestjs-api/src/todos/todos.service.ts +53 -53
  148. package/templates/nestjs-api/src/users/users.controller.ts +14 -14
  149. package/templates/nestjs-api/src/users/users.module.ts +12 -12
  150. package/templates/nestjs-api/src/users/users.service.ts +19 -19
  151. package/templates/nestjs-api/tsconfig.json +39 -39
  152. package/templates/nextjs-web/README.md +76 -68
  153. package/templates/nextjs-web/app/actions/auth.ts +108 -108
  154. package/templates/nextjs-web/app/dashboard/error.tsx +39 -39
  155. package/templates/nextjs-web/app/dashboard/loading.tsx +14 -14
  156. package/templates/nextjs-web/app/dashboard/page.tsx +5 -5
  157. package/templates/nextjs-web/app/globals.css +93 -93
  158. package/templates/nextjs-web/app/layout.tsx +29 -29
  159. package/templates/nextjs-web/app/login/page.tsx +5 -5
  160. package/templates/nextjs-web/app/page.tsx +28 -28
  161. package/templates/nextjs-web/app/register/page.tsx +5 -5
  162. package/templates/nextjs-web/components/ui/button.tsx +56 -56
  163. package/templates/nextjs-web/components/ui/card.tsx +79 -79
  164. package/templates/nextjs-web/components/ui/input.tsx +25 -25
  165. package/templates/nextjs-web/components/ui/label.tsx +24 -24
  166. package/templates/nextjs-web/features/auth/LoginForm.tsx +140 -140
  167. package/templates/nextjs-web/features/auth/RegisterForm.tsx +159 -159
  168. package/templates/nextjs-web/features/auth/api.ts +35 -35
  169. package/templates/nextjs-web/features/auth/index.ts +3 -3
  170. package/templates/nextjs-web/features/dashboard/DashboardView.tsx +204 -204
  171. package/templates/nextjs-web/features/dashboard/api.ts +9 -9
  172. package/templates/nextjs-web/features/dashboard/components.tsx +74 -74
  173. package/templates/nextjs-web/features/dashboard/index.ts +3 -3
  174. package/templates/nextjs-web/hooks/index.ts +4 -4
  175. package/templates/nextjs-web/lib/api-client.ts +89 -89
  176. package/templates/nextjs-web/lib/api.ts +115 -115
  177. package/templates/nextjs-web/lib/axios-global-config.ts +17 -17
  178. package/templates/nextjs-web/lib/utils.ts +6 -6
  179. package/templates/nextjs-web/lib/wexts-client.ts +4 -4
  180. package/templates/nextjs-web/next-env.d.ts +6 -6
  181. package/templates/nextjs-web/next.config.ts +20 -20
  182. package/templates/nextjs-web/package-lock.json +3254 -3254
  183. package/templates/nextjs-web/package.json +37 -37
  184. package/templates/nextjs-web/postcss.config.js +6 -6
  185. package/templates/nextjs-web/tailwind.config.ts +69 -69
  186. package/templates/nextjs-web/tsconfig.json +1 -1
  187. package/templates/nixpacks.toml +11 -11
  188. package/templates/root-package.json +31 -31
  189. package/templates/server.ts +66 -66
  190. package/templates/tsconfig.json +30 -30
  191. package/dist/chunk-2MCBBWEA.js +0 -1
  192. package/dist/chunk-2MCBBWEA.js.map +0 -1
  193. package/dist/chunk-3OM7CHCA.js.map +0 -1
  194. package/dist/chunk-63MTCWU2.mjs +0 -361
  195. package/dist/chunk-63MTCWU2.mjs.map +0 -1
  196. package/dist/chunk-667BQCEM.js +0 -375
  197. package/dist/chunk-667BQCEM.js.map +0 -1
  198. package/dist/chunk-67IJ6H4J.mjs +0 -44
  199. package/dist/chunk-67IJ6H4J.mjs.map +0 -1
  200. package/dist/chunk-6SVQEGEX.mjs +0 -44
  201. package/dist/chunk-6SVQEGEX.mjs.map +0 -1
  202. package/dist/chunk-7NSRDJ5C.mjs +0 -1
  203. package/dist/chunk-ASDXAK6G.js +0 -44
  204. package/dist/chunk-ASDXAK6G.js.map +0 -1
  205. package/dist/chunk-CKZ4VSCB.mjs +0 -18
  206. package/dist/chunk-CKZ4VSCB.mjs.map +0 -1
  207. package/dist/chunk-DW6GOKMF.js +0 -57
  208. package/dist/chunk-DW6GOKMF.js.map +0 -1
  209. package/dist/chunk-EFZPSZWO.mjs +0 -1
  210. package/dist/chunk-EFZPSZWO.mjs.map +0 -1
  211. package/dist/chunk-FCEZDH42.mjs.map +0 -1
  212. package/dist/chunk-FYGXL4V7.js +0 -361
  213. package/dist/chunk-FYGXL4V7.js.map +0 -1
  214. package/dist/chunk-GKVPGKAH.js +0 -66
  215. package/dist/chunk-GKVPGKAH.js.map +0 -1
  216. package/dist/chunk-GWP6PNSP.js +0 -225
  217. package/dist/chunk-GWP6PNSP.js.map +0 -1
  218. package/dist/chunk-HQKTXE7E.mjs +0 -225
  219. package/dist/chunk-HQKTXE7E.mjs.map +0 -1
  220. package/dist/chunk-HSFLZUJN.mjs +0 -57
  221. package/dist/chunk-HSFLZUJN.mjs.map +0 -1
  222. package/dist/chunk-HU63F22V.js +0 -361
  223. package/dist/chunk-HU63F22V.js.map +0 -1
  224. package/dist/chunk-J5LGTIGS.mjs +0 -10
  225. package/dist/chunk-J5LGTIGS.mjs.map +0 -1
  226. package/dist/chunk-JMBD6DOP.js +0 -225
  227. package/dist/chunk-JMBD6DOP.js.map +0 -1
  228. package/dist/chunk-K7EIJSYQ.js +0 -1
  229. package/dist/chunk-K7EIJSYQ.js.map +0 -1
  230. package/dist/chunk-KXYLEUSW.mjs.map +0 -1
  231. package/dist/chunk-MTHKZO55.js +0 -44
  232. package/dist/chunk-MTHKZO55.js.map +0 -1
  233. package/dist/chunk-NNQFLD7O.mjs +0 -361
  234. package/dist/chunk-NNQFLD7O.mjs.map +0 -1
  235. package/dist/chunk-NU2UB242.js +0 -82
  236. package/dist/chunk-NU2UB242.js.map +0 -1
  237. package/dist/chunk-NULGSZFE.mjs +0 -57
  238. package/dist/chunk-NULGSZFE.mjs.map +0 -1
  239. package/dist/chunk-O42L6HOX.js.map +0 -1
  240. package/dist/chunk-ONXNE2A6.mjs +0 -375
  241. package/dist/chunk-ONXNE2A6.mjs.map +0 -1
  242. package/dist/chunk-OTBYRUBE.mjs +0 -225
  243. package/dist/chunk-OTBYRUBE.mjs.map +0 -1
  244. package/dist/chunk-OTSAVKLY.mjs +0 -66
  245. package/dist/chunk-OTSAVKLY.mjs.map +0 -1
  246. package/dist/chunk-PZ5AY32C.js +0 -10
  247. package/dist/chunk-PZ5AY32C.js.map +0 -1
  248. package/dist/chunk-QP2TMRLG.js +0 -57
  249. package/dist/chunk-QP2TMRLG.js.map +0 -1
  250. package/dist/chunk-RS23R3ZQ.mjs +0 -82
  251. package/dist/chunk-RS23R3ZQ.mjs.map +0 -1
  252. package/dist/chunk-STTOPUZ2.mjs.map +0 -1
  253. package/dist/chunk-VMT3LALB.mjs +0 -51
  254. package/dist/chunk-VMT3LALB.mjs.map +0 -1
  255. package/dist/chunk-VNNVLQLJ.mjs.map +0 -1
  256. package/dist/chunk-W3YRVEFQ.js +0 -66
  257. package/dist/chunk-W3YRVEFQ.js.map +0 -1
  258. package/dist/chunk-WF65EDRZ.js.map +0 -1
  259. package/dist/chunk-WMHVXEYQ.mjs +0 -66
  260. package/dist/chunk-WMHVXEYQ.mjs.map +0 -1
  261. package/dist/chunk-XVKTIYHY.js +0 -51
  262. package/dist/chunk-XVKTIYHY.js.map +0 -1
  263. package/dist/codegen-MRZDLCYI.js +0 -13
  264. package/dist/codegen-MRZDLCYI.js.map +0 -1
  265. package/dist/codegen-UI5HTMXE.mjs +0 -13
  266. package/dist/codegen-UI5HTMXE.mjs.map +0 -1
  267. package/dist/dev-server-JKRVBWPY.mjs +0 -13
  268. package/dist/dev-server-JKRVBWPY.mjs.map +0 -1
  269. package/dist/dev-server-TLL7UQMR.js +0 -13
  270. package/dist/dev-server-TLL7UQMR.js.map +0 -1
  271. package/dist/index-BsNaOUtH.d.mts +0 -44
  272. package/dist/index-BsNaOUtH.d.ts +0 -44
  273. package/dist/index-CrbXnXsO.d.ts +0 -62
  274. package/dist/index-kEbGExWM.d.mts +0 -62
  275. package/templates/nestjs-api/.env +0 -4
  276. package/templates/nextjs-web/.env +0 -1
@@ -1,108 +1,108 @@
1
- 'use server';
2
-
3
- import { cookies } from 'next/headers';
4
- import { redirect } from 'next/navigation';
5
- import { api } from '@/lib/api';
6
-
7
- export type ActionState = {
8
- message?: string;
9
- errors?: {
10
- email?: string[];
11
- password?: string[];
12
- };
13
- };
14
-
15
- export async function loginAction(prevState: ActionState, formData: FormData): Promise<ActionState> {
16
- const email = formData.get('email') as string;
17
- const password = formData.get('password') as string;
18
-
19
- const errors: { email?: string[]; password?: string[] } = {};
20
-
21
- if (!email || !email.includes('@')) {
22
- errors.email = ['Invalid email address'];
23
- }
24
-
25
- if (!password || password.length < 6) {
26
- errors.password = ['Password must be at least 6 characters'];
27
- }
28
-
29
- if (Object.keys(errors).length > 0) {
30
- return { errors };
31
- }
32
-
33
- try {
34
- // Use SDK - no URLs needed!
35
- const data = await api.auth.login({ email, password });
36
-
37
- // Store JWT token
38
- if (data.access_token) {
39
- const cookieStore = await cookies();
40
- cookieStore.set('wexts_token', data.access_token, {
41
- httpOnly: true,
42
- secure: process.env.NODE_ENV === 'production',
43
- maxAge: 60 * 60 * 24 * 7, // 1 week
44
- path: '/',
45
- });
46
- } else {
47
- return {
48
- message: 'Login failed: No token received',
49
- };
50
- }
51
- } catch (error: any) {
52
- console.error('Login error:', error);
53
- return {
54
- message: error.message || 'Invalid credentials',
55
- };
56
- }
57
-
58
- redirect('/dashboard');
59
- }
60
-
61
- export async function registerAction(prevState: ActionState, formData: FormData): Promise<ActionState> {
62
- const email = formData.get('email') as string;
63
- const password = formData.get('password') as string;
64
- const name = formData.get('name') as string;
65
-
66
- const errors: { email?: string[]; password?: string[] } = {};
67
-
68
- if (!email || !email.includes('@')) {
69
- errors.email = ['Invalid email address'];
70
- }
71
-
72
- if (!password || password.length < 6) {
73
- errors.password = ['Password must be at least 6 characters'];
74
- }
75
-
76
- if (Object.keys(errors).length > 0) {
77
- return { errors };
78
- }
79
-
80
- try {
81
- // Use SDK - no URLs needed!
82
- const data = await api.auth.register({ email, password, name });
83
-
84
- // Store JWT token
85
- if (data.access_token) {
86
- const cookieStore = await cookies();
87
- cookieStore.set('wexts_token', data.access_token, {
88
- httpOnly: true,
89
- secure: process.env.NODE_ENV === 'production',
90
- maxAge: 60 * 60 * 24 * 7,
91
- path: '/',
92
- });
93
- }
94
- } catch (error: any) {
95
- console.error('Register error:', error);
96
- return {
97
- message: error.message || 'Registration failed',
98
- };
99
- }
100
-
101
- redirect('/dashboard');
102
- }
103
-
104
- export async function logoutAction() {
105
- const cookieStore = await cookies();
106
- cookieStore.delete('wexts_token');
107
- redirect('/login');
108
- }
1
+ 'use server';
2
+
3
+ import { cookies } from 'next/headers';
4
+ import { redirect } from 'next/navigation';
5
+ import { api } from '@/lib/api';
6
+
7
+ export type ActionState = {
8
+ message?: string;
9
+ errors?: {
10
+ email?: string[];
11
+ password?: string[];
12
+ };
13
+ };
14
+
15
+ export async function loginAction(prevState: ActionState, formData: FormData): Promise<ActionState> {
16
+ const email = formData.get('email') as string;
17
+ const password = formData.get('password') as string;
18
+
19
+ const errors: { email?: string[]; password?: string[] } = {};
20
+
21
+ if (!email || !email.includes('@')) {
22
+ errors.email = ['Invalid email address'];
23
+ }
24
+
25
+ if (!password || password.length < 6) {
26
+ errors.password = ['Password must be at least 6 characters'];
27
+ }
28
+
29
+ if (Object.keys(errors).length > 0) {
30
+ return { errors };
31
+ }
32
+
33
+ try {
34
+ // Legacy SDK call retained for deprecated template compatibility.
35
+ const data = await api.auth.login({ email, password });
36
+
37
+ // Store JWT token
38
+ if (data.access_token) {
39
+ const cookieStore = await cookies();
40
+ cookieStore.set('wexts_token', data.access_token, {
41
+ httpOnly: true,
42
+ secure: process.env.NODE_ENV === 'production',
43
+ maxAge: 60 * 60 * 24 * 7, // 1 week
44
+ path: '/',
45
+ });
46
+ } else {
47
+ return {
48
+ message: 'Login failed: No token received',
49
+ };
50
+ }
51
+ } catch (error: any) {
52
+ console.error('Login error:', error);
53
+ return {
54
+ message: error.message || 'Invalid credentials',
55
+ };
56
+ }
57
+
58
+ redirect('/dashboard');
59
+ }
60
+
61
+ export async function registerAction(prevState: ActionState, formData: FormData): Promise<ActionState> {
62
+ const email = formData.get('email') as string;
63
+ const password = formData.get('password') as string;
64
+ const name = formData.get('name') as string;
65
+
66
+ const errors: { email?: string[]; password?: string[] } = {};
67
+
68
+ if (!email || !email.includes('@')) {
69
+ errors.email = ['Invalid email address'];
70
+ }
71
+
72
+ if (!password || password.length < 6) {
73
+ errors.password = ['Password must be at least 6 characters'];
74
+ }
75
+
76
+ if (Object.keys(errors).length > 0) {
77
+ return { errors };
78
+ }
79
+
80
+ try {
81
+ // Legacy SDK call retained for deprecated template compatibility.
82
+ const data = await api.auth.register({ email, password, name });
83
+
84
+ // Store JWT token
85
+ if (data.access_token) {
86
+ const cookieStore = await cookies();
87
+ cookieStore.set('wexts_token', data.access_token, {
88
+ httpOnly: true,
89
+ secure: process.env.NODE_ENV === 'production',
90
+ maxAge: 60 * 60 * 24 * 7,
91
+ path: '/',
92
+ });
93
+ }
94
+ } catch (error: any) {
95
+ console.error('Register error:', error);
96
+ return {
97
+ message: error.message || 'Registration failed',
98
+ };
99
+ }
100
+
101
+ redirect('/dashboard');
102
+ }
103
+
104
+ export async function logoutAction() {
105
+ const cookieStore = await cookies();
106
+ cookieStore.delete('wexts_token');
107
+ redirect('/login');
108
+ }
@@ -1,39 +1,39 @@
1
- 'use client';
2
-
3
- import { useEffect } from 'react';
4
- import { Button } from '@/components/ui/button';
5
- import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
6
- import { AlertTriangle } from 'lucide-react';
7
-
8
- export default function DashboardError({
9
- error,
10
- reset,
11
- }: {
12
- error: Error & { digest?: string };
13
- reset: () => void;
14
- }) {
15
- useEffect(() => {
16
- console.error(error);
17
- }, [error]);
18
-
19
- return (
20
- <div className="min-h-screen bg-background flex items-center justify-center p-8">
21
- <Card className="glass border-destructive/20 max-w-md w-full">
22
- <CardHeader>
23
- <CardTitle className="text-destructive flex items-center gap-2">
24
- <AlertTriangle className="w-5 h-5" />
25
- Something went wrong
26
- </CardTitle>
27
- </CardHeader>
28
- <CardContent className="space-y-4">
29
- <p className="text-muted-foreground">
30
- We encountered an error while loading your dashboard. Please try again.
31
- </p>
32
- <Button onClick={reset} className="w-full">
33
- Try again
34
- </Button>
35
- </CardContent>
36
- </Card>
37
- </div>
38
- );
39
- }
1
+ 'use client';
2
+
3
+ import { useEffect } from 'react';
4
+ import { Button } from '@/components/ui/button';
5
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
6
+ import { AlertTriangle } from 'lucide-react';
7
+
8
+ export default function DashboardError({
9
+ error,
10
+ reset,
11
+ }: {
12
+ error: Error & { digest?: string };
13
+ reset: () => void;
14
+ }) {
15
+ useEffect(() => {
16
+ console.error(error);
17
+ }, [error]);
18
+
19
+ return (
20
+ <div className="min-h-screen bg-background flex items-center justify-center p-8">
21
+ <Card className="glass border-destructive/20 max-w-md w-full">
22
+ <CardHeader>
23
+ <CardTitle className="text-destructive flex items-center gap-2">
24
+ <AlertTriangle className="w-5 h-5" />
25
+ Something went wrong
26
+ </CardTitle>
27
+ </CardHeader>
28
+ <CardContent className="space-y-4">
29
+ <p className="text-muted-foreground">
30
+ We encountered an error while loading your dashboard. Please try again.
31
+ </p>
32
+ <Button onClick={reset} className="w-full">
33
+ Try again
34
+ </Button>
35
+ </CardContent>
36
+ </Card>
37
+ </div>
38
+ );
39
+ }
@@ -1,14 +1,14 @@
1
- import { Loader2 } from 'lucide-react';
2
-
3
- export default function DashboardLoading() {
4
- return (
5
- <div className="min-h-screen bg-background flex items-center justify-center">
6
- <div className="text-center space-y-4">
7
- <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/10 text-primary animate-pulse">
8
- <Loader2 className="w-8 h-8 animate-spin" />
9
- </div>
10
- <p className="text-muted-foreground animate-pulse">Loading dashboard...</p>
11
- </div>
12
- </div>
13
- );
14
- }
1
+ import { Loader2 } from 'lucide-react';
2
+
3
+ export default function DashboardLoading() {
4
+ return (
5
+ <div className="min-h-screen bg-background flex items-center justify-center">
6
+ <div className="text-center space-y-4">
7
+ <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/10 text-primary animate-pulse">
8
+ <Loader2 className="w-8 h-8 animate-spin" />
9
+ </div>
10
+ <p className="text-muted-foreground animate-pulse">Loading dashboard...</p>
11
+ </div>
12
+ </div>
13
+ );
14
+ }
@@ -1,5 +1,5 @@
1
- import { DashboardView } from '@/features/dashboard';
2
-
3
- export default function DashboardPage() {
4
- return <DashboardView />;
5
- }
1
+ import { DashboardView } from '@/features/dashboard';
2
+
3
+ export default function DashboardPage() {
4
+ return <DashboardView />;
5
+ }
@@ -1,93 +1,93 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- @layer base {
6
- :root {
7
- /* Brand Colors - Deep Violet & Electric Purple */
8
- --background: 260 30% 98%;
9
- --foreground: 260 40% 10%;
10
-
11
- --primary: 265 89% 66%;
12
- --primary-foreground: 210 40% 98%;
13
-
14
- --secondary: 260 20% 90%;
15
- --secondary-foreground: 260 40% 10%;
16
-
17
- --muted: 260 20% 96%;
18
- --muted-foreground: 260 20% 40%;
19
-
20
- --accent: 265 89% 96%;
21
- --accent-foreground: 265 89% 66%;
22
-
23
- --destructive: 0 84% 60%;
24
- --destructive-foreground: 210 40% 98%;
25
-
26
- --border: 260 20% 90%;
27
- --input: 260 20% 90%;
28
- --ring: 265 89% 66%;
29
-
30
- --radius: 1rem;
31
- }
32
-
33
- .dark {
34
- --background: 260 40% 5%;
35
- --foreground: 210 40% 98%;
36
-
37
- --primary: 265 89% 66%;
38
- --primary-foreground: 210 40% 98%;
39
-
40
- --secondary: 260 30% 15%;
41
- --secondary-foreground: 210 40% 98%;
42
-
43
- --muted: 260 30% 15%;
44
- --muted-foreground: 215 20% 65%;
45
-
46
- --accent: 260 30% 15%;
47
- --accent-foreground: 210 40% 98%;
48
-
49
- --destructive: 0 62% 30%;
50
- --destructive-foreground: 210 40% 98%;
51
-
52
- --border: 260 30% 15%;
53
- --input: 260 30% 15%;
54
- --ring: 265 89% 66%;
55
- }
56
- }
57
-
58
- @layer base {
59
- * {
60
- @apply border-border;
61
- }
62
- body {
63
- @apply bg-background text-foreground antialiased;
64
- font-feature-settings: "rlig" 1, "calt" 1;
65
- }
66
- }
67
-
68
- @layer utilities {
69
- .glass {
70
- @apply bg-white/10 backdrop-blur-lg border border-white/20 shadow-xl;
71
- }
72
- .glass-dark {
73
- @apply bg-black/30 backdrop-blur-lg border border-white/10 shadow-xl;
74
- }
75
-
76
- .text-gradient {
77
- @apply bg-clip-text text-transparent bg-gradient-to-r from-violet-600 to-indigo-600 dark:from-violet-400 dark:to-indigo-400;
78
- }
79
-
80
- .animate-float {
81
- animation: float 6s ease-in-out infinite;
82
- }
83
-
84
- .animate-pulse-slow {
85
- animation: pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
86
- }
87
- }
88
-
89
- @keyframes float {
90
- 0% { transform: translateY(0px); }
91
- 50% { transform: translateY(-20px); }
92
- 100% { transform: translateY(0px); }
93
- }
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ /* Brand Colors - Deep Violet & Electric Purple */
8
+ --background: 260 30% 98%;
9
+ --foreground: 260 40% 10%;
10
+
11
+ --primary: 265 89% 66%;
12
+ --primary-foreground: 210 40% 98%;
13
+
14
+ --secondary: 260 20% 90%;
15
+ --secondary-foreground: 260 40% 10%;
16
+
17
+ --muted: 260 20% 96%;
18
+ --muted-foreground: 260 20% 40%;
19
+
20
+ --accent: 265 89% 96%;
21
+ --accent-foreground: 265 89% 66%;
22
+
23
+ --destructive: 0 84% 60%;
24
+ --destructive-foreground: 210 40% 98%;
25
+
26
+ --border: 260 20% 90%;
27
+ --input: 260 20% 90%;
28
+ --ring: 265 89% 66%;
29
+
30
+ --radius: 1rem;
31
+ }
32
+
33
+ .dark {
34
+ --background: 260 40% 5%;
35
+ --foreground: 210 40% 98%;
36
+
37
+ --primary: 265 89% 66%;
38
+ --primary-foreground: 210 40% 98%;
39
+
40
+ --secondary: 260 30% 15%;
41
+ --secondary-foreground: 210 40% 98%;
42
+
43
+ --muted: 260 30% 15%;
44
+ --muted-foreground: 215 20% 65%;
45
+
46
+ --accent: 260 30% 15%;
47
+ --accent-foreground: 210 40% 98%;
48
+
49
+ --destructive: 0 62% 30%;
50
+ --destructive-foreground: 210 40% 98%;
51
+
52
+ --border: 260 30% 15%;
53
+ --input: 260 30% 15%;
54
+ --ring: 265 89% 66%;
55
+ }
56
+ }
57
+
58
+ @layer base {
59
+ * {
60
+ @apply border-border;
61
+ }
62
+ body {
63
+ @apply bg-background text-foreground antialiased;
64
+ font-feature-settings: "rlig" 1, "calt" 1;
65
+ }
66
+ }
67
+
68
+ @layer utilities {
69
+ .glass {
70
+ @apply bg-white/10 backdrop-blur-lg border border-white/20 shadow-xl;
71
+ }
72
+ .glass-dark {
73
+ @apply bg-black/30 backdrop-blur-lg border border-white/10 shadow-xl;
74
+ }
75
+
76
+ .text-gradient {
77
+ @apply bg-clip-text text-transparent bg-gradient-to-r from-violet-600 to-indigo-600 dark:from-violet-400 dark:to-indigo-400;
78
+ }
79
+
80
+ .animate-float {
81
+ animation: float 6s ease-in-out infinite;
82
+ }
83
+
84
+ .animate-pulse-slow {
85
+ animation: pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
86
+ }
87
+ }
88
+
89
+ @keyframes float {
90
+ 0% { transform: translateY(0px); }
91
+ 50% { transform: translateY(-20px); }
92
+ 100% { transform: translateY(0px); }
93
+ }
@@ -1,29 +1,29 @@
1
- import type { Metadata } from 'next';
2
- import { Inter } from 'next/font/google';
3
- import { WextsProvider } from '@/lib/wexts-client';
4
- import { Toaster } from 'react-hot-toast';
5
- import './globals.css';
6
-
7
- const inter = Inter({ subsets: ['latin'] });
8
-
9
- export const metadata: Metadata = {
10
- title: 'wexts Web App',
11
- description: 'Modern web application built with wexts',
12
- };
13
-
14
- export default function RootLayout({
15
- children,
16
- }: {
17
- children: React.ReactNode;
18
- }) {
19
- return (
20
- <html lang="en">
21
- <body className={inter.className}>
22
- <WextsProvider baseUrl={process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5050'}>
23
- {children}
24
- <Toaster position="top-center" />
25
- </WextsProvider>
26
- </body>
27
- </html>
28
- );
29
- }
1
+ import type { Metadata } from 'next';
2
+ import { Inter } from 'next/font/google';
3
+ import { WextsProvider } from '@/lib/wexts-client';
4
+ import { Toaster } from 'react-hot-toast';
5
+ import './globals.css';
6
+
7
+ const inter = Inter({ subsets: ['latin'] });
8
+
9
+ export const metadata: Metadata = {
10
+ title: 'wexts Web App',
11
+ description: 'Modern web application built with wexts',
12
+ };
13
+
14
+ export default function RootLayout({
15
+ children,
16
+ }: {
17
+ children: React.ReactNode;
18
+ }) {
19
+ return (
20
+ <html lang="en">
21
+ <body className={inter.className}>
22
+ <WextsProvider baseUrl={process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5050'}>
23
+ {children}
24
+ <Toaster position="top-center" />
25
+ </WextsProvider>
26
+ </body>
27
+ </html>
28
+ );
29
+ }
@@ -1,5 +1,5 @@
1
- import { LoginForm } from '@/features/auth';
2
-
3
- export default function LoginPage() {
4
- return <LoginForm />;
5
- }
1
+ import { LoginForm } from '@/features/auth';
2
+
3
+ export default function LoginPage() {
4
+ return <LoginForm />;
5
+ }
@@ -1,28 +1,28 @@
1
- 'use client';
2
-
3
- import { useAuth } from '@/lib/wexts-client';
4
- import { useRouter } from 'next/navigation';
5
- import { useEffect } from 'react';
6
-
7
- export default function Home() {
8
- const { isAuthenticated, user, loading } = useAuth();
9
- const router = useRouter();
10
-
11
- useEffect(() => {
12
- if (!loading && !isAuthenticated) {
13
- router.push('/login');
14
- } else if (!loading && isAuthenticated) {
15
- router.push('/dashboard');
16
- }
17
- }, [isAuthenticated, loading, router]);
18
-
19
- if (loading) {
20
- return (
21
- <div className="min-h-screen flex items-center justify-center">
22
- <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-violet-600"></div>
23
- </div>
24
- );
25
- }
26
-
27
- return null;
28
- }
1
+ 'use client';
2
+
3
+ import { useAuth } from '@/lib/wexts-client';
4
+ import { useRouter } from 'next/navigation';
5
+ import { useEffect } from 'react';
6
+
7
+ export default function Home() {
8
+ const { isAuthenticated, user, loading } = useAuth();
9
+ const router = useRouter();
10
+
11
+ useEffect(() => {
12
+ if (!loading && !isAuthenticated) {
13
+ router.push('/login');
14
+ } else if (!loading && isAuthenticated) {
15
+ router.push('/dashboard');
16
+ }
17
+ }, [isAuthenticated, loading, router]);
18
+
19
+ if (loading) {
20
+ return (
21
+ <div className="min-h-screen flex items-center justify-center">
22
+ <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-violet-600"></div>
23
+ </div>
24
+ );
25
+ }
26
+
27
+ return null;
28
+ }
@@ -1,5 +1,5 @@
1
- import { RegisterForm } from '@/features/auth';
2
-
3
- export default function RegisterPage() {
4
- return <RegisterForm />;
5
- }
1
+ import { RegisterForm } from '@/features/auth';
2
+
3
+ export default function RegisterPage() {
4
+ return <RegisterForm />;
5
+ }