Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solved issue #238 #264

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
<link rel="icon" type="image/svg+xml" href="./src/assets/stationsaarthi.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Station Saarthi</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" /> <style>
/* Style for the Google Translate element */
#google_element {
position: absolute;
Expand Down
19 changes: 17 additions & 2 deletions frontend/src/Pages/LoginPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ const Login = () => {
const [password, setPassword] = useState('');
const [loginSuccess, setLoginSuccess] = useState(false); // State for login success message
const [errors,setErrors] = useState({})
const [passwordVisible, setPasswordVisible] = useState(false); // State for password visibility
const navigate = useNavigate();

const togglePasswordVisibility = () => {
setPasswordVisible(!passwordVisible); // Toggle password visibility
};

const RegisterClick = () => {
navigate('/Register'); // Navigates to the login page
Expand Down Expand Up @@ -93,14 +98,24 @@ const Login = () => {
<div className="mb-6">
<label className="block mb-2 font-semibold text-gray-700" htmlFor="password">Password</label>
<input
type="password"
type={passwordVisible ? "text" : "password"}
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Enter your password"
className="w-full px-4 py-2 transition duration-300 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
/> <button
type="button"
onClick={togglePasswordVisibility}
style={{ position:'relative', bottom:'32px', left:'280px'}}
>
{passwordVisible ? (
<span className="material-symbols-outlined">visibility_off</span> // Closed eye icon
) : (
<span className="material-symbols-outlined">visibility</span> // Open eye icon
)}
</button>
{errors.password && <div className="text-red-800">{errors.password}</div>}
</div>

Expand Down
242 changes: 137 additions & 105 deletions frontend/src/Pages/Register.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useMemo } from "react";
import React, { useState, useEffect } from "react";
import logo from "../assets/stationsaarthi.svg";
import { useNavigate } from "react-router-dom";
import backicon from "../assets/svg/backicon.svg";
Expand All @@ -7,63 +7,35 @@ import { FaFacebook } from "react-icons/fa";
import { jwtDecode } from "jwt-decode";
import { registerValidation } from "../validations/validation";

// Reusable FormInput component
const FormInput = ({
label,
type,
value,
onChange,
placeholder,
pattern,
maxLength,
required,
errorMessage,
}) => (
<div className="mb-4">
<label className="block mb-1 font-medium text-gray-700">{label}</label>
<input
type={type}
value={value}
onChange={onChange}
placeholder={placeholder}
pattern={pattern}
maxLength={maxLength}
className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required={required}
/>
{errorMessage && <p className="text-sm text-red-500">{errorMessage}</p>}
</div>
);

const Register = () => {
useEffect(() => {
document.title = "Station Saarthi | Register";
}, []);

useEffect(() => {
document.title = 'Station Saarthi | Register';
}, []);

const navigate = useNavigate();
const LoginClick = () => navigate("/Login");
const HomeClick = () => navigate("/");

const [formData, setFormData] = useState({
name: "",
phoneNumber: "",
email: "",
password: "",
});

const [username, setUserName] = useState(""); // Changed from name to username
const [phoneNumber, setPhoneNumber] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmationMessage, setConfirmationMessage] = useState("");
const [passwordStrength, setPasswordStrength] = useState(""); // State for password strength feedback
const [errors, setErrors] = useState({});
const [passwordVisible, setPasswordVisible] = useState(false); // State for password visibility

const handleChange = (e) => {
const { id, value } = e.target;
setFormData((prevData) => ({ ...prevData, [id]: value }));
};

const handleRegister = async (e) => {
e.preventDefault();

try {
await registerValidation.validate(formData, { abortEarly: false });
await registerValidation.validate(
{ username, password, phoneNumber, email }, // Updated validation call
{ abortEarly: false }
);
setErrors({});
} catch (error) {
const newErrors = {};
Expand All @@ -82,7 +54,13 @@ const Register = () => {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ ...formData, isGoogle: false }),
body: JSON.stringify({
name: username, // Updated from name to username
phoneNumber: phoneNumber ? phoneNumber : "",
email,
password,
isGoogle: false,
}),
}
);

Expand All @@ -92,8 +70,12 @@ const Register = () => {
setConfirmationMessage(
"Your account is created successfully. Please login to access the website."
);
setFormData({ name: "", phoneNumber: "", email: "", password: "" });
setUserName(""); // Reset username
setPhoneNumber("");
setEmail("");
setPassword("");
} else {
console.log(data.error);
setConfirmationMessage(`Error: ${data.error}`);
}
} catch (error) {
Expand Down Expand Up @@ -127,15 +109,16 @@ const Register = () => {

// Update password strength when password changes
useEffect(() => {
setPasswordStrength(checkPasswordStrength(formData.password));
}, [formData.password]);
setPasswordStrength(checkPasswordStrength(password));
}, [password]);

// Handle Google success
const handleGoogleLoginSuccess = async (credentialResponse) => {
const token = credentialResponse.credential;

// Decode the token to extract user information
const decoded = jwtDecode(token);
console.log("Decoded Google Token:", decoded);

try {
const response = await fetch(
Expand All @@ -147,7 +130,7 @@ const Register = () => {
},
body: JSON.stringify({
name: decoded.name,
phoneNumber: formData.phoneNumber,
phoneNumber: phoneNumber ? phoneNumber : "",
email: decoded.email,
password: "",
isGoogle: true,
Expand All @@ -161,7 +144,10 @@ const Register = () => {
setConfirmationMessage(
"Your account is created successfully. Please login to access the website."
);
setFormData({ name: "", phoneNumber: "", email: "", password: "" });
setUserName(""); // Reset username
setPhoneNumber("");
setEmail("");
setPassword("");
} else {
setConfirmationMessage(`Error: ${data.error}`);
}
Expand All @@ -175,7 +161,9 @@ const Register = () => {
console.log("Google Sign-In failed");
};

const MemoizedFormInput = useMemo(() => FormInput, []);
const togglePasswordVisibility = () => {
setPasswordVisible(!passwordVisible); // Toggle password visibility
};

return (
<>
Expand Down Expand Up @@ -210,65 +198,109 @@ const Register = () => {
Register
</h2>

<MemoizedFormInput
label="Name"
type="text"
value={formData.name}
onChange={handleChange}
placeholder="Enter your name"
required
/>
<div className="mb-4">
<label
className="block mb-1 font-semibold text-gray-700"
htmlFor="username" // Updated id reference
>
Username
</label>
<input
type="text"
id="username" // Updated id reference
value={username}
onChange={(e) => setUserName(e.target.value)} // Updated setter
placeholder="Enter your username"
className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
{errors.username && <div className="text-red-800">{errors.username}</div>}
</div>

<MemoizedFormInput
label="Phone Number"
type="tel"
value={formData.phoneNumber}
onChange={handleChange}
placeholder="Enter your phone number"
pattern="\d{10}"
maxLength="10"
required
errorMessage={
formData.phoneNumber && formData.phoneNumber.length !== 10
? "Please enter a valid 10-digit phone number."
: ""
}
/>
<div className="mb-4">
<label
className="block mb-1 font-medium text-gray-700"
htmlFor="phoneNumber"
>
Phone Number
</label>
<input
type="tel"
id="phoneNumber"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
placeholder="Enter your phone number"
pattern="\d{10}"
maxLength="10"
className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
{errors.phoneNumber && <div className="text-red-800">{errors.phoneNumber}</div>}
</div>

<MemoizedFormInput
label="Email"
type="email"
value={formData.email}
onChange={handleChange}
placeholder="Enter your email"
required
/>
<div className="mb-4">
<label
className="block mb-1 font-medium text-gray-700"
htmlFor="email"
>
Email
</label>
<input
type="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter your email"
className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
{errors.email && <div className="text-red-800">{errors.email}</div>}
</div>

<MemoizedFormInput
label="Password"
type="password"
value={formData.password}
onChange={handleChange}
placeholder="Create a password"
required
/>
<p
className={`mt-1 text-sm ${
passwordStrength === "Strong"
? "text-green-500"
: passwordStrength === "Moderate"
? "text-yellow-500"
: "text-red-500"
}`}
>
{formData.password && `Password strength: ${passwordStrength}`}
</p>
{passwordStrength === "Weak" && (
<p className="text-xs text-gray-500">
Try using a longer password with uppercase letters, numbers, and
symbols for a stronger password.
<div className="mb-5">
<label
className="block mb-1 font-medium text-gray-700"
htmlFor="password"
>
Password
</label>
<input
type={passwordVisible ? "text" : "password"} // Change the type based on password visibility
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Create a password"
className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/> <button
type="button"
onClick={togglePasswordVisibility}
style={{ position:'relative', bottom:'30px', left:'430px'}}
>
{passwordVisible ? (
<span className="material-symbols-outlined">visibility_off</span> // Closed eye icon
) : (
<span className="material-symbols-outlined">visibility</span> // Open eye icon
)}
</button>
<p
className={`mt-1 text-sm ${
passwordStrength === "Strong"
? "text-green-500"
: passwordStrength === "Moderate"
? "text-yellow-500"
: "text-red-500"
}`}
>
{password && `Password strength: ${passwordStrength}`}
</p>
)}
{passwordStrength === "Weak" && (
<p className="text-xs text-gray-500">
Try using a mix of upper/lowercase letters, numbers, and symbols.
</p>
)}
{errors.password && <div className="text-red-800">{errors.password}</div>}
</div>

<button
type="submit"
Expand Down
Loading