Backup: 2025-07-21 18:13 - I got Claude Code
Some checks failed
CI/CD Pipeline / Backend Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Tests (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
E2E Tests / E2E Tests - ${{ github.event.inputs.environment || 'staging' }} (push) Has been cancelled
E2E Tests / Notify Results (push) Has been cancelled
Dependency Updates / Update Dependencies (push) Has been cancelled

[Restore from backup: vip-coordinator-backup-2025-07-21-18-13-I got Claude Code]
This commit is contained in:
2025-07-21 18:13:00 +02:00
parent 36cb8e8886
commit 8ace1ab2c1
33 changed files with 3507 additions and 3656 deletions

View File

@@ -1,68 +1,57 @@
import { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import { apiCall } from './utils/api';
import { apiCall } from './config/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<User | null>(null);
const [user, setUser] = useState<any>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Check if user is already authenticated
const token = localStorage.getItem('authToken');
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
if (token) {
apiCall('/auth/me', {
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(({ data }) => {
if (data) {
setUser(data as User);
localStorage.setItem('user', JSON.stringify(data));
.then(res => {
if (res.ok) {
return res.json();
} else {
// Token is invalid, remove it
localStorage.removeItem('authToken');
localStorage.removeItem('user');
setUser(null);
throw new Error('Invalid token');
}
})
.then(userData => {
setUser(userData);
setLoading(false);
})
.catch(error => {
console.error('Auth check failed:', error);
localStorage.removeItem('authToken');
localStorage.removeItem('user');
setUser(null);
setLoading(false);
});
} else {
setLoading(false);
}
}, []);
const handleLogin = (userData: User) => {
const handleLogin = (userData: any) => {
setUser(userData);
};
const handleLogout = () => {
localStorage.removeItem('authToken');
localStorage.removeItem('user');
setUser(null);
// Optionally call logout endpoint
apiCall('/auth/logout', { method: 'POST' })
@@ -82,52 +71,13 @@ function App() {
// Handle OAuth callback route even when not logged in
if (window.location.pathname === '/auth/callback' || window.location.pathname === '/auth/google/callback') {
return (
<Router>
<Routes>
<Route path="*" element={<OAuthCallback />} />
</Routes>
</Router>
);
return <Login onLogin={handleLogin} />;
}
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">