no separate login/register page, use modal throughout
This commit is contained in:
41
frontend/src/components/AuthButton.tsx
Normal file
41
frontend/src/components/AuthButton.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
|
||||
interface AuthButtonProps {
|
||||
mode: 'login' | 'signup';
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
asLink?: boolean;
|
||||
}
|
||||
|
||||
const AuthButton: React.FC<AuthButtonProps> = ({ mode, className = '', children, asLink = false }) => {
|
||||
const { openAuthModal } = useAuth();
|
||||
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
openAuthModal(mode);
|
||||
};
|
||||
|
||||
if (asLink) {
|
||||
return (
|
||||
<a
|
||||
href="#"
|
||||
onClick={handleClick}
|
||||
className={className}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={handleClick}
|
||||
className={className}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default AuthButton;
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useRef, useCallback } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import PasswordStrengthMeter from "./PasswordStrengthMeter";
|
||||
import PasswordInput from "./PasswordInput";
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import React, { useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import AuthModal from "./AuthModal";
|
||||
|
||||
const Navbar: React.FC = () => {
|
||||
const { user, logout } = useAuth();
|
||||
const { user, logout, openAuthModal } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [showAuthModal, setShowAuthModal] = useState(false);
|
||||
const [authModalMode, setAuthModalMode] = useState<"login" | "signup">(
|
||||
"login"
|
||||
);
|
||||
const [searchFilters, setSearchFilters] = useState({
|
||||
search: "",
|
||||
location: "",
|
||||
@@ -20,11 +15,6 @@ const Navbar: React.FC = () => {
|
||||
navigate("/");
|
||||
};
|
||||
|
||||
const openAuthModal = (mode: "login" | "signup") => {
|
||||
setAuthModalMode(mode);
|
||||
setShowAuthModal(true);
|
||||
};
|
||||
|
||||
const handleSearch = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
const params = new URLSearchParams();
|
||||
@@ -204,12 +194,6 @@ const Navbar: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<AuthModal
|
||||
show={showAuthModal}
|
||||
onHide={() => setShowAuthModal(false)}
|
||||
initialMode={authModalMode}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
import React from 'react';
|
||||
import { Navigate, useLocation } from 'react-router-dom';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import React, { useEffect } from "react";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
interface PrivateRouteProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const PrivateRoute: React.FC<PrivateRouteProps> = ({ children }) => {
|
||||
const { user, loading } = useAuth();
|
||||
const location = useLocation();
|
||||
const { user, loading, openAuthModal } = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && !user) {
|
||||
openAuthModal("login");
|
||||
}
|
||||
}, [loading, user, openAuthModal]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="d-flex justify-content-center align-items-center" style={{ minHeight: '80vh' }}>
|
||||
<div
|
||||
className="d-flex justify-content-center align-items-center"
|
||||
style={{ minHeight: "80vh" }}
|
||||
>
|
||||
<div className="spinner-border text-primary" role="status">
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
@@ -20,7 +27,21 @@ const PrivateRoute: React.FC<PrivateRouteProps> = ({ children }) => {
|
||||
);
|
||||
}
|
||||
|
||||
return user ? <>{children}</> : <Navigate to="/login" state={{ from: location }} replace />;
|
||||
if (!user) {
|
||||
return (
|
||||
<div
|
||||
className="d-flex justify-content-center align-items-center"
|
||||
style={{ minHeight: "80vh" }}
|
||||
>
|
||||
<div className="text-center">
|
||||
<i className="bi bi-lock display-1 text-muted mb-3"></i>
|
||||
<h3>Please log in or sign up to access this page.</h3>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export default PrivateRoute;
|
||||
export default PrivateRoute;
|
||||
|
||||
Reference in New Issue
Block a user