diorama 0.1.0

Preview terminal color themes with realistic scenarios
use ratatui::text::Line;

use super::*;

pub(super) fn git_log_panel() -> Panel {
    let lines = vec![
        Line::from(vec![
            s("$ ", WHITE),
            s("git log --graph --oneline --all --decorate", BRIGHT_WHITE),
        ]),
        blank(),
        Line::from(vec![
            s("* ", YELLOW),
            s("a1b2c3d ", YELLOW),
            sb("(HEAD -> main) ", GREEN),
            s(
                "fix: handle edge case in JSON parser for nested arrays",
                WHITE,
            ),
        ]),
        Line::from(vec![
            s("| ", RED),
            s("Author: Alice Chen ", WHITE),
            s("<alice@dev.io>", BRIGHT_BLACK),
            s(" (", BRIGHT_BLACK),
            s("2 hours ago", CYAN),
            s(")", BRIGHT_BLACK),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("e4f5a6b ", YELLOW),
            s(
                "feat: add JSON output format with pretty-printing support",
                WHITE,
            ),
        ]),
        Line::from(vec![
            s("| ", RED),
            s("Author: Bob Martinez ", WHITE),
            s("<bob@dev.io>", BRIGHT_BLACK),
            s(" (", BRIGHT_BLACK),
            s("5 hours ago", CYAN),
            s(")", BRIGHT_BLACK),
        ]),
        Line::from(vec![
            s("*   ", YELLOW),
            s("b7c8d9e ", YELLOW),
            sb("(origin/main) ", RED),
            s("Merge branch 'feature/auth' into main", WHITE),
        ]),
        Line::from(vec![sb("|\\  ", RED)]),
        Line::from(vec![
            s("| * ", RED),
            s("f0a1b2c ", YELLOW),
            sb("(origin/feature/auth) ", RED),
            s(
                "feat: implement JWT token validation and refresh flow",
                WHITE,
            ),
        ]),
        Line::from(vec![
            s("| * ", RED),
            s("3d4e5f6 ", YELLOW),
            s("feat: add login endpoint with rate limiting", WHITE),
        ]),
        Line::from(vec![
            s("| * ", RED),
            s("7a8b9c0 ", YELLOW),
            s("feat: create auth middleware with role-based access", WHITE),
        ]),
        Line::from(vec![
            s("| * ", RED),
            s("c2d3e4f ", YELLOW),
            s("test: add integration tests for auth flow", WHITE),
        ]),
        Line::from(vec![sb("|/  ", RED)]),
        Line::from(vec![
            s("*   ", YELLOW),
            s("d1e2f3a ", YELLOW),
            s("Merge branch 'refactor/config' into main", WHITE),
        ]),
        Line::from(vec![sb("|\\  ", RED)]),
        Line::from(vec![
            s("| * ", MAGENTA),
            s("5e6f7a8 ", YELLOW),
            s("refactor: extract config module into separate crate", WHITE),
        ]),
        Line::from(vec![
            s("| * ", MAGENTA),
            s("9b0c1d2 ", YELLOW),
            s("refactor: replace env vars with typed config struct", WHITE),
        ]),
        Line::from(vec![sb("|/  ", MAGENTA)]),
        Line::from(vec![
            s("* ", YELLOW),
            s("4b5c6d7 ", YELLOW),
            sb("(tag: v1.2.0) ", MAGENTA),
            s("chore: release version 1.2.0", WHITE),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("8e9f0a1 ", YELLOW),
            s(
                "docs: update README with API examples and curl snippets",
                WHITE,
            ),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("2b3c4d5 ", YELLOW),
            s("fix: prevent SQL injection in search endpoint", WHITE),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("6f7a8b9 ", YELLOW),
            s("perf: add composite database index for user lookups", WHITE),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("a3b4c5d ", YELLOW),
            sb("(tag: v1.1.0) ", MAGENTA),
            s("chore: release version 1.1.0", WHITE),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("e6f7a8b ", YELLOW),
            s("feat: add health check endpoint at /api/v1/health", WHITE),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("1c2d3e4 ", YELLOW),
            s(
                "ci: add GitHub Actions workflow for automated testing",
                WHITE,
            ),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("f5a6b7c ", YELLOW),
            s("fix: correct timezone handling in event scheduling", WHITE),
        ]),
        Line::from(vec![
            s("* ", YELLOW),
            s("8d9e0f1 ", YELLOW),
            sb("(tag: v1.0.0) ", MAGENTA),
            s("chore: initial release", WHITE),
        ]),
    ];

    Panel {
        title: "Git Log".into(),
        icon: '\u{e725}',
        border_color: YELLOW,
        content: lines,
    }
}

pub(super) fn git_diff_panel() -> Panel {
    let lines = vec![
        Line::from(vec![
            s("$ ", WHITE),
            s("git diff HEAD~1 --stat", BRIGHT_WHITE),
        ]),
        Line::from(vec![
            s(" src/handler.rs | ", WHITE),
            sb("14 ", GREEN),
            s("++++++++", GREEN),
            s("---", RED),
        ]),
        Line::from(vec![
            s(" src/config.rs  |  ", WHITE),
            sb("4 ", GREEN),
            s("++", GREEN),
        ]),
        Line::from(vec![
            s(" src/error.rs   |  ", WHITE),
            sb("8 ", GREEN),
            s("+++++", GREEN),
            s("-", RED),
        ]),
        Line::from(vec![
            s(" 3 files changed, ", WHITE),
            sb("19 insertions(+)", GREEN),
            s(", ", WHITE),
            sb("4 deletions(-)", RED),
        ]),
        blank(),
        Line::from(vec![sb(
            "diff --git a/src/handler.rs b/src/handler.rs",
            WHITE,
        )]),
        Line::from(vec![s("index 3a4b5c6..7d8e9f0 100644", BRIGHT_BLACK)]),
        Line::from(vec![sb("--- a/src/handler.rs", RED)]),
        Line::from(vec![sb("+++ b/src/handler.rs", GREEN)]),
        Line::from(vec![
            sb("@@ -12,7 +12,14 @@", CYAN),
            s(" impl Handler {", WHITE),
        ]),
        Line::from(vec![s(
            "     pub fn handle_request(&self, req: &Request) -> Result<Response> {",
            WHITE,
        )]),
        Line::from(vec![s("         let body = req.body();", WHITE)]),
        Line::from(vec![s(
            "         let headers = req.headers().clone();",
            WHITE,
        )]),
        Line::from(vec![sb("-        let response = process(body);", RED)]),
        Line::from(vec![sb(
            "+        let response = match self.process(body) {",
            GREEN,
        )]),
        Line::from(vec![sb("+            Ok(resp) => resp,", GREEN)]),
        Line::from(vec![sb(
            "+            Err(AppError::NotFound(msg)) => {",
            GREEN,
        )]),
        Line::from(vec![sb(
            "+                tracing::warn!(\"Resource not found: {msg}\");",
            GREEN,
        )]),
        Line::from(vec![sb(
            "+                return Ok(Response::not_found(&msg));",
            GREEN,
        )]),
        Line::from(vec![sb("+            }", GREEN)]),
        Line::from(vec![sb("+            Err(e) => {", GREEN)]),
        Line::from(vec![sb(
            "+                tracing::error!(\"Internal error: {e:#}\");",
            GREEN,
        )]),
        Line::from(vec![sb(
            "+                return Ok(Response::internal_error());",
            GREEN,
        )]),
        Line::from(vec![sb("+            }", GREEN)]),
        Line::from(vec![sb("+        };", GREEN)]),
        Line::from(vec![s(
            "         Ok(response.with_headers(headers))",
            WHITE,
        )]),
        Line::from(vec![s("     }", WHITE)]),
        blank(),
        Line::from(vec![sb(
            "diff --git a/src/config.rs b/src/config.rs",
            WHITE,
        )]),
        Line::from(vec![s("index 1a2b3c4..5d6e7f8 100644", BRIGHT_BLACK)]),
        Line::from(vec![sb("--- a/src/config.rs", RED)]),
        Line::from(vec![sb("+++ b/src/config.rs", GREEN)]),
        Line::from(vec![
            sb("@@ -5,6 +5,10 @@", CYAN),
            s(" pub struct Config {", WHITE),
        ]),
        Line::from(vec![s("     pub host: String,", WHITE)]),
        Line::from(vec![s("     pub port: u16,", WHITE)]),
        Line::from(vec![sb(
            "+    /// Maximum number of concurrent connections",
            GREEN,
        )]),
        Line::from(vec![sb("+    pub max_connections: usize,", GREEN)]),
        Line::from(vec![sb(
            "+    /// Request timeout in milliseconds (0 = no timeout)",
            GREEN,
        )]),
        Line::from(vec![sb("+    pub timeout_ms: u64,", GREEN)]),
        Line::from(vec![s("     pub database_url: String,", WHITE)]),
        Line::from(vec![s("     pub log_level: String,", WHITE)]),
        Line::from(vec![s(" }", WHITE)]),
        blank(),
        Line::from(vec![sb("diff --git a/src/error.rs b/src/error.rs", WHITE)]),
        Line::from(vec![s("index 8c9d0e1..2f3a4b5 100644", BRIGHT_BLACK)]),
        Line::from(vec![sb("--- a/src/error.rs", RED)]),
        Line::from(vec![sb("+++ b/src/error.rs", GREEN)]),
        Line::from(vec![
            sb("@@ -1,8 +1,14 @@", CYAN),
            s(" use thiserror::Error;", WHITE),
        ]),
        blank(),
        Line::from(vec![s(" #[derive(Debug, Error)]", WHITE)]),
        Line::from(vec![s(" pub enum AppError {", WHITE)]),
        Line::from(vec![sb("-    #[error(\"internal error\")]", RED)]),
        Line::from(vec![sb("-    Internal,", RED)]),
        Line::from(vec![sb("+    #[error(\"internal error: {0}\")]", GREEN)]),
        Line::from(vec![sb("+    Internal(String),", GREEN)]),
        Line::from(vec![sb("+", GREEN)]),
        Line::from(vec![sb("+    #[error(\"not found: {0}\")]", GREEN)]),
        Line::from(vec![sb("+    NotFound(String),", GREEN)]),
        Line::from(vec![sb("+", GREEN)]),
        Line::from(vec![sb(
            "+    #[error(\"request timeout after {0}ms\")]",
            GREEN,
        )]),
        Line::from(vec![sb("+    Timeout(u64),", GREEN)]),
        Line::from(vec![s(" }", WHITE)]),
    ];

    Panel {
        title: "Git Diff".into(),
        icon: '\u{e728}',
        border_color: GREEN,
        content: lines,
    }
}