xtablo-source/go-backend/internal/web/views/home.go
2026-05-09 20:18:24 +02:00

242 lines
7.1 KiB
Go

package views
import (
"fmt"
"strings"
"time"
"github.com/a-h/templ"
tablomodel "xtablo-backend/internal/tablos"
)
const overviewProjectsPreviewLimit = 6
func sidebarNavItemClass(active bool) string {
if active {
return "sidebar-nav-item is-active"
}
return "sidebar-nav-item"
}
func isActivePath(activePath string, href string) bool {
return strings.TrimSpace(activePath) != "" && activePath == href
}
func sidebarNavItemID(href string) string {
switch href {
case "/":
return "sidebar-nav-home"
default:
slug := strings.Trim(strings.ReplaceAll(href, "/", "-"), "-")
if slug == "" {
slug = "item"
}
return "sidebar-nav-" + slug
}
}
type quickAction struct {
Title string
Description string
Icon string
}
type sidebarNavItem struct {
Href string
Label string
Icon string
Active bool
DividerAfter bool
}
type sidebarProjectItem struct {
Href string
Label string
Icon string
}
type dashboardTask struct {
Title string
Project string
ProjectKey string
ProjectHue string
Date string
Status string
StatusTone string
Completed bool
}
func dashboardDateLabel(now time.Time) string {
return now.Format("Monday, January 2")
}
func dashboardTodayLabel() string {
return dashboardDateLabel(time.Now())
}
func dashboardGreetingName(displayName string) string {
displayName = strings.TrimSpace(displayName)
if displayName == "" {
return "Arthur"
}
if len(displayName) == 1 {
return strings.ToUpper(displayName)
}
return strings.ToUpper(displayName[:1]) + displayName[1:]
}
func overviewQuickActions() []quickAction {
return []quickAction{
{Title: "Créer un projet", Description: "Définir les objectifs et le périmètre", Icon: "folder-plus"},
{Title: "Créer une tâche", Description: "Découper le travail en actions", Icon: "circle-plus"},
{Title: "Inviter l'équipe", Description: "Ajouter des collaborateurs", Icon: "user-plus"},
{Title: "Envoyer un message", Description: "Communiquer rapidement", Icon: "chat"},
}
}
func overviewTasks() []dashboardTask {
return []dashboardTask{
{Title: "yo", Project: "Hello", ProjectKey: "H", ProjectHue: "blue", Date: "Apr 16, 2026", Status: "À faire", StatusTone: "info", Completed: false},
{Title: "yo", Project: "Hello", ProjectKey: "H", ProjectHue: "blue", Date: "Apr 16, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
{Title: "hello", Project: "margot", ProjectKey: "M", ProjectHue: "red", Date: "Mar 7, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
{Title: "Bonjour", Project: "Jean Macon interet pour le produit de ta mere", ProjectKey: "J", ProjectHue: "purple", Date: "Feb 24, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
{Title: "Bonjour", Project: "Jean Macon interet pour le produit de ta mere", ProjectKey: "J", ProjectHue: "purple", Date: "Feb 21, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
{Title: "Faire ceci", Project: "bikip56648 / Arthur Belleville", ProjectKey: "B", ProjectHue: "blue", Date: "Nov 18, 2025", Status: "Terminé", StatusTone: "success", Completed: true},
{Title: "Hello monsieur", Project: "bikip56648 / Arthur Belleville", ProjectKey: "B", ProjectHue: "blue", Date: "Nov 18, 2025", Status: "Terminé", StatusTone: "success", Completed: true},
}
}
func OverviewProjectsFromTablos(tablos []tablomodel.Record) []TabloCardView {
projects := make([]TabloCardView, 0, len(tablos))
for _, tablo := range tablos {
statusLabel, statusTone, progress := overviewProjectStatus(tablo.Status)
projects = append(projects, TabloCardView{
ID: tablo.ID.String(),
Name: tablo.Name,
Status: string(tablo.Status),
StatusLabel: statusLabel,
StatusTone: statusTone,
Initial: projectInitial(tablo.Name),
Accent: overviewProjectAccent(tablo.Name),
CardDateLabel: tablo.CreatedAt.Format("Jan 02, 2006"),
Progress: progress,
ProgressLabel: progressPercentLabel(progress),
DeleteRequestURL: "/tablos/" + tablo.ID.String(),
})
}
return projects
}
func visibleOverviewProjects(projects []TabloCardView, showAll bool) []TabloCardView {
if showAll || len(projects) <= overviewProjectsPreviewLimit {
return projects
}
return projects[:overviewProjectsPreviewLimit]
}
func hiddenOverviewProjectsCount(projects []TabloCardView, showAll bool) int {
if showAll || len(projects) <= overviewProjectsPreviewLimit {
return 0
}
return len(projects) - overviewProjectsPreviewLimit
}
func sidebarPrimaryNavItems(activePath string) []sidebarNavItem {
return []sidebarNavItem{
{Href: "/", Label: "Aperçu", Icon: "panels", Active: isActivePath(activePath, "/"), DividerAfter: true},
{Href: "/tasks", Label: "Tâches", Icon: "tasks", Active: isActivePath(activePath, "/tasks")},
{Href: "/tablos", Label: "Projets", Icon: "layers", Active: isActivePath(activePath, "/tablos"), DividerAfter: true},
{Href: "/planning", Label: "Planning", Icon: "planning", Active: isActivePath(activePath, "/planning")},
{Href: "/chat", Label: "Discussions", Icon: "chat", Active: isActivePath(activePath, "/chat")},
{Href: "/files", Label: "Fichiers", Icon: "files", Active: isActivePath(activePath, "/files")},
}
}
func sidebarProjectItems() []sidebarProjectItem {
return []sidebarProjectItem{
{Href: "/tablos/hello", Label: "Hello", Icon: "bolt"},
{Href: "/tablos/atelier", Label: "Atelier Produit", Icon: "gem"},
{Href: "/tablos/arthur", Label: "Arthur Belleville", Icon: "bolt"},
{Href: "/tablos/equipe", Label: "Equipe Design", Icon: "bolt"},
}
}
func sidebarFooterNavItems(activePath string) []sidebarNavItem {
return []sidebarNavItem{
{Href: "/feedback", Label: "Feedback", Icon: "send", Active: isActivePath(activePath, "/feedback")},
}
}
func toneClass(tone string) string {
switch tone {
case "warning":
return "tone-warning"
case "success":
return "tone-success"
default:
return "tone-info"
}
}
func projectAccentClass(accent string) string {
switch accent {
case "purple":
return "project-accent-purple"
case "red":
return "project-accent-red"
default:
return "project-accent-blue"
}
}
func taskRowClass(completed bool) string {
if completed {
return "task-row is-complete"
}
return "task-row"
}
func taskCheckClass(completed bool) string {
if completed {
return "task-check is-complete"
}
return "task-check"
}
func progressPercentLabel(progress int) string {
return fmt.Sprintf("%d%%", progress)
}
func progressInlineStyle(progress int) templ.SafeCSS {
return templ.SanitizeCSS("width", templ.SafeCSSProperty(progressPercentLabel(progress)))
}
func overviewProjectStatus(status tablomodel.Status) (string, string, int) {
switch status {
case tablomodel.StatusInProgress:
return "En cours", "warning", 50
case tablomodel.StatusDone:
return "Terminé", "success", 100
default:
return "À faire", "info", 0
}
}
func overviewProjectAccent(name string) string {
switch len(strings.TrimSpace(name)) % 3 {
case 1:
return "purple"
case 2:
return "red"
default:
return "blue"
}
}
func projectInitial(name string) string {
name = strings.TrimSpace(name)
if name == "" {
return "P"
}
return strings.ToUpper(name[:1])
}