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

I have implemented the validation for the new users using firebase. #76

Merged
merged 4 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
44 changes: 23 additions & 21 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// App.js
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Navbar from './components/Navbar';
Expand All @@ -11,36 +12,37 @@ import { AuthProvider } from './context/AuthContext';
import Support from './components/Support';
import Settings from './components/Setting';
import ImageQRCodeGenerator from './components/ImageQRCodeGenerator';
import SocialMedia from './components/SocialMedia';
import SocialMedia from './components/SocialMedia';
import BulkQRCode from './components/BulkQRCode';
import QRScanner from './components/QRScanner';
import PdfQRCodeGenerator from './components/PDFToQR';
import { ThemeProvider } from './context/ThemeContext';
import { Toaster } from 'react-hot-toast';
import ProtectedRoute from './components/ProtectedRoute';

export default function App() {
return (
<AuthProvider>
<ThemeProvider>
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/dashboard" element={<DashboardPage />} />
<Route path="/qr-code" element={<QRCodePage />} />
<Route path="/profile" element={<ProfilePage />} />
<Route path="/support" element={<Support />} />
<Route path="/settings" element={<Settings />} />
<Route path="/image-qr-code" element={<ImageQRCodeGenerator />} />
<Route path="/social-media-qr" element={<SocialMedia />} />
<Route path="/bulk-qr-code" element={<BulkQRCode />} />
<Route path="/qr-scanner" element={<QRScanner />} />
<Route path="/pdf-qr-code" element={<PdfQRCodeGenerator />} />
</Routes>
<Toaster />
</Router>
<Router>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/dashboard" element={<ProtectedRoute><DashboardPage /></ProtectedRoute>} />
<Route path="/qr-code" element={<QRCodePage />} />
<Route path="/profile" element={<ProfilePage />} />
<Route path="/support" element={<Support />} />
<Route path="/settings" element={<Settings />} />
<Route path="/image-qr-code" element={<ImageQRCodeGenerator />} />
<Route path="/social-media-qr" element={<SocialMedia />} />
<Route path="/bulk-qr-code" element={<BulkQRCode />} />
<Route path="/qr-scanner" element={<QRScanner />} />
<Route path="/pdf-qr-code" element={<PdfQRCodeGenerator />} />
{/* Remove the line for Verify */}
{/* <Route path="/verify" element={<Verify />} /> */}
</Routes>
</Router>
</ThemeProvider>
</AuthProvider>
);
Expand Down
40 changes: 30 additions & 10 deletions src/components/Login.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,56 @@


import React, { useState } from 'react';
import { signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
import { auth } from '../firebase';
import { useNavigate } from 'react-router-dom';
import { FcGoogle } from "react-icons/fc";
import { motion } from 'framer-motion';
import toast from 'react-hot-toast';
import { useAuth } from "../context/AuthContext";

export default function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const navigate = useNavigate();
const { setCurrentUser } = useAuth(); // Get setCurrentUser from Auth context

const handleSubmit = async (e) => {
e.preventDefault();
try {
await signInWithEmailAndPassword(auth, email, password);
navigate('/dashboard');
toast.success("Login Successful");
const userCredential = await signInWithEmailAndPassword(auth, email, password);
const user = userCredential.user;

// Set currentUser from context
setCurrentUser(user);

// Navigate only if user is verified
if (user.emailVerified) {
navigate('/dashboard');
} else {
alert('Please verify your email before logging in.');
}
} catch (error) {
toast.error('Something went wrong');
console.error(error.message);
alert(error.message);
}
};

const handleGoogleLogin = async () => {
const provider = new GoogleAuthProvider();
try {
await signInWithPopup(auth, provider);
navigate('/dashboard');
const userCredential = await signInWithPopup(auth, provider);
const user = userCredential.user;

// Set currentUser from context
setCurrentUser(user);

// Navigate only if user is verified
if (user.emailVerified) {
navigate('/dashboard');
} else {
alert('Please verify your email before logging in.');
}
} catch (error) {
toast.error('Something went wrong');
console.error(error.message);
alert(error.message);
}
};

Expand Down
114 changes: 37 additions & 77 deletions src/components/Navbar.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

import React, { useState, useEffect, useRef, useContext } from "react";
import { useAuth } from "../context/AuthContext";
import { Link, useNavigate } from "react-router-dom";
import { ThemeContext } from "../context/ThemeContext";
import toast from "react-hot-toast";

import {
FaUser,
Expand All @@ -22,69 +22,17 @@ export default function Navbar() {
const navigate = useNavigate();
const [dropdownOpen, setDropdownOpen] = useState(false);
const dropdownRef = useRef(null);

const { darkMode, setDarkMode } = useContext(ThemeContext);

const handleLogout = async () => {
// Show a confirmation toast
const confirmation = toast(
(t) => (
<div>
<p>Are you sure you want to log out?</p>
<div className="flex justify-between">
<button
onClick={() => {
toast.dismiss(t.id); // Dismiss the confirmation toast
}}
className="text-blue-600 hover:bg-blue-200 px-4 py-2 bg-blue-100 m-2 mt-4 rounded-md "
>
Cancel
</button>
<button
onClick={async () => {
toast.dismiss(t.id); // Dismiss the confirmation toast
try {
await logout(); // Proceed with logout
navigate("/"); // Redirect to the home page after logout
toast.success("Logged out");
} catch (error) {
console.error("Failed to log out", error);
toast.error("Logout failed. Please try again."); // Show an error message
}
}}
className="text-red-600 hover:bg-red-200 px-4 py-2 bg-red-100 m-2 mt-4 rounded-md "
>
Log out
</button>
</div>
</div>
),
{
duration: 0, // Keep the toast open until dismissed
position: 'top-center', // Adjust position if needed
}
)
};

const handleToggleTheme = () => {
setDarkMode((prevMode) => {
const newMode = !prevMode;

// Show toast notification when theme changes
toast(`Theme changed to ${newMode ? 'Dark' : 'Light'} mode!`, {
icon: `${newMode ? '🌙' :'☀️'}`,
style: {
borderRadius: '10px',
background: `${newMode ? '#333' : '#fff'} `,
color: `${newMode ? '#fff' : '#333'}`,
},
});

return newMode;
});
try {
await logout();
navigate("/"); // Redirect to the home page after logout
} catch (error) {
console.error("Failed to log out", error);
}
};


const toggleDropdown = () => {
setDropdownOpen(!dropdownOpen);
};
Expand All @@ -105,10 +53,11 @@ export default function Navbar() {

return (
<nav
className={`p-4 shadow-lg ${darkMode
className={`p-4 shadow-lg ${
darkMode
? "bg-[#00050e] border-b-[1px] border-[#333333]"
: "bg-gradient-to-r from-indigo-600 to-purple-600"
}`}
}`}
>
<div className="container mx-auto flex justify-between items-center">
<div className="flex items-center space-x-3">
Expand Down Expand Up @@ -150,13 +99,15 @@ export default function Navbar() {
<div className="relative" ref={dropdownRef}>
{dropdownOpen && (
<div className="absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded-md shadow-lg py-2 z-20">
<Link
to="/dashboard"
className="flex items-center px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300"
>
<FaUser className="mr-2" />
Dashboard
</Link>
{currentUser.emailVerified && ( // Check if the user is verified
<Link
to="/dashboard"
className="flex items-center px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300"
>
<FaUser className="mr-2" />
Dashboard
</Link>
)}
<Link
to="/profile"
className="flex items-center px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300"
Expand All @@ -183,7 +134,9 @@ export default function Navbar() {
</div>
</div>
<button
onClick={handleToggleTheme}
onClick={() => {
setDarkMode(!darkMode);
}}
className="text-white hover:text-indigo-200 transition duration-300 text-xl"
>
{darkMode ? <MdLightMode /> : <FaMoon />}
Expand Down Expand Up @@ -220,13 +173,15 @@ export default function Navbar() {
<div className="md:hidden mt-2 w-full bg-white dark:bg-gray-800 rounded-md shadow-lg py-2 z-20">
{currentUser ? (
<>
<Link
to="/dashboard"
className="flex items-center px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300"
>
<FaUser className="mr-2" />
Dashboard
</Link>
{currentUser.emailVerified && ( // Check if the user is verified
<Link
to="/dashboard"
className="flex items-center px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300"
>
<FaUser className="mr-2" />
Dashboard
</Link>
)}
<Link
to="/profile"
className="flex items-center px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300"
Expand All @@ -249,7 +204,9 @@ export default function Navbar() {
Logout
</button>
<button
onClick={() => { setDarkMode(!darkMode); }}
onClick={() => {
setDarkMode(!darkMode);
}}
className="flex items-center gap-2 px-4 py-2 text-gray-700 dark:text-white hover:bg-indigo-500 hover:text-white transition duration-300 w-full"
>
{darkMode ? <MdLightMode size={16} /> : <FaMoon size={10} />} Toggle Dark Mode
Expand Down Expand Up @@ -278,3 +235,6 @@ export default function Navbar() {
</nav>
);
}



36 changes: 36 additions & 0 deletions src/components/ProtectedRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@


import React, { useEffect, useState } from 'react';
import { Navigate } from 'react-router-dom';
import { auth, onAuthStateChanged } from '../firebase'; // Ensure the correct import

const ProtectedRoute = ({ children }) => {
const [loading, setLoading] = useState(true);
const [isAuthorized, setIsAuthorized] = useState(false);

useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
// Check if the user has verified their email
setIsAuthorized(user.emailVerified);
} else {
setIsAuthorized(false);
}
setLoading(false);
});

return () => unsubscribe();
}, []);

if (loading) {
return <div>Loading...</div>; // Show loading indicator while checking auth
}

if (!isAuthorized) {
return <Navigate to="/login" />;
}

return children;
};

export default ProtectedRoute;
Loading
Loading