design: refonte UI — journal de bord (Playfair + JetBrains Mono, palette encre/crème/ambre)

This commit is contained in:
2026-03-11 18:46:04 +01:00
parent 23dbc3f870
commit c3a7bdfef7
6 changed files with 453 additions and 164 deletions

View File

@@ -1,45 +1,45 @@
{% extends "base.html" %}
{% block title %}{% if entry %}Modifier{% else %}Nouvelle entrée{% endif %}{% endblock %}
{% block title %}{% if entry %}Modifier l'entrée{% else %}Nouvelle journée{% endif %}{% endblock %}
{% block content %}
<h1 class="text-xl font-bold mb-4">
{% if entry %}Modifier le {{ entry.date }}{% else %}Nouvelle journée{% endif %}
</h1>
<div class="mb-5">
<p class="font-display text-2xl font-semibold" style="color:var(--ink);">
{% if entry %}Modifier{% else %}Nouvelle journée{% endif %}
</p>
</div>
<form method="POST" class="space-y-5">
<!-- Date -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Date</label>
<label class="field-label">Date</label>
<input type="date" name="date"
value="{{ entry.date.isoformat() if entry else today }}"
class="w-full border rounded-lg px-3 py-2 text-sm" required>
class="field-input" required>
</div>
<!-- Type de journée -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Type de journée</label>
<label class="field-label">Type de journée</label>
<div class="grid grid-cols-3 gap-2">
{% for value, label in day_types %}
<label class="cursor-pointer">
<label class="pill-option">
<input type="radio" name="day_type" value="{{ value }}"
{% if entry and entry.day_type == value %}checked{% elif not entry and value == 'WORK' %}checked{% endif %}
class="sr-only peer"
onchange="updateJourneyVisibility(this.value)">
<div class="text-center text-sm py-2 px-1 rounded-lg border-2 border-gray-200
peer-checked:border-blue-500 peer-checked:bg-blue-50 peer-checked:text-blue-700
hover:border-gray-300 transition">
{{ label }}
</div>
<span class="pill-inner">{{ label }}</span>
</label>
{% endfor %}
</div>
</div>
<!-- Trajet domicile-travail -->
<div id="journey-section"
class="{% if entry and entry.day_type in day_types_without_journey %}hidden{% endif %}">
<label class="block text-sm font-medium text-gray-700 mb-1">Trajet domicile-travail</label>
<label class="field-label">Trajet domicile-travail</label>
<select name="journey_profile_id" id="journey_profile_id"
onchange="updateMotorVehicleVisibility(this.value)"
class="w-full border rounded-lg px-3 py-2 text-sm">
class="field-input">
<option value="">— Pas de déplacement —</option>
{% for jid, jdata in journeys.items() %}
<option value="{{ jid }}"
@@ -52,68 +52,67 @@
</select>
</div>
<!-- Véhicule à moteur -->
<div id="motor-vehicle-section" class="{% if not entry or not entry.motor_vehicle_id %}hidden{% endif %}">
<label class="block text-sm font-medium text-gray-700 mb-1">Véhicule à moteur utilisé</label>
<label class="field-label">Véhicule à moteur utilisé</label>
<div class="grid grid-cols-2 gap-2">
{% for vid, vdata in motor_vehicles.items() %}
<label class="cursor-pointer">
<label class="pill-option">
<input type="radio" name="motor_vehicle_id" value="{{ vid }}"
{% if entry and entry.motor_vehicle_id == vid %}checked{% endif %}
class="sr-only peer">
<div class="text-center text-sm py-2 px-1 rounded-lg border-2 border-gray-200
peer-checked:border-orange-500 peer-checked:bg-orange-50 peer-checked:text-orange-700
hover:border-gray-300 transition">
{{ vdata.name }}
</div>
{% if entry and entry.motor_vehicle_id == vid %}checked{% endif %}>
<span class="pill-inner" style="font-size:0.72rem;">{{ vdata.name }}</span>
</label>
{% endfor %}
</div>
</div>
<!-- Plages horaires -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Plages horaires</label>
<label class="field-label">Plages horaires</label>
<div id="time-slots" class="space-y-2">
{% if entry and entry.time_slots %}
{% for slot in entry.time_slots %}
<div class="flex gap-2 items-center time-slot-row">
<input type="time" name="start_time" value="{{ slot.start_time.strftime('%H:%M') }}"
class="flex-1 border rounded-lg px-3 py-2 text-sm">
<span class="text-gray-400"></span>
class="field-input flex-1" style="padding:0.5rem 0.6rem; font-family:'JetBrains Mono',monospace; font-size:0.9rem;">
<span style="color:var(--mist); font-size:1rem;"></span>
<input type="time" name="end_time" value="{{ slot.end_time.strftime('%H:%M') }}"
class="flex-1 border rounded-lg px-3 py-2 text-sm">
class="field-input flex-1" style="padding:0.5rem 0.6rem; font-family:'JetBrains Mono',monospace; font-size:0.9rem;">
<button type="button" onclick="this.closest('.time-slot-row').remove()"
class="text-red-400 hover:text-red-600 text-xl leading-none">×</button>
class="text-lg leading-none transition-colors" style="color:var(--mist);"
onmouseover="this.style.color='var(--rust)'" onmouseout="this.style.color='var(--mist)'">×</button>
</div>
{% endfor %}
{% else %}
<div class="flex gap-2 items-center time-slot-row">
<input type="time" name="start_time" class="flex-1 border rounded-lg px-3 py-2 text-sm">
<span class="text-gray-400"></span>
<input type="time" name="end_time" class="flex-1 border rounded-lg px-3 py-2 text-sm">
<input type="time" name="start_time"
class="field-input flex-1" style="padding:0.5rem 0.6rem; font-family:'JetBrains Mono',monospace; font-size:0.9rem;">
<span style="color:var(--mist); font-size:1rem;"></span>
<input type="time" name="end_time"
class="field-input flex-1" style="padding:0.5rem 0.6rem; font-family:'JetBrains Mono',monospace; font-size:0.9rem;">
<button type="button" onclick="this.closest('.time-slot-row').remove()"
class="text-red-400 hover:text-red-600 text-xl leading-none">×</button>
class="text-lg leading-none" style="color:var(--mist);"
onmouseover="this.style.color='var(--rust)'" onmouseout="this.style.color='var(--mist)'">×</button>
</div>
{% endif %}
</div>
<button type="button" onclick="addTimeSlot()"
class="mt-2 text-sm text-blue-600 hover:underline">+ Ajouter une plage</button>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Commentaire</label>
<textarea name="comment" rows="2"
class="w-full border rounded-lg px-3 py-2 text-sm"
placeholder="Formation, déplacement exceptionnel...">{{ entry.comment if entry and entry.comment else '' }}</textarea>
</div>
<div class="flex gap-3 pt-2">
<button type="submit"
class="flex-1 bg-blue-600 text-white py-3 rounded-lg font-semibold hover:bg-blue-700 transition">
Enregistrer
class="mt-2 text-xs font-semibold" style="color:var(--amber); letter-spacing:0.05em;">
+ Ajouter une plage
</button>
<a href="/" class="flex-1 text-center bg-gray-100 text-gray-700 py-3 rounded-lg font-semibold hover:bg-gray-200 transition">
Annuler
</a>
</div>
<!-- Commentaire -->
<div>
<label class="field-label">Commentaire</label>
<textarea name="comment" rows="2" class="field-input"
placeholder="Formation, déplacement exceptionnel…">{{ entry.comment if entry and entry.comment else '' }}</textarea>
</div>
<!-- Actions -->
<div class="flex gap-3 pt-1">
<button type="submit" class="btn-primary flex-1">Enregistrer</button>
<a href="/" class="btn-ghost flex-1">Annuler</a>
</div>
</form>
@@ -145,11 +144,14 @@ function addTimeSlot() {
const row = document.createElement('div');
row.className = 'flex gap-2 items-center time-slot-row';
row.innerHTML = `
<input type="time" name="start_time" class="flex-1 border rounded-lg px-3 py-2 text-sm">
<span class="text-gray-400">→</span>
<input type="time" name="end_time" class="flex-1 border rounded-lg px-3 py-2 text-sm">
<input type="time" name="start_time"
class="field-input flex-1" style="padding:0.5rem 0.6rem;font-family:'JetBrains Mono',monospace;font-size:0.9rem;">
<span style="color:var(--mist);font-size:1rem;">→</span>
<input type="time" name="end_time"
class="field-input flex-1" style="padding:0.5rem 0.6rem;font-family:'JetBrains Mono',monospace;font-size:0.9rem;">
<button type="button" onclick="this.closest('.time-slot-row').remove()"
class="text-red-400 hover:text-red-600 text-xl leading-none">×</button>
class="text-lg leading-none" style="color:var(--mist);"
onmouseover="this.style.color='var(--rust)'" onmouseout="this.style.color='var(--mist)'">×</button>
`;
container.appendChild(row);
}