96 lines
3.5 KiB
HTML
96 lines
3.5 KiB
HTML
{% extends 'base.html' %}
|
|
{% block title %}Dashboard{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="page-header d-flex justify-content-between align-items-center">
|
|
<h1><i class="bi bi-speedometer2 me-2 text-warning"></i>Dashboard</h1>
|
|
<a href="{{ url_for('new_job') }}" class="btn btn-sm" style="background:#ff6b35;color:#fff">
|
|
<i class="bi bi-plus-lg me-1"></i>Nouveau calcul
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Stats -->
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-3">
|
|
<div class="stat-card">
|
|
<div class="label">CA ce mois</div>
|
|
<div class="value">{{ stats.month_revenue or 0 }} €</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="stat-card">
|
|
<div class="label">CA total</div>
|
|
<div class="value">{{ stats.total_revenue or 0 }} €</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="stat-card">
|
|
<div class="label">Commandes</div>
|
|
<div class="value">{{ stats.total_jobs or 0 }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="stat-card">
|
|
<div class="label">Marge brute moy.</div>
|
|
<div class="value">{{ stats.avg_margin or 0 }} %</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Alertes stock bas -->
|
|
{% if low_stock %}
|
|
<div class="alert alert-warning d-flex align-items-center gap-2 mb-4">
|
|
<i class="bi bi-exclamation-triangle-fill"></i>
|
|
<span>
|
|
Stock bas ou rupture :
|
|
{% for m in low_stock %}
|
|
<strong>{{ m.name }}</strong> ({{ m.stock_g|round(0)|int }} g){% if not loop.last %}, {% endif %}
|
|
{% endfor %}
|
|
— <a href="{{ url_for('materials') }}" class="alert-link">Gérer les stocks</a>
|
|
</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Dernières commandes -->
|
|
<div class="card">
|
|
<div class="card-header d-flex justify-content-between align-items-center py-3">
|
|
<span><i class="bi bi-clock-history me-2"></i>Dernières commandes</span>
|
|
<a href="{{ url_for('jobs') }}" class="btn btn-sm btn-outline-secondary">Tout voir</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if jobs %}
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr><th>Nom</th><th>Client</th><th>Matière</th><th>Fichier</th>
|
|
<th>Poids</th><th>Durée</th><th class="text-end">Prix final</th><th></th></tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for j in jobs %}
|
|
<tr>
|
|
<td><a href="{{ url_for('job_detail', id=j.id) }}" class="text-decoration-none fw-semibold">{{ j.name }}</a></td>
|
|
<td>{{ j.client_name or '—' }}</td>
|
|
<td>
|
|
{% if j.material_name %}
|
|
<span class="badge bg-light text-dark">{{ j.material_name }}</span>
|
|
{% else %}—{% endif %}
|
|
</td>
|
|
<td class="text-muted small">{{ j.source_file or '—' }}</td>
|
|
<td>{{ j.weight_g }} g</td>
|
|
<td>{{ j.print_time_s | fmt_time }}</td>
|
|
<td class="text-end fw-bold" style="color:#ff6b35">{{ j.final_price }} €</td>
|
|
<td><a href="{{ url_for('job_detail', id=j.id) }}" class="btn btn-sm btn-outline-secondary py-0">→</a></td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<div class="text-center text-muted py-5">
|
|
<i class="bi bi-inbox fs-1"></i>
|
|
<p class="mt-2">Aucune commande pour l'instant.</p>
|
|
<a href="{{ url_for('new_job') }}" class="btn btn-sm" style="background:#ff6b35;color:#fff">Créer le premier calcul</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|