- Dashboard: French header "Mes Projets", underline-tab view toggle (grid/list), filter tabs (Tous/Pas commencé/En cours/Terminé) with JS client-side filtering
- Cards: display status derived from progress (À faire/En cours/Terminé), rounded-xl p-6, w-8 h-8 avatar, green-500 progress bar, dashed "Créé le" footer
- Click on card/row navigates to /tablos/{uuid} via event delegation (delete zone stops propagation)
- List view: single-column grid, rows show status + title + date + task count
- CSS: .view-tab and .filter-tab with .is-active state
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
73 lines
2.5 KiB
Go
73 lines
2.5 KiB
Go
package templates
|
|
|
|
import "strings"
|
|
|
|
// BreadcrumbItem represents one crumb in the top header breadcrumb trail.
|
|
// If Href is empty, the item renders as plain text (current page — no link).
|
|
type BreadcrumbItem struct {
|
|
Label string
|
|
Href string
|
|
}
|
|
|
|
// sidebarNavItem describes one entry in the sidebar primary navigation list.
|
|
type sidebarNavItem struct {
|
|
Href string
|
|
Label string
|
|
Icon string
|
|
Active bool
|
|
DividerBefore bool
|
|
}
|
|
|
|
// navItemWrapperClass returns the Tailwind class string for a nav item wrapper.
|
|
func navItemWrapperClass(active bool) string {
|
|
if active {
|
|
return "flex w-full px-2.5 py-2 rounded-md cursor-pointer bg-purple-100 font-semibold"
|
|
}
|
|
return "flex w-full px-2.5 py-2 rounded-md cursor-pointer hover:bg-gray-100 font-medium"
|
|
}
|
|
|
|
// navItemLabelClass returns the Tailwind class string for a nav item text label.
|
|
func navItemLabelClass(active bool) string {
|
|
if active {
|
|
return "text-base font-normal text-[#804EEC]"
|
|
}
|
|
return "text-base font-normal text-gray-500"
|
|
}
|
|
|
|
// navItemIconClass returns the Tailwind class string for a nav item icon wrapper.
|
|
func navItemIconClass(active bool) string {
|
|
if active {
|
|
return "[&>svg]:w-5 [&>svg]:h-5 text-[#804EEC]"
|
|
}
|
|
return "[&>svg]:w-5 [&>svg]:h-5 text-gray-500"
|
|
}
|
|
|
|
// isActivePath reports whether activePath matches href.
|
|
func isActivePath(activePath string, href string) bool {
|
|
return strings.TrimSpace(activePath) != "" && activePath == href
|
|
}
|
|
|
|
// tabloDisplayStatus derives a display status from progress for client-side filtering.
|
|
// "pas-commence" = 0% (no tasks or none done), "en-cours" = 1-99%, "termine" = 100%.
|
|
func tabloDisplayStatus(progress, totalTasks int) string {
|
|
if totalTasks == 0 || progress == 0 {
|
|
return "pas-commence"
|
|
}
|
|
if progress >= 100 {
|
|
return "termine"
|
|
}
|
|
return "en-cours"
|
|
}
|
|
|
|
// sidebarPrimaryNavItems returns the ordered sidebar nav items.
|
|
// French labels match the production app. DividerBefore adds an <hr> separator before the item.
|
|
func sidebarPrimaryNavItems(activePath string) []sidebarNavItem {
|
|
return []sidebarNavItem{
|
|
{Href: "/", Label: "Aperçu", Icon: "panels", Active: isActivePath(activePath, "/")},
|
|
{Href: "#", Label: "Tâches", Icon: "tasks", Active: false, DividerBefore: true},
|
|
{Href: "/", Label: "Projets", Icon: "layers", Active: false},
|
|
{Href: "/planning", Label: "Planning", Icon: "planning", Active: isActivePath(activePath, "/planning"), DividerBefore: true},
|
|
{Href: "#", Label: "Discussions", Icon: "chat", Active: false},
|
|
{Href: "#", Label: "Fichiers", Icon: "files", Active: false},
|
|
}
|
|
}
|