Skip to content

Commit

Permalink
Merge pull request #264 from Devanshu1603/main
Browse files Browse the repository at this point in the history
close: #238
  • Loading branch information
dhairyagothi authored Oct 16, 2024
2 parents 61d915c + e29f05c commit 0f3fb48
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 109 deletions.
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

0 comments on commit 0f3fb48

Please sign in to comment.