summaryrefslogtreecommitdiff
path: root/app/views/targets
diff options
context:
space:
mode:
Diffstat (limited to 'app/views/targets')
-rw-r--r--app/views/targets/create.html.erb2
-rw-r--r--app/views/targets/edit.html.erb2
-rw-r--r--app/views/targets/index.html.erb68
-rw-r--r--app/views/targets/new.html.erb85
-rw-r--r--app/views/targets/show.html.erb3
-rw-r--r--app/views/targets/update.html.erb2
6 files changed, 162 insertions, 0 deletions
diff --git a/app/views/targets/create.html.erb b/app/views/targets/create.html.erb
new file mode 100644
index 0000000..51e2782
--- /dev/null
+++ b/app/views/targets/create.html.erb
@@ -0,0 +1,2 @@
+<h1>Targets#create</h1>
+<p>Find me in app/views/targets/create.html.erb</p>
diff --git a/app/views/targets/edit.html.erb b/app/views/targets/edit.html.erb
new file mode 100644
index 0000000..849bf7f
--- /dev/null
+++ b/app/views/targets/edit.html.erb
@@ -0,0 +1,2 @@
+<h1>Targets#edit</h1>
+<p>Find me in app/views/targets/edit.html.erb</p>
diff --git a/app/views/targets/index.html.erb b/app/views/targets/index.html.erb
new file mode 100644
index 0000000..b552038
--- /dev/null
+++ b/app/views/targets/index.html.erb
@@ -0,0 +1,68 @@
+<h1 class="display-1">Cibles</h1>
+
+<div class="btn-group my-3">
+ <%= link_to "Nouvelle Cible", new_target_path, class: "btn btn-primary" %>
+</div>
+
+<div class="table-responsive">
+ <table class="table table-sm table-striped table-hover align-middle mb-0">
+ <thead class="table-light">
+ <tr>
+ <th>Nom</th>
+ <th>Répartition</tr>
+ <th class="text-end" style="width: 140px;">Total %</th>
+ <th class="text-nowrap" style="width: 190px;">Créé le</th>
+ <th class="text-end" style="width: 180px;">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ <% if @targets.present? %>
+ <% @targets.each do |t| %>
+ <% sum_pct = t.target_allocations.sum { |a| a.percentage.to_f } %>
+ <% badge_class = (sum_pct - 100.0).abs <= 0.01 ? "bg-success" : "bg-danger" %>
+ <tr>
+ <td class="fw-semibold">
+ <%= link_to t.name.presence || "Objectif ##{t.id}", t %>
+ </td>
+ <td>
+ <% if t.target_allocations.empty? %>
+ <span class="text-muted">Aucune répartition définie</span>
+ <% else %>
+ <ul class="list-unstyled mb-0 d-flex flex-wrap gap-2">
+ <% t.target_allocations.each do |a| %>
+ <li class="badge text-bg-light border">
+ <%= a.nutrient_profile&.name || "Profil ##{a.nutrient_profile_id}" %>
+ — <%= number_with_precision(a.percentage.to_f, precision: 2) %>%
+ </li>
+ <% end %>
+ </ul>
+ <% end %>
+ </td>
+ <td class="text-end">
+ <span class="badge <%= badge_class %>">
+ <%= number_with_precision(sum_pct, precision: 2) %>%
+ </span>
+ </td>
+ <td class="text-nowrap">
+ <%= l(t.created_at, format: :short) %>
+ </td>
+ <td class="text-end text-nowrap">
+ <%= link_to "Voir", t, class: "btn btn-outline-secondary btn-sm" %>
+ <%= link_to "Modifier", edit_target_path(t), class: "btn btn-outline-primary btn-sm" %>
+ <%# FIXME: Doesn't work. %>
+ <%= link_to "Supprimer", t, class: "btn btn-outline-danger btn-sm",
+ data: { turbo_method: :delete, turbo_confirm: "Supprimer cet objectif ?" } %>
+ </td>
+ </tr>
+ <% end %>
+ <% else %>
+ <tr>
+ <td colspan="5" class="text-center py-4 text-muted">
+ Aucun objectif pour le moment.&nbsp;
+ <%= link_to "Créer le premier", new_target_path %>.
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+</div>
diff --git a/app/views/targets/new.html.erb b/app/views/targets/new.html.erb
new file mode 100644
index 0000000..42cb7bd
--- /dev/null
+++ b/app/views/targets/new.html.erb
@@ -0,0 +1,85 @@
+<% content_for :title, "Ajouter une Cible" %>
+
+<h1 class="display-1">Ajouter une Cible</h1>
+
+<%= form_with(model: @target) do |f| %>
+ <div class="card shadow-sm">
+ <div class="card-header">
+ <%= f.text_field :name, class: "form-control", placeholder: "Nom de la cible" %>
+ </div>
+
+ <div class="card-body p-0">
+ <div class="table-responsive">
+ <table class="table table-hover align-middle mb-0">
+ <thead class="table-light">
+ <tr>
+ <th>Profil</th>
+ <th class="text-end" style="width: 180px;">Proportion</th>
+ </tr>
+ </thead>
+ <tbody id="alloc-table-body">
+ <%= f.fields_for :target_allocations do |af| %>
+ <% np = af.object.nutrient_profile %>
+ <tr>
+ <td>
+ <%= af.hidden_field :nutrient_profile_id %>
+ <strong><%= np&.name.capitalize || "Profil ##{af.object.nutrient_profile_id}" %></strong>
+ </td>
+ <td class="text-end">
+ <div class="input-group input-group-sm" style="max-width: 160px; margin-left:auto;">
+ <%= af.number_field :percentage,
+ in: 0..100, step: 0.5,
+ class: "form-control text-end alloc-input",
+ placeholder: "0.0",
+ data: { action: "input->alloc#sum" } %>
+ <span class="input-group-text">%</span>
+ </div>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td class="small text-muted">Ajustez chaque pourcentage pour totaliser 100%.</td>
+ <td class="text-end">
+ <span class="badge bg-secondary" id="alloc-total">Total : 0%</span>
+ </td>
+ </tr>
+ </tfoot>
+ </table>
+ </div>
+ </div>
+
+ <div class="card-footer d-flex gap-2 justify-content-end">
+ <div class="btn-group">
+ <%= f.submit "Enregistrer l’objectif", class: "btn btn-primary", id: "submit-btn" %>
+ <%= link_to "Annuler", targets_path, class: "btn btn-secondary" %>
+ </div>
+ </div>
+ </div>
+<% end %>
+
+<script>
+ // Lightweight client-side sum check (no Stimulus required).
+ document.addEventListener("turbo:load", initAllocSum);
+ document.addEventListener("DOMContentLoaded", initAllocSum);
+
+ function initAllocSum() {
+ const inputs = document.querySelectorAll(".alloc-input");
+ const totalBadge = document.getElementById("alloc-total");
+ const submitBtn = document.getElementById("submit-btn");
+ if (!inputs.length || !totalBadge) return;
+
+ function updateTotal() {
+ let sum = 0;
+ inputs.forEach(i => sum += parseFloat(i.value || "0"));
+ const rounded = Math.round(sum * 100) / 100;
+ totalBadge.textContent = `Total : ${rounded}%`;
+ totalBadge.className = "badge " + (Math.abs(rounded - 100) < 0.01 ? "bg-success" : "bg-danger");
+ if (submitBtn) submitBtn.disabled = !(Math.abs(rounded - 100) < 0.01);
+ }
+
+ inputs.forEach(i => i.addEventListener("input", updateTotal));
+ updateTotal();
+ }
+</script>
diff --git a/app/views/targets/show.html.erb b/app/views/targets/show.html.erb
new file mode 100644
index 0000000..1525609
--- /dev/null
+++ b/app/views/targets/show.html.erb
@@ -0,0 +1,3 @@
+<h1>Targets#show</h1>
+
+<%# TODO: add table comparing this target with the most recent measurement. %>
diff --git a/app/views/targets/update.html.erb b/app/views/targets/update.html.erb
new file mode 100644
index 0000000..a39287c
--- /dev/null
+++ b/app/views/targets/update.html.erb
@@ -0,0 +1,2 @@
+<h1>Targets#update</h1>
+<p>Find me in app/views/targets/update.html.erb</p>
Copyright 2019--2025 Marius PETER