178 lines
4 KiB
Go
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"
|
|
}
|