add dashboard

This commit is contained in:
Σlie *
2026-02-27 22:49:25 +01:00
parent d716272903
commit 6d421c7780

View File

@ -1,35 +1,142 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Iceberg Price Tracker</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🧊 Iceberg Price Tracker</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body class="bg-gray-900 text-white p-10">
<h1 class="text-3xl font-bold mb-6">🧊 Iceberg Dashboard</h1>
<body class="bg-gray-900 text-gray-100 min-h-screen p-6 md:p-12">
<form action="/add" method="POST" class="mb-10">
<input type="text" name="name" placeholder="Nom Produit..." class="p-2 rounded bg-gray-800 border border-gray-700 w-1/2">
<input type="text" name="link" placeholder="Lien Amazon..." class="p-2 rounded bg-gray-800 border border-gray-700 w-1/2">
<button type="submit" class="bg-blue-600 px-4 py-2 rounded">Ajouter</button>
</form>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div th:each="product : ${products}" class="bg-gray-800 p-4 rounded-xl shadow-lg">
<div class="flex items-center gap-4 mb-4">
<img th:src="${product.imageUrl}" class="w-16 h-16 object-contain rounded">
<h2 class="flex-1 font-semibold text-sm" th:text="${product.name}">Nom du produit</h2>
<a th:href="@{'/delete/' + ${product.id}}" class="text-red-500">🗑️</a>
<div class="max-w-6xl mx-auto">
<header class="mb-10 flex justify-between items-center">
<h1 class="text-4xl font-extrabold tracking-tight text-white">
🧊 Iceberg <span class="text-blue-500">Tracker</span>
</h1>
<div class="text-sm text-gray-400 bg-gray-800 px-3 py-1 rounded-full border border-gray-700">
Statut : <span class="text-green-400">Connecté</span>
</div>
</header>
<canvas th:id="'chart-' + ${product.id}"></canvas>
<section class="bg-gray-800 p-6 rounded-2xl border border-gray-700 shadow-xl mb-10">
<h2 class="text-xl font-semibold mb-4 text-gray-200">Ajouter un produit à surveiller</h2>
<form th:action="@{/add}" method="POST" class="flex flex-col md:flex-row gap-4">
<input type="text" name="name" required placeholder="Nom du produit (ex: Station Soudure)"
class="flex-1 p-3 rounded-lg bg-gray-900 border border-gray-600 focus:border-blue-500 focus:outline-none transition">
<input type="url" name="link" required placeholder="Lien Amazon (https://...)"
class="flex-1 p-3 rounded-lg bg-gray-900 border border-gray-600 focus:border-blue-500 focus:outline-none transition">
<button type="submit" class="bg-blue-600 hover:bg-blue-500 text-white font-bold py-3 px-8 rounded-lg transition duration-200 transform hover:scale-105">
Démarrer le tracking
</button>
</form>
</section>
<script th:inline="javascript">
/* Code pour générer le graphique Chart.js pour chaque produit */
</script>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-8">
<div th:each="product : ${products}" th:if="${product != null}"
class="bg-gray-800 rounded-2xl border border-gray-700 overflow-hidden shadow-lg hover:border-gray-500 transition duration-300">
<div class="p-6">
<div class="flex items-start gap-4 mb-6">
<div class="bg-white p-2 rounded-lg w-24 h-24 flex items-center justify-center shrink-0">
<img th:src="${product.imageUrl ?: 'https://via.placeholder.com/150'}"
class="max-w-full max-h-full object-contain" alt="Image produit">
</div>
<div class="flex-1 overflow-hidden">
<h3 class="text-lg font-bold text-white truncate" th:text="${product.name}">Nom</h3>
<a th:href="${product.link}" target="_blank" class="text-blue-400 text-xs hover:underline truncate block mb-2 italic">
Voir sur le site ↗
</a>
<a th:href="@{'/delete/' + ${product.id}}"
onclick="return confirm('Arrêter de suivre ce produit ?')"
class="text-red-400 text-xs font-semibold hover:text-red-300 transition">
🗑️ Supprimer le tracking
</a>
</div>
</div>
<div class="relative h-64 w-full bg-gray-900/50 rounded-xl p-2">
<canvas th:id="'chart-' + ${product.id}"></canvas>
</div>
</div>
<script th:inline="javascript">
(function() {
const productId = [[${product.id}]];
const ctx = document.getElementById('chart-' + productId);
if (ctx) {
fetch('/api/prices/' + productId)
.then(res => res.json())
.then(data => {
if (!data || data.length === 0) {
// Optionnel : afficher un message si pas de données
return;
}
// Extraction des labels (dates) et des prix
const labels = data.map(d => {
const date = new Date(d.dateCheck);
return date.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' });
});
const prices = data.map(d => d.price);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Prix (€)',
data: prices,
borderColor: '#3b82f6', // Bleu
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 3,
fill: true,
tension: 0.4, // Courbe lisse
pointRadius: 4,
pointBackgroundColor: '#3b82f6'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
backgroundColor: '#1f2937',
titleColor: '#9ca3af',
bodyColor: '#ffffff',
borderColor: '#374151',
borderWidth: 1,
displayColors: false
}
},
scales: {
y: {
beginAtZero: false,
grid: { color: 'rgba(255, 255, 255, 0.05)' },
ticks: { color: '#9ca3af' }
},
x: {
grid: { display: false },
ticks: { color: '#9ca3af' }
}
}
}
});
})
.catch(err => console.error("Erreur API:", err));
}
})();
</script>
</div>
</div>
<div th:if="${#lists.isEmpty(products)}" class="text-center py-20 bg-gray-800 rounded-3xl border-2 border-dashed border-gray-700">
<p class="text-gray-400 text-xl italic">Aucun produit en cours de surveillance. Ajoutez-en un au-dessus !</p>
</div>
</div>
</body>
</html>