Skip to content

Commit 7317449

Browse files
authored
Merge pull request #54 from FSDSTR0225/dev
Dev
2 parents 239ea9d + c9cc345 commit 7317449

32 files changed

+1085
-387
lines changed

src/components/home/NumbersSection.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export const NumbersSection = () => {
7070
</div>
7171
<div className="flex flex-col items-center">
7272
<span className="text-3xl sm:text-4xl md:text-5xl font-bold text-secondary-50 mb-2 block">+{acceptedApplications * 100}</span>
73-
<span className="text-neutral-20 text-sm md:text-base block">Applications accepted</span>
73+
<span className="text-neutral-20 text-sm md:text-base block">Hired</span>
7474
</div>
7575
</div>
7676
</div>

src/components/home/StackTechnologies.jsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ export const StackTechnologies = () => {
1414
];
1515

1616
const techImages = [
17-
'https://cdn.worldvectorlogo.com/logos/mongodb-icon-2.svg',
18-
'https://cdn.worldvectorlogo.com/logos/react-2.svg',
19-
'https://cdn.worldvectorlogo.com/logos/typescript.svg',
20-
'https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Unofficial_JavaScript_logo_2.svg/1024px-Unofficial_JavaScript_logo_2.svg.png',
21-
'https://cdn.worldvectorlogo.com/logos/python-5.svg',
22-
'https://static.cdnlogo.com/logos/m/88/mysql.svg',
23-
'https://raw.githubusercontent.com/devicons/devicon/ca28c779441053191ff11710fe24a9e6c23690d6/icons/nodejs/nodejs-plain-wordmark.svg',
24-
'https://cdn.worldvectorlogo.com/logos/postgresql.svg'
17+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751453660/mongodb-icon_odsgnz.svg',
18+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751453733/react-icon_urbntl.svg',
19+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751453808/typescript-icon_yeafon.svg',
20+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751453935/javascript-icon_emsenf.png',
21+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751454010/python-icon_quwslf.svg',
22+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751454075/mysql-icon_jnh7zm.svg',
23+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751454113/nodejs-icon_zza7u2.svg',
24+
'https://res.cloudinary.com/djxyqh8fx/image/upload/v1751454149/postgresql-icon_q0tmkq.svg'
2525
];
2626

2727
const techCategories = [

src/components/settings/ChangePasswordModal.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import React, { useEffect } from "react";
22
import { useForm } from "react-hook-form"
3-
import { updateProfile } from "../../services/profileService";
43

54
export default function ChangePasswordModal({ open, setOpen, profileData, onProfileUpdate, onSubmit }) {
65
const {
76
register,
87
handleSubmit,
9-
control,
108
reset,
119
watch,
1210
formState: { isSubmitting }

src/components/settings/RemoveAccountModal.jsx

Lines changed: 46 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,53 @@
11
import React, { useEffect } from "react";
22
import { useForm } from "react-hook-form"
3-
import { updateProfile } from "../../services/profileService";
43

5-
export default function RemoveAccountModal({ open, setOpen, profileData, onProfileUpdate, onSubmit }) {
4+
export default function RemoveAccountModal({ open, setOpen, profileData, onSubmit }) {
5+
66
const {
77
register,
88
handleSubmit,
9-
control,
109
reset,
11-
watch,
12-
formState: { isSubmitting }
10+
formState: { isSubmitting, errors }
1311
} = useForm();
1412

15-
// Observar las contraseñas para validar que coincidan
16-
const newPassword = watch("newPassword");
17-
1813
useEffect(() => {
19-
if (profileData) {
20-
reset({
21-
oldPassword: "",
22-
newPassword: "",
23-
confirmPassword: "",
24-
});
25-
} else {
14+
if (open) {
2615
reset({
27-
oldPassword: "",
28-
newPassword: "",
29-
confirmPassword: "",
16+
email: "",
3017
});
3118
}
32-
}, [profileData, reset]);
19+
}, [open, reset]);
3320

3421
const handleClose = () => {
3522
reset();
3623
setOpen(false);
3724
};
3825

39-
const handlePassSubmit = async (data) => {
26+
const handleDeleteSubmit = async (data) => {
4027
try {
41-
if (data.newPassword !== data.confirmPassword) {
42-
alert("Your new passwords don't match");
28+
// Debug: ver qué emails estamos comparando
29+
console.log("Email ingresado:", data.email);
30+
console.log("Email del perfil:", profileData?.email);
31+
32+
// Verificar que el email coincida con el del usuario
33+
const inputEmail = data.email?.trim().toLowerCase();
34+
const profileEmail = profileData?.email?.trim().toLowerCase();
35+
36+
if (inputEmail !== profileEmail) {
37+
alert(`The email doesn't match your account email. Expected: ${profileData?.email}`);
4338
return;
4439
}
4540

41+
// Llamar a onSubmit (igual que en updatePassword)
4642
if (onSubmit) {
4743
await onSubmit(data);
4844
}
4945

50-
if (onProfileUpdate) {
51-
onProfileUpdate({ password: data.newPassword });
52-
}
53-
5446
handleClose();
55-
47+
5648
} catch (error) {
57-
console.error("Error when you tried change the password: ",error);
49+
console.error("Error when trying to delete account:", error);
50+
alert("Error deleting account. Please try again.");
5851
}
5952
}
6053

@@ -63,60 +56,46 @@ export default function RemoveAccountModal({ open, setOpen, profileData, onProfi
6356
return (
6457
<div className="modal modal-open fixed inset-0 flex justify-center items-center z-50">
6558
<div className="modal-box max-w-3xl bg-neutral-80 border border-neutral-70 rounded-lg p-6 relative">
66-
<form onSubmit={handleSubmit(handlePassSubmit)} className="flex flex-col gap-4">
67-
<h2 className="text-2xl font-bold text-center">Remove your account</h2>
68-
69-
70-
71-
72-
{/*Email*/}
73-
<div className="form-control">
74-
<label className="block text-sm text-neutral-20 mb-1">
75-
<span className="label-text font-semibold">Email</span>
76-
</label>
77-
<input
78-
type="password"
79-
{...register("newPassword", {
80-
required: "Your email is requiered"
81-
})}
82-
placeholder="Enter your email"
83-
className="input input-bordered bg-neutral-90 text-neutral-0 border-neutral-60 w-full placeholder-neutral-40 placeholder:italic"
84-
/>
59+
<form onSubmit={handleSubmit(handleDeleteSubmit)} className="flex flex-col gap-4">
60+
<h2 className="text-2xl font-bold text-center text-red-500">Remove your account</h2>
61+
62+
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
63+
<strong>Warning:</strong> This action cannot be undone. Your account and all associated data will be permanently deleted.
8564
</div>
86-
87-
{/* Password*/}
65+
66+
{/* Email */}
8867
<div className="form-control">
8968
<label className="block text-sm text-neutral-20 mb-1">
90-
<span className="label-text font-semibold">Password</span>
69+
<span className="label-text font-semibold">Confirm your email</span>
9170
</label>
9271
<input
93-
type="password"
94-
{...register("Password", {
95-
required: "Your password is requiered",
96-
validate: value => value === newPassword
72+
type="email"
73+
{...register("email", {
74+
required: "Your email is required"
9775
})}
98-
placeholder="Enter your password"
99-
className="input input-bordered bg-neutral-90 text-neutral-0 border-neutral-60 w-full placeholder-neutral-40 placeholder:italic"
76+
placeholder="Enter your email to confirm"
77+
className="input input-bordered bg-neutral-90 text-neutral-0 border-neutral-60 w-full placeholder-neutral-40 placeholder:italic"
10078
/>
79+
{errors.email && (
80+
<span className="text-red-500 text-sm mt-1">{errors.email.message}</span>
81+
)}
10182
</div>
102-
103-
104-
83+
10584
{/* Buttons */}
10685
<div className="flex justify-end gap-4 pt-4">
10786
<button
108-
type="submit"
109-
disabled={isSubmitting}
110-
className="btn bg-red-600 text-neutral-0 hover:bg-red-500 border "
87+
type="button"
88+
onClick={handleClose}
89+
className="btn bg-neutral-90 border border-neutral-70 text-neutral-0 hover:text-primary-40"
11190
>
112-
{isSubmitting ? "Changing..." : "Remove your account"}
91+
Cancel
11392
</button>
11493
<button
115-
type="button"
116-
onClick={handleClose}
117-
className="btn bg-neutral-90 border border-neutral-70 text-neutral-0 hover:text-primary-40"
94+
type="submit"
95+
disabled={isSubmitting}
96+
className="btn bg-red-600 text-neutral-0 hover:bg-red-700 border"
11897
>
119-
Cancel
98+
{isSubmitting ? "Deleting..." : "Delete Account Permanently"}
12099
</button>
121100
</div>
122101
</form>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { useState } from "react";
2+
import { forgotPassword } from "../../services/authService";
3+
4+
export const ForgotPasswordModal = ({ open, setOpen }) => {
5+
6+
const [email, setEmail] = useState("");
7+
const [message, setMessage] = useState("");
8+
const [isLoading, setIsLoading] = useState(false);
9+
10+
const handleClose = () => {
11+
setEmail("");
12+
setMessage("");
13+
setOpen(false);
14+
};
15+
16+
const handleSendEmail = async () => {
17+
if (!email.trim()) {
18+
setMessage("Please, add your email");
19+
return;
20+
}
21+
22+
setIsLoading(true);
23+
setMessage("");
24+
25+
try {
26+
console.log(email)
27+
const res = await forgotPassword(email);
28+
setMessage(res.message || "Mail Send. Check your inbox.");
29+
setTimeout(() => {
30+
handleClose();
31+
}, 2000);
32+
} catch (error) {
33+
console.error("Error sending email", error?.message);
34+
setMessage(error?.message || "Error sending email");
35+
} finally {
36+
setIsLoading(false);
37+
}
38+
};
39+
40+
if (!open) return null;
41+
42+
return (
43+
<div className="modal modal-open fixed inset-0 flex justify-center items-center z-50 ">
44+
<div className="modal-box max-w-md bg-neutral-80 p-6 relative">
45+
<h2 className="text-2xl font-bold text-center">Recover password</h2>
46+
47+
<div className="form-control">
48+
<label className="block text-sm font-semibold">Email</label>
49+
<input
50+
type="email"
51+
value={email}
52+
onChange={(e) => setEmail(e.target.value)}
53+
placeholder="Enter your email"
54+
className="input input-bordered w-full bg-neutral-60"
55+
required
56+
/>
57+
</div>
58+
59+
{message && (
60+
<p className="text-sm text-start text-secondary-60">{message}</p>
61+
)}
62+
63+
<div className="flex justify-end gap-4 pt-4">
64+
<button
65+
onClick={handleSendEmail}
66+
className="btn bg-primary-60 text-neutral-10 hover:bg-primary-70 w-full md:w-auto"
67+
disabled={isLoading}
68+
>
69+
{isLoading ? "Sending..." : "Send link"}
70+
</button>
71+
<button
72+
type="button"
73+
onClick={handleClose}
74+
className="btn bg-neutral-70 text-neutral-10 hover:bg-neutral-60 border border-neutral-60 w-full md:w-auto"
75+
>
76+
Cancel
77+
</button>
78+
</div>
79+
</div>
80+
</div>
81+
);
82+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { useState } from "react";
2+
import { useParams, useNavigate } from "react-router";
3+
import { resetPassword } from "../../services/authService";
4+
5+
export const ResetPassword = () => {
6+
7+
const { token } = useParams();
8+
const navigate = useNavigate();
9+
10+
const [password, setPassword] = useState("");
11+
const [message, setMessage] = useState("");
12+
const [isSubmitting, setIsSubmitting] = useState(false);
13+
14+
const handleSubmit = async (e) => {
15+
e.preventDefault();
16+
setIsSubmitting(true);
17+
setMessage("");
18+
19+
try {
20+
const res = await resetPassword(token, password);
21+
setMessage(res.msg || "Password updated successfully.");
22+
setTimeout(() => navigate("/login"), 2000);
23+
} catch (err) {
24+
setMessage(err.message);
25+
} finally {
26+
setIsSubmitting(false);
27+
}
28+
};
29+
30+
return (
31+
<div className="min-h-screen flex items-center justify-center bg-neutral-60 px-4">
32+
<div className="bg-neutral-80 shadow-lg rounded-lg p-8 max-w-md w-full">
33+
<h2 className="text-2xl font-bold text-center mb-4">
34+
Reset your Password
35+
</h2>
36+
37+
<form onSubmit={handleSubmit} className="space-y-4">
38+
<input
39+
type="password"
40+
placeholder="New password"
41+
value={password}
42+
onChange={(e) => setPassword(e.target.value)}
43+
required
44+
className="input input-bordered w-full bg-neutral-90"
45+
/>
46+
47+
<button
48+
type="submit"
49+
className="btn bg-primary-60 text-neutral-10 hover:bg-primary-70 w-full"
50+
disabled={isSubmitting}
51+
>
52+
{isSubmitting ? "Saving..." : "Change password"}
53+
</button>
54+
</form>
55+
56+
{message && (
57+
<p className="mt-4 text-center text-sm text-primary-60">{message}</p>
58+
)}
59+
</div>
60+
</div>
61+
);
62+
}

0 commit comments

Comments
 (0)