1package tui
2
3import (
4 "github.com/charmbracelet/bubbles/textinput"
5 tea "github.com/charmbracelet/bubbletea"
6 "github.com/charmbracelet/lipgloss"
7)
8
9// Login holds the state for the login form.
10type Login struct {
11 focusIndex int
12 inputs []textinput.Model
13}
14
15// NewLogin creates a new login model. This function was missing.
16func NewLogin() tea.Model {
17 m := Login{
18 inputs: make([]textinput.Model, 2),
19 }
20
21 var t textinput.Model
22 for i := range m.inputs {
23 t = textinput.New()
24 t.Cursor.Style = focusedStyle
25 t.CharLimit = 64
26
27 switch i {
28 case 0:
29 t.Placeholder = "Email"
30 t.Focus()
31 t.Prompt = "✉️ > "
32 case 1:
33 t.Placeholder = "Password"
34 t.EchoMode = textinput.EchoPassword
35 t.Prompt = "🔑 > "
36 }
37 m.inputs[i] = t
38 }
39
40 return m
41}
42
43// Init initializes the login model.
44func (m Login) Init() tea.Cmd {
45 return textinput.Blink
46}
47
48// Update handles messages for the login model.
49func (m Login) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
50 switch msg := msg.(type) {
51 case tea.KeyMsg:
52 switch msg.Type {
53 // On Enter, if we are on the last field, submit the credentials.
54 case tea.KeyEnter:
55 if m.focusIndex == len(m.inputs)-1 {
56 return m, func() tea.Msg {
57 return Credentials{
58 Email: m.inputs[0].Value(),
59 Password: m.inputs[1].Value(),
60 }
61 }
62 }
63 fallthrough
64 // Cycle focus between inputs.
65 case tea.KeyTab, tea.KeyShiftTab, tea.KeyUp, tea.KeyDown:
66 s := msg.String()
67 if s == "up" || s == "shift+tab" {
68 m.focusIndex--
69 } else {
70 m.focusIndex++
71 }
72
73 if m.focusIndex >= len(m.inputs) {
74 m.focusIndex = 0
75 } else if m.focusIndex < 0 {
76 m.focusIndex = len(m.inputs) - 1
77 }
78
79 cmds := make([]tea.Cmd, len(m.inputs))
80 for i := 0; i < len(m.inputs); i++ {
81 if i == m.focusIndex {
82 cmds[i] = m.inputs[i].Focus()
83 } else {
84 m.inputs[i].Blur()
85 }
86 }
87 return m, tea.Batch(cmds...)
88 }
89 }
90
91 // Update the focused input field.
92 var cmds = make([]tea.Cmd, len(m.inputs))
93 for i := range m.inputs {
94 m.inputs[i], cmds[i] = m.inputs[i].Update(msg)
95 }
96 return m, tea.Batch(cmds...)
97}
98
99// View renders the login form.
100func (m Login) View() string {
101 return lipgloss.JoinVertical(lipgloss.Left,
102 titleStyle.Render("Welcome to Email CLI"),
103 "Please enter your credentials.",
104 m.inputs[0].View(),
105 m.inputs[1].View(),
106 helpStyle.Render("\nenter: submit • tab: next field • esc: quit"),
107 )
108}