tempo_cli/ui/
widgets.rs

1use ratatui::{
2    style::{Color, Modifier, Style},
3    text::{Line, Span},
4    widgets::{Block, Borders, Gauge, Paragraph, Table, Row, Cell, List, ListItem},
5};
6use chrono::{DateTime, Local};
7
8use crate::{
9    models::{Project, Session},
10    ui::formatter::Formatter,
11};
12
13pub struct StatusWidget;
14pub struct ProgressWidget;
15pub struct SummaryWidget;
16
17// Centralized color scheme
18pub struct ColorScheme;
19
20impl ColorScheme {
21    pub fn get_context_color(context: &str) -> Color {
22        match context {
23            "terminal" => Color::Cyan,
24            "ide" => Color::Magenta, 
25            "linked" => Color::Yellow,
26            "manual" => Color::Blue,
27            _ => Color::White,
28        }
29    }
30
31    pub fn active_status() -> Color { Color::Green }
32    pub fn project_name() -> Color { Color::Yellow }
33    pub fn duration() -> Color { Color::Green }
34    pub fn path() -> Color { Color::Gray }
35    pub fn timestamp() -> Color { Color::Gray }
36    pub fn border() -> Color { Color::Cyan }
37}
38
39impl StatusWidget {
40    pub fn render_status_text(project_name: &str, duration: i64, start_time: &str, context: &str) -> String {
41        format!(
42            "● ACTIVE | {} | Time: {} | Started: {} | Context: {}",
43            project_name,
44            Formatter::format_duration(duration),
45            start_time,
46            context
47        )
48    }
49
50    pub fn render_idle_text() -> String {
51        "○ IDLE | No active time tracking session | Use 'vibe session start' to begin tracking".to_string()
52    }
53}
54
55impl ProgressWidget {
56    pub fn calculate_daily_progress(completed_seconds: i64, target_hours: f64) -> u16 {
57        let total_hours = completed_seconds as f64 / 3600.0;
58        let progress = (total_hours / target_hours * 100.0).min(100.0) as u16;
59        progress
60    }
61
62    pub fn format_progress_label(completed_seconds: i64, target_hours: f64) -> String {
63        let total_hours = completed_seconds as f64 / 3600.0;
64        let progress = (total_hours / target_hours * 100.0).min(100.0) as u16;
65        format!("Daily Progress ({:.1}h / {:.1}h) - {}%", total_hours, target_hours, progress)
66    }
67}
68
69impl SummaryWidget {
70    pub fn format_project_summary(project_name: &str, total_time: i64, session_count: usize, active_count: usize) -> String {
71        format!(
72            "Project: {} | Total Time: {} | Sessions: {} total, {} active",
73            project_name,
74            Formatter::format_duration(total_time),
75            session_count,
76            active_count
77        )
78    }
79
80    pub fn format_session_line(start_time: &DateTime<Local>, duration: i64, context: &str, is_active: bool) -> String {
81        let status_char = if is_active { "●" } else { "✓" };
82        let duration_str = if is_active {
83            format!("{} (active)", Formatter::format_duration(duration))
84        } else {
85            Formatter::format_duration(duration)
86        };
87
88        format!(
89            "{} {} | {} | {}",
90            status_char,
91            start_time.format("%H:%M:%S"),
92            duration_str,
93            context
94        )
95    }
96}