summaryrefslogtreecommitdiff
path: root/internal/tui/shared.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tui/shared.go')
-rw-r--r--internal/tui/shared.go92
1 files changed, 57 insertions, 35 deletions
diff --git a/internal/tui/shared.go b/internal/tui/shared.go
index 7271293..9025fb8 100644
--- a/internal/tui/shared.go
+++ b/internal/tui/shared.go
@@ -13,34 +13,57 @@ import (
"github.com/charmbracelet/lipgloss/v2"
)
+// Maximum content width for large displays - prevents over-stretching
+const maxContentWidth = 180
+
var (
+ // Color palette
+ colorAccent = lipgloss.Color("4") // Blue accent
+ colorAccentBright = lipgloss.Color("12") // Bright blue
+ colorTimerActive = lipgloss.Color("2") // Green for active timer
+ colorTimerText = lipgloss.Color("10") // Bright green
+ colorDimmed = lipgloss.Color("242") // Dimmed text
+ colorSubtle = lipgloss.Color("238") // Very subtle borders/separators
+ colorFg = lipgloss.Color("253") // Main foreground
+ colorBg = lipgloss.Color("235") // Slightly lighter than terminal default
+ colorBarBg = lipgloss.Color("236") // Bar background
+ colorSelected = lipgloss.Color("4") // Selection background
+ colorSelectedFg = lipgloss.Color("15") // White text on selection
+ colorDate = lipgloss.Color("6") // Cyan for dates
+ colorWarning = lipgloss.Color("1") // Red for warnings/errors
+
// Styles for the TUI
- topBarInactiveStyle = lipgloss.NewStyle().
- Background(lipgloss.Color("21")).
- Foreground(lipgloss.Color("230")).
- Padding(0, 1)
+ topBarStyle = lipgloss.NewStyle().
+ Background(colorBarBg).
+ Foreground(colorFg).
+ Padding(0, 1)
bottomBarStyle = lipgloss.NewStyle().
- Background(lipgloss.Color("238")).
- Foreground(lipgloss.Color("252"))
+ Background(colorBarBg).
+ Foreground(colorDimmed)
// Box styles
selectedBoxStyle = lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
- BorderForeground(lipgloss.Color("62")).
+ BorderForeground(colorAccent).
Padding(1, 2)
unselectedBoxStyle = lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
- BorderForeground(lipgloss.Color("238")).
+ BorderForeground(colorSubtle).
Padding(1, 2)
activeTimerStyle = lipgloss.NewStyle().
- Foreground(lipgloss.Color("196")).
+ Foreground(colorTimerText).
Bold(true)
+ activeBoxStyle = lipgloss.NewStyle().
+ Border(lipgloss.RoundedBorder()).
+ BorderForeground(colorTimerActive).
+ Padding(1, 2)
+
inactiveTimerStyle = lipgloss.NewStyle().
- Foreground(lipgloss.Color("246"))
+ Foreground(colorDimmed)
)
// FormatDuration formats a duration in a human-readable way
@@ -66,7 +89,7 @@ func getContractorInfo(ctx context.Context, q *queries.Queries) (ContractorInfo,
}
return ContractorInfo{
- name: c.Name,
+ name: c.Name,
label: c.Label,
email: c.Email,
}, nil
@@ -133,8 +156,8 @@ func getMostRecentTimerInfo(ctx context.Context, q *queries.Queries) (TimerInfo,
}
// RenderTopBar renders the top bar with view name and time stats
-func RenderTopBar(m AppModel) string {
- left := fmt.Sprintf("👊 Punchcard ♦️ - %s", m.selectedBox.String())
+func RenderTopBar(m AppModel, contentWidth int) string {
+ leftText := fmt.Sprintf("Punchcard / %s", m.selectedBox.String())
today := m.timeStats.TodayTotal
week := m.timeStats.WeekTotal
@@ -145,35 +168,35 @@ func RenderTopBar(m AppModel) string {
week += activeTime
}
- right := fmt.Sprintf("Today: %s | Week: %s", FormatDuration(today), FormatDuration(week))
+ rightText := fmt.Sprintf("today %s week %s", FormatDuration(today), FormatDuration(week))
- // Use lipgloss to create left and right aligned content
leftStyle := lipgloss.NewStyle().Align(lipgloss.Left)
rightStyle := lipgloss.NewStyle().Align(lipgloss.Right)
- // Calculate available width for content (minus padding)
- contentWidth := m.width - 2 // Account for horizontal padding
+ // Account for the 2 chars of padding in topBarStyle
+ innerWidth := contentWidth - 2
- // Create a layout with left and right content
content := lipgloss.JoinHorizontal(
lipgloss.Top,
- leftStyle.Width(contentWidth/2).Render(left),
- rightStyle.Width(contentWidth/2).Render(right),
+ leftStyle.Width(innerWidth/2).Render(leftText),
+ rightStyle.Width(innerWidth-innerWidth/2).Render(rightText),
)
- return topBarInactiveStyle.Width(m.width).Render(content)
+ return topBarStyle.Width(contentWidth).Render(content)
}
// RenderBottomBar renders the bottom bar with key bindings
-func RenderBottomBar(m AppModel, bindings []KeyBinding, err error) string {
+func RenderBottomBar(m AppModel, bindings []KeyBinding, err error, contentWidth int) string {
var content string
- // Style for keys (inherits background from bottomBarStyle)
- keyStyle := bottomBarStyle.Bold(true)
- // Style for descriptions (inherits background from bottomBarStyle)
- descStyle := bottomBarStyle
- // Style for separators (inherits background from bottomBarStyle)
- sepStyle := bottomBarStyle
+ keyStyle := lipgloss.NewStyle().
+ Background(lipgloss.Color("240")).
+ Foreground(lipgloss.Color("15")).
+ Padding(0, 1)
+ descStyle := lipgloss.NewStyle().
+ Background(colorBarBg).
+ Foreground(colorDimmed)
+ sepStyle := lipgloss.NewStyle().Background(colorBarBg)
for i, binding := range bindings {
if binding.Hide {
@@ -184,20 +207,19 @@ func RenderBottomBar(m AppModel, bindings []KeyBinding, err error) string {
continue
}
if i > 0 {
- content += sepStyle.Render(" ")
+ content += sepStyle.Render(" ")
}
- content += keyStyle.Render(fmt.Sprintf("[%s]", binding.Key))
- content += descStyle.Render(fmt.Sprintf(" %s", desc))
+ content += keyStyle.Render(binding.Key)
+ content += descStyle.Render(" " + desc)
}
if err != nil {
- // Style for errors (inherits background, adds red foreground)
- errorStyle := bottomBarStyle.Bold(true).Foreground(lipgloss.Color("196"))
+ errStyle := lipgloss.NewStyle().Background(colorBarBg).Bold(true).Foreground(colorWarning)
content += sepStyle.Render(" ")
- content += errorStyle.Render(err.Error())
+ content += errStyle.Render(err.Error())
}
- return bottomBarStyle.Width(m.width).Align(lipgloss.Left).Render(content)
+ return bottomBarStyle.Width(contentWidth).Align(lipgloss.Left).Render(content)
}
// GetAppData fetches all data needed for the TUI