"use client"; import { useState } from "react"; import { GitDiffResponse } from "@/types/git"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { cn } from "@/lib/utils"; import { FileCode, FileDiff, WrapText } from "lucide-react"; import { HelpTip } from "@/components/ui/help-tip"; interface GitDiffViewerProps { stagedDiff: GitDiffResponse | undefined; unstagedDiff: GitDiffResponse | undefined; isLoadingStaged: boolean; isLoadingUnstaged: boolean; } function DiffContent({ diff, isLoading, wrap, }: { diff: GitDiffResponse | undefined; isLoading: boolean; wrap: boolean; }) { if (isLoading) { return (
{Array.from({ length: 10 }).map((_, i) => ( ))}
); } if (!diff || !diff.diff) { return (

No changes to display

); } // Parse diff and colorize const lines = diff.diff.split("\n"); return ( // overflow-x-auto is the horizontal-scroll affordance for un-wrapped long // lines on a phone; smaller mobile font, back to the desktop size at sm+.
        {lines.map((line, i) => {
          let className = "";
          if (line.startsWith("+") && !line.startsWith("+++")) {
            className = "bg-green-500/10 text-green-700 dark:text-green-400";
          } else if (line.startsWith("-") && !line.startsWith("---")) {
            className = "bg-red-500/10 text-red-700 dark:text-red-400";
          } else if (line.startsWith("@@")) {
            className = "bg-blue-500/10 text-blue-700 dark:text-blue-400";
          } else if (line.startsWith("diff") || line.startsWith("index")) {
            className = "text-muted-foreground font-semibold";
          }

          return (
            
{line || " "}
); })}
); } export function GitDiffViewer({ stagedDiff, unstagedDiff, isLoadingStaged, isLoadingUnstaged, }: GitDiffViewerProps) { const stagedCount = stagedDiff?.files_changed || 0; const unstagedCount = unstagedDiff?.files_changed || 0; const [wrap, setWrap] = useState(false); return (
Changes
{/* HelpTip wraps an inner span, never the TabsTrigger itself — TooltipTrigger's asChild would clobber the trigger's own data-state and break the active-tab highlight (see task-tabs.tsx for the fuller writeup of this bug class). */} Working Directory {unstagedCount > 0 && ( {unstagedCount} )} Staged {stagedCount > 0 && ( {stagedCount} )}
); }