package templates import ( "net/url" "github.com/google/uuid" ) type EtapeFilterKind string const ( EtapeFilterAll EtapeFilterKind = "all" EtapeFilterUnassigned EtapeFilterKind = "unassigned" EtapeFilterEtape EtapeFilterKind = "etape" ) type EtapeFilter struct { Kind EtapeFilterKind EtapeID uuid.UUID } type EtapeTaskCounts struct { All int Unassigned int ByEtape map[uuid.UUID]int } type EtapeCreateForm struct { Title string Description string } type EtapeCreateErrors struct { Title string General string } func (f EtapeFilter) QueryValue() string { switch f.Kind { case EtapeFilterUnassigned: return "unassigned" case EtapeFilterEtape: return f.EtapeID.String() default: return "" } } func (f EtapeFilter) QuerySuffix() string { if value := f.QueryValue(); value != "" { return "&etape=" + url.QueryEscape(value) } return "" } func (f EtapeFilter) TaskEtapeIDValue() string { if f.Kind == EtapeFilterEtape { return f.EtapeID.String() } return "" } func (f EtapeFilter) IsAll() bool { return f.Kind == "" || f.Kind == EtapeFilterAll } func (f EtapeFilter) IsUnassigned() bool { return f.Kind == EtapeFilterUnassigned } func (f EtapeFilter) IsEtape(id uuid.UUID) bool { return f.Kind == EtapeFilterEtape && f.EtapeID == id } func etapeCount(counts EtapeTaskCounts, id uuid.UUID) int { if counts.ByEtape == nil { return 0 } return counts.ByEtape[id] } func etapeChipClasses(active bool) string { base := "inline-flex items-center gap-2 rounded border px-3 py-1.5 text-sm whitespace-nowrap" if active { return base + " border-slate-800 bg-slate-900 text-white" } return base + " border-slate-200 bg-white text-slate-700 hover:border-slate-400" }