Backup: 2025-06-08 00:29 - User and admin online ready for dockerhub
[Restore from backup: vip-coordinator-backup-2025-06-08-00-29-user and admin online ready for dockerhub]
This commit is contained in:
@@ -1,57 +1,68 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
|
||||
import { apiCall } from './config/api';
|
||||
import { apiCall } from './utils/api';
|
||||
import VipList from './pages/VipList';
|
||||
import VipDetails from './pages/VipDetails';
|
||||
import DriverList from './pages/DriverList';
|
||||
import DriverDashboard from './pages/DriverDashboard';
|
||||
import Dashboard from './pages/Dashboard';
|
||||
import AdminDashboard from './pages/AdminDashboard';
|
||||
import PendingApproval from './pages/PendingApproval';
|
||||
import UserManagement from './components/UserManagement';
|
||||
import Login from './components/Login';
|
||||
import OAuthCallback from './components/OAuthCallback';
|
||||
import './App.css';
|
||||
import { User } from './types';
|
||||
|
||||
function App() {
|
||||
const [user, setUser] = useState<any>(null);
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Check if user is already authenticated
|
||||
const token = localStorage.getItem('authToken');
|
||||
if (token) {
|
||||
const savedUser = localStorage.getItem('user');
|
||||
|
||||
if (token && savedUser) {
|
||||
// Use saved user data for faster initial load
|
||||
setUser(JSON.parse(savedUser));
|
||||
setLoading(false);
|
||||
|
||||
// Then verify with server
|
||||
apiCall('/auth/me', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
if (res.ok) {
|
||||
return res.json();
|
||||
.then(({ data }) => {
|
||||
if (data) {
|
||||
setUser(data as User);
|
||||
localStorage.setItem('user', JSON.stringify(data));
|
||||
} else {
|
||||
// Token is invalid, remove it
|
||||
localStorage.removeItem('authToken');
|
||||
throw new Error('Invalid token');
|
||||
localStorage.removeItem('user');
|
||||
setUser(null);
|
||||
}
|
||||
})
|
||||
.then(userData => {
|
||||
setUser(userData);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Auth check failed:', error);
|
||||
setLoading(false);
|
||||
localStorage.removeItem('authToken');
|
||||
localStorage.removeItem('user');
|
||||
setUser(null);
|
||||
});
|
||||
} else {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleLogin = (userData: any) => {
|
||||
const handleLogin = (userData: User) => {
|
||||
setUser(userData);
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
localStorage.removeItem('authToken');
|
||||
localStorage.removeItem('user');
|
||||
setUser(null);
|
||||
// Optionally call logout endpoint
|
||||
apiCall('/auth/logout', { method: 'POST' })
|
||||
@@ -71,13 +82,52 @@ function App() {
|
||||
|
||||
// Handle OAuth callback route even when not logged in
|
||||
if (window.location.pathname === '/auth/callback' || window.location.pathname === '/auth/google/callback') {
|
||||
return <Login onLogin={handleLogin} />;
|
||||
return (
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="*" element={<OAuthCallback />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return <Login onLogin={handleLogin} />;
|
||||
}
|
||||
|
||||
// Check if user is pending approval
|
||||
if (user.role !== 'administrator' && (!user.status || user.status === 'pending')) {
|
||||
return (
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="*" element={<PendingApproval />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
// Check if user is deactivated
|
||||
if (user.status === 'deactivated') {
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center p-4">
|
||||
<div className="bg-white rounded-2xl shadow-xl max-w-md w-full p-8 text-center">
|
||||
<div className="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg className="w-8 h-8 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-slate-800 mb-2">Account Deactivated</h1>
|
||||
<p className="text-slate-600 mb-6">
|
||||
Your account has been deactivated. Please contact an administrator for assistance.
|
||||
</p>
|
||||
<button onClick={handleLogout} className="btn btn-secondary w-full">
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-50">
|
||||
|
||||
Reference in New Issue
Block a user