wexts 4.0.0 → 4.1.5

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 (189) hide show
  1. package/README.md +49 -49
  2. package/bin/wexts.cjs +2 -2
  3. package/package.json +153 -148
  4. package/templates/.dockerignore +43 -43
  5. package/templates/.env.example +17 -17
  6. package/templates/Dockerfile +60 -60
  7. package/templates/Procfile +1 -1
  8. package/templates/README.md +67 -67
  9. package/templates/api-sdk.ts +115 -115
  10. package/templates/docker-compose.yml +34 -34
  11. package/templates/nestjs-api/.env.example +3 -3
  12. package/templates/nestjs-api/README.md +87 -87
  13. package/templates/nestjs-api/nest-cli.json +6 -6
  14. package/templates/nestjs-api/package.json +40 -40
  15. package/templates/nestjs-api/prisma/migrations/20251123205437_init/migration.sql +24 -24
  16. package/templates/nestjs-api/prisma/migrations/migration_lock.toml +3 -3
  17. package/templates/nestjs-api/prisma/schema.prisma +29 -29
  18. package/templates/nestjs-api/src/app.module.ts +17 -17
  19. package/templates/nestjs-api/src/auth/auth.controller.ts +27 -27
  20. package/templates/nestjs-api/src/auth/auth.module.ts +37 -37
  21. package/templates/nestjs-api/src/auth/auth.service.ts +86 -86
  22. package/templates/nestjs-api/src/auth/dto/auth.dto.ts +22 -22
  23. package/templates/nestjs-api/src/auth/guards/jwt-auth.guard.ts +5 -5
  24. package/templates/nestjs-api/src/auth/strategies/jwt.strategy.ts +27 -27
  25. package/templates/nestjs-api/src/main.ts +32 -32
  26. package/templates/nestjs-api/src/prisma/prisma.module.ts +9 -9
  27. package/templates/nestjs-api/src/prisma/prisma.service.ts +14 -14
  28. package/templates/nestjs-api/src/todos/dto/todo.dto.ts +24 -24
  29. package/templates/nestjs-api/src/todos/todos.controller.ts +39 -39
  30. package/templates/nestjs-api/src/todos/todos.module.ts +11 -11
  31. package/templates/nestjs-api/src/todos/todos.service.ts +53 -53
  32. package/templates/nestjs-api/src/users/users.controller.ts +14 -14
  33. package/templates/nestjs-api/src/users/users.module.ts +12 -12
  34. package/templates/nestjs-api/src/users/users.service.ts +19 -19
  35. package/templates/nestjs-api/tsconfig.json +39 -39
  36. package/templates/nextjs-web/README.md +76 -76
  37. package/templates/nextjs-web/app/actions/auth.ts +108 -108
  38. package/templates/nextjs-web/app/dashboard/error.tsx +39 -39
  39. package/templates/nextjs-web/app/dashboard/loading.tsx +14 -14
  40. package/templates/nextjs-web/app/dashboard/page.tsx +5 -5
  41. package/templates/nextjs-web/app/globals.css +93 -93
  42. package/templates/nextjs-web/app/layout.tsx +29 -29
  43. package/templates/nextjs-web/app/login/page.tsx +5 -5
  44. package/templates/nextjs-web/app/page.tsx +28 -28
  45. package/templates/nextjs-web/app/register/page.tsx +5 -5
  46. package/templates/nextjs-web/components/ui/button.tsx +56 -56
  47. package/templates/nextjs-web/components/ui/card.tsx +79 -79
  48. package/templates/nextjs-web/components/ui/input.tsx +25 -25
  49. package/templates/nextjs-web/components/ui/label.tsx +24 -24
  50. package/templates/nextjs-web/features/auth/LoginForm.tsx +140 -140
  51. package/templates/nextjs-web/features/auth/RegisterForm.tsx +159 -159
  52. package/templates/nextjs-web/features/auth/api.ts +35 -35
  53. package/templates/nextjs-web/features/auth/index.ts +3 -3
  54. package/templates/nextjs-web/features/dashboard/DashboardView.tsx +204 -204
  55. package/templates/nextjs-web/features/dashboard/api.ts +9 -9
  56. package/templates/nextjs-web/features/dashboard/components.tsx +74 -74
  57. package/templates/nextjs-web/features/dashboard/index.ts +3 -3
  58. package/templates/nextjs-web/hooks/index.ts +4 -4
  59. package/templates/nextjs-web/lib/api-client.ts +89 -89
  60. package/templates/nextjs-web/lib/api.ts +115 -115
  61. package/templates/nextjs-web/lib/axios-global-config.ts +17 -17
  62. package/templates/nextjs-web/lib/utils.ts +6 -6
  63. package/templates/nextjs-web/lib/wexts-client.ts +4 -4
  64. package/templates/nextjs-web/next-env.d.ts +6 -6
  65. package/templates/nextjs-web/next.config.ts +20 -20
  66. package/templates/nextjs-web/package.json +37 -37
  67. package/templates/nextjs-web/postcss.config.js +6 -6
  68. package/templates/nextjs-web/tailwind.config.ts +69 -69
  69. package/templates/nextjs-web/tsconfig.json +41 -41
  70. package/templates/nixpacks.toml +11 -11
  71. package/templates/root-package.json +31 -31
  72. package/templates/server.ts +66 -66
  73. package/templates/tsconfig.json +30 -30
  74. package/dist/chunk-2KAQYLVN.js +0 -1
  75. package/dist/chunk-2KAQYLVN.js.map +0 -1
  76. package/dist/chunk-2LJVUMXW.js +0 -228
  77. package/dist/chunk-2LJVUMXW.js.map +0 -1
  78. package/dist/chunk-7QKLIVRF.js +0 -94
  79. package/dist/chunk-7QKLIVRF.js.map +0 -1
  80. package/dist/chunk-7WULUGLH.mjs +0 -22
  81. package/dist/chunk-7WULUGLH.mjs.map +0 -1
  82. package/dist/chunk-BG56B4DE.js +0 -106
  83. package/dist/chunk-BG56B4DE.js.map +0 -1
  84. package/dist/chunk-CLM5PNSG.mjs +0 -496
  85. package/dist/chunk-CLM5PNSG.mjs.map +0 -1
  86. package/dist/chunk-DNLGCKTT.js +0 -31
  87. package/dist/chunk-DNLGCKTT.js.map +0 -1
  88. package/dist/chunk-JHOVXH3X.mjs +0 -65
  89. package/dist/chunk-JHOVXH3X.mjs.map +0 -1
  90. package/dist/chunk-MXINIFPC.js +0 -105
  91. package/dist/chunk-MXINIFPC.js.map +0 -1
  92. package/dist/chunk-SE32ZPOZ.js +0 -496
  93. package/dist/chunk-SE32ZPOZ.js.map +0 -1
  94. package/dist/chunk-UAL54DVV.mjs +0 -106
  95. package/dist/chunk-UAL54DVV.mjs.map +0 -1
  96. package/dist/chunk-WCKSKU3C.js +0 -65
  97. package/dist/chunk-WCKSKU3C.js.map +0 -1
  98. package/dist/chunk-WU6FW77M.mjs +0 -105
  99. package/dist/chunk-WU6FW77M.mjs.map +0 -1
  100. package/dist/chunk-XE4OXN2W.js +0 -12
  101. package/dist/chunk-XE4OXN2W.js.map +0 -1
  102. package/dist/chunk-YBM3IJEA.mjs +0 -94
  103. package/dist/chunk-YBM3IJEA.mjs.map +0 -1
  104. package/dist/chunk-YN6WIWNQ.mjs +0 -228
  105. package/dist/chunk-YN6WIWNQ.mjs.map +0 -1
  106. package/dist/chunk-YSLEF5C5.mjs +0 -1
  107. package/dist/chunk-YSLEF5C5.mjs.map +0 -1
  108. package/dist/chunk-ZX7QIN24.mjs +0 -31
  109. package/dist/chunk-ZX7QIN24.mjs.map +0 -1
  110. package/dist/cli/index.d.mts +0 -11
  111. package/dist/cli/index.d.ts +0 -11
  112. package/dist/cli/index.js +0 -332
  113. package/dist/cli/index.js.map +0 -1
  114. package/dist/cli/index.mjs +0 -334
  115. package/dist/cli/index.mjs.map +0 -1
  116. package/dist/client/index.d.mts +0 -21
  117. package/dist/client/index.d.ts +0 -21
  118. package/dist/client/index.js +0 -12
  119. package/dist/client/index.js.map +0 -1
  120. package/dist/client/index.mjs +0 -12
  121. package/dist/client/index.mjs.map +0 -1
  122. package/dist/codegen/index.d.mts +0 -2
  123. package/dist/codegen/index.d.ts +0 -2
  124. package/dist/codegen/index.js +0 -15
  125. package/dist/codegen/index.js.map +0 -1
  126. package/dist/codegen/index.mjs +0 -15
  127. package/dist/codegen/index.mjs.map +0 -1
  128. package/dist/decorators-BT1FFqN0.d.mts +0 -29
  129. package/dist/decorators-DvS58PqC.d.ts +0 -29
  130. package/dist/dev-server/index.d.mts +0 -1
  131. package/dist/dev-server/index.d.ts +0 -1
  132. package/dist/dev-server/index.js +0 -13
  133. package/dist/dev-server/index.js.map +0 -1
  134. package/dist/dev-server/index.mjs +0 -13
  135. package/dist/dev-server/index.mjs.map +0 -1
  136. package/dist/index-7QeQEf37.d.ts +0 -92
  137. package/dist/index-7RvU-jGE.d.mts +0 -66
  138. package/dist/index-7RvU-jGE.d.ts +0 -66
  139. package/dist/index-8nzxy0NN.d.mts +0 -92
  140. package/dist/index-Co5ZsLqq.d.ts +0 -58
  141. package/dist/index-D94W1__r.d.mts +0 -58
  142. package/dist/index-DQmyVp6F.d.mts +0 -27
  143. package/dist/index-KL_1BrQb.d.ts +0 -27
  144. package/dist/index.d.mts +0 -258
  145. package/dist/index.d.ts +0 -258
  146. package/dist/index.js +0 -410
  147. package/dist/index.js.map +0 -1
  148. package/dist/index.mjs +0 -410
  149. package/dist/index.mjs.map +0 -1
  150. package/dist/nest/index.d.mts +0 -3
  151. package/dist/nest/index.d.ts +0 -3
  152. package/dist/nest/index.js +0 -38
  153. package/dist/nest/index.js.map +0 -1
  154. package/dist/nest/index.mjs +0 -38
  155. package/dist/nest/index.mjs.map +0 -1
  156. package/dist/next/index.d.mts +0 -66
  157. package/dist/next/index.d.ts +0 -66
  158. package/dist/next/index.js +0 -226
  159. package/dist/next/index.js.map +0 -1
  160. package/dist/next/index.mjs +0 -188
  161. package/dist/next/index.mjs.map +0 -1
  162. package/dist/rpc/index.d.mts +0 -2
  163. package/dist/rpc/index.d.ts +0 -2
  164. package/dist/rpc/index.js +0 -23
  165. package/dist/rpc/index.js.map +0 -1
  166. package/dist/rpc/index.mjs +0 -23
  167. package/dist/rpc/index.mjs.map +0 -1
  168. package/dist/runtime/index.d.mts +0 -55
  169. package/dist/runtime/index.d.ts +0 -55
  170. package/dist/runtime/index.js +0 -213
  171. package/dist/runtime/index.js.map +0 -1
  172. package/dist/runtime/index.mjs +0 -213
  173. package/dist/runtime/index.mjs.map +0 -1
  174. package/dist/types/index.d.mts +0 -12
  175. package/dist/types/index.d.ts +0 -12
  176. package/dist/types/index.js +0 -2
  177. package/dist/types/index.js.map +0 -1
  178. package/dist/types/index.mjs +0 -3
  179. package/dist/types/index.mjs.map +0 -1
  180. package/dist/types-7d_fC-C3.d.mts +0 -32
  181. package/dist/types-7d_fC-C3.d.ts +0 -32
  182. package/dist/vercel-builder/index.d.mts +0 -58
  183. package/dist/vercel-builder/index.d.ts +0 -58
  184. package/dist/vercel-builder/index.js +0 -330
  185. package/dist/vercel-builder/index.js.map +0 -1
  186. package/dist/vercel-builder/index.mjs +0 -330
  187. package/dist/vercel-builder/index.mjs.map +0 -1
  188. package/templates/nestjs-api/package-lock.json +0 -5623
  189. package/templates/nextjs-web/package-lock.json +0 -3254
@@ -1,140 +1,140 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { useRouter } from 'next/navigation';
5
- import { login } from './api';
6
- import { Button } from '@/components/ui/button';
7
- import { Input } from '@/components/ui/input';
8
- import { Label } from '@/components/ui/label';
9
- import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
10
- import Link from 'next/link';
11
- import { Zap, Mail, Lock, ArrowRight, Loader2 } from 'lucide-react';
12
-
13
- export function LoginForm() {
14
- const router = useRouter();
15
- const [loading, setLoading] = useState(false);
16
- const [error, setError] = useState('');
17
-
18
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
19
- e.preventDefault();
20
- setLoading(true);
21
- setError('');
22
-
23
- const formData = new FormData(e.currentTarget);
24
- const data = Object.fromEntries(formData.entries());
25
-
26
- try {
27
- await login(data);
28
- router.push('/dashboard');
29
- } catch (err: any) {
30
- console.error(err);
31
- setError(err.response?.data?.message || 'Login failed. Please check your credentials.');
32
- } finally {
33
- setLoading(false);
34
- }
35
- };
36
-
37
- return (
38
- <div className="min-h-screen flex items-center justify-center relative overflow-hidden bg-background">
39
- {/* Animated Background Elements */}
40
- <div className="absolute inset-0 overflow-hidden pointer-events-none">
41
- <div className="absolute -top-[20%] -left-[10%] w-[50%] h-[50%] rounded-full bg-primary/20 blur-[100px] animate-float" />
42
- <div className="absolute top-[40%] -right-[10%] w-[40%] h-[40%] rounded-full bg-indigo-500/20 blur-[100px] animate-float" style={{ animationDelay: '2s' }} />
43
- <div className="absolute -bottom-[10%] left-[20%] w-[30%] h-[30%] rounded-full bg-violet-500/20 blur-[100px] animate-float" style={{ animationDelay: '4s' }} />
44
- </div>
45
-
46
- <div className="w-full max-w-md p-8 relative z-10">
47
- <Card className="glass border-white/20 shadow-2xl backdrop-blur-xl">
48
- <CardHeader className="text-center">
49
- <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/10 mb-6 mx-auto text-primary">
50
- <Zap className="w-8 h-8" />
51
- </div>
52
- <CardTitle className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-indigo-600">
53
- Welcome Back
54
- </CardTitle>
55
- <CardDescription>
56
- Sign in to continue to wexts
57
- </CardDescription>
58
- </CardHeader>
59
- <CardContent>
60
- <form onSubmit={handleSubmit} className="space-y-6">
61
- {error && (
62
- <div className="p-4 rounded-xl bg-destructive/10 text-destructive text-sm font-medium border border-destructive/20 animate-pulse-slow flex items-center gap-2">
63
- <span className="text-lg">⚠️</span>
64
- {error}
65
- </div>
66
- )}
67
-
68
- <div className="space-y-4">
69
- <div className="space-y-2">
70
- <Label htmlFor="email">Email Address</Label>
71
- <div className="relative">
72
- <Mail className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
73
- <Input
74
- id="email"
75
- name="email"
76
- type="email"
77
- placeholder="name@example.com"
78
- required
79
- className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
80
- />
81
- </div>
82
- </div>
83
-
84
- <div className="space-y-2">
85
- <div className="flex items-center justify-between">
86
- <Label htmlFor="password">Password</Label>
87
- <Link href="#" className="text-xs font-medium text-primary hover:text-primary/80 transition-colors">
88
- Forgot password?
89
- </Link>
90
- </div>
91
- <div className="relative">
92
- <Lock className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
93
- <Input
94
- id="password"
95
- name="password"
96
- type="password"
97
- placeholder="••••••••"
98
- required
99
- className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
100
- />
101
- </div>
102
- </div>
103
- </div>
104
-
105
- <Button
106
- type="submit"
107
- disabled={loading}
108
- className="w-full bg-gradient-to-r from-primary to-indigo-600 hover:from-primary/90 hover:to-indigo-600/90 shadow-lg shadow-primary/25 group"
109
- >
110
- {loading ? (
111
- <>
112
- <Loader2 className="w-4 h-4 mr-2 animate-spin" />
113
- Signing in...
114
- </>
115
- ) : (
116
- <>
117
- Sign in
118
- <ArrowRight className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
119
- </>
120
- )}
121
- </Button>
122
- </form>
123
- </CardContent>
124
- <CardFooter className="justify-center">
125
- <div className="text-center text-sm text-muted-foreground">
126
- Don't have an account?{' '}
127
- <Link href="/register" className="font-semibold text-primary hover:text-primary/80 transition-colors">
128
- Create account
129
- </Link>
130
- </div>
131
- </CardFooter>
132
- </Card>
133
-
134
- <p className="text-center mt-8 text-xs text-muted-foreground/60">
135
- &copy; 2025 wexts Inc. All rights reserved.
136
- </p>
137
- </div>
138
- </div>
139
- );
140
- }
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import { login } from './api';
6
+ import { Button } from '@/components/ui/button';
7
+ import { Input } from '@/components/ui/input';
8
+ import { Label } from '@/components/ui/label';
9
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
10
+ import Link from 'next/link';
11
+ import { Zap, Mail, Lock, ArrowRight, Loader2 } from 'lucide-react';
12
+
13
+ export function LoginForm() {
14
+ const router = useRouter();
15
+ const [loading, setLoading] = useState(false);
16
+ const [error, setError] = useState('');
17
+
18
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
19
+ e.preventDefault();
20
+ setLoading(true);
21
+ setError('');
22
+
23
+ const formData = new FormData(e.currentTarget);
24
+ const data = Object.fromEntries(formData.entries());
25
+
26
+ try {
27
+ await login(data);
28
+ router.push('/dashboard');
29
+ } catch (err: any) {
30
+ console.error(err);
31
+ setError(err.response?.data?.message || 'Login failed. Please check your credentials.');
32
+ } finally {
33
+ setLoading(false);
34
+ }
35
+ };
36
+
37
+ return (
38
+ <div className="min-h-screen flex items-center justify-center relative overflow-hidden bg-background">
39
+ {/* Animated Background Elements */}
40
+ <div className="absolute inset-0 overflow-hidden pointer-events-none">
41
+ <div className="absolute -top-[20%] -left-[10%] w-[50%] h-[50%] rounded-full bg-primary/20 blur-[100px] animate-float" />
42
+ <div className="absolute top-[40%] -right-[10%] w-[40%] h-[40%] rounded-full bg-indigo-500/20 blur-[100px] animate-float" style={{ animationDelay: '2s' }} />
43
+ <div className="absolute -bottom-[10%] left-[20%] w-[30%] h-[30%] rounded-full bg-violet-500/20 blur-[100px] animate-float" style={{ animationDelay: '4s' }} />
44
+ </div>
45
+
46
+ <div className="w-full max-w-md p-8 relative z-10">
47
+ <Card className="glass border-white/20 shadow-2xl backdrop-blur-xl">
48
+ <CardHeader className="text-center">
49
+ <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/10 mb-6 mx-auto text-primary">
50
+ <Zap className="w-8 h-8" />
51
+ </div>
52
+ <CardTitle className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-indigo-600">
53
+ Welcome Back
54
+ </CardTitle>
55
+ <CardDescription>
56
+ Sign in to continue to wexts
57
+ </CardDescription>
58
+ </CardHeader>
59
+ <CardContent>
60
+ <form onSubmit={handleSubmit} className="space-y-6">
61
+ {error && (
62
+ <div className="p-4 rounded-xl bg-destructive/10 text-destructive text-sm font-medium border border-destructive/20 animate-pulse-slow flex items-center gap-2">
63
+ <span className="text-lg">⚠️</span>
64
+ {error}
65
+ </div>
66
+ )}
67
+
68
+ <div className="space-y-4">
69
+ <div className="space-y-2">
70
+ <Label htmlFor="email">Email Address</Label>
71
+ <div className="relative">
72
+ <Mail className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
73
+ <Input
74
+ id="email"
75
+ name="email"
76
+ type="email"
77
+ placeholder="name@example.com"
78
+ required
79
+ className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
80
+ />
81
+ </div>
82
+ </div>
83
+
84
+ <div className="space-y-2">
85
+ <div className="flex items-center justify-between">
86
+ <Label htmlFor="password">Password</Label>
87
+ <Link href="#" className="text-xs font-medium text-primary hover:text-primary/80 transition-colors">
88
+ Forgot password?
89
+ </Link>
90
+ </div>
91
+ <div className="relative">
92
+ <Lock className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
93
+ <Input
94
+ id="password"
95
+ name="password"
96
+ type="password"
97
+ placeholder="••••••••"
98
+ required
99
+ className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
100
+ />
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ <Button
106
+ type="submit"
107
+ disabled={loading}
108
+ className="w-full bg-gradient-to-r from-primary to-indigo-600 hover:from-primary/90 hover:to-indigo-600/90 shadow-lg shadow-primary/25 group"
109
+ >
110
+ {loading ? (
111
+ <>
112
+ <Loader2 className="w-4 h-4 mr-2 animate-spin" />
113
+ Signing in...
114
+ </>
115
+ ) : (
116
+ <>
117
+ Sign in
118
+ <ArrowRight className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
119
+ </>
120
+ )}
121
+ </Button>
122
+ </form>
123
+ </CardContent>
124
+ <CardFooter className="justify-center">
125
+ <div className="text-center text-sm text-muted-foreground">
126
+ Don't have an account?{' '}
127
+ <Link href="/register" className="font-semibold text-primary hover:text-primary/80 transition-colors">
128
+ Create account
129
+ </Link>
130
+ </div>
131
+ </CardFooter>
132
+ </Card>
133
+
134
+ <p className="text-center mt-8 text-xs text-muted-foreground/60">
135
+ &copy; 2025 wexts Inc. All rights reserved.
136
+ </p>
137
+ </div>
138
+ </div>
139
+ );
140
+ }
@@ -1,159 +1,159 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { useRouter } from 'next/navigation';
5
- import { register } from './api';
6
- import { Button } from '@/components/ui/button';
7
- import { Input } from '@/components/ui/input';
8
- import { Label } from '@/components/ui/label';
9
- import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
10
- import Link from 'next/link';
11
- import { Zap, Mail, Lock, ArrowRight, Loader2, UserPlus } from 'lucide-react';
12
-
13
- export function RegisterForm() {
14
- const router = useRouter();
15
- const [loading, setLoading] = useState(false);
16
- const [error, setError] = useState('');
17
-
18
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
19
- e.preventDefault();
20
- setLoading(true);
21
- setError('');
22
-
23
- const formData = new FormData(e.currentTarget);
24
- const data = Object.fromEntries(formData.entries());
25
-
26
- // Validate passwords match
27
- if (data.password !== data.confirmPassword) {
28
- setError('Passwords do not match');
29
- setLoading(false);
30
- return;
31
- }
32
-
33
- try {
34
- await register(data);
35
- router.push('/login?registered=true');
36
- } catch (err: any) {
37
- console.error(err);
38
- setError(err.response?.data?.message || 'Registration failed. Please try again.');
39
- } finally {
40
- setLoading(false);
41
- }
42
- };
43
-
44
- return (
45
- <div className="min-h-screen flex items-center justify-center relative overflow-hidden bg-background">
46
- {/* Animated Background Elements */}
47
- <div className="absolute inset-0 overflow-hidden pointer-events-none">
48
- <div className="absolute -top-[20%] -left-[10%] w-[50%] h-[50%] rounded-full bg-primary/20 blur-[100px] animate-float" />
49
- <div className="absolute top-[40%] -right-[10%] w-[40%] h-[40%] rounded-full bg-indigo-500/20 blur-[100px] animate-float" style={{ animationDelay: '2s' }} />
50
- <div className="absolute -bottom-[10%] left-[20%] w-[30%] h-[30%] rounded-full bg-violet-500/20 blur-[100px] animate-float" style={{ animationDelay: '4s' }} />
51
- </div>
52
-
53
- <div className="w-full max-w-md p-8 relative z-10">
54
- <Card className="glass border-white/20 shadow-2xl backdrop-blur-xl">
55
- <CardHeader className="text-center">
56
- <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/10 mb-6 mx-auto text-primary">
57
- <UserPlus className="w-8 h-8" />
58
- </div>
59
- <CardTitle className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-indigo-600">
60
- Create Account
61
- </CardTitle>
62
- <CardDescription>
63
- Join wexts today
64
- </CardDescription>
65
- </CardHeader>
66
- <CardContent>
67
- <form onSubmit={handleSubmit} className="space-y-6">
68
- {error && (
69
- <div className="p-4 rounded-xl bg-destructive/10 text-destructive text-sm font-medium border border-destructive/20 animate-pulse-slow flex items-center gap-2">
70
- <span className="text-lg">⚠️</span>
71
- {error}
72
- </div>
73
- )}
74
-
75
- <div className="space-y-4">
76
- <div className="space-y-2">
77
- <Label htmlFor="email">Email Address</Label>
78
- <div className="relative">
79
- <Mail className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
80
- <Input
81
- id="email"
82
- name="email"
83
- type="email"
84
- placeholder="name@example.com"
85
- required
86
- className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
87
- />
88
- </div>
89
- </div>
90
-
91
- <div className="space-y-2">
92
- <Label htmlFor="password">Password</Label>
93
- <div className="relative">
94
- <Lock className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
95
- <Input
96
- id="password"
97
- name="password"
98
- type="password"
99
- placeholder="••••••••"
100
- required
101
- minLength={6}
102
- className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
103
- />
104
- </div>
105
- </div>
106
-
107
- <div className="space-y-2">
108
- <Label htmlFor="confirmPassword">Confirm Password</Label>
109
- <div className="relative">
110
- <Lock className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
111
- <Input
112
- id="confirmPassword"
113
- name="confirmPassword"
114
- type="password"
115
- placeholder="••••••••"
116
- required
117
- minLength={6}
118
- className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
119
- />
120
- </div>
121
- </div>
122
- </div>
123
-
124
- <Button
125
- type="submit"
126
- disabled={loading}
127
- className="w-full bg-gradient-to-r from-primary to-indigo-600 hover:from-primary/90 hover:to-indigo-600/90 shadow-lg shadow-primary/25 group"
128
- >
129
- {loading ? (
130
- <>
131
- <Loader2 className="w-4 h-4 mr-2 animate-spin" />
132
- Creating account...
133
- </>
134
- ) : (
135
- <>
136
- Create account
137
- <ArrowRight className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
138
- </>
139
- )}
140
- </Button>
141
- </form>
142
- </CardContent>
143
- <CardFooter className="justify-center">
144
- <div className="text-center text-sm text-muted-foreground">
145
- Already have an account?{' '}
146
- <Link href="/login" className="font-semibold text-primary hover:text-primary/80 transition-colors">
147
- Sign in
148
- </Link>
149
- </div>
150
- </CardFooter>
151
- </Card>
152
-
153
- <p className="text-center mt-8 text-xs text-muted-foreground/60">
154
- &copy; 2025 wexts Inc. All rights reserved.
155
- </p>
156
- </div>
157
- </div>
158
- );
159
- }
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import { register } from './api';
6
+ import { Button } from '@/components/ui/button';
7
+ import { Input } from '@/components/ui/input';
8
+ import { Label } from '@/components/ui/label';
9
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
10
+ import Link from 'next/link';
11
+ import { Zap, Mail, Lock, ArrowRight, Loader2, UserPlus } from 'lucide-react';
12
+
13
+ export function RegisterForm() {
14
+ const router = useRouter();
15
+ const [loading, setLoading] = useState(false);
16
+ const [error, setError] = useState('');
17
+
18
+ const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
19
+ e.preventDefault();
20
+ setLoading(true);
21
+ setError('');
22
+
23
+ const formData = new FormData(e.currentTarget);
24
+ const data = Object.fromEntries(formData.entries());
25
+
26
+ // Validate passwords match
27
+ if (data.password !== data.confirmPassword) {
28
+ setError('Passwords do not match');
29
+ setLoading(false);
30
+ return;
31
+ }
32
+
33
+ try {
34
+ await register(data);
35
+ router.push('/login?registered=true');
36
+ } catch (err: any) {
37
+ console.error(err);
38
+ setError(err.response?.data?.message || 'Registration failed. Please try again.');
39
+ } finally {
40
+ setLoading(false);
41
+ }
42
+ };
43
+
44
+ return (
45
+ <div className="min-h-screen flex items-center justify-center relative overflow-hidden bg-background">
46
+ {/* Animated Background Elements */}
47
+ <div className="absolute inset-0 overflow-hidden pointer-events-none">
48
+ <div className="absolute -top-[20%] -left-[10%] w-[50%] h-[50%] rounded-full bg-primary/20 blur-[100px] animate-float" />
49
+ <div className="absolute top-[40%] -right-[10%] w-[40%] h-[40%] rounded-full bg-indigo-500/20 blur-[100px] animate-float" style={{ animationDelay: '2s' }} />
50
+ <div className="absolute -bottom-[10%] left-[20%] w-[30%] h-[30%] rounded-full bg-violet-500/20 blur-[100px] animate-float" style={{ animationDelay: '4s' }} />
51
+ </div>
52
+
53
+ <div className="w-full max-w-md p-8 relative z-10">
54
+ <Card className="glass border-white/20 shadow-2xl backdrop-blur-xl">
55
+ <CardHeader className="text-center">
56
+ <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/10 mb-6 mx-auto text-primary">
57
+ <UserPlus className="w-8 h-8" />
58
+ </div>
59
+ <CardTitle className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-indigo-600">
60
+ Create Account
61
+ </CardTitle>
62
+ <CardDescription>
63
+ Join wexts today
64
+ </CardDescription>
65
+ </CardHeader>
66
+ <CardContent>
67
+ <form onSubmit={handleSubmit} className="space-y-6">
68
+ {error && (
69
+ <div className="p-4 rounded-xl bg-destructive/10 text-destructive text-sm font-medium border border-destructive/20 animate-pulse-slow flex items-center gap-2">
70
+ <span className="text-lg">⚠️</span>
71
+ {error}
72
+ </div>
73
+ )}
74
+
75
+ <div className="space-y-4">
76
+ <div className="space-y-2">
77
+ <Label htmlFor="email">Email Address</Label>
78
+ <div className="relative">
79
+ <Mail className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
80
+ <Input
81
+ id="email"
82
+ name="email"
83
+ type="email"
84
+ placeholder="name@example.com"
85
+ required
86
+ className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
87
+ />
88
+ </div>
89
+ </div>
90
+
91
+ <div className="space-y-2">
92
+ <Label htmlFor="password">Password</Label>
93
+ <div className="relative">
94
+ <Lock className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
95
+ <Input
96
+ id="password"
97
+ name="password"
98
+ type="password"
99
+ placeholder="••••••••"
100
+ required
101
+ minLength={6}
102
+ className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
103
+ />
104
+ </div>
105
+ </div>
106
+
107
+ <div className="space-y-2">
108
+ <Label htmlFor="confirmPassword">Confirm Password</Label>
109
+ <div className="relative">
110
+ <Lock className="absolute left-3 top-3 w-4 h-4 text-muted-foreground" />
111
+ <Input
112
+ id="confirmPassword"
113
+ name="confirmPassword"
114
+ type="password"
115
+ placeholder="••••••••"
116
+ required
117
+ minLength={6}
118
+ className="pl-10 bg-secondary/50 border-transparent focus:border-primary/50 focus:bg-background transition-all"
119
+ />
120
+ </div>
121
+ </div>
122
+ </div>
123
+
124
+ <Button
125
+ type="submit"
126
+ disabled={loading}
127
+ className="w-full bg-gradient-to-r from-primary to-indigo-600 hover:from-primary/90 hover:to-indigo-600/90 shadow-lg shadow-primary/25 group"
128
+ >
129
+ {loading ? (
130
+ <>
131
+ <Loader2 className="w-4 h-4 mr-2 animate-spin" />
132
+ Creating account...
133
+ </>
134
+ ) : (
135
+ <>
136
+ Create account
137
+ <ArrowRight className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
138
+ </>
139
+ )}
140
+ </Button>
141
+ </form>
142
+ </CardContent>
143
+ <CardFooter className="justify-center">
144
+ <div className="text-center text-sm text-muted-foreground">
145
+ Already have an account?{' '}
146
+ <Link href="/login" className="font-semibold text-primary hover:text-primary/80 transition-colors">
147
+ Sign in
148
+ </Link>
149
+ </div>
150
+ </CardFooter>
151
+ </Card>
152
+
153
+ <p className="text-center mt-8 text-xs text-muted-foreground/60">
154
+ &copy; 2025 wexts Inc. All rights reserved.
155
+ </p>
156
+ </div>
157
+ </div>
158
+ );
159
+ }