package models import ( "time" "task-dashboard/internal/config" ) type TimelineItemType string const ( TimelineItemTypeTask TimelineItemType = "task" TimelineItemTypeMeal TimelineItemType = "meal" TimelineItemTypeCard TimelineItemType = "card" TimelineItemTypeEvent TimelineItemType = "event" TimelineItemTypeGTask TimelineItemType = "gtask" // Google Tasks ) type DaySection string const ( DaySectionToday DaySection = "today" DaySectionTomorrow DaySection = "tomorrow" DaySectionLater DaySection = "later" ) type TimelineItem struct { ID string `json:"id"` Type TimelineItemType `json:"type"` Title string `json:"title"` Time time.Time `json:"time"` EndTime *time.Time `json:"end_time,omitempty"` Description string `json:"description,omitempty"` URL string `json:"url,omitempty"` OriginalItem interface{} `json:"-"` // UI enhancement fields IsCompleted bool `json:"is_completed"` IsOverdue bool `json:"is_overdue"` IsAllDay bool `json:"is_all_day"` // True if time is midnight (no specific time) DaySection DaySection `json:"day_section"` Source string `json:"source"` // "todoist", "trello", "plantoeat", "calendar", "gtasks" // Source-specific metadata ListID string `json:"list_id,omitempty"` // For Google Tasks } // ComputeDaySection sets the DaySection, IsOverdue, and IsAllDay based on the item's time func (item *TimelineItem) ComputeDaySection(now time.Time) { // Use configured display timezone for consistent comparisons tz := config.GetDisplayTimezone() localNow := now.In(tz) localItemTime := item.Time.In(tz) today := time.Date(localNow.Year(), localNow.Month(), localNow.Day(), 0, 0, 0, 0, tz) tomorrow := today.AddDate(0, 0, 1) dayAfterTomorrow := today.AddDate(0, 0, 2) itemDay := time.Date(localItemTime.Year(), localItemTime.Month(), localItemTime.Day(), 0, 0, 0, 0, tz) // Check if item is overdue (before today) item.IsOverdue = itemDay.Before(today) // Check if item is all-day (midnight time means no specific time) item.IsAllDay = localItemTime.Hour() == 0 && localItemTime.Minute() == 0 if itemDay.Before(tomorrow) { item.DaySection = DaySectionToday } else if itemDay.Before(dayAfterTomorrow) { item.DaySection = DaySectionTomorrow } else { item.DaySection = DaySectionLater } }