Files
pop/cmd/contacts.go

184 lines
4.3 KiB
Go

package cmd
import (
"encoding/json"
"fmt"
"github.com/frenocorp/pop/internal/contact"
"github.com/spf13/cobra"
)
func contactCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "contact",
Short: "Manage contacts",
Long: `List, add, edit, and delete contacts.`,
}
cmd.AddCommand(contactListCmd())
cmd.AddCommand(contactAddCmd())
cmd.AddCommand(contactEditCmd())
cmd.AddCommand(contactDeleteCmd())
return cmd
}
func contactListCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List all contacts",
RunE: func(cmd *cobra.Command, args []string) error {
manager := contact.NewContactManager()
page, _ := cmd.Flags().GetInt("page")
pageSize, _ := cmd.Flags().GetInt("page-size")
search, _ := cmd.Flags().GetString("search")
req := contact.ListContactsRequest{
Page: page,
PageSize: pageSize,
Search: search,
}
resp, err := manager.List(req)
if err != nil {
return fmt.Errorf("failed to list contacts: %w", err)
}
if len(resp.Contacts) == 0 {
fmt.Println("No contacts found")
return nil
}
data, _ := json.MarshalIndent(resp.Contacts, "", " ")
fmt.Println(string(data))
return nil
},
}
cmd.Flags().IntP("page", "p", 0, "Page number")
cmd.Flags().IntP("page-size", "n", 10, "Items per page")
cmd.Flags().StringP("search", "s", "", "Search by email or name")
return cmd
}
func contactAddCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add",
Short: "Add a new contact",
RunE: func(cmd *cobra.Command, args []string) error {
email, _ := cmd.Flags().GetString("email")
name, _ := cmd.Flags().GetString("name")
phone, _ := cmd.Flags().GetString("phone")
if email == "" {
return fmt.Errorf("email is required")
}
manager := contact.NewContactManager()
req := contact.CreateContactRequest{
Email: email,
Name: name,
Phone: phone,
}
contact, err := manager.Create(req)
if err != nil {
return fmt.Errorf("failed to create contact: %w", err)
}
data, _ := json.MarshalIndent(contact, "", " ")
fmt.Printf("Created contact:\n%s\n", string(data))
return nil
},
}
cmd.Flags().StringP("email", "e", "", "Contact email (required)")
cmd.Flags().StringP("name", "n", "", "Contact name")
cmd.Flags().StringP("phone", "p", "", "Contact phone")
return cmd
}
func contactEditCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "edit <id>",
Short: "Edit a contact",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("contact ID is required")
}
id := args[0]
manager := contact.NewContactManager()
_, err := manager.Get(id)
if err != nil {
return fmt.Errorf("failed to get contact: %w", err)
}
name, _ := cmd.Flags().GetString("name")
phone, _ := cmd.Flags().GetString("phone")
address, _ := cmd.Flags().GetString("address")
notes, _ := cmd.Flags().GetString("notes")
req := contact.UpdateContactRequest{}
// Only set pointer fields when the flag was explicitly changed
if cmd.Flags().Changed("name") {
req.Name = &name
}
if cmd.Flags().Changed("phone") {
req.Phone = &phone
}
if cmd.Flags().Changed("address") {
req.Address = &address
}
if cmd.Flags().Changed("notes") {
req.Notes = &notes
}
updated, err := manager.Update(id, req)
if err != nil {
return fmt.Errorf("failed to update contact: %w", err)
}
data, _ := json.MarshalIndent(updated, "", " ")
fmt.Printf("Updated contact:\n%s\n", string(data))
return nil
},
}
cmd.Flags().StringP("name", "n", "", "New name")
cmd.Flags().StringP("phone", "p", "", "New phone")
cmd.Flags().StringP("address", "a", "", "New address")
cmd.Flags().StringP("notes", "o", "", "New notes")
return cmd
}
func contactDeleteCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "delete <id>",
Short: "Delete a contact",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("contact ID is required")
}
id := args[0]
manager := contact.NewContactManager()
if err := manager.Delete(id); err != nil {
return fmt.Errorf("failed to delete contact: %w", err)
}
fmt.Printf("Deleted contact: %s\n", id)
return nil
},
}
return cmd
}