package views import ( "strings" "github.com/charmbracelet/lipgloss" "task/internal/ticket" ) // StatusMenu renders a status picker overlay. type StatusMenu struct { Cursor int Width int Styles StatusMenuStyles } // StatusMenuStyles holds styles for the status picker. type StatusMenuStyles struct { Box lipgloss.Style Title lipgloss.Style Selected lipgloss.Style Normal lipgloss.Style } // NewStatusMenu creates a menu with the given status pre-selected. func NewStatusMenu(current ticket.Status, width int, styles StatusMenuStyles) StatusMenu { return StatusMenu{ Cursor: current.Index(), Width: width, Styles: styles, } } // MoveDown moves the selection down. func (m *StatusMenu) MoveDown() { if m.Cursor < len(ticket.AllStatuses)-1 { m.Cursor++ } } // MoveUp moves the selection up. func (m *StatusMenu) MoveUp() { if m.Cursor > 0 { m.Cursor-- } } // Selected returns the currently highlighted status. func (m StatusMenu) Selected() ticket.Status { if m.Cursor < 0 || m.Cursor >= len(ticket.AllStatuses) { return ticket.StatusTodo } return ticket.AllStatuses[m.Cursor] } // View renders the status menu. func (m StatusMenu) View() string { var lines []string lines = append(lines, m.Styles.Title.Render("Set status")) for i, st := range ticket.AllStatuses { label := " " + st.Label() if i == m.Cursor { label = m.Styles.Selected.Render("▸ " + st.Label()) } else { label = m.Styles.Normal.Render(label) } lines = append(lines, label) } body := strings.Join(lines, "\n") w := m.Width if w < 20 { w = 20 } return m.Styles.Box.Width(min(40, w-2)).Render(body) } func min(a, b int) int { if a < b { return a } return b }