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

Modify Navbar #434

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
9 changes: 9 additions & 0 deletions frontend/src/components/Navbar/Navbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,20 @@
}
}
.nav-link {
border-radius: 10px;
padding: 6px 9px;
border: 2px solid #6a6060;
display: inline-block;
text-decoration: none;
position: relative;
vertical-align: bottom;
}
.nav-link:hover{
background-color: #039aff;
color: black;
border: 2px solid black;
}


.nav-link::after {
content: '';
Expand Down
239 changes: 3 additions & 236 deletions frontend/src/components/Signup/Signup.js
Original file line number Diff line number Diff line change
@@ -1,236 +1,3 @@
import React, { useEffect, useState } from "react";
import { useCreateUserWithEmailAndPassword } from "react-firebase-hooks/auth";
import { useNavigate } from "react-router-dom";
import { registerValidation } from "../../validations/validation";
import { auth, signInWithGoogle } from "../Firebase/firebase"; // Import Firebase auth and Google sign-in
import GoogleButton from '../GoogleButton/GoogleButton';
import toast from "react-hot-toast";
import Footer from "../Footer/Footer.js";

function Signup() {
const trustedDomains = ["gmail.com", "yahoo.com", "outlook.com", "icloud.com", "hotmail.com"];
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [error, setError] = useState("");
const [successMessage, setSuccessMessage] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const [errors, setErrors] = useState({});
const [emailError, setEmailError] = useState(""); // State for email validation feedback
const navigate = useNavigate();

const [createUserWithEmailAndPassword, user, loading, firebaseError] =
useCreateUserWithEmailAndPassword(auth);

const handlePasswordVisibility = () => {
setShowPassword(!showPassword);
};

const handleConfirmPasswordVisibility = () => {
setShowConfirmPassword(!showConfirmPassword);
};

useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((currentUser) => {
if (currentUser) {
navigate("/dashboard", { replace: true });
}
});
return () => unsubscribe();
}, [navigate]);

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

// Check email format
if (!regex.test(email)) {
toast.error("Invalid email");
return;
}

// Check email domain
const emailDomain = email.split("@")[1];
if (!trustedDomains.includes(emailDomain)) {
setEmailError("Please use a trusted email provider (Gmail, Yahoo, Outlook, iCloud, Hotmail).");
return;
} else {
setEmailError(""); // Clear error if valid
}

try {
await registerValidation.validate(
{ email, password, confirmPassword },
{ abortEarly: false }
);
setErrors({});
} catch (error) {
const newErrors = {};
error.inner.forEach((err) => {
newErrors[err.path] = err.message;
});

setErrors(newErrors);
return;
}

// Firebase signup
try {
await createUserWithEmailAndPassword(email, password);
setSuccessMessage("Signup successful! Redirecting to login...");
setEmail("");
setPassword("");
setConfirmPassword("");
setTimeout(() => {
navigate("/login");
}, 2000); // Redirect after 2 seconds
} catch (firebaseError) {
setError(firebaseError?.message || "Error signing up.");
}
};

const handleGoogleSignup = async () => {
try {
await signInWithGoogle();
navigate("/dashboard"); // Redirect after successful Google sign-in
} catch (error) {
setError("Error signing in with Google.");
}
};

return (
<>
<style>
{`
.signup-card {
background: linear-gradient(145deg, #f0f0f0, #e6e6e6);
border-radius: 20px;
box-shadow: 0 0 20px rgba(0, 123, 255, 0.3);
transition: all 0.3s ease;
}
.signup-card:hover {
box-shadow: 0 0 30px rgba(0, 123, 255, 0.5);
transform: translateY(-5px);
}
.card-body {
padding: 2rem;
}
`}
</style>
<div className="container mt-5 justify-content-center" style={{ height: "auto" }}>
<div className="row justify-content-center" style={{ width: "100%" }}>
<div className="col-md-6">
<div className="card shadow signup-card">
<div className="card-body">
<h2 className="text-center mb-4">Sign Up</h2>
{error && <div className="alert alert-danger">{error}</div>}
{successMessage && (
<div className="alert alert-success">{successMessage}</div>
)}
{emailError && <div className="alert alert-danger">{emailError}</div>} {/* Email error message */}
<form onSubmit={handleSignup} noValidate>
<div className="mb-3">
<label htmlFor="email" className="form-label">Email:</label>
<input
type="email"
id="email"
className="form-control"
placeholder="Enter your email"
value={email}
onChange={(e) => {
setEmail(e.target.value);
setEmailError(""); // Clear email error on change
}}
/>
{errors.email && <div className="text-danger">{errors.email}</div>}
</div>
<div style={{ position: "relative", width: "100%" }} className="mb-3">
<label htmlFor="password" className="form-label">Password:</label>
<input
type={showPassword ? "text" : "password"}
id="password"
className="form-control"
placeholder="Enter your password"
value={password}
onChange={(e) => setPassword(e.target.value)}
pattern="^(?=.*\d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9])\S{8,}$"
title="Password must contain at least one number, one alphabet, one symbol, and be at least 8 characters long"
required
/>
{errors.password && <div className="text-danger">{errors.password}</div>}
<span
style={{
color: "black",
position: "absolute",
top: "55%",
right: "10px",
backgroundColor: "#fff",
border: "none",
cursor: "pointer",
}}
className="material-symbols-outlined"
onClick={handlePasswordVisibility}
>
{showPassword ? "visibility_off" : "visibility"}
</span>
</div>

<div className="mb-3" style={{ position: "relative", width: "100%" }}>
<label htmlFor="confirmPassword" className="form-label">Confirm Password:</label>
<input
type={showConfirmPassword ? "text" : "password"}
id="confirmPassword"
className="form-control"
placeholder="Confirm your password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
pattern="^(?=.*\d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9])\S{8,}$"
title="Password must contain at least one number, one alphabet, one symbol, and be at least 8 characters long"
required
/>
{errors.confirmPassword && <div className="text-danger">{errors.confirmPassword}</div>}
<span
style={{
color: "black",
position: "absolute",
top: "55%",
right: "10px",
backgroundColor: "#fff",
border: "none",
cursor: "pointer",
}}
className="material-symbols-outlined"
onClick={handleConfirmPasswordVisibility}
>
{showConfirmPassword ? "visibility_off" : "visibility"}
</span>
</div>
<button type="submit" className="btn btn-primary w-100" disabled={loading}>
{loading ? "Signing up..." : "Sign Up"}
</button>
</form>
<div className="text-center mt-3">
<GoogleButton onClick={handleGoogleSignup} />
</div>
<p className="mt-3 text-center">
Already have an account?{" "}
<span
className="text-primary"
style={{ cursor: "pointer" }}
onClick={() => navigate("/login")}
>
Login
</span>
</p>
</div>
</div>
</div>
</div>
<Footer />
</div>
</>
);
}

export default Signup;
version https://git-lfs.github.com/spec/v1
oid sha256:7c0b8b8d06f5718c86683e66c3522cb4d632eac8f164c2a0c89d63748eb063f0
size 9140
49 changes: 3 additions & 46 deletions frontend/src/components/profileCard/ProfileCard.js
Git LFS file not shown
25 changes: 3 additions & 22 deletions frontend/src/index.js
Git LFS file not shown
Loading