wexts 3.0.2 → 4.1.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 (288) 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-342VRT25.mjs +504 -0
  8. package/dist/chunk-342VRT25.mjs.map +1 -0
  9. package/dist/chunk-7HNQWJWV.js +504 -0
  10. package/dist/chunk-7HNQWJWV.js.map +1 -0
  11. package/dist/chunk-7QKLIVRF.js +94 -0
  12. package/dist/chunk-7QKLIVRF.js.map +1 -0
  13. package/dist/chunk-7SSCNCTW.mjs +137 -0
  14. package/dist/chunk-7SSCNCTW.mjs.map +1 -0
  15. package/dist/chunk-7TLSPR65.mjs +95 -0
  16. package/dist/chunk-7TLSPR65.mjs.map +1 -0
  17. package/dist/{chunk-FCEZDH42.mjs → chunk-7WULUGLH.mjs} +5 -3
  18. package/dist/chunk-7WULUGLH.mjs.map +1 -0
  19. package/dist/chunk-AVMQJWYD.js +95 -0
  20. package/dist/chunk-AVMQJWYD.js.map +1 -0
  21. package/dist/{chunk-WF65EDRZ.js → chunk-BG56B4DE.js} +20 -2
  22. package/dist/chunk-BG56B4DE.js.map +1 -0
  23. package/dist/chunk-CLM5PNSG.mjs +496 -0
  24. package/dist/chunk-CLM5PNSG.mjs.map +1 -0
  25. package/dist/chunk-DNLGCKTT.js +31 -0
  26. package/dist/chunk-DNLGCKTT.js.map +1 -0
  27. package/dist/{chunk-VNNVLQLJ.mjs → chunk-JHOVXH3X.mjs} +2 -2
  28. package/dist/chunk-JHOVXH3X.mjs.map +1 -0
  29. package/dist/chunk-MXINIFPC.js +105 -0
  30. package/dist/chunk-MXINIFPC.js.map +1 -0
  31. package/dist/chunk-O4II6N34.js +137 -0
  32. package/dist/chunk-O4II6N34.js.map +1 -0
  33. package/dist/chunk-SE32ZPOZ.js +496 -0
  34. package/dist/chunk-SE32ZPOZ.js.map +1 -0
  35. package/dist/{chunk-STTOPUZ2.mjs → chunk-UAL54DVV.mjs} +21 -3
  36. package/dist/chunk-UAL54DVV.mjs.map +1 -0
  37. package/dist/{chunk-3OM7CHCA.js → chunk-WCKSKU3C.js} +1 -1
  38. package/dist/chunk-WCKSKU3C.js.map +1 -0
  39. package/dist/chunk-WU6FW77M.mjs +105 -0
  40. package/dist/chunk-WU6FW77M.mjs.map +1 -0
  41. package/dist/chunk-XE4OXN2W.js +0 -0
  42. package/dist/chunk-XE4OXN2W.js.map +1 -1
  43. package/dist/chunk-YBM3IJEA.mjs +94 -0
  44. package/dist/chunk-YBM3IJEA.mjs.map +1 -0
  45. package/dist/{chunk-KXYLEUSW.mjs → chunk-YN6WIWNQ.mjs} +69 -83
  46. package/dist/chunk-YN6WIWNQ.mjs.map +1 -0
  47. package/dist/chunk-YSLEF5C5.mjs +0 -0
  48. package/dist/chunk-YSLEF5C5.mjs.map +0 -0
  49. package/dist/chunk-ZX7QIN24.mjs +31 -0
  50. package/dist/chunk-ZX7QIN24.mjs.map +1 -0
  51. package/dist/cli/index.d.mts +22 -0
  52. package/dist/cli/index.d.ts +22 -0
  53. package/dist/cli/index.js +676 -292
  54. package/dist/cli/index.js.map +1 -1
  55. package/dist/cli/index.mjs +678 -293
  56. package/dist/cli/index.mjs.map +1 -1
  57. package/dist/client/index.d.mts +10 -1
  58. package/dist/client/index.d.ts +10 -1
  59. package/dist/client/index.js +5 -2
  60. package/dist/client/index.js.map +1 -1
  61. package/dist/client/index.mjs +7 -4
  62. package/dist/client/index.mjs.map +0 -0
  63. package/dist/codegen/index.d.mts +2 -1
  64. package/dist/codegen/index.d.ts +2 -1
  65. package/dist/codegen/index.js +6 -3
  66. package/dist/codegen/index.js.map +1 -1
  67. package/dist/codegen/index.mjs +8 -5
  68. package/dist/codegen/index.mjs.map +0 -0
  69. package/dist/decorators-BT1FFqN0.d.mts +29 -0
  70. package/dist/decorators-DvS58PqC.d.ts +29 -0
  71. package/dist/dev-server/index.d.mts +1 -1
  72. package/dist/dev-server/index.d.ts +1 -1
  73. package/dist/dev-server/index.js +3 -3
  74. package/dist/dev-server/index.js.map +1 -1
  75. package/dist/dev-server/index.mjs +3 -3
  76. package/dist/dev-server/index.mjs.map +0 -0
  77. package/dist/{index-SjUaHgFr.d.ts → index-7QeQEf37.d.ts} +27 -10
  78. package/dist/{index-tFGPFVfQ.d.mts → index-7RvU-jGE.d.mts} +0 -1
  79. package/dist/{index-tFGPFVfQ.d.ts → index-7RvU-jGE.d.ts} +0 -1
  80. package/dist/{index-SjUaHgFr.d.mts → index-8nzxy0NN.d.mts} +27 -10
  81. package/dist/index-Co5ZsLqq.d.ts +58 -0
  82. package/dist/index-D94W1__r.d.mts +58 -0
  83. package/dist/index-DQmyVp6F.d.mts +27 -0
  84. package/dist/index-KL_1BrQb.d.ts +27 -0
  85. package/dist/index.d.mts +54 -7
  86. package/dist/index.d.ts +54 -7
  87. package/dist/index.js +70 -29
  88. package/dist/index.js.map +1 -1
  89. package/dist/index.mjs +62 -21
  90. package/dist/index.mjs.map +1 -1
  91. package/dist/nest/index.d.mts +3 -1
  92. package/dist/nest/index.d.ts +3 -1
  93. package/dist/nest/index.js +20 -2
  94. package/dist/nest/index.js.map +1 -1
  95. package/dist/nest/index.mjs +21 -3
  96. package/dist/nest/index.mjs.map +0 -0
  97. package/dist/next/index.d.mts +7 -2
  98. package/dist/next/index.d.ts +7 -2
  99. package/dist/next/index.js +135 -5
  100. package/dist/next/index.js.map +1 -1
  101. package/dist/next/index.mjs +133 -4
  102. package/dist/next/index.mjs.map +1 -1
  103. package/dist/rpc/index.d.mts +2 -0
  104. package/dist/rpc/index.d.ts +2 -0
  105. package/dist/rpc/index.js +23 -0
  106. package/dist/rpc/index.js.map +1 -0
  107. package/dist/rpc/index.mjs +23 -0
  108. package/dist/{chunk-7NSRDJ5C.mjs.map → rpc/index.mjs.map} +0 -0
  109. package/dist/runtime/index.d.mts +55 -0
  110. package/dist/runtime/index.d.ts +55 -0
  111. package/dist/runtime/index.js +221 -0
  112. package/dist/runtime/index.js.map +1 -0
  113. package/dist/runtime/index.mjs +221 -0
  114. package/dist/runtime/index.mjs.map +1 -0
  115. package/dist/types/index.d.mts +0 -0
  116. package/dist/types/index.d.ts +0 -0
  117. package/dist/types/index.js +0 -0
  118. package/dist/types/index.js.map +1 -1
  119. package/dist/types/index.mjs +1 -1
  120. package/dist/types/index.mjs.map +0 -0
  121. package/dist/types-7d_fC-C3.d.mts +32 -0
  122. package/dist/types-7d_fC-C3.d.ts +32 -0
  123. package/dist/vercel-builder/index.d.mts +58 -0
  124. package/dist/vercel-builder/index.d.ts +58 -0
  125. package/dist/vercel-builder/index.js +330 -0
  126. package/dist/vercel-builder/index.js.map +1 -0
  127. package/dist/vercel-builder/index.mjs +330 -0
  128. package/dist/vercel-builder/index.mjs.map +1 -0
  129. package/package.json +37 -16
  130. package/templates/.dockerignore +43 -43
  131. package/templates/.env.example +0 -0
  132. package/templates/Dockerfile +60 -60
  133. package/templates/Procfile +1 -1
  134. package/templates/README.md +67 -58
  135. package/templates/api-sdk.ts +115 -115
  136. package/templates/docker-compose.yml +34 -34
  137. package/templates/nestjs-api/.env.example +0 -0
  138. package/templates/nestjs-api/README.md +87 -79
  139. package/templates/nestjs-api/nest-cli.json +6 -6
  140. package/templates/nestjs-api/package.json +40 -40
  141. package/templates/nestjs-api/prisma/dev.db +0 -0
  142. package/templates/nestjs-api/prisma/migrations/20251123205437_init/migration.sql +0 -0
  143. package/templates/nestjs-api/prisma/migrations/migration_lock.toml +0 -0
  144. package/templates/nestjs-api/prisma/schema.prisma +29 -29
  145. package/templates/nestjs-api/src/app.module.ts +17 -17
  146. package/templates/nestjs-api/src/auth/auth.controller.ts +27 -27
  147. package/templates/nestjs-api/src/auth/auth.module.ts +37 -29
  148. package/templates/nestjs-api/src/auth/auth.service.ts +86 -86
  149. package/templates/nestjs-api/src/auth/dto/auth.dto.ts +22 -22
  150. package/templates/nestjs-api/src/auth/guards/jwt-auth.guard.ts +5 -5
  151. package/templates/nestjs-api/src/auth/strategies/jwt.strategy.ts +27 -19
  152. package/templates/nestjs-api/src/main.ts +32 -32
  153. package/templates/nestjs-api/src/prisma/prisma.module.ts +9 -9
  154. package/templates/nestjs-api/src/prisma/prisma.service.ts +14 -14
  155. package/templates/nestjs-api/src/todos/dto/todo.dto.ts +24 -24
  156. package/templates/nestjs-api/src/todos/todos.controller.ts +39 -39
  157. package/templates/nestjs-api/src/todos/todos.module.ts +11 -11
  158. package/templates/nestjs-api/src/todos/todos.service.ts +53 -53
  159. package/templates/nestjs-api/src/users/users.controller.ts +14 -14
  160. package/templates/nestjs-api/src/users/users.module.ts +12 -12
  161. package/templates/nestjs-api/src/users/users.service.ts +19 -19
  162. package/templates/nestjs-api/tsconfig.json +39 -39
  163. package/templates/nextjs-web/README.md +76 -68
  164. package/templates/nextjs-web/app/actions/auth.ts +108 -108
  165. package/templates/nextjs-web/app/dashboard/error.tsx +39 -39
  166. package/templates/nextjs-web/app/dashboard/loading.tsx +14 -14
  167. package/templates/nextjs-web/app/dashboard/page.tsx +5 -5
  168. package/templates/nextjs-web/app/globals.css +93 -93
  169. package/templates/nextjs-web/app/layout.tsx +29 -29
  170. package/templates/nextjs-web/app/login/page.tsx +5 -5
  171. package/templates/nextjs-web/app/page.tsx +28 -28
  172. package/templates/nextjs-web/app/register/page.tsx +5 -5
  173. package/templates/nextjs-web/components/ui/button.tsx +56 -56
  174. package/templates/nextjs-web/components/ui/card.tsx +79 -79
  175. package/templates/nextjs-web/components/ui/input.tsx +25 -25
  176. package/templates/nextjs-web/components/ui/label.tsx +24 -24
  177. package/templates/nextjs-web/features/auth/LoginForm.tsx +140 -140
  178. package/templates/nextjs-web/features/auth/RegisterForm.tsx +159 -159
  179. package/templates/nextjs-web/features/auth/api.ts +35 -35
  180. package/templates/nextjs-web/features/auth/index.ts +3 -3
  181. package/templates/nextjs-web/features/dashboard/DashboardView.tsx +204 -204
  182. package/templates/nextjs-web/features/dashboard/api.ts +9 -9
  183. package/templates/nextjs-web/features/dashboard/components.tsx +74 -74
  184. package/templates/nextjs-web/features/dashboard/index.ts +3 -3
  185. package/templates/nextjs-web/hooks/index.ts +4 -4
  186. package/templates/nextjs-web/lib/api-client.ts +89 -89
  187. package/templates/nextjs-web/lib/api.ts +115 -115
  188. package/templates/nextjs-web/lib/axios-global-config.ts +17 -17
  189. package/templates/nextjs-web/lib/utils.ts +6 -6
  190. package/templates/nextjs-web/lib/wexts-client.ts +4 -4
  191. package/templates/nextjs-web/next-env.d.ts +6 -6
  192. package/templates/nextjs-web/next.config.ts +20 -20
  193. package/templates/nextjs-web/package.json +37 -37
  194. package/templates/nextjs-web/postcss.config.js +6 -6
  195. package/templates/nextjs-web/tailwind.config.ts +69 -69
  196. package/templates/nextjs-web/tsconfig.json +1 -1
  197. package/templates/nixpacks.toml +11 -11
  198. package/templates/root-package.json +31 -31
  199. package/templates/server.ts +66 -66
  200. package/templates/tsconfig.json +30 -30
  201. package/dist/chunk-2MCBBWEA.js +0 -1
  202. package/dist/chunk-2MCBBWEA.js.map +0 -1
  203. package/dist/chunk-3OM7CHCA.js.map +0 -1
  204. package/dist/chunk-63MTCWU2.mjs +0 -361
  205. package/dist/chunk-63MTCWU2.mjs.map +0 -1
  206. package/dist/chunk-667BQCEM.js +0 -375
  207. package/dist/chunk-667BQCEM.js.map +0 -1
  208. package/dist/chunk-67IJ6H4J.mjs +0 -44
  209. package/dist/chunk-67IJ6H4J.mjs.map +0 -1
  210. package/dist/chunk-6SVQEGEX.mjs +0 -44
  211. package/dist/chunk-6SVQEGEX.mjs.map +0 -1
  212. package/dist/chunk-7NSRDJ5C.mjs +0 -1
  213. package/dist/chunk-ASDXAK6G.js +0 -44
  214. package/dist/chunk-ASDXAK6G.js.map +0 -1
  215. package/dist/chunk-CKZ4VSCB.mjs +0 -18
  216. package/dist/chunk-CKZ4VSCB.mjs.map +0 -1
  217. package/dist/chunk-DW6GOKMF.js +0 -57
  218. package/dist/chunk-DW6GOKMF.js.map +0 -1
  219. package/dist/chunk-EFZPSZWO.mjs +0 -1
  220. package/dist/chunk-EFZPSZWO.mjs.map +0 -1
  221. package/dist/chunk-FCEZDH42.mjs.map +0 -1
  222. package/dist/chunk-FYGXL4V7.js +0 -361
  223. package/dist/chunk-FYGXL4V7.js.map +0 -1
  224. package/dist/chunk-GKVPGKAH.js +0 -66
  225. package/dist/chunk-GKVPGKAH.js.map +0 -1
  226. package/dist/chunk-GWP6PNSP.js +0 -225
  227. package/dist/chunk-GWP6PNSP.js.map +0 -1
  228. package/dist/chunk-HQKTXE7E.mjs +0 -225
  229. package/dist/chunk-HQKTXE7E.mjs.map +0 -1
  230. package/dist/chunk-HSFLZUJN.mjs +0 -57
  231. package/dist/chunk-HSFLZUJN.mjs.map +0 -1
  232. package/dist/chunk-HU63F22V.js +0 -361
  233. package/dist/chunk-HU63F22V.js.map +0 -1
  234. package/dist/chunk-J5LGTIGS.mjs +0 -10
  235. package/dist/chunk-J5LGTIGS.mjs.map +0 -1
  236. package/dist/chunk-JMBD6DOP.js +0 -225
  237. package/dist/chunk-JMBD6DOP.js.map +0 -1
  238. package/dist/chunk-K7EIJSYQ.js +0 -1
  239. package/dist/chunk-K7EIJSYQ.js.map +0 -1
  240. package/dist/chunk-KXYLEUSW.mjs.map +0 -1
  241. package/dist/chunk-MTHKZO55.js +0 -44
  242. package/dist/chunk-MTHKZO55.js.map +0 -1
  243. package/dist/chunk-NNQFLD7O.mjs +0 -361
  244. package/dist/chunk-NNQFLD7O.mjs.map +0 -1
  245. package/dist/chunk-NU2UB242.js +0 -82
  246. package/dist/chunk-NU2UB242.js.map +0 -1
  247. package/dist/chunk-NULGSZFE.mjs +0 -57
  248. package/dist/chunk-NULGSZFE.mjs.map +0 -1
  249. package/dist/chunk-O42L6HOX.js.map +0 -1
  250. package/dist/chunk-ONXNE2A6.mjs +0 -375
  251. package/dist/chunk-ONXNE2A6.mjs.map +0 -1
  252. package/dist/chunk-OTBYRUBE.mjs +0 -225
  253. package/dist/chunk-OTBYRUBE.mjs.map +0 -1
  254. package/dist/chunk-OTSAVKLY.mjs +0 -66
  255. package/dist/chunk-OTSAVKLY.mjs.map +0 -1
  256. package/dist/chunk-PZ5AY32C.js +0 -10
  257. package/dist/chunk-PZ5AY32C.js.map +0 -1
  258. package/dist/chunk-QP2TMRLG.js +0 -57
  259. package/dist/chunk-QP2TMRLG.js.map +0 -1
  260. package/dist/chunk-RS23R3ZQ.mjs +0 -82
  261. package/dist/chunk-RS23R3ZQ.mjs.map +0 -1
  262. package/dist/chunk-STTOPUZ2.mjs.map +0 -1
  263. package/dist/chunk-VMT3LALB.mjs +0 -51
  264. package/dist/chunk-VMT3LALB.mjs.map +0 -1
  265. package/dist/chunk-VNNVLQLJ.mjs.map +0 -1
  266. package/dist/chunk-W3YRVEFQ.js +0 -66
  267. package/dist/chunk-W3YRVEFQ.js.map +0 -1
  268. package/dist/chunk-WF65EDRZ.js.map +0 -1
  269. package/dist/chunk-WMHVXEYQ.mjs +0 -66
  270. package/dist/chunk-WMHVXEYQ.mjs.map +0 -1
  271. package/dist/chunk-XVKTIYHY.js +0 -51
  272. package/dist/chunk-XVKTIYHY.js.map +0 -1
  273. package/dist/codegen-MRZDLCYI.js +0 -13
  274. package/dist/codegen-MRZDLCYI.js.map +0 -1
  275. package/dist/codegen-UI5HTMXE.mjs +0 -13
  276. package/dist/codegen-UI5HTMXE.mjs.map +0 -1
  277. package/dist/dev-server-JKRVBWPY.mjs +0 -13
  278. package/dist/dev-server-JKRVBWPY.mjs.map +0 -1
  279. package/dist/dev-server-TLL7UQMR.js +0 -13
  280. package/dist/dev-server-TLL7UQMR.js.map +0 -1
  281. package/dist/index-BsNaOUtH.d.mts +0 -44
  282. package/dist/index-BsNaOUtH.d.ts +0 -44
  283. package/dist/index-CrbXnXsO.d.ts +0 -62
  284. package/dist/index-kEbGExWM.d.mts +0 -62
  285. package/templates/nestjs-api/.env +0 -4
  286. package/templates/nestjs-api/package-lock.json +0 -5623
  287. package/templates/nextjs-web/.env +0 -1
  288. package/templates/nextjs-web/package-lock.json +0 -3254
@@ -1,68 +1,76 @@
1
- # Fusion Next.js Web
2
-
3
- Modern Next.js 16 frontend with wexts integration.
4
-
5
- ## Features
6
-
7
- - ✅ Next.js 16 (App Router)
8
- - ✅ React 19
9
- - Tailwind CSS v4
10
- - ✅ TypeScript
11
- - wexts Provider & Hooks
12
- - ✅ Authentication Flow
13
- - ✅ Todo Management Dashboard
14
-
15
- ## Setup
16
-
17
- ```bash
18
- # Install dependencies
19
- npm install
20
-
21
- # Copy environment variables
22
- cp .env.local.example .env.local
23
-
24
- # Update NEXT_PUBLIC_API_URL in .env.local to point to your API
25
-
26
- # Start development server
27
- npm run dev
28
- ```
29
-
30
- ## Project Structure
31
-
32
- ```
33
- app/
34
- ├── layout.tsx # Root layout with FusionProvider
35
- ├── page.tsx # Homepage with auth redirect
36
- ├── globals.css # Global styles
37
- ├── login/
38
- │ └── page.tsx # Login page
39
- ├── register/
40
- │ └── page.tsx # Registration page
41
- └── dashboard/
42
- └── page.tsx # Protected dashboard with todos
43
- ```
44
-
45
- ## Using Fusion Hooks
46
-
47
- ```tsx
48
- import { useFusion, useAuth } from 'wexts/next';
49
-
50
- function MyComponent() {
51
- const { client } = useFusion();
52
- const { user, isAuthenticated } = useAuth();
53
-
54
- // Make API calls
55
- const data = await client.get('/endpoint');
56
- }
57
- ```
58
-
59
- ## Building for Production
60
-
61
- ```bash
62
- npm run build
63
- npm start
64
- ```
65
-
66
- ## Environment Variables
67
-
68
- - `NEXT_PUBLIC_API_URL` - Backend API URL (default: http://localhost:5050)
1
+ # Deprecated Legacy Web Template
2
+
3
+ This template predates the verified `examples/hello-rpc` runtime/RPC/security model. It is retained for compatibility and should not be used as the production reference.
4
+
5
+ Use `examples/hello-rpc` for the canonical generated-RPC path.
6
+
7
+ ---
8
+
9
+ # Fusion Next.js Web
10
+
11
+ Modern Next.js 16 frontend with wexts integration.
12
+
13
+ ## Features
14
+
15
+ - ✅ Next.js 16 (App Router)
16
+ - ✅ React 19
17
+ - ✅ Tailwind CSS v4
18
+ - TypeScript
19
+ - ✅ wexts Provider & Hooks
20
+ - ✅ Authentication Flow
21
+ - Todo Management Dashboard
22
+
23
+ ## Setup
24
+
25
+ ```bash
26
+ # Install dependencies
27
+ npm install
28
+
29
+ # Copy environment variables
30
+ cp .env.local.example .env.local
31
+
32
+ # Update NEXT_PUBLIC_API_URL in .env.local to point to your API
33
+
34
+ # Start development server
35
+ npm run dev
36
+ ```
37
+
38
+ ## Project Structure
39
+
40
+ ```
41
+ app/
42
+ ├── layout.tsx # Root layout with FusionProvider
43
+ ├── page.tsx # Homepage with auth redirect
44
+ ├── globals.css # Global styles
45
+ ├── login/
46
+ │ └── page.tsx # Login page
47
+ ├── register/
48
+ │ └── page.tsx # Registration page
49
+ └── dashboard/
50
+ └── page.tsx # Protected dashboard with todos
51
+ ```
52
+
53
+ ## Using Fusion Hooks
54
+
55
+ ```tsx
56
+ import { useFusion, useAuth } from 'wexts/next';
57
+
58
+ function MyComponent() {
59
+ const { client } = useFusion();
60
+ const { user, isAuthenticated } = useAuth();
61
+
62
+ // Make API calls
63
+ const data = await client.get('/endpoint');
64
+ }
65
+ ```
66
+
67
+ ## Building for Production
68
+
69
+ ```bash
70
+ npm run build
71
+ npm start
72
+ ```
73
+
74
+ ## Environment Variables
75
+
76
+ - `NEXT_PUBLIC_API_URL` - Backend API URL (default: http://localhost:5050)
@@ -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
+ }