feat(19): tablo card — icon+title+status pill, date, progress, edit+trash

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Arthur Belleville 2026-05-17 22:20:53 +02:00
parent af8b4fa38f
commit 7864c39872
No known key found for this signature in database

View file

@ -125,7 +125,7 @@ templ TabloProjectCard(card TabloCardView, csrfToken string) {
>
<!-- Card view (default: visible in grid layout) -->
<div class="bg-white rounded-xl p-5 border border-[#EAECF0] hover:shadow-md transition-shadow cursor-pointer project-card flex flex-col gap-3">
<!-- Row 1: icon + title -->
<!-- Row 1: icon + title + status pill -->
<div class="flex items-center gap-3">
if card.Tablo.Color.Valid && card.Tablo.Color.String != "" {
<div class="w-8 h-8 rounded-lg flex items-center justify-center shrink-0" style={ "background-color: " + card.Tablo.Color.String }>
@ -144,38 +144,51 @@ templ TabloProjectCard(card TabloCardView, csrfToken string) {
</span>
</div>
}
<h3 class="text-base font-semibold text-gray-900 flex-1 line-clamp-2">{ card.Tablo.Title }</h3>
</div>
<!-- Row 2: status badge + edit + delete (same line) -->
<div class="flex items-center justify-between pt-1 border-t border-gray-100">
<h3 class="text-sm font-semibold text-gray-900 flex-1 line-clamp-1">{ card.Tablo.Title }</h3>
if card.Tablo.Status == "archived" {
<span class="px-2.5 py-1 rounded-full text-xs font-medium bg-gray-100 text-gray-600 border border-gray-200">Archivé</span>
<span class="shrink-0 px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600 border border-gray-200">Archivé</span>
} else {
<span class="px-2.5 py-1 rounded-full text-xs font-medium bg-green-50 text-green-600 border border-green-200">Actif</span>
<span class="shrink-0 px-2 py-0.5 rounded-full text-xs font-medium bg-green-50 text-green-600 border border-green-200">Actif</span>
}
<div class="flex items-center gap-1">
<a
href={ templ.SafeURL("/tablos/" + card.Tablo.ID.String()) }
class="inline-flex items-center justify-center w-8 h-8 rounded-md text-gray-400 hover:text-blue-600 hover:bg-blue-50 transition-colors"
aria-label="Edit tablo"
onclick="event.stopPropagation()"
>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4" aria-hidden="true"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</a>
<div class="tablo-delete-zone">
@ui.IconButton(ui.IconButtonProps{
Label: "Delete tablo",
Icon: "trash",
Variant: ui.IconButtonVariantDanger,
Tone: ui.IconButtonToneGhost,
Type: "button",
Attrs: templ.Attributes{
"hx-get": "/tablos/" + card.Tablo.ID.String() + "/delete-confirm",
"hx-target": "closest .tablo-delete-zone",
"hx-swap": "outerHTML",
},
})
</div>
</div>
<!-- Row 2: creation date -->
<div class="flex items-center gap-1.5 text-xs text-gray-500">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3.5 h-3.5 shrink-0" aria-hidden="true"><path d="M8 2v4"></path><path d="M16 2v4"></path><rect width="18" height="18" x="3" y="4" rx="2"></rect><path d="M3 10h18"></path></svg>
<span>{ card.Tablo.CreatedAt.Time.Format("2 Jan 2006") }</span>
</div>
<!-- Row 3: progress bar -->
<div class="project-card-progress-row">
<div class="flex justify-between items-center mb-1.5">
<span class="text-xs text-gray-500">{ strconv.Itoa(card.DoneTasks) }/{ strconv.Itoa(card.TotalTasks) } tâches</span>
<span class="text-xs font-semibold text-gray-700">{ strconv.Itoa(card.Progress) }%</span>
</div>
<div class="w-full bg-gray-100 rounded-full h-1.5 project-progress-track">
<div class="bg-purple-500 h-1.5 rounded-full project-card-progress-bar" style={ "width: " + strconv.Itoa(card.Progress) + "%" }></div>
</div>
</div>
<!-- Row 4: edit + delete -->
<div class="flex items-center gap-1 pt-1 border-t border-gray-100">
<a
href={ templ.SafeURL("/tablos/" + card.Tablo.ID.String()) }
class="inline-flex items-center justify-center w-7 h-7 rounded-md text-gray-400 hover:text-blue-600 hover:bg-blue-50 transition-colors"
aria-label="Edit tablo"
onclick="event.stopPropagation()"
>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-3.5 h-3.5" aria-hidden="true"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
</a>
<div class="tablo-delete-zone">
@ui.IconButton(ui.IconButtonProps{
Label: "Delete tablo",
Icon: "trash",
Variant: ui.IconButtonVariantDanger,
Tone: ui.IconButtonToneGhost,
Type: "button",
Attrs: templ.Attributes{
"hx-get": "/tablos/" + card.Tablo.ID.String() + "/delete-confirm",
"hx-target": "closest .tablo-delete-zone",
"hx-swap": "outerHTML",
},
})
</div>
</div>
</div>