Skip to content

Commit

Permalink
Refactor authentication components to improve structure and styling, …
Browse files Browse the repository at this point in the history
…including form handling for login, signup, and logout
  • Loading branch information
upayanmazumder committed Nov 28, 2024
1 parent c2f1da8 commit 5939c6e
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 149 deletions.
31 changes: 26 additions & 5 deletions app/src/components/auth/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,49 @@ import styles from './auth.module.css';

const Auth = () => {
const [user, setUser] = useState(null);
const [showLogin, setShowLogin] = useState(true); // Control which form to display

useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
});

// Cleanup the subscription when the component is unmounted
return () => unsubscribe();
}, []);

return (
<div className={styles.authContainer}>
{user ? (
<div>
<h2>Welcome, {user.email}</h2>
<p>You are already signed in.</p>
<h2 className={styles.authHeader}>Welcome, {user.email}</h2>
<p className={styles.authMessage}>
You are already signed in.
</p>
<br />
<Logout />
</div>
) : (
<div>
<Login />
<Signup />
<h2 className={styles.authHeader}>
{showLogin ? 'Login' : 'Signup'}
</h2>
<div className={styles.toggleContainer}>
<button
className={`${styles.button} ${showLogin ? styles.active : ''}`}
onClick={() => setShowLogin(true)}
>
Login
</button>
<button
className={`${styles.button} ${!showLogin ? styles.active : ''}`}
onClick={() => setShowLogin(false)}
>
Signup
</button>
</div>
<div className={styles.authForm}>
{showLogin ? <Login /> : <Signup />}
</div>
</div>
)}
</div>
Expand Down
179 changes: 105 additions & 74 deletions app/src/components/auth/auth.module.css
Original file line number Diff line number Diff line change
@@ -1,122 +1,153 @@

/* Container for both Login and Signup forms */
.authContainer {
max-width: 420px;
width: 100%;
padding: 40px;
background: linear-gradient(135deg, #1a1a1a, #333);

--primary-bg: #0d1117;
--primary-accent: #1f6feb;
--secondary-accent: #58a6ff;
--text-primary: #c9d1d9;
--text-secondary: #8b949e;
--error-color: #ff7b72;
--success-color: #56d364;
--button-hover: #30363d;


display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 20px auto;
padding: 20px;
max-width: 95%;
width: 400px;
background-color: var(--primary-bg);
border-radius: 12px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.4);
transform: translateY(-20px);
animation: slideIn 0.5s ease-out;
}

@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-50px);
}
to {
opacity: 1;
transform: translateY(0);
}
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
animation: fadeIn 0.5s ease-in-out;
}

/* Header styles */
.authHeader {
color: #0e52a0;
font-size: 2rem;
font-size: 24px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 20px;
text-align: center;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 2px;
animation: fadeInText 1s ease-in-out;
}

@keyframes fadeInText {
0% { opacity: 0; }
100% { opacity: 1; }
.authMessage {
font-size: 16px;
color: var(--text-secondary);
margin-top: 15px;
text-align: center;
}

.success {
color: var(--success-color);
}

.error {
color: var(--error-color);
}

/* Form container styling */
.authForm {
display: flex;
flex-direction: column;
gap: 20px;
gap: 15px;
width: 100%;
}

.authForm label {
font-size: 14px;
color: var(--text-secondary);
}

.authForm input {
padding: 12px;
border: 2px solid #333;
border-radius: 8px;
background-color: #1c1c1c;
color: #fff;
font-size: 1rem;
transition: all 0.3s ease;
padding: 10px;
font-size: 14px;
color: var(--text-primary);
background-color: #161b22;
border: 1px solid var(--primary-accent);
border-radius: 6px;
outline: none;
transition: all 0.3s ease-in-out;
}

.authForm input:focus {
border-color: #0e52a0;
outline: none;
background-color: #121212;
border-color: var(--secondary-accent);
box-shadow: 0 0 4px var(--secondary-accent);
}

.authForm button {
padding: 14px;
background-color: #0e52a0;
color: white;
padding: 12px 0;
font-size: 14px;
font-weight: 600;
color: #fff;
background-color: var(--primary-accent);
border: none;
border-radius: 8px;
font-size: 1.1rem;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
transform: translateY(0);
transition: all 0.3s ease-in-out;
}

.authForm button:hover {
background-color: #0c65ca;
transform: translateY(-2px);
background-color: var(--secondary-accent);
}

.authForm button:active {
transform: translateY(0);
.toggleContainer {
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: 15px;
}

/* Success and error message styling */
.authMessage {
.button {
flex: 1;
padding: 10px 0;
margin: 0 5px;
font-size: 14px;
font-weight: 600;
text-align: center;
font-size: 1rem;
opacity: 0;
animation: fadeInMessage 1s ease-in-out forwards;
}

@keyframes fadeInMessage {
0% { opacity: 0; }
100% { opacity: 1; }
border: 1px solid var(--primary-accent);
border-radius: 6px;
background: transparent;
color: var(--primary-accent);
cursor: pointer;
transition: all 0.3s ease-in-out;
}

.success {
color: #00bcd4;
.button:hover {
background-color: var(--button-hover);
color: var(--secondary-accent);
}

.error {
color: #f44336;
.active {
background-color: var(--primary-accent);
color: #fff;
border: none;
}

/* Mobile responsiveness */
@media (max-width: 600px) {
@media (max-width: 768px) {
.authContainer {
padding: 20px;
width: 100%;
padding: 15px;
}

.authHeader {
font-size: 1.6rem;
font-size: 20px;
}

.button {
font-size: 13px;
}
}

.authForm input,
.authForm button {
font-size: 0.9rem;
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

53 changes: 24 additions & 29 deletions app/src/components/auth/login/login.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,48 @@
'use client';

import React, { useState } from "react";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../../../../shared/firebase";
import React, { useState } from 'react';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../../../../shared/firebase';
import styles from '../auth.module.css';

const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [success, setSuccess] = useState(false);

const handleLogin = async (e) => {
e.preventDefault();
setError("");
setError('');
setSuccess(false);

try {
const userCredential = await signInWithEmailAndPassword(auth, email, password);
console.log("User logged in:", userCredential.user);
console.log('User logged in:', userCredential.user);
setSuccess(true);
} catch (err) {
console.error("Error logging in:", err);
console.error('Error logging in:', err);
setError(err.message);
}
};

return (
<div className={styles.authContainer}>
<h2 className={styles.authHeader}>Login</h2>
<div>
<form className={styles.authForm} onSubmit={handleLogin}>
<div>
<label>Email:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
<label>Email:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<label>Password:</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
<button type="submit">Login</button>
</form>
{success && <p className={`${styles.authMessage} ${styles.success}`}>Login successful!</p>}
Expand Down
Loading

0 comments on commit 5939c6e

Please sign in to comment.