Files
vault171/app/views/items/show.html.erb
David Böhm 44d019b4b5
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
Added Items and Dashboard
2026-05-22 03:52:54 +02:00

242 lines
13 KiB
Plaintext

<!--<%# content_for :title, "Showing item" %>
<div class="md:w-2/3 w-full">
<% if notice.present? %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block" id="notice"><%= notice %></p>
<% end %>
<h1 class="font-bold text-4xl">Showing item</h1>
<%#= render @item %>
<%= link_to "Edit this item", edit_item_path(@item), class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= link_to "Back to items", items_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= button_to "Destroy this item", @item, method: :delete, form_class: "sm:inline-block mt-2 sm:mt-0 sm:ml-2", class: "w-full rounded-md px-3.5 py-2.5 text-white bg-red-600 hover:bg-red-500 font-medium cursor-pointer", data: { turbo_confirm: "Are you sure?" } %>
</div>
-->
<% content_for :title, "Artikel-Details: #{@item.name}" %>
<!-- OBERE AKTIONSLISTE (Yield im Top-Bar deines Hauptlayouts) -->
<% content_for :top_bar_actions do %>
<div class="flex items-center gap-2">
<%= link_to items_path, class: "py-2 px-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 flex items-center gap-1.5 shadow-sm transition" do %>
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" /></svg>
Zurück
<% end %>
<%= link_to edit_item_path(@item), class: "py-2 px-3 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg flex items-center gap-1.5 shadow-sm transition" do %>
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /></svg>
Bearbeiten
<% end %>
</div>
<% end %>
<div class="max-w-4xl mx-auto space-y-6">
<!-- ZWEI-SPALTIGES CORE-LAYOUT -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- LINKE SEITE: STAMMDATEN & VERANTWORTLICHKEIT (2 Spalten breit) -->
<div class="md:col-span-2 space-y-6">
<!-- STAMMDATEN-BOX -->
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 space-y-4">
<div>
<span class="inline-flex items-center py-0.5 px-2.5 rounded-full text-xs font-semibold bg-blue-50 text-blue-800 border border-blue-200">
<%= @item.category.name %>
</span>
<h2 class="text-xl font-bold text-gray-900 mt-2"><%= @item.name %></h2>
</div>
<hr class="border-gray-200">
<div class="grid grid-cols-2 gap-4 text-sm">
<div>
<p class="text-xs font-semibold text-gray-400 uppercase">Artikelnummer (SKU)</p>
<p class="font-mono text-gray-800 font-semibold mt-0.5"><%= @item.sku %></p>
</div>
<div>
<p class="text-xs font-semibold text-gray-400 uppercase">Seriennummer (Hersteller)</p>
<p class="font-mono text-gray-800 font-semibold mt-0.5"><%= @item.serial_number %></p>
</div>
<div>
<p class="text-xs font-semibold text-gray-400 uppercase">Anschaffungspreis</p>
<p class="text-gray-800 mt-0.5 font-medium">
<%= number_to_currency(@item.price, unit: "€", separator: ",", delimiter: ".", format: "%n %u") %>
</p>
</div>
<div>
<p class="text-xs font-semibold text-gray-400 uppercase">Registriert am</p>
<p class="text-gray-600 mt-0.5"><%= l(@item.created_at, format: :short) %></p>
</div>
</div>
<% if @item.notes.present? %>
<hr class="border-gray-200">
<div>
<p class="text-xs font-semibold text-gray-400 uppercase">Beschreibung / Notizen</p>
<p class="text-sm text-gray-600 mt-1 leading-relaxed"><%= @item.notes %></p>
</div>
<% end %>
</div>
<!-- STANDORT / AKTUELLE ZUWEISUNG -->
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6">
<h3 class="text-sm font-bold text-gray-400 uppercase tracking-wider mb-3">Aktueller Status & Aufenthaltsort</h3>
<% if @item.user.present? %>
<div class="flex items-center gap-4 p-4 bg-green-50/50 border border-green-200 rounded-xl">
<div class="p-3 bg-green-100 text-green-700 rounded-lg">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" /></svg>
</div>
<div>
<p class="text-xs font-semibold text-green-800 uppercase tracking-wide">In Benutzung (Mitarbeiter)</p>
<h4 class="text-sm font-bold text-gray-900 mt-0.5"><%= @item.user.name %></h4>
<p class="text-xs text-gray-500"><%= @item.user.department&.name || "Keine Abteilung hinterlegt" %></p>
</div>
</div>
<% elsif @item.room.present? %>
<div class="flex items-center gap-4 p-4 bg-blue-50/50 border border-blue-200 rounded-xl">
<div class="p-3 bg-blue-100 text-blue-700 rounded-lg">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25s-7.5-4.108-7.5-11.25a7.5 7.5 0 1 1 15 0Z" /></svg>
</div>
<div>
<p class="text-xs font-semibold text-blue-800 uppercase tracking-wide">Fest verbaut / Zugewiesener Raum</p>
<h4 class="text-sm font-bold text-gray-900 mt-0.5"><%= @item.room.name %></h4>
<p class="text-xs text-gray-500"><%= @item.room.building %> • <%= @item.room.floor %></p>
</div>
</div>
<% else %>
<div class="flex items-center gap-4 p-4 bg-amber-50/50 border border-amber-200 rounded-xl">
<div class="p-3 bg-amber-100 text-amber-700 rounded-lg">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 0 1-2.247 2.118H6.622a2.25 2.25 0 0 1-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" /></svg>
</div>
<div>
<p class="text-xs font-semibold text-amber-800 uppercase tracking-wide">Verfügbar</p>
<h4 class="text-sm font-bold text-gray-900 mt-0.5">Im Hauptlager</h4>
<p class="text-xs text-gray-500">Bereit zur Zuweisung an Mitarbeiter oder Räume.</p>
</div>
</div>
<% end %>
</div>
</div>
<!-- RECHTE SEITE: INTERNE INVENTAR-PLAKETTE (1 Spalte breit) -->
<div class="space-y-6">
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-4 text-center space-y-4">
<p class="text-xs font-bold text-gray-400 uppercase tracking-wider">Interne Kennzeichnung</p>
<!-- QR-Code Render Box -->
<div class="w-36 h-36 bg-white p-2 border border-gray-200 rounded-lg flex items-center justify-center mx-auto shadow-inner">
<%= @item.generate_qr_code %>
</div>
<div>
<p class="text-xs text-gray-400 font-medium">Inventarnummer</p>
<p class="text-base font-mono font-bold text-blue-600 mt-0.5">#<%= @item.sticker_id %></p>
</div>
<p class="text-[10px] text-gray-400 leading-normal px-2">Vorgedrucktes Etikett vom A4-Bogen. Scan im System führt direkt hierher.</p>
</div>
</div>
</div>
<!-- LEISTE UNTEN: VERLAUFSHISTORIE (Perfektioniertes Icon-Timeline-Design) -->
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 md:p-8">
<div class="mb-4 flex items-center gap-2">
<!-- Heroicon: clock -->
<svg class="h-5 w-5 text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
<h3 class="text-base font-bold text-gray-800">Besitzer- & Standortverlauf</h3>
</div>
<hr class="border-gray-200 mb-6">
<div class="flow-root">
<% if @assignment_logs.any? %>
<ul class="-mb-8">
<% @assignment_logs.each_with_index do |log, index| %>
<% is_last = (index == @assignment_logs.size - 1) %>
<li>
<div class="relative pb-8">
<!-- Vertikale Verbindungslinie nach unten (wird beim letzten Element versteckt) -->
<% unless is_last %>
<span class="absolute top-5 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
<% end %>
<div class="relative flex space-x-3">
<div>
<!-- DER ICON-KREIS: Ändert Farbe und Inhalt dynamisch nach Zuweisungstyp -->
<% if log.user.present? %>
<!-- Zustand: Beim Mitarbeiter (Grün / User-Icon) -->
<span class="h-8 w-8 rounded-full bg-green-50 flex items-center justify-center ring-8 ring-white text-green-600">
<!-- Heroicon: user -->
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" /></svg>
</span>
<% elsif log.room.present? %>
<!-- Zustand: Im Raum (Blau / Pin-Icon) -->
<span class="h-8 w-8 rounded-full bg-blue-50 flex items-center justify-center ring-8 ring-white text-blue-600">
<!-- Heroicon: map-pin -->
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25s-7.5-4.108-7.5-11.25a7.5 7.5 0 1 1 15 0Z" /></svg>
</span>
<% else %>
<!-- Zustand: Im Hauptlager (Grau / Paket-Icon) -->
<span class="h-8 w-8 rounded-full bg-gray-100 flex items-center justify-center ring-8 ring-white text-gray-600">
<!-- Heroicon: cube -->
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><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.5v9l5.25 3.03M12 12.75v9" /></svg>
</span>
<% end %>
</div>
<!-- TEXTINHALT -->
<div class="flex-1 min-w-0 pt-1.5 flex justify-between space-x-4 text-sm">
<div>
<h4 class="font-bold text-gray-800">
<% if log.user.present? %>
Zuweisung an Mitarbeiter: <span class="text-gray-900 font-extrabold"><%= log.user.name %></span>
<% elsif log.room.present? %>
Standortwechsel in Raum: <span class="text-gray-900 font-extrabold"><%= log.room.name_with_building %></span>
<% else %>
Ins Hauptlager übergeben
<% end %>
</h4>
<% if log.returned_at.nil? %>
<span class="inline-flex items-center mt-1.5 py-0.5 px-2 rounded-full text-[10px] font-semibold bg-green-100 text-green-800 border border-green-200">
Aktueller Standort
</span>
<% end %>
</div>
<!-- DATUMSAUSGABE -->
<div class="text-right text-xs whitespace-nowrap text-gray-400 pt-0.5 shrink-0 font-medium">
<time class="text-gray-600">
<%= l(log.assigned_at, format: "%d. %b %Y") %>
<% if log.returned_at.present? %>
bis <%= l(log.returned_at, format: "%d. %b %Y") %>
<% else %>
(Laufend)
<% end %>
</time>
</div>
</div>
</div>
</div>
</li>
<% end %>
</ul>
<% else %>
<div class="text-center py-6 text-gray-400 text-sm">
Bisher wurden keine historischen Übergaben für dieses Gerät verzeichnet.
</div>
<% end %>
</div>
</div>
</div>