Archivage-ZIM/zimit-webapp/templates/index.html
2025-11-05 22:37:24 +01:00

286 lines
No EOL
7.3 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zimit WebApp</title>
<style>
:root {
--bg-color: #121212;
--card-color: #1e1e1e;
--text-color: #e0e0e0;
--accent-color: #00bfa5;
--error-color: #ff5252;
--success-color: #4caf50;
--warn-color: #ffb300;
}
html {
overflow-y: auto;
scrollbar-width: none; /* Firefox */
}
body {
font-family: "Inter", sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
padding-bottom: 70px; /* espace pour le footer fixe */
overflow-y: auto; /* barre visible uniquement si nécessaire */
}
body::-webkit-scrollbar {
display: none; /* Chrome, Edge, Safari */
}
.container {
width: 100%;
max-width: 720px;
flex-grow: 1;
}
.card {
background-color: var(--card-color);
border-radius: 12px;
padding: 28px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
margin-bottom: 22px;
}
h1 {
text-align: center;
margin-bottom: 22px;
color: var(--accent-color);
font-size: 1.8rem;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
input {
width: 100%;
padding: 10px;
margin-bottom: 16px;
border-radius: 6px;
border: 1px solid #333;
background: #222;
color: var(--text-color);
font-size: 1rem;
}
button {
width: 100%;
padding: 12px;
border: none;
border-radius: 8px;
background-color: var(--accent-color);
color: #000;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
transition: background 0.2s ease;
}
button:hover {
background-color: #00d8b4;
}
.task {
background: var(--card-color);
padding: 15px;
border-radius: 8px;
margin-bottom: 10px;
display: flex;
flex-direction: column;
gap: 5px;
border-left: 4px solid transparent;
}
.status {
font-weight: 600;
font-size: 0.95rem;
}
.status.en-cours { color: var(--warn-color); border-color: var(--warn-color); }
.status.terminee { color: var(--success-color); border-color: var(--success-color); }
.status.erreur, .status.annulee { color: var(--error-color); border-color: var(--error-color); }
.cancel-btn, .delete-btn {
margin-top: 5px;
align-self: flex-end;
border: none;
padding: 6px 10px;
border-radius: 6px;
font-size: 0.9rem;
cursor: pointer;
transition: background 0.2s ease;
}
.cancel-btn {
background-color: var(--error-color);
color: #fff;
}
.cancel-btn:hover {
background-color: #ff6666;
}
.delete-btn {
background-color: #444;
color: var(--text-color);
}
.delete-btn:hover {
background-color: #666;
}
/* --- Pied de page fixe --- */
footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
text-align: center;
color: #aaa;
font-size: 0.85rem;
padding: 12px 0;
border-top: 1px solid #333;
background-color: #181818;
z-index: 100;
}
footer span {
color: var(--accent-color);
font-weight: 500;
}
@media (max-width: 600px) {
h1 { font-size: 1.4rem; }
.card { padding: 20px; }
button { font-size: 0.95rem; }
}
</style>
</head>
<body>
<div class="container">
<h1>Archivage Zimit</h1>
<div class="card">
<label for="site">Lien du site web :</label>
<input type="text" id="site" placeholder="http(s)://exemple.com">
<label for="name">Nom de larchive (espace et accent interdit) :</label>
<input type="text" id="name" placeholder="ex: mon_archive">
<label for="title">Titre de larchive :</label>
<input type="text" id="title" placeholder="ex: Mon Archive">
<label for="pageLimit">Nombre de pages limite :</label>
<input type="number" id="pageLimit" value="20" min="1">
<label for="workers">Nombre de workers (respectez les serveurs de destination, 4 max recommandé) :</label>
<input type="number" id="workers" value="4" min="1">
<button id="startBtn">Lancer larchivage</button>
</div>
<div class="card" id="tasksCard">
<h2 style="text-align:center; margin-bottom: 15px;">Archivages en cours</h2>
<div id="tasks"></div>
</div>
</div>
<!-- Pied de page fixe -->
<footer>
Zimit WebApp <a href="https://git.selfitdeploy.com/Willy/-/packages/container/zimit-webapp/1.1.0" style="text-decoration:none"><span>v1.1.0</span></a><br>
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
<img src="https://img.shields.io/badge/License-CC_BY--NC--SA_4.0-lightgrey.svg" alt="License CC BY-NC-SA 4.0"/>
</a>
</footer>
<script>
const tasksDiv = document.getElementById('tasks');
const startBtn = document.getElementById('startBtn');
startBtn.onclick = async () => {
const site = document.getElementById('site').value.trim();
const name = document.getElementById('name').value.trim();
const title = document.getElementById('title').value.trim();
const pageLimit = document.getElementById('pageLimit').value.trim();
const workers = document.getElementById('workers').value.trim();
if (!site || !name || !title) return;
await fetch('/start', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ site, name, title, pageLimit, workers })
});
// Réinitialise les champs après lancement
document.getElementById('site').value = '';
document.getElementById('name').value = '';
document.getElementById('title').value = '';
loadTasks();
};
async function loadTasks() {
const res = await fetch('/status');
if (!res.ok) return;
const data = await res.json();
renderTasks(data);
}
function renderTasks(tasks) {
tasksDiv.innerHTML = '';
Object.entries(tasks).forEach(([id, t]) => {
const div = document.createElement('div');
div.classList.add('task', 'status', t.status.replace(' ', '-'));
div.innerHTML = `
<div><strong>Nom :</strong> ${t.name}</div>
<div><strong>Titre :</strong> ${t.title}</div>
<div><strong>Site :</strong> ${t.site}</div>
<div><strong>Date :</strong> ${t.date}</div>
<div class="status ${t.status.replace(' ', '-')}"><strong>Statut :</strong> ${t.status}</div>
`;
if (t.status === 'en cours') {
const cancelBtn = document.createElement('button');
cancelBtn.textContent = "Annuler";
cancelBtn.className = "cancel-btn";
cancelBtn.onclick = async () => {
await fetch(`/cancel/${id}`, { method: 'POST' });
loadTasks();
};
div.appendChild(cancelBtn);
}
else if (t.status === 'annulee' || t.status === 'erreur') {
const delBtn = document.createElement('button');
delBtn.textContent = "Effacer";
delBtn.className = "delete-btn";
delBtn.onclick = async () => {
await fetch(`/delete/${id}`, { method: 'POST' });
div.remove();
};
div.appendChild(delBtn);
}
tasksDiv.appendChild(div);
});
}
setInterval(loadTasks, 3000);
loadTasks();
</script>
</body>
</html>
<!--
Developed by Willy from Self IT Deploy - License CC BY-NC-SA 4.0
-->