list domains

This commit is contained in:
juancwu 2026-01-23 14:56:16 +00:00
commit 8498f6f0a7
4 changed files with 146 additions and 10 deletions

View file

@ -0,0 +1,30 @@
package menu
import (
"fmt"
"strings"
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
)
func renderDomainItem(item *porkbun.Domain) string {
var b strings.Builder
b.WriteString("Domain: " + item.Domain + "\n")
b.WriteString("Status: " + item.Status + "\n")
b.WriteString("Create Date: " + item.CreateDate + "\n")
b.WriteString("Expire Date: " + item.ExpireDate + "\n")
b.WriteString("Security Lock: " + item.SecurityLock + "\n")
b.WriteString("Whois Privacy: " + item.WhoIsPrivacy + "\n")
b.WriteString(fmt.Sprintln("Auto Renew:", item.AutoRenew))
b.WriteString(fmt.Sprintln("Not Local:", item.NotLocal))
if len(item.Labels) > 0 {
b.WriteString("Labels:\n")
}
for i, label := range item.Labels {
b.WriteString("=> " + label.Title)
if i < len(item.Labels)-1 {
b.WriteString("\n")
}
}
return b.String()
}

View file

@ -6,13 +6,20 @@ import (
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/paginator"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type pingResultMsg struct {
IP string
}
type domainListMsg struct {
Status string
Domains []string
}
type menuItem struct {
id uint8
title, desc string
@ -25,7 +32,6 @@ func (i menuItem) FilterValue() string { return i.title }
const (
domainListAll uint8 = iota
domainGetDetails
dnsRetrieveRecords
dnsCreateRecord
dnsEditRecord
@ -34,16 +40,17 @@ const (
)
type Model struct {
list list.Model
client *porkbun.Client
err error
output string
list list.Model
paginator paginator.Model
domains []string
client *porkbun.Client
err error
output string
}
func New(client *porkbun.Client) *Model {
items := []list.Item{
menuItem{id: domainListAll, title: "Domain: List All", desc: "List all domains in your account"},
menuItem{id: domainGetDetails, title: "Domain: Get Details", desc: "Get details for a specific domain"},
menuItem{id: dnsRetrieveRecords, title: "DNS: Retrieve Records", desc: "Retrieve DNS records for a domain"},
menuItem{id: dnsCreateRecord, title: "DNS: Create Record", desc: "Create a new DNS record"},
menuItem{id: dnsEditRecord, title: "DNS: Edit Record", desc: "Edit an existing DNS record"},
@ -54,9 +61,16 @@ func New(client *porkbun.Client) *Model {
l := list.New(items, list.NewDefaultDelegate(), 0, 0)
l.Title = "Porkbun Actions"
p := paginator.New()
p.Type = paginator.Dots
p.PerPage = 1
p.ActiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "252"}).Render("•")
p.InactiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "238"}).Render("•")
return &Model{
list: l,
client: client,
list: l,
paginator: p,
client: client,
}
}
@ -80,6 +94,16 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
if len(m.domains) > 0 {
var cmd tea.Cmd
m.paginator, cmd = m.paginator.Update(msg)
if msg.String() == "esc" {
m.domains = nil
return m, nil
}
return m, cmd
}
if msg.String() == "enter" {
i, ok := m.list.SelectedItem().(menuItem)
if ok {
@ -87,6 +111,12 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
}
case domainListMsg:
m.paginator.PerPage = 1
m.paginator.SetTotalPages(len(msg.Domains))
m.paginator.Page = 0
m.domains = msg.Domains
case pingResultMsg:
m.output = fmt.Sprintf("Ping successful!\nYour IP: %s", msg.IP)
return m, nil
@ -105,12 +135,32 @@ func (m *Model) View() string {
if m.output != "" {
return fmt.Sprintf("%s\n\n(Press Esc to go back)", m.output)
}
if len(m.domains) > 0 {
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.domains[m.paginator.Page], m.paginator.View())
}
return m.list.View()
}
func (m *Model) handleSelection(i menuItem) (tea.Model, tea.Cmd) {
// TODO: Implement other actions. For now, just Ping.
switch i.id {
case domainListAll:
return m, func() tea.Msg {
resp, err := m.client.DomainListAll(0, true)
if err != nil {
return messages.ErrorMsg(err)
}
var domains []string
for _, domain := range resp.Domains {
view := renderDomainItem(&domain)
domains = append(domains, view)
}
return domainListMsg{
Status: resp.Status,
Domains: domains,
}
}
case utilPing:
return m, func() tea.Msg {
resp, err := m.client.Ping()