diff --git a/src/App.js b/src/App.js index e348d88..9aa68b8 100644 --- a/src/App.js +++ b/src/App.js @@ -51,6 +51,7 @@ import ContactUs from './pages/ContactUs'; import TermsOfService from './pages/TermsOfService'; import PrivacyPolicy from './pages/PrivacyPolicy'; import AcceptInvitation from './pages/AcceptInvitation'; +import NotFound from './pages/NotFound'; const PrivateRoute = ({ children, adminOnly = false }) => { const { user, loading } = useAuth(); @@ -280,6 +281,9 @@ function App() { } /> + + {/* 404 - Catch all undefined routes */} + } /> diff --git a/src/pages/AcceptInvitation.js b/src/pages/AcceptInvitation.js index 1825b32..5410c0f 100644 --- a/src/pages/AcceptInvitation.js +++ b/src/pages/AcceptInvitation.js @@ -19,6 +19,8 @@ const AcceptInvitation = () => { const [invitation, setInvitation] = useState(null); const [loading, setLoading] = useState(true); const [submitting, setSubmitting] = useState(false); + const [success, setSuccess] = useState(false); + const [successUser, setSuccessUser] = useState(null); const [error, setError] = useState(null); const [formData, setFormData] = useState({ password: '', @@ -134,19 +136,23 @@ const AcceptInvitation = () => { const { access_token, user } = response.data; localStorage.setItem('token', access_token); - toast.success('Welcome to LOAF! Your account has been created successfully.'); - // Call login to update auth context if (login) { await login(invitation.email, formData.password); } - // Redirect based on role - if (user.role === 'admin' || user.role === 'superadmin') { - navigate('/admin'); - } else { - navigate('/dashboard'); - } + // Show success state + setSuccessUser(user); + setSuccess(true); + + // Auto-redirect after 3 seconds + setTimeout(() => { + if (user.role === 'admin' || user.role === 'superadmin') { + navigate('/admin'); + } else { + navigate('/dashboard'); + } + }, 3000); } catch (error) { const errorMessage = error.response?.data?.detail || 'Failed to accept invitation'; toast.error(errorMessage); @@ -206,6 +212,83 @@ const AcceptInvitation = () => { ); } + if (success) { + const redirectPath = successUser?.role === 'admin' || successUser?.role === 'superadmin' ? '/admin' : '/dashboard'; + + return ( +
+ + {/* Success Animation */} +
+
+ +
+
+ + {/* Success Message */} +

+ Welcome to LOAF! 🎉 +

+

+ Your account has been created successfully. +

+ + {/* User Info Card */} +
+
+
+

+ Name +

+

+ {successUser?.first_name} {successUser?.last_name} +

+
+
+

+ Email +

+

+ {successUser?.email} +

+
+
+

+ Role +

+
{getRoleBadge(successUser?.role)}
+
+
+

+ Status +

+ + {successUser?.status} + +
+
+
+ + {/* Redirect Info */} +
+

+ + Redirecting you to your dashboard in 3 seconds... +

+
+ + {/* Manual Continue Button */} + +
+
+ ); + } + return (
diff --git a/src/pages/NotFound.js b/src/pages/NotFound.js new file mode 100644 index 0000000..21d68b0 --- /dev/null +++ b/src/pages/NotFound.js @@ -0,0 +1,81 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Button } from '../components/ui/button'; +import { Card } from '../components/ui/card'; +import { Home, ArrowLeft, Search } from 'lucide-react'; + +const NotFound = () => { + const navigate = useNavigate(); + + return ( +
+ + {/* 404 Illustration */} +
+
+

+ 404 +

+
+ +
+
+
+ + {/* Message */} +

+ Page Not Found +

+

+ Oops! The page you're looking for doesn't exist. It might have been moved or deleted. +

+ + {/* Action Buttons */} +
+ + +
+ + {/* Help Text */} +
+

+ Need help? Contact us at{' '} + + support@loaftx.org + +

+
+
+
+ ); +}; + +export default NotFound;