package main import ( "charmcal/mite" "errors" "fmt" "strconv" "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/huh" ) // updateForm handles processing tea.Msg's related to form processing func (m model) updateForm(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "esc": m.tuiMode = MODE_CAL return m, nil case "ctrl+c": return m, tea.Quit } } newForm, formCmd := m.formData.form.Update(msg) m.formData.form = newForm.(*huh.Form) if m.formData.form.State == huh.StateCompleted { // fmt.Printf("%#v", m.timeData.entries) // clientID := m.formData.form.GetString("client") serviceID := m.formData.form.GetString("service") projectID := m.formData.form.GetString("project") description := m.formData.form.GetString("description") minutes := m.formData.form.GetString("minutes") tracker := m.formData.form.GetBool("tracker") minutesInt, err1 := strconv.ParseInt(minutes, 10, 64) serviceIDInt, err2 := strconv.ParseInt(serviceID, 10, 64) projectIDInt, err3 := strconv.ParseInt(projectID, 10, 64) if errors.Join(err1, err2, err3) != nil { m.statusBarMessage = errors.Join(err1, err2, err3).Error() m.tuiMode = MODE_CAL } else { id, err := m.miteAPI.AddTimeEntry(m.dest.Format(time.DateOnly), int(minutesInt), description, int(projectIDInt), int(serviceIDInt)) if err != nil { m.statusBarMessage = err.Error() m.tuiMode = MODE_CAL } else { if tracker { _, _, err = m.miteAPI.StartTimeTracker(id) if err != nil { m.statusBarMessage = err.Error() m.tuiMode = MODE_CAL } else { m.statusBarMessage = "Successfully logged time and started tracker" m.tuiMode = MODE_CAL return m, m.fetchMiteData() } } else { m.statusBarMessage = "Successfully logged time" m.tuiMode = MODE_CAL return m, m.fetchMiteData() } } } } return m, formCmd } func (m model) buildForm() *huh.Form { clOptions := []huh.Option[string]{} for _, cust := range m.formData.customers { op := miteToHuhOption(cust) clOptions = append(clOptions, op) } svcOptions := []huh.Option[string]{} for _, svc := range m.formData.services { op := miteToHuhOption(svc) svcOptions = append(svcOptions, op) } projOptions := []huh.Option[string]{ { Key: "[no project]", Value: "0", }, } for _, proj := range m.formData.projects { op := miteToHuhOption(proj) projOptions = append(projOptions, op) } // cl := huh.NewSelect[string](). // Key("client"). // Options(clOptions...). // Title("Client").Height(5).Value(&m.formData.selected.customer) sl := huh.NewSelect[string](). Key("service"). Options(svcOptions...). Title("Service"). Height(6) pl := huh.NewSelect[string](). Key("project"). Title("Project"). Options(projOptions...). Height(6) description := huh.NewText(). Key("description"). Title("description"). Validate(func(s string) error { if s == "" { return errors.New("must enter a description") } return nil }) defMinutes := "0" minutes := huh.NewInput(). Key("minutes"). CharLimit(5). Validate( func(s string) error { h, err := strconv.ParseInt(s, 10, 64) if err != nil { return err } if h < 0 { return errors.New("must be positive") } return err }). Title("Minutes"). Value(&defMinutes) confirmTracker := huh.NewConfirm(). Key("tracker"). Affirmative("Yes"). Negative("No"). Title("Start tracker") form := huh.NewForm( huh.NewGroup( pl, sl, description, ), huh.NewGroup( minutes, confirmTracker, ), ) return form } func miteToHuhOption[T mite.APIObject](i T) huh.Option[string] { return huh.Option[string]{ Key: i.GetName(), Value: fmt.Sprint(i.GetID()), } }