gitstack 5.3.0

Git history viewer with insights - Author stats, file heatmap, code ownership
Documentation
use ratatui::Frame;

use super::dashboard::{
    render_dashboard_branches_panel, render_dashboard_commits_panel, render_dashboard_files_panel,
    render_dashboard_footer, render_dashboard_main_panel, render_dashboard_stash_panel,
    render_dashboard_status_panel,
};
use super::helpers::calculate_layout_areas;
use super::overlays::{
    render_blame_view_overlay, render_branch_compare_overlay, render_branch_select_overlay,
    render_change_coupling_view_overlay, render_detail_overlay, render_file_history_view_overlay,
    render_handoff_view_overlay, render_heatmap_view_overlay, render_help_overlay,
    render_impact_score_view_overlay, render_next_actions_view_overlay,
    render_ownership_view_overlay, render_patch_view_overlay, render_pr_create_overlay,
    render_preset_save_dialog, render_quality_score_view_overlay, render_quick_action_overlay,
    render_quick_commit_overlay, render_related_files_overlay, render_review_pack_view_overlay,
    render_review_queue_overlay, render_stash_view_overlay, render_stats_view_overlay,
    render_status_view_overlay, render_timeline_view_overlay, render_topology_view_overlay,
};
use crate::app::{App, InputMode, SidebarPanel};

/// Render the UI with a split layout
pub fn render(frame: &mut Frame, app: &App) {
    let area = frame.area();
    let layout = calculate_layout_areas(area, app);

    // Dashboard layout
    render_dashboard_footer(frame, layout.footer, app);

    // Render 5 sidebar panels
    let panels = SidebarPanel::all();
    for (i, &panel) in panels.iter().enumerate() {
        let is_active = app.active_sidebar_panel == panel && app.sidebar_focused;
        match panel {
            SidebarPanel::Status => {
                render_dashboard_status_panel(frame, layout.sidebar_panels[i], app, is_active)
            }
            SidebarPanel::Commits => {
                render_dashboard_commits_panel(frame, layout.sidebar_panels[i], app, is_active)
            }
            SidebarPanel::Branches => {
                render_dashboard_branches_panel(frame, layout.sidebar_panels[i], app, is_active)
            }
            SidebarPanel::Files => {
                render_dashboard_files_panel(frame, layout.sidebar_panels[i], app, is_active)
            }
            SidebarPanel::Stash => {
                render_dashboard_stash_panel(frame, layout.sidebar_panels[i], app, is_active)
            }
        }
    }

    // Render main panel
    render_dashboard_main_panel(frame, layout.dashboard_main, app);

    // Help overlay (highest priority)
    if app.show_help {
        render_help_overlay(frame, app);
        return;
    }

    // Detail overlay (single mode or when Enter key is pressed)
    if app.show_detail {
        render_detail_overlay(frame, app);
    }

    // Branch selection overlay (also shown in branch creation mode)
    if app.input_mode == InputMode::BranchSelect || app.input_mode == InputMode::BranchCreate {
        render_branch_select_overlay(frame, app);
    }

    // Status view overlay
    if app.input_mode == InputMode::StatusView {
        render_status_view_overlay(frame, app);
    }

    // QuickCommit overlay
    if app.input_mode == InputMode::CommitInput {
        render_quick_commit_overlay(frame, app);
    }

    // Topology view overlay
    if app.input_mode == InputMode::TopologyView {
        render_topology_view_overlay(frame, app);
    }

    // Stats view overlay
    if app.input_mode == InputMode::StatsView {
        render_stats_view_overlay(frame, app);
    }

    // Heatmap view overlay
    if app.input_mode == InputMode::HeatmapView {
        render_heatmap_view_overlay(frame, app);
    }

    // File history view overlay
    if app.input_mode == InputMode::FileHistoryView {
        render_file_history_view_overlay(frame, app);
    }

    // Timeline view overlay
    if app.input_mode == InputMode::TimelineView {
        render_timeline_view_overlay(frame, app);
    }

    // Blame view overlay
    if app.input_mode == InputMode::BlameView {
        render_blame_view_overlay(frame, app);
    }

    // Code ownership view overlay
    if app.input_mode == InputMode::OwnershipView {
        render_ownership_view_overlay(frame, app);
    }

    // Stash view overlay
    if app.input_mode == InputMode::StashView {
        render_stash_view_overlay(frame, app);
    }

    // Patch view overlay
    if app.input_mode == InputMode::PatchView {
        render_patch_view_overlay(frame, app);
    }

    // Branch compare view overlay
    if app.input_mode == InputMode::BranchCompareView {
        render_branch_compare_overlay(frame, app);
    }

    // Related files view overlay
    if app.input_mode == InputMode::RelatedFilesView {
        render_related_files_overlay(frame, app);
    }

    // Impact Score view overlay
    if app.input_mode == InputMode::ImpactScoreView {
        render_impact_score_view_overlay(frame, app);
    }

    // Change Coupling view overlay
    if app.input_mode == InputMode::ChangeCouplingView {
        render_change_coupling_view_overlay(frame, app);
    }

    // Quality Score view overlay
    if app.input_mode == InputMode::QualityScoreView {
        render_quality_score_view_overlay(frame, app);
    }

    // Preset save dialog
    if app.input_mode == InputMode::PresetSave {
        render_preset_save_dialog(frame, app);
    }

    if app.input_mode == InputMode::QuickActionView {
        render_quick_action_overlay(frame, app);
    }

    // Review queue view overlay
    if app.input_mode == InputMode::ReviewQueueView {
        render_review_queue_overlay(frame, app);
    }

    // PR create overlay
    if app.input_mode == InputMode::PrCreate {
        render_pr_create_overlay(frame, app);
    }

    // Review pack view overlay
    if app.input_mode == InputMode::ReviewPackView {
        render_review_pack_view_overlay(frame, app);
    }

    // Next actions view overlay
    if app.input_mode == InputMode::NextActionsView {
        render_next_actions_view_overlay(frame, app);
    }

    // Handoff view overlay
    if app.input_mode == InputMode::HandoffView {
        render_handoff_view_overlay(frame, app);
    }
}