The Change PIN screen was the only screen with its state (pinInput, pinStage, pinMessage) stored directly on the top-level model. Extract it into a changePinModel in screen_changepin.go to match the pattern used by all other screens. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
112 lines
2.4 KiB
Go
112 lines
2.4 KiB
Go
package banking
|
|
|
|
import (
|
|
"strings"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
)
|
|
|
|
type changePinModel struct {
|
|
input string
|
|
stage int // 0=old, 1=new, 2=confirm, 3=done
|
|
newPin string
|
|
done bool
|
|
}
|
|
|
|
func newChangePinModel() changePinModel {
|
|
return changePinModel{}
|
|
}
|
|
|
|
func (m changePinModel) Update(msg tea.Msg) (changePinModel, tea.Cmd) {
|
|
keyMsg, ok := msg.(tea.KeyMsg)
|
|
if !ok {
|
|
return m, nil
|
|
}
|
|
|
|
if m.stage == 3 {
|
|
m.done = true
|
|
return m, nil
|
|
}
|
|
|
|
switch keyMsg.Type {
|
|
case tea.KeyEnter:
|
|
switch m.stage {
|
|
case 0:
|
|
if m.input != "" {
|
|
m.stage = 1
|
|
m.input = ""
|
|
}
|
|
case 1:
|
|
if len(m.input) >= 4 {
|
|
m.newPin = m.input
|
|
m.stage = 2
|
|
m.input = ""
|
|
}
|
|
case 2:
|
|
if m.input == m.newPin {
|
|
m.stage = 3
|
|
} else {
|
|
m.input = ""
|
|
m.newPin = ""
|
|
m.stage = 1
|
|
}
|
|
}
|
|
case tea.KeyEscape:
|
|
m.done = true
|
|
case tea.KeyBackspace:
|
|
if len(m.input) > 0 {
|
|
m.input = m.input[:len(m.input)-1]
|
|
}
|
|
default:
|
|
ch := keyMsg.String()
|
|
if len(ch) == 1 && ch[0] >= 32 && ch[0] < 127 && len(m.input) < 12 {
|
|
m.input += ch
|
|
}
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
func (m changePinModel) View() string {
|
|
var b strings.Builder
|
|
|
|
b.WriteString("\n")
|
|
b.WriteString(centerText("CHANGE PIN"))
|
|
b.WriteString("\n\n")
|
|
b.WriteString(thinDivider())
|
|
b.WriteString("\n\n")
|
|
|
|
if m.stage == 3 {
|
|
b.WriteString(titleStyle.Render(" PIN CHANGED SUCCESSFULLY"))
|
|
b.WriteString("\n\n")
|
|
b.WriteString(baseStyle.Render(" YOUR NEW PIN IS NOW ACTIVE."))
|
|
b.WriteString("\n")
|
|
b.WriteString(baseStyle.Render(" PLEASE USE YOUR NEW PIN FOR ALL FUTURE TRANSACTIONS."))
|
|
b.WriteString("\n\n")
|
|
b.WriteString(dimStyle.Render(" PRESS ANY KEY TO RETURN TO MAIN MENU"))
|
|
} else {
|
|
prompts := []string{" CURRENT PIN: ", " NEW PIN: ", " CONFIRM PIN: "}
|
|
for i := 0; i < m.stage; i++ {
|
|
b.WriteString(baseStyle.Render(prompts[i]))
|
|
b.WriteString(baseStyle.Render(strings.Repeat("*", 4)))
|
|
b.WriteString("\n")
|
|
}
|
|
if m.stage < 3 {
|
|
b.WriteString(titleStyle.Render(prompts[m.stage]))
|
|
masked := strings.Repeat("*", len(m.input))
|
|
b.WriteString(inputStyle.Render(masked))
|
|
b.WriteString(inputStyle.Render("_"))
|
|
b.WriteString("\n")
|
|
}
|
|
b.WriteString("\n")
|
|
if m.stage == 1 {
|
|
b.WriteString(dimStyle.Render(" PIN MUST BE AT LEAST 4 CHARACTERS"))
|
|
b.WriteString("\n")
|
|
}
|
|
b.WriteString("\n")
|
|
b.WriteString(dimStyle.Render(" PRESS ESC TO RETURN TO MAIN MENU"))
|
|
}
|
|
b.WriteString("\n")
|
|
|
|
return b.String()
|
|
}
|