1package components
2
3import (
4 "strings"
5
6 "gordon/internal/adapters/in/cli/ui/styles"
7
8 "github.com/charmbracelet/lipgloss"
9)
10
11// Status represents a status type for rendering.
12type Status int
13
14const (
15 StatusSuccess Status = iota
16 StatusError
17 StatusWarning
18 StatusInfo
19 StatusPending
20 StatusRunning
21 StatusStopped
22)
23
24// StatusConfig holds configuration for status rendering.
25type StatusConfig struct {
26 Status Status
27 Label string
28 Icon string
29 Style lipgloss.Style
30 Badge bool // If true, render as a badge with background
31 Compact bool // If true, render icon only
32}
33
34// DefaultStatusConfigs provides default configurations for each status type.
35var DefaultStatusConfigs = map[Status]StatusConfig{
36 StatusSuccess: {
37 Icon: styles.IconSuccess,
38 Style: styles.Theme.Success,
39 },
40 StatusError: {
41 Icon: styles.IconError,
42 Style: styles.Theme.Error,
43 },
44 StatusWarning: {
45 Icon: styles.IconWarning,
46 Style: styles.Theme.Warning,
47 },
48 StatusInfo: {
49 Icon: styles.IconInfo,
50 Style: styles.Theme.Info,
51 },
52 StatusPending: {
53 Icon: styles.IconPending,
54 Style: styles.Theme.Muted,
55 },
56 StatusRunning: {
57 Icon: styles.IconSuccess,
58 Style: styles.Theme.Success,
59 },
60 StatusStopped: {
61 Icon: styles.IconError,
62 Style: styles.Theme.Error,
63 },
64}
65
66// RenderStatus renders a status with icon and optional label.
67func RenderStatus(status Status, label string) string {
68 config := DefaultStatusConfigs[status]
69 if label == "" {
70 return config.Style.Render(config.Icon)
71 }
72 return config.Style.Render(config.Icon + " " + label)
73}
74
75// RenderStatusBadge renders a status as a badge with background.
76func RenderStatusBadge(status Status, label string) string {
77 var badgeStyle lipgloss.Style
78 switch status {
79 case StatusSuccess, StatusRunning:
80 badgeStyle = styles.Theme.BadgeSuccess
81 case StatusError, StatusStopped:
82 badgeStyle = styles.Theme.BadgeError
83 case StatusWarning:
84 badgeStyle = styles.Theme.BadgeWarning
85 case StatusPending:
86 badgeStyle = styles.Theme.BadgePending
87 default:
88 badgeStyle = styles.Theme.BadgeInfo
89 }
90 return badgeStyle.Render(label)
91}
92
93// ParseStatus converts a string status to Status type.
94func ParseStatus(s string) Status {
95 switch strings.ToLower(s) {
96 case "success", "ok", "active", "healthy":
97 return StatusSuccess
98 case "error", "failed", "unhealthy":
99 return StatusError
100 case "warning", "degraded":
101 return StatusWarning
102 case "info":
103 return StatusInfo
104 case "pending", "starting", "waiting":
105 return StatusPending
106 case "running", "up":
107 return StatusRunning
108 case "stopped", "down", "exited":
109 return StatusStopped
110 default:
111 return StatusInfo
112 }
113}
114
115// StatusIndicator is a simple status indicator component.
116type StatusIndicator struct {
117 Status Status
118 Label string
119 Badge bool
120}
121
122// NewStatusIndicator creates a new status indicator.
123func NewStatusIndicator(status Status, label string) StatusIndicator {
124 return StatusIndicator{
125 Status: status,
126 Label: label,
127 Badge: false,
128 }
129}
130
131// NewStatusBadge creates a new status badge (with background).
132func NewStatusBadge(status Status, label string) StatusIndicator {
133 return StatusIndicator{
134 Status: status,
135 Label: label,
136 Badge: true,
137 }
138}
139
140// View renders the status indicator.
141func (s StatusIndicator) View() string {
142 if s.Badge {
143 return RenderStatusBadge(s.Status, s.Label)
144 }
145 return RenderStatus(s.Status, s.Label)
146}
147
148// ContainerStatusIndicator renders container status with appropriate styling.
149func ContainerStatusIndicator(status string) string {
150 parsed := ParseStatus(status)
151 return RenderStatus(parsed, status)
152}
153
154// ContainerStatusBadge renders container status as a badge.
155func ContainerStatusBadge(status string) string {
156 parsed := ParseStatus(status)
157 return RenderStatusBadge(parsed, status)
158}