1- import { useState , FormEvent } from "react" ;
2- import { Eye , EyeOff , ArrowLeft } from "lucide-react" ;
1+ /* eslint-disable @typescript-eslint/no-explicit-any */
2+ import { register } from "@/services/authService" ; // ← MUDE para register
33import { Image } from "@unpic/react" ;
44import { motion } from "framer-motion" ;
5+ import { ArrowLeft , Eye , EyeOff } from "lucide-react" ;
6+ import { FormEvent , useState } from "react" ;
57import PhoneInput from "react-phone-number-input" ;
68import "react-phone-number-input/style.css" ;
79
@@ -59,6 +61,9 @@ export default function RegisterSide() {
5961 const [ telefoneError , setTelefoneError ] = useState ( "" ) ;
6062 const [ passwordError , setPasswordError ] = useState ( "" ) ;
6163 const [ cpfError , setCpfError ] = useState ( "" ) ;
64+
65+ const [ isLoading , setIsLoading ] = useState ( false ) ;
66+ const [ apiError , setApiError ] = useState ( "" ) ;
6267
6368 const handleRevealPassword = ( ) => setShowPassword ( ( prev ) => ! prev ) ;
6469
@@ -70,41 +75,67 @@ export default function RegisterSide() {
7075 return `${ digits . slice ( 0 , 3 ) } .${ digits . slice ( 3 , 6 ) } .${ digits . slice ( 6 , 9 ) } -${ digits . slice ( 9 ) } ` ;
7176 } ;
7277
73- const handleSubmit = ( e : FormEvent ) => {
78+ const handleSubmit = async ( e : FormEvent ) => {
7479 e . preventDefault ( ) ;
7580 setNomeError ( "" ) ;
7681 setEmailError ( "" ) ;
7782 setTelefoneError ( "" ) ;
7883 setPasswordError ( "" ) ;
7984 setCpfError ( "" ) ;
85+ setApiError ( "" ) ;
8086
8187 let isValid = true ;
8288
83- if ( ! nome ) { setNomeError ( "O campo de nome é obrigatório." ) ; isValid = false ; }
89+ if ( ! nome ) {
90+ setNomeError ( "O campo de nome é obrigatório." ) ;
91+ isValid = false ;
92+ }
8493
8594 if ( ! email ) {
86- setEmailError ( "O campo de e-mail é obrigatório." ) ; isValid = false ;
95+ setEmailError ( "O campo de e-mail é obrigatório." ) ;
96+ isValid = false ;
8797 } else {
8898 const emailRegex = / ^ [ ^ \s @ ] + @ [ ^ \s @ ] + \. [ ^ \s @ ] + $ / ;
89- if ( ! emailRegex . test ( email ) ) { setEmailError ( "Por favor, insira um e-mail válido." ) ; isValid = false ; }
99+ if ( ! emailRegex . test ( email ) ) {
100+ setEmailError ( "Por favor, insira um e-mail válido." ) ;
101+ isValid = false ;
102+ }
90103 }
91104
92- if ( ! telefone ) { setTelefoneError ( "O campo de telefone é obrigatório." ) ; isValid = false ; }
105+ if ( ! telefone ) {
106+ setTelefoneError ( "O campo de telefone é obrigatório." ) ;
107+ isValid = false ;
108+ }
93109
94110 if ( ! password ) {
95- setPasswordError ( "O campo de senha é obrigatório." ) ; isValid = false ;
111+ setPasswordError ( "O campo de senha é obrigatório." ) ;
112+ isValid = false ;
96113 } else if ( password . length < 6 ) {
97- setPasswordError ( "A senha precisa conter pelo menos 6 caracteres." ) ; isValid = false ;
114+ setPasswordError ( "A senha precisa conter pelo menos 6 caracteres." ) ;
115+ isValid = false ;
98116 }
99117
100- if ( ! cpf ) {
101- setCpfError ( "O campo de CPF é obrigatório." ) ; isValid = false ;
102- } else if ( cpf . replace ( / \D / g, "" ) . length < 11 ) {
103- setCpfError ( "Por favor, insira um CPF válido." ) ; isValid = false ;
118+ if ( cpf && cpf . replace ( / \D / g, "" ) . length > 0 && cpf . replace ( / \D / g, "" ) . length !== 11 ) {
119+ setCpfError ( "CPF inválido. Deve conter 11 dígitos." ) ;
120+ isValid = false ;
104121 }
105122
106123 if ( isValid ) {
107- console . log ( "Cadastro válido!" , { nome, email, telefone, password, cpf } ) ;
124+ setIsLoading ( true ) ;
125+ try {
126+ const result = await register ( {
127+ email : email ,
128+ password : password ,
129+ name : nome ,
130+ } ) ;
131+ console . log ( "Cadastro bem sucedido:" , result ) ;
132+ window . location . href = "/login?registered=true" ;
133+ } catch ( error : any ) {
134+ console . error ( "Erro no cadastro:" , error ) ;
135+ setApiError ( error . message || "Erro ao cadastrar. Tente novamente." ) ;
136+ } finally {
137+ setIsLoading ( false ) ;
138+ }
108139 }
109140 } ;
110141
@@ -144,6 +175,12 @@ export default function RegisterSide() {
144175
145176 < form className = "relative z-10 space-y-5 w-full max-w-2xl mx-auto my-8" onSubmit = { handleSubmit } >
146177
178+ { apiError && (
179+ < div className = "p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-xl" >
180+ < p className = "text-sm text-red-600 dark:text-red-400 text-center" > { apiError } </ p >
181+ </ div >
182+ ) }
183+
147184 < div >
148185 < label htmlFor = "nome" className = "block text-sm font-semibold text-gray-700 dark:text-neutral-300 mb-1.5" >
149186 Nome
@@ -153,10 +190,11 @@ export default function RegisterSide() {
153190 type = "text"
154191 value = { nome }
155192 onChange = { ( e ) => setNome ( e . target . value ) }
156- placeholder = "Bene Santos"
193+ placeholder = "benevanio"
194+ disabled = { isLoading }
157195 className = { `w-full px-4 py-3.5 rounded-xl border bg-white/80 dark:bg-neutral-800/80 backdrop-blur-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-neutral-500 focus:outline-none focus:ring-2 transition-all shadow-sm ${
158196 nomeError ? "border-red-500 focus:ring-red-500" : "border-gray-200 dark:border-neutral-700 focus:ring-blue-500 focus:border-transparent"
159- } `}
197+ } ${ isLoading ? "opacity-50 cursor-not-allowed" : "" } `}
160198 />
161199 { nomeError && < p className = "mt-1.5 text-xs text-red-500 font-medium" > { nomeError } </ p > }
162200 </ div >
@@ -170,10 +208,11 @@ export default function RegisterSide() {
170208 type = "email"
171209 value = { email }
172210 onChange = { ( e ) => setEmail ( e . target . value ) }
173- placeholder = "lbene17@gmail.com"
211+ placeholder = "benevanio@dev.com.br"
212+ disabled = { isLoading }
174213 className = { `w-full px-4 py-3.5 rounded-xl border bg-white/80 dark:bg-neutral-800/80 backdrop-blur-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-neutral-500 focus:outline-none focus:ring-2 transition-all shadow-sm ${
175214 emailError ? "border-red-500 focus:ring-red-500" : "border-gray-200 dark:border-neutral-700 focus:ring-blue-500 focus:border-transparent"
176- } `}
215+ } ${ isLoading ? "opacity-50 cursor-not-allowed" : "" } `}
177216 />
178217 { emailError && < p className = "mt-1.5 text-xs text-red-500 font-medium" > { emailError } </ p > }
179218 </ div >
@@ -184,12 +223,13 @@ export default function RegisterSide() {
184223 </ label >
185224 < div className = { `flex rounded-xl border bg-white/80 dark:bg-neutral-800/80 backdrop-blur-sm shadow-sm overflow-hidden transition-all focus-within:ring-2 ${
186225 telefoneError ? "border-red-500 focus-within:ring-red-500" : "border-gray-200 dark:border-neutral-700 focus-within:ring-blue-500"
187- } `} >
226+ } ${ isLoading ? "opacity-50" : "" } `} >
188227 < PhoneInput
189228 international
190229 defaultCountry = "BR"
191230 value = { telefone }
192231 onChange = { setTelefone }
232+ disabled = { isLoading }
193233 className = "w-full px-4 py-3.5 text-gray-900 dark:text-white bg-transparent focus:outline-none phone-input-custom"
194234 placeholder = "(34) 23456-7890"
195235 />
@@ -208,13 +248,15 @@ export default function RegisterSide() {
208248 value = { password }
209249 onChange = { ( e ) => setPassword ( e . target . value ) }
210250 placeholder = "Ex: ••••••••••••"
251+ disabled = { isLoading }
211252 className = { `w-full px-4 py-3.5 rounded-xl border bg-white/80 dark:bg-neutral-800/80 backdrop-blur-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-neutral-500 focus:outline-none focus:ring-2 transition-all shadow-sm ${
212253 passwordError ? "border-red-500 focus:ring-red-500" : "border-gray-200 dark:border-neutral-700 focus:ring-blue-500 focus:border-transparent"
213- } `}
254+ } ${ isLoading ? "opacity-50 cursor-not-allowed" : "" } `}
214255 />
215256 < button
216257 type = "button"
217258 onClick = { handleRevealPassword }
259+ disabled = { isLoading }
218260 className = "absolute inset-y-0 right-0 pr-4 flex items-center text-gray-400 dark:text-neutral-500 hover:text-blue-500 dark:hover:text-blue-400 transition-colors"
219261 >
220262 { showPassword ? < EyeOff className = "h-5 w-5" /> : < Eye className = "h-5 w-5" /> }
@@ -225,29 +267,31 @@ export default function RegisterSide() {
225267
226268 < div >
227269 < label htmlFor = "cpf" className = "block text-sm font-semibold text-gray-700 dark:text-neutral-300 mb-1.5" >
228- CPF
270+ CPF < span className = "text-gray-400 dark:text-neutral-500 text-xs font-normal" > (opcional) </ span >
229271 </ label >
230272 < input
231273 id = "cpf"
232274 type = "text"
233275 value = { cpf }
234276 onChange = { ( e ) => setCpf ( formatCpf ( e . target . value ) ) }
235277 placeholder = "091.000.000-00"
278+ disabled = { isLoading }
236279 className = { `w-full px-4 py-3.5 rounded-xl border bg-white/80 dark:bg-neutral-800/80 backdrop-blur-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-neutral-500 focus:outline-none focus:ring-2 transition-all shadow-sm ${
237280 cpfError ? "border-red-500 focus:ring-red-500" : "border-gray-200 dark:border-neutral-700 focus:ring-blue-500 focus:border-transparent"
238- } `}
281+ } ${ isLoading ? "opacity-50 cursor-not-allowed" : "" } `}
239282 />
240283 { cpfError && < p className = "mt-1.5 text-xs text-red-500 font-medium" > { cpfError } </ p > }
241284 </ div >
242285
243286 < motion . button
244287 type = "submit"
245- whileHover = { { scale : 1.01 } }
246- whileTap = { { scale : 0.99 } }
247- className = "w-full bg-gradient-to-r from-blue-600 via-purple-600 to-teal-600 hover:opacity-95 text-white py-3.5 px-4 rounded-xl font-bold text-base focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all shadow-md shadow-blue-500/10 cursor-pointer"
288+ disabled = { isLoading }
289+ whileHover = { { scale : isLoading ? 1 : 1.01 } }
290+ whileTap = { { scale : isLoading ? 1 : 0.99 } }
291+ className = "w-full bg-gradient-to-r from-blue-600 via-purple-600 to-teal-600 hover:opacity-95 text-white py-3.5 px-4 rounded-xl font-bold text-base focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all shadow-md shadow-blue-500/10 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
248292 >
249- Cadastrar
250- </ motion . button >
293+ { isLoading ? "Cadastrando..." : " Cadastrar" }
294+ </ motion . button >
251295 </ form >
252296
253297 < div className = "relative z-10 w-full max-w-2xl mx-auto" >
@@ -260,15 +304,14 @@ export default function RegisterSide() {
260304 </ div >
261305 </ div >
262306
263- { /* Botões Sociais Atualizados com Hover translúcido e bordas combinando */ }
264307 < div className = "grid grid-cols-3 gap-4" >
265- < button className = "flex justify-center items-center py-3 px-4 border border-gray-200 dark:border-neutral-800 rounded-xl bg-white/50 dark:bg-neutral-800/50 hover:bg-gray-50 dark:hover:bg-neutral-700/50 transition-all shadow-sm cursor-pointer" >
308+ < button type = "button" disabled = { isLoading } className = "flex justify-center items-center py-3 px-4 border border-gray-200 dark:border-neutral-800 rounded-xl bg-white/50 dark:bg-neutral-800/50 hover:bg-gray-50 dark:hover:bg-neutral-700/50 transition-all shadow-sm cursor-pointer disabled:opacity-50 " >
266309 < Image src = "/google.png" alt = "Google" width = { 20 } height = { 20 } className = "object-contain" />
267310 </ button >
268- < button className = "flex justify-center items-center py-3 px-4 border border-gray-200 dark:border-neutral-800 rounded-xl bg-white/50 dark:bg-neutral-800/50 hover:bg-gray-50 dark:hover:bg-neutral-700/50 transition-all shadow-sm cursor-pointer" >
311+ < button type = "button" disabled = { isLoading } className = "flex justify-center items-center py-3 px-4 border border-gray-200 dark:border-neutral-800 rounded-xl bg-white/50 dark:bg-neutral-800/50 hover:bg-gray-50 dark:hover:bg-neutral-700/50 transition-all shadow-sm cursor-pointer disabled:opacity-50 " >
269312 < Image src = "/facebook.png" alt = "Facebook" width = { 20 } height = { 20 } className = "object-contain" />
270313 </ button >
271- < button className = "flex justify-center items-center py-3 px-4 border border-gray-200 dark:border-neutral-800 rounded-xl bg-white/50 dark:bg-neutral-800/50 hover:bg-gray-50 dark:hover:bg-neutral-700/50 transition-all shadow-sm cursor-pointer" >
314+ < button type = "button" disabled = { isLoading } className = "flex justify-center items-center py-3 px-4 border border-gray-200 dark:border-neutral-800 rounded-xl bg-white/50 dark:bg-neutral-800/50 hover:bg-gray-50 dark:hover:bg-neutral-700/50 transition-all shadow-sm cursor-pointer disabled:opacity-50 " >
272315 < svg className = "h-5 w-5 fill-gray-900 dark:fill-white transition-colors" viewBox = "0 0 24 24" >
273316 < path d = "M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M15.97 4.17c.66-.81 1.11-1.93.99-3.06-1 .04-2.21.67-2.93 1.49-.62.69-1.16 1.84-1.01 2.96 1.12.09 2.27-.58 2.95-1.39z" />
274317 </ svg >
@@ -278,4 +321,4 @@ export default function RegisterSide() {
278321
279322 </ main >
280323 ) ;
281- }
324+ }
0 commit comments