refactor: extract changePinModel into its own sub-model
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>
This commit is contained in:
111
internal/shell/banking/screen_changepin.go
Normal file
111
internal/shell/banking/screen_changepin.go
Normal file
@@ -0,0 +1,111 @@
|
||||
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()
|
||||
}
|
||||
Reference in New Issue
Block a user