22
33import React , { useState } from 'react' ;
44import Link from 'next/link' ;
5- import { motion } from 'framer-motion' ;
5+ import { useRouter } from 'next/navigation' ;
6+ import { useAuthStore } from '@/store/authStore' ;
7+ import { useMutation } from '@tanstack/react-query' ;
8+ import axios from 'axios' ;
9+ import { toast } from 'sonner' ;
610import {
711 Github ,
812 Chrome ,
@@ -12,11 +16,62 @@ import {
1216 Mail ,
1317 User ,
1418 Building2 ,
15- ShieldCheck
19+ ShieldCheck ,
20+ Loader2
1621} from 'lucide-react' ;
1722
23+ const API_URL = process . env . NEXT_PUBLIC_API_URL || 'http://localhost:3000/api/v1' ;
24+
1825export default function RegisterPage ( ) {
19- const [ isLoading , setIsLoading ] = useState ( false ) ;
26+ const router = useRouter ( ) ;
27+ const login = useAuthStore ( ( state ) => state . login ) ;
28+
29+ // Form State
30+ const [ fullName , setFullName ] = useState ( '' ) ;
31+ const [ email , setEmail ] = useState ( '' ) ;
32+ const [ companyName , setCompanyName ] = useState ( '' ) ;
33+ const [ password , setPassword ] = useState ( '' ) ;
34+
35+ const { mutate : handleRegister , isPending } = useMutation ( {
36+ mutationFn : async ( ) => {
37+ const response = await axios . post ( `${ API_URL } /auth/register` , {
38+ name : fullName ,
39+ email,
40+ password,
41+ companyName
42+ } ) ;
43+ return response . data ;
44+ } ,
45+ onSuccess : ( data ) => {
46+ console . log ( "Registration success:" , data ) ;
47+ // Assuming the API returns user and token structure similar to login
48+ // If the API automatically logs them in, great.
49+ // If not, we might need to redirect to login or auto-login.
50+ // Based on typical auth flows, we usually get a token back.
51+ if ( data . token && data . user ) {
52+ login ( data . user , data . token ) ;
53+ toast . success ( "Workspace created successfully!" ) ;
54+ router . push ( '/dashboard' ) ;
55+ } else {
56+ toast . success ( "Account created! Please log in." ) ;
57+ router . push ( '/auth/login' ) ;
58+ }
59+ } ,
60+ onError : ( error : any ) => {
61+ console . error ( "Registration error:" , error ) ;
62+ const message = error . response ?. data ?. error || "Registration failed. Please try again." ;
63+ toast . error ( message ) ;
64+ }
65+ } ) ;
66+
67+ const onSubmit = ( e : React . FormEvent ) => {
68+ e . preventDefault ( ) ;
69+ if ( ! fullName || ! email || ! companyName || ! password ) {
70+ toast . error ( "Please fill in all fields" ) ;
71+ return ;
72+ }
73+ handleRegister ( ) ;
74+ } ;
2075
2176 return (
2277 < div className = "min-h-screen bg-slate-950 flex flex-col lg:flex-row overflow-hidden font-sans" >
@@ -83,26 +138,59 @@ export default function RegisterPage() {
83138 < div className = "relative flex justify-center text-xs uppercase font-black tracking-[0.3em]" > < span className = "bg-slate-950 px-4 text-slate-700" > Or with email</ span > </ div >
84139 </ div >
85140
86- < form className = "space-y-6" >
141+ < form onSubmit = { onSubmit } className = "space-y-6" >
87142 < div className = "grid grid-cols-2 gap-4" >
88- < InputField icon = { User } label = "Full Name" placeholder = "Alex Rivera" />
89- < InputField icon = { Mail } label = "Work Email" placeholder = "alex@company.com" />
143+ < InputField
144+ icon = { User }
145+ label = "Full Name"
146+ placeholder = "Alex Rivera"
147+ value = { fullName }
148+ onChange = { ( e : any ) => setFullName ( e . target . value ) }
149+ />
150+ < InputField
151+ icon = { Mail }
152+ label = "Work Email"
153+ placeholder = "alex@company.com"
154+ type = "email"
155+ value = { email }
156+ onChange = { ( e : any ) => setEmail ( e . target . value ) }
157+ />
90158 </ div >
91- < InputField icon = { Building2 } label = "Company Name" placeholder = "Acme Inc." />
92- < InputField icon = { Lock } label = "Password" placeholder = "••••••••" type = "password" />
159+ < InputField
160+ icon = { Building2 }
161+ label = "Company Name"
162+ placeholder = "Acme Inc."
163+ value = { companyName }
164+ onChange = { ( e : any ) => setCompanyName ( e . target . value ) }
165+ />
166+ < InputField
167+ icon = { Lock }
168+ label = "Password"
169+ placeholder = "••••••••"
170+ type = "password"
171+ value = { password }
172+ onChange = { ( e : any ) => setPassword ( e . target . value ) }
173+ />
93174
94175 < div className = "flex items-center space-x-3 p-4 bg-blue-600/5 border border-blue-500/10 rounded-2xl" >
95176 < ShieldCheck className = "w-5 h-5 text-blue-500" />
96177 < p className = "text-[10px] font-bold text-blue-400 uppercase tracking-widest" > Auto-KYC enabled. Verification takes 3-5 mins.</ p >
97178 </ div >
98179
99- < Link
100- href = "/dashboard"
101- className = "flex w-full justify-center items-center space-x-3 bg-white text-black py-5 rounded-2xl font-black text-lg hover:bg-slate-200 transition-all active:scale-95 shadow-xl shadow-white/5 mt-8"
180+ < button
181+ type = "submit"
182+ disabled = { isPending }
183+ className = "flex w-full justify-center items-center space-x-3 bg-white text-black py-5 rounded-2xl font-black text-lg hover:bg-slate-200 transition-all active:scale-95 shadow-xl shadow-white/5 mt-8 disabled:opacity-50 disabled:cursor-not-allowed"
102184 >
103- < span > Initialize My Console</ span >
104- < ArrowRight className = "w-5 h-5" />
105- </ Link >
185+ { isPending ? (
186+ < Loader2 className = "w-5 h-5 animate-spin" />
187+ ) : (
188+ < >
189+ < span > Initialize My Console</ span >
190+ < ArrowRight className = "w-5 h-5" />
191+ </ >
192+ ) }
193+ </ button >
106194 </ form >
107195
108196 < p className = "text-center text-sm font-bold text-slate-500" >
@@ -123,23 +211,26 @@ export default function RegisterPage() {
123211
124212function SocialButton ( { icon : Icon , label } : any ) {
125213 return (
126- < button className = "flex items-center justify-center space-x-3 bg-white/5 border border-white/10 p-4 rounded-2xl hover:bg-white/10 transition-all group" >
214+ < button type = "button" className = "flex items-center justify-center space-x-3 bg-white/5 border border-white/10 p-4 rounded-2xl hover:bg-white/10 transition-all group" >
127215 < Icon className = "w-5 h-5 text-slate-400 group-hover:text-white transition-colors" />
128216 < span className = "text-sm font-bold text-white" > { label } </ span >
129217 </ button >
130218 )
131219}
132220
133- function InputField ( { icon : Icon , label, placeholder, type = "text" } : any ) {
221+ function InputField ( { icon : Icon , label, placeholder, type = "text" , value , onChange } : any ) {
134222 return (
135223 < div className = "space-y-3" >
136224 < label className = "text-[10px] font-black text-slate-500 uppercase tracking-widest px-1" > { label } </ label >
137225 < div className = "relative" >
138226 < Icon className = "absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-600" />
139227 < input
140228 type = { type }
229+ value = { value }
230+ onChange = { onChange }
141231 className = "w-full bg-slate-900 border border-white/5 rounded-2xl p-4 pl-12 text-sm text-white focus:outline-none focus:ring-2 focus:ring-blue-600/50 transition-all placeholder:text-slate-700"
142232 placeholder = { placeholder }
233+ required
143234 />
144235 </ div >
145236 </ div >
0 commit comments