RELEASE V.1.2.0 - Voici les fonctionnalités :
-> Mode sombre -> Updater
This commit is contained in:
1 parent
383354d854
commit
5fac0d4032
9 files changed
+1011
-2
No files matched your search
@@ -0,0 +1,140 @@
|
||||
.maj-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.maj-card {
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.maj-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding-bottom: 24px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.maj-header wcs-mat-icon {
|
||||
font-size: 48px;
|
||||
color: #0088ce;
|
||||
}
|
||||
|
||||
.maj-title h3 {
|
||||
margin: 0 0 4px 0;
|
||||
font-size: 18px;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.version-text {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.maj-body {
|
||||
min-height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.maj-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.maj-actions p {
|
||||
color: #6b7280;
|
||||
margin: 0;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.alert-new-version {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
background: #fef3c7;
|
||||
border-left: 4px solid #d97706;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
text-align: left;
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.alert-new-version strong {
|
||||
display: block;
|
||||
color: #92400e;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.alert-new-version p {
|
||||
color: #b45309;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.progress-container wcs-progress-bar {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-weight: bold;
|
||||
color: #0088ce;
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.progress-details {
|
||||
font-size: 13px !important;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.maj-actions.success {
|
||||
color: #16a34a;
|
||||
}
|
||||
.maj-actions.success p {
|
||||
color: #15803d;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Dark mode adjustments */
|
||||
body.dark-mode .maj-header {
|
||||
border-bottom-color: #333;
|
||||
}
|
||||
|
||||
body.dark-mode .maj-title h3 {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
body.dark-mode .alert-new-version {
|
||||
background: #451a03;
|
||||
border-color: #f59e0b;
|
||||
}
|
||||
|
||||
body.dark-mode .alert-new-version strong {
|
||||
color: #fde68a;
|
||||
}
|
||||
|
||||
body.dark-mode .alert-new-version p {
|
||||
color: #fcd34d;
|
||||
}
|
||||
|
||||
body.dark-mode .progress-text {
|
||||
color: #38bdf8;
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import './SystemeMaj.css';
|
||||
|
||||
export default function SystemeMaj() {
|
||||
const [status, setStatus] = useState('idle'); // idle, checking, available, updating, success
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [version, setVersion] = useState('v0.1.0 (Bêta)');
|
||||
const [newVersion, setNewVersion] = useState(null);
|
||||
|
||||
const [logs, setLogs] = useState([]);
|
||||
const [stepName, setStepName] = useState('');
|
||||
|
||||
const checkForUpdates = () => {
|
||||
setStatus('checking');
|
||||
setTimeout(() => {
|
||||
// Pour une vérification réelle, on pourrait interroger un endpoint /api/check-update
|
||||
setNewVersion('Dernière version (Git)');
|
||||
setStatus('available');
|
||||
}, 1500);
|
||||
};
|
||||
|
||||
const applyUpdate = async () => {
|
||||
setStatus('updating');
|
||||
setProgress(0);
|
||||
|
||||
try {
|
||||
// Démarre la mise à jour sur le backend
|
||||
await fetch('http://localhost:3001/api/update', { method: 'POST' });
|
||||
|
||||
// Polling de l'état
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
const res = await fetch('http://localhost:3001/api/update/status');
|
||||
const data = await res.json();
|
||||
|
||||
setProgress(data.progress);
|
||||
setStepName(data.step);
|
||||
setLogs(data.logs || []);
|
||||
|
||||
if (data.status === 'success') {
|
||||
clearInterval(interval);
|
||||
setStatus('success');
|
||||
setVersion('À jour');
|
||||
setNewVersion(null);
|
||||
|
||||
// Reset le backend après succès
|
||||
setTimeout(() => {
|
||||
fetch('http://localhost:3001/api/update/reset', { method: 'POST' });
|
||||
window.location.reload();
|
||||
}, 3000);
|
||||
} else if (data.status === 'error') {
|
||||
clearInterval(interval);
|
||||
setStatus('error');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Erreur de connexion avec l'updater:", err);
|
||||
}
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
console.error("Impossible de lancer la mise à jour:", error);
|
||||
setStatus('error');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="panel-layout">
|
||||
<div className="nav-panel">
|
||||
<wcs-nav>
|
||||
<wcs-nav-item>
|
||||
<wcs-mat-icon icon="update"></wcs-mat-icon>
|
||||
<span>Mises à jour</span>
|
||||
</wcs-nav-item>
|
||||
</wcs-nav>
|
||||
</div>
|
||||
|
||||
<div className="panel-content maj-content">
|
||||
<div className="page-header">
|
||||
<h2>Système de mises à jour</h2>
|
||||
<span className="station-type-badge ville" style={{ background: '#0088ce', color: '#fff' }}>Espace Administrateur</span>
|
||||
</div>
|
||||
|
||||
<div className="widget-card maj-card">
|
||||
<div className="maj-header">
|
||||
<wcs-mat-icon icon="system_update_alt" size="l"></wcs-mat-icon>
|
||||
<div className="maj-title">
|
||||
<h3>Version Actuelle</h3>
|
||||
<p className="version-text">{version}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="maj-body">
|
||||
{status === 'idle' && (
|
||||
<div className="maj-actions">
|
||||
<p>Votre système semble à jour. Vous pouvez forcer une vérification pour synchroniser avec le dépôt.</p>
|
||||
<wcs-button onClick={checkForUpdates} className="wcs-primary">Vérifier les mises à jour</wcs-button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === 'checking' && (
|
||||
<div className="maj-actions">
|
||||
<wcs-spinner></wcs-spinner>
|
||||
<p>Recherche de mises à jour sur le serveur Git distant...</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === 'available' && (
|
||||
<div className="maj-actions">
|
||||
<div className="alert-new-version">
|
||||
<wcs-mat-icon icon="new_releases" style={{ color: '#d97706' }}></wcs-mat-icon>
|
||||
<div>
|
||||
<strong>Mise à jour prête : {newVersion}</strong>
|
||||
<p>Cette action va exécuter `git pull`, puis recompiler l'application. Le panel sera temporairement indisponible.</p>
|
||||
</div>
|
||||
</div>
|
||||
<wcs-button onClick={applyUpdate} className="wcs-primary">Lancer la mise à jour (PM2)</wcs-button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === 'updating' && (
|
||||
<div className="maj-actions" style={{ maxWidth: '600px', width: '100%' }}>
|
||||
<p>Mise à jour en cours sur le serveur...</p>
|
||||
<div className="progress-container">
|
||||
<wcs-progress-bar value={progress}></wcs-progress-bar>
|
||||
<span className="progress-text">{progress}%</span>
|
||||
</div>
|
||||
<p className="progress-details" style={{ fontWeight: 'bold', margin: '10px 0' }}>
|
||||
Étape : {stepName || "Initialisation..."}
|
||||
</p>
|
||||
<div className="terminal-logs" style={{ background: '#1e1e1e', color: '#e0e0e0', padding: '10px', borderRadius: '6px', height: '150px', overflowY: 'auto', fontFamily: 'monospace', fontSize: '12px', textAlign: 'left' }}>
|
||||
{logs.length === 0 ? "En attente des logs..." : logs.map((log, i) => (
|
||||
<div key={i}>{log}</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === 'error' && (
|
||||
<div className="maj-actions error">
|
||||
<wcs-mat-icon icon="error" style={{ color: '#dc2626', fontSize: '48px' }}></wcs-mat-icon>
|
||||
<p style={{ color: '#dc2626', fontWeight: 'bold' }}>Une erreur critique est survenue durant la mise à jour.</p>
|
||||
<p>Consultez les logs du serveur (PM2) ou vérifiez les permissions Git.</p>
|
||||
<wcs-button onClick={() => setStatus('idle')} className="wcs-secondary">Retour</wcs-button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{status === 'success' && (
|
||||
<div className="maj-actions success">
|
||||
<wcs-mat-icon icon="check_circle" style={{ color: '#16a34a', fontSize: '48px' }}></wcs-mat-icon>
|
||||
<p>Mise à jour compilée et déployée avec succès !</p>
|
||||
<p>L'application va se recharger automatiquement pour appliquer les changements...</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user