Archivage-ZIM/zimit-webapp/templates/index.html

243 lines
6.1 KiB
HTML
Raw 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 Web Interface</title>
<style>
:root {
--bg-color: #121212;
--card-color: #1e1e1e;
--text-color: #e0e0e0;
--accent-color: #00bfa5;
--error-color: #ff5252;
--success-color: #4caf50;
--warn-color: #ffb300;
}
body {
font-family: "Inter", sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
margin: 0;
padding: 20px;
}
.container {
width: 100%;
max-width: 720px;
}
.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;
}
@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="https://exemple.com">
<label for="name">Nom de larchive :</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 :</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>
<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>