133 lines
3.9 KiB
JavaScript
133 lines
3.9 KiB
JavaScript
import React, { useState, useEffect, useCallback } from 'react';
|
|
import LoginPage from './pages/LoginPage';
|
|
import DashboardPage from './pages/DashboardPage';
|
|
import AppsPage from './pages/AppsPage';
|
|
import MonitoringPage from './pages/MonitoringPage';
|
|
import DeploymentsPage from './pages/DeploymentsPage';
|
|
import GiteaPage from './pages/GiteaPage';
|
|
import DockerPage from './pages/DockerPage';
|
|
import DocumentationPage from './pages/DocumentationPage';
|
|
import InventairePage from './pages/InventairePage';
|
|
import TerminalPage from './pages/TerminalPage';
|
|
import Sidebar from './components/Sidebar';
|
|
import useWebSocket from './hooks/useWebSocket';
|
|
import { getMe, getApps, logout as apiLogout } from './utils/api';
|
|
export default function App() {
|
|
const [authenticated, setAuthenticated] = useState(false);
|
|
const [loading, setLoading] = useState(true);
|
|
const [currentPage, setCurrentPage] = useState('dashboard');
|
|
const [apps, setApps] = useState([]);
|
|
// Vérifier l'authentification au chargement
|
|
useEffect(() => {
|
|
const token = localStorage.getItem('dashboard_token');
|
|
if (token) {
|
|
getMe()
|
|
.then(() => {
|
|
setAuthenticated(true);
|
|
fetchApps();
|
|
})
|
|
.catch(() => {
|
|
localStorage.removeItem('dashboard_token');
|
|
setAuthenticated(false);
|
|
})
|
|
.finally(() => setLoading(false));
|
|
} else {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
const fetchApps = async () => {
|
|
try {
|
|
const res = await getApps();
|
|
setApps(res.data);
|
|
} catch (err) {
|
|
console.error('Erreur chargement apps:', err);
|
|
}
|
|
};
|
|
// WebSocket handler
|
|
const handleWsMessage = useCallback((data) => {
|
|
if (data.type === 'health_update') {
|
|
setApps(data.data);
|
|
}
|
|
}, []);
|
|
const { connected: wsConnected } = useWebSocket(
|
|
authenticated ? handleWsMessage : null
|
|
);
|
|
const handleLogin = (data) => {
|
|
setAuthenticated(true);
|
|
fetchApps();
|
|
};
|
|
const handleLogout = async () => {
|
|
try {
|
|
await apiLogout();
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
localStorage.removeItem('dashboard_token');
|
|
setAuthenticated(false);
|
|
setApps([]);
|
|
};
|
|
if (loading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-dark-950">
|
|
<div className="flex items-center gap-3">
|
|
<svg className="animate-spin h-8 w-8 text-primary-500" viewBox="0 0 24 24">
|
|
<circle
|
|
className="opacity-25"
|
|
cx="12"
|
|
cy="12"
|
|
r="10"
|
|
stroke="currentColor"
|
|
strokeWidth="4"
|
|
fill="none"
|
|
/>
|
|
<path
|
|
className="opacity-75"
|
|
fill="currentColor"
|
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
/>
|
|
</svg>
|
|
<span className="text-gray-400">Chargement...</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
if (!authenticated) {
|
|
return <LoginPage onLogin={handleLogin} />;
|
|
}
|
|
const renderPage = () => {
|
|
switch (currentPage) {
|
|
case 'dashboard':
|
|
return <DashboardPage apps={apps} />;
|
|
case 'apps':
|
|
return <AppsPage apps={apps} onRefresh={fetchApps} />;
|
|
case 'deployments':
|
|
return <DeploymentsPage />;
|
|
case 'gitea':
|
|
return <GiteaPage />;
|
|
case 'docker':
|
|
return <DockerPage />;
|
|
case 'monitoring':
|
|
return <MonitoringPage />;
|
|
case 'documentation':
|
|
return <DocumentationPage />;
|
|
case 'inventaire':
|
|
return <InventairePage />;
|
|
case 'terminal':
|
|
return <TerminalPage />;
|
|
default:
|
|
return <DashboardPage apps={apps} />;
|
|
}
|
|
};
|
|
return (
|
|
<div className="min-h-screen bg-dark-950">
|
|
<Sidebar
|
|
currentPage={currentPage}
|
|
onNavigate={setCurrentPage}
|
|
onLogout={handleLogout}
|
|
wsConnected={wsConnected}
|
|
/>
|
|
<main className="ml-64 p-8">{renderPage()}</main>
|
|
</div>
|
|
);
|
|
}
|