xtablo-source/backend/templates/dashboard_forms.go
Arthur Belleville 5d0c201e86
Some checks failed
backend-ci / Backend tests (pull_request) Failing after 53s
backend-ci / Backend tests (push) Failing after 1s
Some work
2026-05-23 17:26:01 +02:00

178 lines
4 KiB
Go

package templates
import (
"fmt"
"time"
"backend/internal/db/sqlc"
)
// DashboardHomeData is view-model data for the authenticated home dashboard (Paper v2).
type DashboardHomeData struct {
Stats DashboardStats
TasksToday []DashboardTaskView
TasksWeek []DashboardTaskView
PendingTask int
TodayEvents []DashboardTodayEventView
NowLabel string
}
type DashboardStats struct {
ActiveProjects int
TasksInProgress int
DueThisWeek int
}
type DashboardTaskView struct {
ID string
Title string
TabloTitle string
TabloID string
Status sqlc.TaskStatus
StatusLabel string
BadgeClass string
Href string
}
type DashboardTodayEventView struct {
TimeLabel string
Title string
Meta string
URL string
IsHighlight bool
}
func BuildDashboardHomeData(
cards []TabloCardView,
taskRows []sqlc.ListOpenTasksByUserRow,
eventRows []sqlc.ListUserEventsRangeRow,
now time.Time,
) DashboardHomeData {
stats := DashboardStats{}
for _, c := range cards {
if c.Tablo.Status == "active" {
stats.ActiveProjects++
}
}
today := dateOnly(now)
weekStart := MondayOf(today)
weekEnd := weekStart.AddDate(0, 0, 6)
var tasksToday, tasksWeek []DashboardTaskView
for _, row := range taskRows {
stats.TasksInProgress++
created := row.CreatedAt.Time
view := dashboardTaskFromRow(row)
if sameDay(created, today) {
tasksToday = append(tasksToday, view)
} else if !created.Before(weekStart) && !created.After(weekEnd) {
tasksWeek = append(tasksWeek, view)
stats.DueThisWeek++
}
}
events := make([]DashboardTodayEventView, 0, len(eventRows))
for i, row := range eventRows {
meta := PlanningEventTimeRange(row)
if row.TabloTitle != "" {
if meta != "" {
meta += " · "
}
meta += row.TabloTitle
}
timeLabel := FormatEventTime(row.StartTime)
if timeLabel == "" {
timeLabel = "—"
}
events = append(events, DashboardTodayEventView{
TimeLabel: timeLabel,
Title: row.Title,
Meta: meta,
URL: PlanningEventURL(row),
IsHighlight: i == 0,
})
}
return DashboardHomeData{
Stats: stats,
TasksToday: tasksToday,
TasksWeek: tasksWeek,
PendingTask: len(taskRows),
TodayEvents: events,
NowLabel: now.Format("15:04"),
}
}
func dashboardTaskFromRow(row sqlc.ListOpenTasksByUserRow) DashboardTaskView {
label, badge := taskStatusBadge(row.Status)
return DashboardTaskView{
ID: row.ID.String(),
Title: row.Title,
TabloTitle: row.TabloTitle,
TabloID: row.TabloID.String(),
Status: row.Status,
StatusLabel: label,
BadgeClass: badge,
Href: "/tablos/" + row.TabloID.String() + "/tasks",
}
}
func taskStatusBadge(status sqlc.TaskStatus) (label, class string) {
switch status {
case sqlc.TaskStatusInReview:
return "Revue", "task-badge task-badge-high"
case sqlc.TaskStatusInProgress:
return "En cours", "task-badge task-badge-medium"
default:
return "À faire", "task-badge task-badge-low"
}
}
func tablosFrenchDate(t time.Time) string {
weekdays := [...]string{
"dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi",
}
months := [...]string{
"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre",
}
return fmt.Sprintf(
"%s %d %s %d",
weekdays[t.Weekday()],
t.Day(),
months[t.Month()-1],
t.Year(),
)
}
func dateOnly(t time.Time) time.Time {
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
func sameDay(a, b time.Time) bool {
ay, am, ad := a.Date()
by, bm, bd := b.Date()
return ay == by && am == bm && ad == bd
}
func PendingTaskLabel(n int) string {
if n == 1 {
return "1 en attente"
}
return fmt.Sprintf("%d en attente", n)
}
func HomeTodayTimeClass(highlight bool) string {
if highlight {
return "home-today-time is-highlight"
}
return "home-today-time"
}
func HomeTodayCardClass(highlight bool) string {
if highlight {
return "home-today-event-card is-highlight"
}
return "home-today-event-card"
}