feat: GarageManager v2.1 - véhicules, interventions, pièces
- Application FastAPI avec SQLite et Jinja2 - Gestion des véhicules (VIN, immatriculation, infos libres) - Gestion des interventions avec statut (en_attente/en_cours/termine) - Gestion des pièces détachées avec photos - Tableau de bord avec statistiques - Déploiement Docker + Traefik (HTTPS) - README complet en français
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Dashboard - GarageManager{% endblock %}
|
||||
{% block content %}
|
||||
<div class="mb-8">
|
||||
<h2 class="text-2xl font-bold text-slate-800">Dashboard</h2>
|
||||
<p class="text-slate-500 mt-1">Vue d'ensemble de votre garage</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div><p class="text-sm text-slate-500">Véhicules</p><p class="text-3xl font-bold text-slate-800 mt-1">{{ stats.nb_vehicules }}</p></div>
|
||||
<div class="bg-purple-100 p-3 rounded-full"><i class="fas fa-car text-purple-500 text-xl"></i></div>
|
||||
</div>
|
||||
<a href="/vehicules" class="text-xs text-purple-500 hover:underline mt-3 inline-block">Voir tous →</a>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div><p class="text-sm text-slate-500">En attente</p><p class="text-3xl font-bold text-yellow-500 mt-1">{{ stats.nb_en_attente }}</p></div>
|
||||
<div class="bg-yellow-100 p-3 rounded-full"><i class="fas fa-clock text-yellow-500 text-xl"></i></div>
|
||||
</div>
|
||||
<a href="/interventions?statut=en_attente" class="text-xs text-yellow-500 hover:underline mt-3 inline-block">Voir →</a>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div><p class="text-sm text-slate-500">En cours</p><p class="text-3xl font-bold text-blue-500 mt-1">{{ stats.nb_en_cours }}</p></div>
|
||||
<div class="bg-blue-100 p-3 rounded-full"><i class="fas fa-spinner text-blue-500 text-xl"></i></div>
|
||||
</div>
|
||||
<a href="/interventions?statut=en_cours" class="text-xs text-blue-500 hover:underline mt-3 inline-block">Voir →</a>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div><p class="text-sm text-slate-500">Terminées</p><p class="text-3xl font-bold text-green-500 mt-1">{{ stats.nb_termine }}</p></div>
|
||||
<div class="bg-green-100 p-3 rounded-full"><i class="fas fa-check-circle text-green-500 text-xl"></i></div>
|
||||
</div>
|
||||
<a href="/interventions?statut=termine" class="text-xs text-green-500 hover:underline mt-3 inline-block">Voir →</a>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div><p class="text-sm text-slate-500">Coût pièces</p><p class="text-3xl font-bold text-slate-800 mt-1">{{ "%.0f"|format(stats.cout_pieces) }} €</p></div>
|
||||
<div class="bg-red-100 p-3 rounded-full"><i class="fas fa-cog text-red-400 text-xl"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div><p class="text-sm text-slate-500">Total dépensé</p><p class="text-3xl font-bold text-orange-500 mt-1">{{ "%.0f"|format(stats.cout_total) }} €</p></div>
|
||||
<div class="bg-orange-100 p-3 rounded-full"><i class="fas fa-euro-sign text-orange-500 text-xl"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow">
|
||||
<div class="p-6 border-b border-gray-100 flex justify-between items-center">
|
||||
<h3 class="font-semibold text-slate-800">Interventions récentes</h3>
|
||||
<a href="/interventions/new" class="bg-orange-500 text-white px-4 py-2 rounded-lg text-sm hover:bg-orange-600 transition">+ Nouvelle</a>
|
||||
</div>
|
||||
{% if recent %}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-50 text-slate-600 text-xs uppercase">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left">Véhicule</th>
|
||||
<th class="px-6 py-3 text-left">Description</th>
|
||||
<th class="px-6 py-3 text-left">Statut</th>
|
||||
<th class="px-6 py-3 text-left">Coût total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
{% for i in recent %}
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-6 py-4 font-medium text-slate-800"><a href="/vehicules/{{ i.vehicule_id }}" class="hover:text-orange-500">{{ i.immatriculation }}<br><span class="text-xs font-normal text-slate-400">{{ i.marque }} {{ i.modele }}</span></a></td>
|
||||
<td class="px-6 py-4 text-slate-600"><a href="/interventions/{{ i.id }}" class="hover:text-orange-500">{{ i.description[:60] }}{% if i.description|length > 60 %}...{% endif %}</a></td>
|
||||
<td class="px-6 py-4">
|
||||
{% if i.statut == 'en_attente' %}<span class="bg-yellow-100 text-yellow-700 px-2 py-1 rounded-full text-xs">En attente</span>
|
||||
{% elif i.statut == 'en_cours' %}<span class="bg-blue-100 text-blue-700 px-2 py-1 rounded-full text-xs">En cours</span>
|
||||
{% else %}<span class="bg-green-100 text-green-700 px-2 py-1 rounded-full text-xs">Terminé</span>{% endif %}
|
||||
</td>
|
||||
<td class="px-6 py-4 font-semibold text-slate-700">{{ "%.0f"|format(i.cout_main_oeuvre + i.cout_pieces) }} €</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="p-8 text-center text-slate-400">
|
||||
<i class="fas fa-tools text-3xl mb-3"></i><p>Aucune intervention pour l'instant</p>
|
||||
<a href="/interventions/new" class="text-orange-500 hover:underline text-sm mt-2 inline-block">Créer la première →</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user