Remove test.php and enhance null safety and sorting across components

- Deleted `test.php` as it was no longer in use.
- Enhanced null safety checks in `Inventory.php`, `StdOut-detail.php`, `Backups.php`, and `SwitchsSAN.php` to prevent potential warnings.
- Refactored `SwitchsSAN.php` to improve sorting logic for ports based on errors, vFabric, and Port ID.
- Added seasonal snow effect script in `all.php` with toggle functionality for user engagement.
- Updated navigation bar (`navbar.html`) to include a new VIO page link.
- Introduced a new `VIO.php` page to display VIO monitoring details with table export and sorting features.
This commit is contained in:
e025532
2026-02-04 14:52:49 +01:00
parent b0c9cafc46
commit d5b45dbc22
9 changed files with 544 additions and 175 deletions

View File

@@ -335,6 +335,207 @@
?>
<style>
/* 1. CONFIGURATION DES COULEURS */
:root {
/* Par défaut (Mode Clair / bg-light) : Gris visible sur blanc */
--snow-color: rgba(160, 160, 160, 0.9);
}
/* 2. DÉTECTION DU MODE SOMBRE BASÉE SUR TON SCRIPT */
/* Ton script ajoute la classe 'bg-dark' au body, on s'en sert ici */
body.bg-dark {
--snow-color: rgba(255, 255, 255, 0.9) !important;
}
/* Gestion des préférences système (OS) au cas où le script JS n'a pas encore chargé */
@media (prefers-color-scheme: dark) {
body:not(.bg-light) { /* Sauf si l'utilisateur a forcé le mode clair */
--snow-color: rgba(255, 255, 255, 0.9);
}
}
/* 3. STYLES DU CANVAS ET DU BOUTON */
#snow-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999; /* Au-dessus de tout */
pointer-events: none; /* LAISSE PASSER LES CLICS (Vital !) */
}
#snow-toggle-btn {
position: fixed;
/* Positionné un peu au-dessus du bas pour ne pas gêner d'autres footers */
bottom: 20px;
right: 20px;
z-index: 10000;
background: transparent;
color: var(--snow-color); /* Le bouton prend aussi la couleur du thème */
border: 1px solid var(--snow-color);
border-radius: 50%;
width: 35px;
height: 35px;
cursor: pointer;
font-size: 18px;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
opacity: 0.5; /* Discret par défaut */
}
#snow-toggle-btn:hover {
opacity: 1;
background: rgba(128, 128, 128, 0.2);
}
</style>
<canvas id="snow-canvas"></canvas>
<button id="snow-toggle-btn" title="Activer/Désactiver la neige">❄️</button>
<script>
(function() {
// --- 1. GESTION DES DATES (15 Déc au 5 Jan) ---
const now = new Date();
const month = now.getMonth() + 1; // JS compte les mois de 0 à 11, donc on ajoute 1
const day = now.getDate();
// La condition : (Mois = 12 ET Jour >= 15) OU (Mois = 1 ET Jour <= 5)
const isSeason = (month === 12 && day >= 15) || (month === 1 && day <= 5);
const canvas = document.getElementById('snow-canvas');
const toggleBtn = document.getElementById('snow-toggle-btn');
// Si on n'est pas dans la période, on cache tout et on arrête le script.
if (!isSeason) {
if (canvas) canvas.style.display = 'none';
if (toggleBtn) toggleBtn.style.display = 'none';
return; // Arrêt immédiat du script
}
// --- 2. CONFIGURATION ---
const ctx = canvas.getContext('2d');
let width = window.innerWidth;
let height = window.innerHeight;
const maxFlakes = 80;
let flakes = [];
let animationId;
let isSnowing = false;
// Gestion du redimensionnement
canvas.width = width;
canvas.height = height;
window.addEventListener('resize', () => {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
});
// --- 3. CLASSE FLOCON ---
class Snowflake {
constructor() {
this.reset(true);
}
reset(initial = false) {
this.x = Math.random() * width;
this.y = initial ? Math.random() * height : -10;
this.radius = Math.random() * 3 + 1;
this.speed = Math.random() * 1.5 + 0.5;
this.drift = Math.random() * 2 - 1;
}
update() {
this.y += this.speed;
this.x += this.drift;
if (this.y > height || this.x > width || this.x < 0) {
this.reset();
}
}
draw(color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
ctx.fill();
}
}
// --- 4. ANIMATION ---
function initFlakes() {
flakes = [];
for (let i = 0; i < maxFlakes; i++) {
flakes.push(new Snowflake());
}
}
function animate() {
if (!isSnowing) {
ctx.clearRect(0, 0, width, height);
return;
}
ctx.clearRect(0, 0, width, height);
// Récupération dynamique de la couleur (compatible avec ton script Light Switch)
const style = getComputedStyle(document.body);
const currentColor = style.getPropertyValue('--snow-color').trim();
flakes.forEach(flake => {
flake.update();
flake.draw(currentColor);
});
animationId = requestAnimationFrame(animate);
}
// --- 5. BOUTON & INIT ---
function toggleSnow() {
isSnowing = !isSnowing;
updateButtonState();
if (isSnowing) {
initFlakes();
animate();
localStorage.setItem('snow-preference', 'on');
} else {
cancelAnimationFrame(animationId);
ctx.clearRect(0, 0, width, height);
localStorage.setItem('snow-preference', 'off');
}
}
function updateButtonState() {
if(isSnowing) {
toggleBtn.style.opacity = "1";
toggleBtn.style.background = "rgba(128, 128, 128, 0.3)";
} else {
toggleBtn.style.opacity = "0.5";
toggleBtn.style.background = "transparent";
}
}
toggleBtn.addEventListener('click', toggleSnow);
const savedPref = localStorage.getItem('snow-preference');
if (savedPref !== 'off') {
isSnowing = true;
initFlakes();
animate();
updateButtonState();
}
})();
</script>
<!-- MODAL WAIT -->
<div class="modal fade bs-example-modal-sm" id="wait" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" style="padding-top: 15%;">
<div class="modal-dialog modal-sm">
@@ -351,4 +552,7 @@
</div>
</div>
</div>
</div>
</div>