✨ feat(templates-points-controle): Ajoute la gestion et l'application de modèles de points de contrôle aux produits.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
|
||||
{% if not is_online() %}
|
||||
<div class="bg-red-600 text-white text-center py-2 px-4 font-bold text-sm sticky top-0 z-[60]">
|
||||
Votre site internet n'est actuellement pas en ligne. Aucun référencement n'est possible. Pour demander sa mise en ligne, rendez-vous dans votre intranet pour effectuer la demande d'activation.
|
||||
Votre site internet n'est actuellement pas en ligne. Aucun référencement n'est possible et aucun paiement ne sera possible. Pour demander sa mise en ligne, rendez-vous dans votre intranet pour effectuer la demande d'activation.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -45,14 +45,17 @@
|
||||
{% endmacro %}
|
||||
{% import _self as menu %}
|
||||
|
||||
{{ menu.nav_link(path('app_crm'), 'Dashboard', '<path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>', 'app_crm') }}
|
||||
{{ menu.nav_link(path('app_crm_reservation'), 'Planing de réservation', '<path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>', 'app_crm_reservation') }}
|
||||
{{ menu.nav_link(path('app_crm_product'), 'Produits', '<path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>', 'app_crm_product') }}
|
||||
{{ menu.nav_link(path('app_crm_formules'), 'Formules', '<path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>', 'app_crm_formules') }}
|
||||
{{ menu.nav_link(path('app_crm_facture'), 'Facture', '<path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>', 'app_crm_facture') }}
|
||||
{{ menu.nav_link(path('app_crm_customer'), 'Clients', '<path d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path>', 'app_clients') }}
|
||||
{{ menu.nav_link(path('app_crm_prestataire'), 'Prestataires', '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>', 'app_crm_prestataire') }}
|
||||
|
||||
{{ menu.nav_link(path('app_crm'), 'Dashboard', '<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-2.25A2.25 2.25 0 0113.5 18v-2.25z" />', 'app_crm') }}
|
||||
{{ menu.nav_link(path('app_crm_reservation'), 'Planing de réservation', '<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />', 'app_crm_reservation') }}
|
||||
{{ menu.nav_link(path('app_template_point_controle_index'), 'Modèles de contrôle', '<path stroke-linecap="round" stroke-linejoin="round" d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z" />', 'app_template_point_controle_index') }}
|
||||
{{ menu.nav_link(path('app_crm_product'), 'Produits', '<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />', 'app_crm_product') }}
|
||||
{{ menu.nav_link(path('app_crm_formules'), 'Formules', '<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-9-5.25L3 7.5m18 0l-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />', 'app_crm_formules') }}
|
||||
{{ menu.nav_link(path('app_crm_facture'), 'Facture', '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />', 'app_crm_facture') }}
|
||||
{{ menu.nav_link(path('app_crm_customer'), 'Clients', '<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" />', 'app_crm_customer') }}
|
||||
{{ menu.nav_link(path('app_crm_devis'), 'Devis', '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 00-3.7-3.7 48.678 48.678 0 00-7.324 0 4.006 4.006 0 00-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3l-3-3m-12 3c0 1.232.046 2.453.138 3.662a4.006 4.006 0 003.7 3.7 48.656 48.656 0 007.324 0 4.006 4.006 0 003.7-3.7c.017-.22.032-.441.046-.662M4.5 12l3 3m-3-3l-3 3" />', 'app_crm_devis') }}
|
||||
{{ menu.nav_link(path('app_crm_contrats'), 'Contrat de location', '<path stroke-linecap="round" stroke-linejoin="round" d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z" />', 'app_crm_contrats') }}
|
||||
{{ menu.nav_link(path('app_crm_prestataire'), 'Prestataires', '<path stroke-linecap="round" stroke-linejoin="round" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>', 'app_crm_prestataire') }}
|
||||
|
||||
{% set pendingCount = getPendingOrderSessionCount() %}
|
||||
<a data-turbo="false" href="{{ path('app_crm_flow') }}" class="flex items-center justify-between px-4 py-3 rounded-xl transition-all duration-200 group {{ app.current_route == 'app_crm_flow' ? 'bg-blue-600 text-white shadow-lg shadow-blue-500/30' : 'hover:bg-slate-800 text-slate-400' }}">
|
||||
<div class="flex items-center space-x-3">
|
||||
@@ -223,4 +226,4 @@
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -618,6 +618,30 @@
|
||||
Points de Contrôle (Entretien)
|
||||
</h3>
|
||||
|
||||
{# TEMPLATE SELECTION #}
|
||||
{% if templates is defined and templates|length > 0 %}
|
||||
<div class="mb-8 p-6 bg-slate-900/30 rounded-2xl border border-white/5 backdrop-blur-sm">
|
||||
<label class="text-[10px] font-black text-slate-300 uppercase tracking-widest mb-3 block flex items-center gap-2">
|
||||
<svg class="w-3 h-3 text-teal-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"></path></svg>
|
||||
Importer un modèle
|
||||
</label>
|
||||
<div class="flex flex-col sm:flex-row gap-4">
|
||||
<select id="template-selector" class="flex-1 bg-slate-900/50 border-white/5 rounded-2xl text-white py-3 px-4 text-sm focus:ring-teal-500/20 focus:border-teal-500 transition-all outline-none">
|
||||
<option value="">Choisir un modèle...</option>
|
||||
{% for t in templates %}
|
||||
<option value="{{ t.id }}">{{ t.name }} ({{ t.points|length }} points)</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button is="template-apply" type="button"
|
||||
data-selector="#template-selector"
|
||||
data-url-pattern="{{ path('app_template_point_controle_apply', {'id': 'TEMPLATE_ID', 'productId': product.id}) }}"
|
||||
class="px-6 py-3 bg-teal-600 hover:bg-teal-500 text-white text-[10px] font-black uppercase tracking-widest rounded-2xl transition-all shadow-lg shadow-teal-600/20 whitespace-nowrap">
|
||||
Appliquer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="space-y-3 mb-8">
|
||||
{% for point in product.productPointControlls %}
|
||||
<div class="flex items-center justify-between p-4 bg-white/5 border border-white/5 rounded-2xl group hover:bg-white/10 transition-all">
|
||||
|
||||
36
templates/dashboard/template_point_controle/edit.twig
Normal file
36
templates/dashboard/template_point_controle/edit.twig
Normal file
@@ -0,0 +1,36 @@
|
||||
{% extends 'dashboard/base.twig' %}
|
||||
|
||||
{% block title %}Éditer le modèle{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="max-w-2xl mx-auto space-y-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-2xl font-bold text-white">Éditer le modèle</h1>
|
||||
<a href="{{ path('app_template_point_controle_index') }}" class="text-slate-400 hover:text-white transition-colors">Retour</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-800 rounded-xl p-6 shadow-sm border border-slate-700">
|
||||
<form method="post" class="space-y-6">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-slate-300 mb-2">Nom du modèle</label>
|
||||
<input type="text" id="name" name="name" value="{{ template.name }}" required
|
||||
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-4 py-2 text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="points" class="block text-sm font-medium text-slate-300 mb-2">Points de contrôle (un par ligne)</label>
|
||||
<textarea id="points" name="points" rows="10" required
|
||||
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-4 py-2 text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all font-mono text-sm">{{ template.points|join('
|
||||
') }}</textarea>
|
||||
<p class="mt-1 text-xs text-slate-500">Saisissez chaque point de contrôle sur une nouvelle ligne.</p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end pt-4">
|
||||
<button type="submit" class="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors">
|
||||
Mettre à jour
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
54
templates/dashboard/template_point_controle/index.twig
Normal file
54
templates/dashboard/template_point_controle/index.twig
Normal file
@@ -0,0 +1,54 @@
|
||||
{% extends 'dashboard/base.twig' %}
|
||||
|
||||
{% block title %}Modèles de points de contrôle{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="space-y-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-2xl font-bold text-white">Modèles de points de contrôle</h1>
|
||||
<a href="{{ path('app_template_point_controle_new') }}" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
|
||||
Nouveau modèle
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-800 rounded-xl overflow-hidden shadow-sm border border-slate-700">
|
||||
<table class="w-full text-left text-sm text-slate-400">
|
||||
<thead class="bg-slate-900/50 text-xs uppercase font-medium text-slate-300">
|
||||
<tr>
|
||||
<th class="px-6 py-4">Nom</th>
|
||||
<th class="px-6 py-4">Points</th>
|
||||
<th class="px-6 py-4 text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-700">
|
||||
{% for template in templates %}
|
||||
<tr class="hover:bg-slate-700/30 transition-colors">
|
||||
<td class="px-6 py-4 font-medium text-white">{{ template.name }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<ul class="list-disc list-inside">
|
||||
{% for point in template.points|slice(0, 3) %}
|
||||
<li>{{ point }}</li>
|
||||
{% endfor %}
|
||||
{% if template.points|length > 3 %}
|
||||
<li class="list-none text-xs italic opacity-70">+ {{ template.points|length - 3 }} autres...</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-right space-x-2">
|
||||
<a href="{{ path('app_template_point_controle_edit', {'id': template.id}) }}" class="text-blue-400 hover:text-blue-300 transition-colors">Éditer</a>
|
||||
<form method="post" action="{{ path('app_template_point_controle_delete', {'id': template.id}) }}" class="inline-block" onsubmit="return confirm('Êtes-vous sûr ?');">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ template.id) }}">
|
||||
<button class="text-red-400 hover:text-red-300 transition-colors">Supprimer</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="3" class="px-6 py-8 text-center italic opacity-50">Aucun modèle trouvé.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
37
templates/dashboard/template_point_controle/new.twig
Normal file
37
templates/dashboard/template_point_controle/new.twig
Normal file
@@ -0,0 +1,37 @@
|
||||
{% extends 'dashboard/base.twig' %}
|
||||
|
||||
{% block title %}Nouveau modèle de points de contrôle{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="max-w-2xl mx-auto space-y-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-2xl font-bold text-white">Nouveau modèle</h1>
|
||||
<a href="{{ path('app_template_point_controle_index') }}" class="text-slate-400 hover:text-white transition-colors">Retour</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-800 rounded-xl p-6 shadow-sm border border-slate-700">
|
||||
<form method="post" class="space-y-6">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-slate-300 mb-2">Nom du modèle</label>
|
||||
<input type="text" id="name" name="name" required
|
||||
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-4 py-2 text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all"
|
||||
placeholder="Ex: Contrôle structure gonflable">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="points" class="block text-sm font-medium text-slate-300 mb-2">Points de contrôle (un par ligne)</label>
|
||||
<textarea id="points" name="points" rows="10" required
|
||||
class="w-full bg-slate-900 border border-slate-700 rounded-lg px-4 py-2 text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all font-mono text-sm"
|
||||
placeholder="Vérifier les coutures Vérifier la soufflerie Nettoyer la bâche..."></textarea>
|
||||
<p class="mt-1 text-xs text-slate-500">Saisissez chaque point de contrôle sur une nouvelle ligne.</p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end pt-4">
|
||||
<button type="submit" class="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors">
|
||||
Créer le modèle
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
{% if not is_online() %}
|
||||
<div class="bg-red-600 text-white text-center py-2 px-4 font-bold text-sm sticky top-0 z-[60]">
|
||||
Votre site internet n'est actuellement pas en ligne. Aucun référencement n'est possible. Pour demander sa mise en ligne, rendez-vous dans votre intranet pour effectuer la demande d'activation.
|
||||
Votre site internet n'est actuellement pas en ligne. Aucun référencement n'est possible et aucun paiement ne sera possible. Pour demander sa mise en ligne, rendez-vous dans votre intranet pour effectuer la demande d'activation.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user