Skip to content

Commit f950b49

Browse files
committed
update validations login and register and other fixes
1 parent 3eb6aab commit f950b49

File tree

6 files changed

+367
-199
lines changed

6 files changed

+367
-199
lines changed

src/components/LikeButtonRounded.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import { PiHeartStraight, PiHeartStraightFill } from "react-icons/pi";
33
import "../animations/LikeButtonRounded.css";
4+
import { AuthContext } from "../context/authContext";
45

56
export const LikeButtonRounded = ({
67
liked,
@@ -33,4 +34,4 @@ export const LikeButtonRounded = ({
3334
)}
3435
</button>
3536
);
36-
};
37+
};

src/features/auth/login.jsx

Lines changed: 172 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,180 @@
1-
import logo from '../../assets/Codepply-Logotype-gradient.svg'
2-
import { useContext, useEffect, useState } from 'react'
3-
import { useForm } from 'react-hook-form';
4-
import { Link, useLocation } from 'react-router';
5-
import { AuthContext } from '../../context/authContext';
1+
import logo from "../../assets/Codepply-Logotype-gradient.svg";
2+
import { useContext, useEffect, useState } from "react";
3+
import { useForm } from "react-hook-form";
4+
import { Link, useLocation } from "react-router";
5+
import { AuthContext } from "../../context/authContext";
66
import { useNavigate } from "react-router";
7-
import { loginUser } from '../../services/authService';
7+
import { loginUser } from "../../services/authService";
88
import { ForgotPasswordModal } from "./ForgotPasswordModal";
99

1010
export const Login = () => {
11-
const { register,
12-
watch,
13-
handleSubmit,
14-
formState: { errors } } = useForm();
15-
const navigate = useNavigate();
16-
const location = useLocation();
17-
const { setToken,profile } = useContext(AuthContext);
18-
19-
const login = async () => {
20-
const resp = await loginUser(watch('email'), watch('password'));
21-
localStorage.setItem('token', resp.token);
22-
setToken(resp.token); // Esto dispara el efecto en el contexto
23-
};
24-
25-
const [showForgotModal, setShowForgotModal] = useState(false);
26-
27-
const handleOpenModal = () => {
28-
setShowForgotModal(true);
29-
};
30-
31-
// Cuando el profile se carga, redirigimos
32-
useEffect(() => {
33-
if (profile) {
34-
const from = location.state?.from;
35-
if (from) {
36-
navigate(from, { replace: true });
37-
} else if (profile.role.type === 'developer') {
38-
navigate(`/profile/${profile._id}`, { replace: true });
39-
} else {
40-
navigate(`/recruiter/${profile._id}`, { replace: true });
41-
}
11+
const {
12+
register,
13+
watch,
14+
handleSubmit,
15+
setError,
16+
clearErrors,
17+
formState: { errors },
18+
} = useForm();
19+
const navigate = useNavigate();
20+
const location = useLocation();
21+
const { setToken, profile } = useContext(AuthContext);
22+
23+
const [loginError, setLoginError] = useState("");
24+
const [showForgotModal, setShowForgotModal] = useState(false);
25+
26+
const email = watch("email");
27+
const password = watch("password");
28+
29+
const login = async () => {
30+
setLoginError("");
31+
32+
let hasEmpty = false;
33+
if (!email) {
34+
setError("email", {
35+
type: "required",
36+
message: "Este campo es requerido",
37+
});
38+
hasEmpty = true;
39+
}
40+
if (!password) {
41+
setError("password", {
42+
type: "required",
43+
message: "This field is required",
44+
});
45+
hasEmpty = true;
46+
}
47+
48+
if (hasEmpty) return;
49+
50+
try {
51+
const resp = await loginUser(email, password);
52+
localStorage.setItem("token", resp.token);
53+
setToken(resp.token);
54+
setLoginError("");
55+
} catch {
56+
setLoginError("Incorrect email or password");
4257
}
43-
}, [profile]);
44-
45-
return (
46-
<div className="flex items-center justify-center px-4 mt-32 mb-56">
47-
<div className="card w-full max-w-md bg-neutral-80 shadow-2xl border-1 border-neutral-60">
48-
49-
<div className="card-body">
50-
<h2 className="text-2xl font-bold text-center mb-4 mt-4">Login Account </h2>
51-
52-
<form onSubmit={handleSubmit(login)} className="space-y-3">
53-
<div className="form-control">
54-
<label className="label">
55-
<span className="label-text text-neutral-20">Email</span>
56-
</label>
57-
<input
58-
type="text"
59-
placeholder="Your email"
60-
className="input input-bordered input-md w-full bg-neutral-60 border-neutral-50"
61-
{...register('email', {
62-
required: {
63-
value: true,
64-
message: 'El campo es requerido'
65-
},
66-
minLength: {
67-
value: 4,
68-
message: 'El campo debe tener al menos 4 caracteres'
69-
}
70-
})}
71-
/>
72-
{
73-
errors.name && <p style={{ color: 'red' }}>{errors.name.message}</p>
74-
}
75-
</div>
76-
77-
<div className="form-control">
78-
<label className="label">
79-
<span className="label-text text-neutral-20">Password</span>
80-
</label>
81-
<input
82-
{...register('password')}
83-
type="password"
84-
placeholder="Your password"
85-
className="input input-bordered input-md w-full bg-neutral-60 border-neutral-50"
86-
/>
87-
</div>
88-
<div className="flex justify-end">
89-
<label className="label">
90-
<button
91-
type="button"
92-
onClick={handleOpenModal}
93-
className="label-text text-neutral-20 hover:underline">
94-
Forgot password?
95-
</button>
96-
</label>
97-
98-
<ForgotPasswordModal open={showForgotModal} setOpen={setShowForgotModal} />
99-
</div>
100-
101-
<div className="form-control mt-6">
102-
<button className="btn bg-gradient-to-r from-primary-60 to-secondary-60 w-full text-lg text-neutral-0 font-semibold tracking-wide hover:bg-primary-70">
103-
Log in
104-
</button>
105-
</div>
106-
</form>
107-
108-
109-
110-
<p className="text-sm text-center mt-2">
111-
Don't have an account yet?{' '}
112-
<Link to={'/register'} className="text-primary-50 hover:underline">Sign Up</Link>
113-
</p>
114-
<img
115-
src={logo}
116-
alt="Codepply Logo"
117-
className="h-6 mx-auto mt-8"
118-
/>
119-
<small className="text-[11px] text-neutral-30 text-center block mt-1">
120-
Codepply Spain ® 2025
121-
</small>
122-
123-
</div>
58+
};
59+
60+
const handleOpenModal = () => {
61+
setShowForgotModal(true);
62+
};
63+
64+
useEffect(() => {
65+
if (email) clearErrors("email");
66+
if (password) clearErrors("password");
67+
if (email || password) setLoginError("");
68+
}, [email, password, clearErrors, setLoginError]);
69+
70+
useEffect(() => {
71+
if (!profile) return;
72+
73+
const from = location.state?.from;
74+
if (from) {
75+
navigate(from, { replace: true });
76+
} else if (profile?.role?.type === "developer") {
77+
navigate(`/profile/${profile._id}`, { replace: true });
78+
} else {
79+
navigate(`/recruiter/${profile._id}`, { replace: true });
80+
}
81+
}, [profile, location, navigate]);
82+
83+
const hasLoginError = loginError !== "";
84+
85+
return (
86+
<div className="flex items-center justify-center px-4 mt-32 mb-56">
87+
<div className="card w-full max-w-md bg-neutral-80 shadow-2xl border-1 border-neutral-60">
88+
<div className="card-body">
89+
<h2 className="text-2xl font-bold text-center mb-4 mt-4">
90+
Login Account
91+
</h2>
92+
93+
<form onSubmit={handleSubmit(login)} className="space-y-3">
94+
<div className="form-control">
95+
<label className="label">
96+
<span className="label-text text-neutral-20">Email</span>
97+
</label>
98+
<input
99+
type="text"
100+
placeholder="Your email"
101+
className={`input input-bordered input-md w-full bg-neutral-60 ${
102+
errors.email || hasLoginError
103+
? "border-red-500"
104+
: "border-neutral-50"
105+
}`}
106+
{...register("email")}
107+
/>
108+
{errors.email && (
109+
<p className="text-sm text-red-500 mt-1">
110+
{errors.email.message}
111+
</p>
112+
)}
113+
</div>
114+
115+
<div className="form-control">
116+
<label className="label">
117+
<span className="label-text text-neutral-20">Password</span>
118+
</label>
119+
<input
120+
type="password"
121+
placeholder="Your password"
122+
className={`input input-bordered input-md w-full bg-neutral-60 ${
123+
errors.password || hasLoginError
124+
? "border-red-500"
125+
: "border-neutral-50"
126+
}`}
127+
{...register("password")}
128+
/>
129+
{errors.password && (
130+
<p className="text-sm text-red-500 mt-1">
131+
{errors.password.message}
132+
</p>
133+
)}
124134
</div>
135+
136+
{hasLoginError && (
137+
<p className="text-sm text-red-500 text-left mt-2">
138+
{loginError}
139+
</p>
140+
)}
141+
142+
<div className="form-control mt-6">
143+
<button className="btn bg-gradient-to-r from-primary-60 to-secondary-60 w-full text-lg text-neutral-0 font-semibold tracking-wide hover:bg-primary-70">
144+
Log in
145+
</button>
146+
</div>
147+
</form>
148+
149+
<div className="flex justify-center mt-2">
150+
<label className="label text-neutral-0">
151+
Forgot password?
152+
<button
153+
type="button"
154+
onClick={handleOpenModal}
155+
className="text-secondary-30 hover:underline"
156+
>
157+
Click here
158+
</button>
159+
</label>
160+
<ForgotPasswordModal
161+
open={showForgotModal}
162+
setOpen={setShowForgotModal}
163+
/>
164+
</div>
165+
166+
<p className="text-sm text-center">
167+
Don't have an account yet?{" "}
168+
<Link to={"/register"} className="text-primary-50 hover:underline">
169+
Sign Up
170+
</Link>
171+
</p>
172+
<img src={logo} alt="Codepply Logo" className="h-6 mx-auto mt-8" />
173+
<small className="text-[11px] text-neutral-30 text-center block mt-1">
174+
Codepply Spain ® 2025
175+
</small>
125176
</div>
126-
);
177+
</div>
178+
</div>
179+
);
127180
};

0 commit comments

Comments
 (0)