251 lines
7.4 KiB
Go
251 lines
7.4 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,
|
|
Color: strings.TrimSpace(tablo.Color),
|
|
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(),
|
|
EditRequestURL: "/tablos/" + tablo.ID.String() + "/edit",
|
|
})
|
|
}
|
|
return projects
|
|
}
|
|
|
|
func visibleOverviewProjects(projects []TabloCardView) []TabloCardView {
|
|
if len(projects) <= overviewProjectsPreviewLimit {
|
|
return projects
|
|
}
|
|
return projects[:overviewProjectsPreviewLimit]
|
|
}
|
|
|
|
func hiddenOverviewProjects(projects []TabloCardView) []TabloCardView {
|
|
if len(projects) <= overviewProjectsPreviewLimit {
|
|
return nil
|
|
}
|
|
return projects[overviewProjectsPreviewLimit:]
|
|
}
|
|
|
|
func hiddenOverviewProjectsCount(projects []TabloCardView) int {
|
|
if 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])
|
|
}
|