wexts 4.1.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.
- package/README.md +49 -49
- package/bin/wexts.cjs +2 -2
- package/package.json +153 -148
- package/templates/.dockerignore +43 -43
- package/templates/.env.example +17 -17
- package/templates/Dockerfile +60 -60
- package/templates/Procfile +1 -1
- package/templates/README.md +67 -67
- package/templates/api-sdk.ts +115 -115
- package/templates/docker-compose.yml +34 -34
- package/templates/nestjs-api/.env.example +3 -3
- package/templates/nestjs-api/README.md +87 -87
- package/templates/nestjs-api/nest-cli.json +6 -6
- package/templates/nestjs-api/package.json +40 -40
- package/templates/nestjs-api/prisma/migrations/20251123205437_init/migration.sql +24 -24
- package/templates/nestjs-api/prisma/migrations/migration_lock.toml +3 -3
- package/templates/nestjs-api/prisma/schema.prisma +29 -29
- package/templates/nestjs-api/src/app.module.ts +17 -17
- package/templates/nestjs-api/src/auth/auth.controller.ts +27 -27
- package/templates/nestjs-api/src/auth/auth.module.ts +37 -37
- package/templates/nestjs-api/src/auth/auth.service.ts +86 -86
- package/templates/nestjs-api/src/auth/dto/auth.dto.ts +22 -22
- package/templates/nestjs-api/src/auth/guards/jwt-auth.guard.ts +5 -5
- package/templates/nestjs-api/src/auth/strategies/jwt.strategy.ts +27 -27
- package/templates/nestjs-api/src/main.ts +32 -32
- package/templates/nestjs-api/src/prisma/prisma.module.ts +9 -9
- package/templates/nestjs-api/src/prisma/prisma.service.ts +14 -14
- package/templates/nestjs-api/src/todos/dto/todo.dto.ts +24 -24
- package/templates/nestjs-api/src/todos/todos.controller.ts +39 -39
- package/templates/nestjs-api/src/todos/todos.module.ts +11 -11
- package/templates/nestjs-api/src/todos/todos.service.ts +53 -53
- package/templates/nestjs-api/src/users/users.controller.ts +14 -14
- package/templates/nestjs-api/src/users/users.module.ts +12 -12
- package/templates/nestjs-api/src/users/users.service.ts +19 -19
- package/templates/nestjs-api/tsconfig.json +39 -39
- package/templates/nextjs-web/README.md +76 -76
- package/templates/nextjs-web/app/actions/auth.ts +108 -108
- package/templates/nextjs-web/app/dashboard/error.tsx +39 -39
- package/templates/nextjs-web/app/dashboard/loading.tsx +14 -14
- package/templates/nextjs-web/app/dashboard/page.tsx +5 -5
- package/templates/nextjs-web/app/globals.css +93 -93
- package/templates/nextjs-web/app/layout.tsx +29 -29
- package/templates/nextjs-web/app/login/page.tsx +5 -5
- package/templates/nextjs-web/app/page.tsx +28 -28
- package/templates/nextjs-web/app/register/page.tsx +5 -5
- package/templates/nextjs-web/components/ui/button.tsx +56 -56
- package/templates/nextjs-web/components/ui/card.tsx +79 -79
- package/templates/nextjs-web/components/ui/input.tsx +25 -25
- package/templates/nextjs-web/components/ui/label.tsx +24 -24
- package/templates/nextjs-web/features/auth/LoginForm.tsx +140 -140
- package/templates/nextjs-web/features/auth/RegisterForm.tsx +159 -159
- package/templates/nextjs-web/features/auth/api.ts +35 -35
- package/templates/nextjs-web/features/auth/index.ts +3 -3
- package/templates/nextjs-web/features/dashboard/DashboardView.tsx +204 -204
- package/templates/nextjs-web/features/dashboard/api.ts +9 -9
- package/templates/nextjs-web/features/dashboard/components.tsx +74 -74
- package/templates/nextjs-web/features/dashboard/index.ts +3 -3
- package/templates/nextjs-web/hooks/index.ts +4 -4
- package/templates/nextjs-web/lib/api-client.ts +89 -89
- package/templates/nextjs-web/lib/api.ts +115 -115
- package/templates/nextjs-web/lib/axios-global-config.ts +17 -17
- package/templates/nextjs-web/lib/utils.ts +6 -6
- package/templates/nextjs-web/lib/wexts-client.ts +4 -4
- package/templates/nextjs-web/next-env.d.ts +6 -6
- package/templates/nextjs-web/next.config.ts +20 -20
- package/templates/nextjs-web/package.json +37 -37
- package/templates/nextjs-web/postcss.config.js +6 -6
- package/templates/nextjs-web/tailwind.config.ts +69 -69
- package/templates/nextjs-web/tsconfig.json +41 -41
- package/templates/nixpacks.toml +11 -11
- package/templates/root-package.json +31 -31
- package/templates/server.ts +66 -66
- package/templates/tsconfig.json +30 -30
- package/dist/chunk-2KAQYLVN.js +0 -1
- package/dist/chunk-2KAQYLVN.js.map +0 -1
- package/dist/chunk-2LJVUMXW.js +0 -228
- package/dist/chunk-2LJVUMXW.js.map +0 -1
- package/dist/chunk-342VRT25.mjs +0 -504
- package/dist/chunk-342VRT25.mjs.map +0 -1
- package/dist/chunk-7HNQWJWV.js +0 -504
- package/dist/chunk-7HNQWJWV.js.map +0 -1
- package/dist/chunk-7QKLIVRF.js +0 -94
- package/dist/chunk-7QKLIVRF.js.map +0 -1
- package/dist/chunk-7SSCNCTW.mjs +0 -137
- package/dist/chunk-7SSCNCTW.mjs.map +0 -1
- package/dist/chunk-7TLSPR65.mjs +0 -95
- package/dist/chunk-7TLSPR65.mjs.map +0 -1
- package/dist/chunk-7WULUGLH.mjs +0 -22
- package/dist/chunk-7WULUGLH.mjs.map +0 -1
- package/dist/chunk-AVMQJWYD.js +0 -95
- package/dist/chunk-AVMQJWYD.js.map +0 -1
- package/dist/chunk-BG56B4DE.js +0 -106
- package/dist/chunk-BG56B4DE.js.map +0 -1
- package/dist/chunk-CLM5PNSG.mjs +0 -496
- package/dist/chunk-CLM5PNSG.mjs.map +0 -1
- package/dist/chunk-DNLGCKTT.js +0 -31
- package/dist/chunk-DNLGCKTT.js.map +0 -1
- package/dist/chunk-JHOVXH3X.mjs +0 -65
- package/dist/chunk-JHOVXH3X.mjs.map +0 -1
- package/dist/chunk-MXINIFPC.js +0 -105
- package/dist/chunk-MXINIFPC.js.map +0 -1
- package/dist/chunk-O4II6N34.js +0 -137
- package/dist/chunk-O4II6N34.js.map +0 -1
- package/dist/chunk-SE32ZPOZ.js +0 -496
- package/dist/chunk-SE32ZPOZ.js.map +0 -1
- package/dist/chunk-UAL54DVV.mjs +0 -106
- package/dist/chunk-UAL54DVV.mjs.map +0 -1
- package/dist/chunk-WCKSKU3C.js +0 -65
- package/dist/chunk-WCKSKU3C.js.map +0 -1
- package/dist/chunk-WU6FW77M.mjs +0 -105
- package/dist/chunk-WU6FW77M.mjs.map +0 -1
- package/dist/chunk-XE4OXN2W.js +0 -12
- package/dist/chunk-XE4OXN2W.js.map +0 -1
- package/dist/chunk-YBM3IJEA.mjs +0 -94
- package/dist/chunk-YBM3IJEA.mjs.map +0 -1
- package/dist/chunk-YN6WIWNQ.mjs +0 -228
- package/dist/chunk-YN6WIWNQ.mjs.map +0 -1
- package/dist/chunk-YSLEF5C5.mjs +0 -1
- package/dist/chunk-YSLEF5C5.mjs.map +0 -1
- package/dist/chunk-ZX7QIN24.mjs +0 -31
- package/dist/chunk-ZX7QIN24.mjs.map +0 -1
- package/dist/cli/index.d.mts +0 -23
- package/dist/cli/index.d.ts +0 -23
- package/dist/cli/index.js +0 -716
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/index.mjs +0 -718
- package/dist/cli/index.mjs.map +0 -1
- package/dist/client/index.d.mts +0 -21
- package/dist/client/index.d.ts +0 -21
- package/dist/client/index.js +0 -13
- package/dist/client/index.js.map +0 -1
- package/dist/client/index.mjs +0 -13
- package/dist/client/index.mjs.map +0 -1
- package/dist/codegen/index.d.mts +0 -2
- package/dist/codegen/index.d.ts +0 -2
- package/dist/codegen/index.js +0 -16
- package/dist/codegen/index.js.map +0 -1
- package/dist/codegen/index.mjs +0 -16
- package/dist/codegen/index.mjs.map +0 -1
- package/dist/decorators-BT1FFqN0.d.mts +0 -29
- package/dist/decorators-DvS58PqC.d.ts +0 -29
- package/dist/dev-server/index.d.mts +0 -1
- package/dist/dev-server/index.d.ts +0 -1
- package/dist/dev-server/index.js +0 -13
- package/dist/dev-server/index.js.map +0 -1
- package/dist/dev-server/index.mjs +0 -13
- package/dist/dev-server/index.mjs.map +0 -1
- package/dist/index-7QeQEf37.d.ts +0 -92
- package/dist/index-7RvU-jGE.d.mts +0 -66
- package/dist/index-7RvU-jGE.d.ts +0 -66
- package/dist/index-8nzxy0NN.d.mts +0 -92
- package/dist/index-Co5ZsLqq.d.ts +0 -58
- package/dist/index-D94W1__r.d.mts +0 -58
- package/dist/index-DQmyVp6F.d.mts +0 -27
- package/dist/index-KL_1BrQb.d.ts +0 -27
- package/dist/index.d.mts +0 -294
- package/dist/index.d.ts +0 -294
- package/dist/index.js +0 -424
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -424
- package/dist/index.mjs.map +0 -1
- package/dist/nest/index.d.mts +0 -3
- package/dist/nest/index.d.ts +0 -3
- package/dist/nest/index.js +0 -38
- package/dist/nest/index.js.map +0 -1
- package/dist/nest/index.mjs +0 -38
- package/dist/nest/index.mjs.map +0 -1
- package/dist/next/index.d.mts +0 -66
- package/dist/next/index.d.ts +0 -66
- package/dist/next/index.js +0 -289
- package/dist/next/index.js.map +0 -1
- package/dist/next/index.mjs +0 -251
- package/dist/next/index.mjs.map +0 -1
- package/dist/rpc/index.d.mts +0 -2
- package/dist/rpc/index.d.ts +0 -2
- package/dist/rpc/index.js +0 -23
- package/dist/rpc/index.js.map +0 -1
- package/dist/rpc/index.mjs +0 -23
- package/dist/rpc/index.mjs.map +0 -1
- package/dist/runtime/index.d.mts +0 -55
- package/dist/runtime/index.d.ts +0 -55
- package/dist/runtime/index.js +0 -221
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/index.mjs +0 -221
- package/dist/runtime/index.mjs.map +0 -1
- package/dist/types/index.d.mts +0 -12
- package/dist/types/index.d.ts +0 -12
- package/dist/types/index.js +0 -2
- package/dist/types/index.js.map +0 -1
- package/dist/types/index.mjs +0 -3
- package/dist/types/index.mjs.map +0 -1
- package/dist/types-7d_fC-C3.d.mts +0 -32
- package/dist/types-7d_fC-C3.d.ts +0 -32
- package/dist/vercel-builder/index.d.mts +0 -58
- package/dist/vercel-builder/index.d.ts +0 -58
- package/dist/vercel-builder/index.js +0 -330
- package/dist/vercel-builder/index.js.map +0 -1
- package/dist/vercel-builder/index.mjs +0 -330
- package/dist/vercel-builder/index.mjs.map +0 -1
|
@@ -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
|
-
© 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
|
+
© 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
|
-
© 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
|
+
© 2025 wexts Inc. All rights reserved.
|
|
155
|
+
</p>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
}
|