Add WireGuard TUI implementation
- Add Go TUI with bubbletea for WireGuard management - Implement client CRUD operations with QR code generation - Add configuration and validation modules - Install/update scripts for client setup - Update Makefile to build binaries to bin/ directory - Add .gitignore for Go projects
This commit is contained in:
143
internal/tui/components/confirm.go
Normal file
143
internal/tui/components/confirm.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
// ConfirmModel represents a confirmation modal
|
||||
type ConfirmModel struct {
|
||||
Message string
|
||||
Yes bool // true = yes, false = no
|
||||
Visible bool
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
// Styles
|
||||
var (
|
||||
confirmModalStyle = lipgloss.NewStyle().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(lipgloss.Color("196")).
|
||||
Padding(1, 2).
|
||||
Background(lipgloss.Color("235"))
|
||||
confirmTitleStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("226")).
|
||||
Bold(true)
|
||||
confirmMessageStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("255")).
|
||||
Width(50)
|
||||
confirmHelpStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("241")).
|
||||
MarginTop(1)
|
||||
)
|
||||
|
||||
// NewConfirm creates a new confirmation modal
|
||||
func NewConfirm(message string, width, height int) *ConfirmModel {
|
||||
return &ConfirmModel{
|
||||
Message: message,
|
||||
Yes: false,
|
||||
Visible: true,
|
||||
Width: width,
|
||||
Height: height,
|
||||
}
|
||||
}
|
||||
|
||||
// Init initializes the confirmation modal
|
||||
func (m *ConfirmModel) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update handles messages for the confirmation modal
|
||||
func (m *ConfirmModel) Update(msg tea.Msg) (*ConfirmModel, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "y", "Y", "left":
|
||||
m.Yes = true
|
||||
case "n", "N", "right":
|
||||
m.Yes = false
|
||||
case "enter":
|
||||
// Confirmed - will be handled by parent
|
||||
return m, nil
|
||||
case "esc":
|
||||
m.Visible = false
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// View renders the confirmation modal
|
||||
func (m *ConfirmModel) View() string {
|
||||
if !m.Visible {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Build modal content
|
||||
content := lipgloss.JoinVertical(
|
||||
lipgloss.Left,
|
||||
confirmTitleStyle.Render("⚠️ Confirm Action"),
|
||||
"",
|
||||
confirmMessageStyle.Render(m.Message),
|
||||
"",
|
||||
m.renderOptions(),
|
||||
)
|
||||
|
||||
// Apply modal style
|
||||
modal := confirmModalStyle.Render(content)
|
||||
|
||||
// Center modal on screen
|
||||
modalWidth := lipgloss.Width(modal)
|
||||
modalHeight := lipgloss.Height(modal)
|
||||
|
||||
x := (m.Width - modalWidth) / 2
|
||||
if x < 0 {
|
||||
x = 0
|
||||
}
|
||||
y := (m.Height - modalHeight) / 2
|
||||
if y < 0 {
|
||||
y = 0
|
||||
}
|
||||
|
||||
return lipgloss.Place(m.Width, m.Height,
|
||||
lipgloss.Left, lipgloss.Top,
|
||||
modal,
|
||||
lipgloss.WithWhitespaceChars(" "),
|
||||
lipgloss.WithWhitespaceForeground(lipgloss.Color("235")),
|
||||
)
|
||||
}
|
||||
|
||||
// renderOptions renders the yes/no options
|
||||
func (m *ConfirmModel) renderOptions() string {
|
||||
yesStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("241"))
|
||||
noStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("241"))
|
||||
|
||||
selectedStyle := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("57")).
|
||||
Bold(true).
|
||||
Underline(true)
|
||||
|
||||
var yesText, noText string
|
||||
if m.Yes {
|
||||
yesText = selectedStyle.Render("[Yes]")
|
||||
noText = noStyle.Render(" No ")
|
||||
} else {
|
||||
yesText = yesStyle.Render(" Yes ")
|
||||
noText = selectedStyle.Render("[No]")
|
||||
}
|
||||
|
||||
helpText := confirmHelpStyle.Render("←/→ to choose • Enter to confirm • Esc to cancel")
|
||||
|
||||
return lipgloss.JoinHorizontal(lipgloss.Left, yesText, " ", noText, "\n", helpText)
|
||||
}
|
||||
|
||||
// IsConfirmed returns true if user confirmed with Yes
|
||||
func (m *ConfirmModel) IsConfirmed() bool {
|
||||
return m.Yes
|
||||
}
|
||||
|
||||
// IsCancelled returns true if user cancelled
|
||||
func (m *ConfirmModel) IsCancelled() bool {
|
||||
return !m.Visible
|
||||
}
|
||||
Reference in New Issue
Block a user