import { useState, useEffect, useCallback } from "react"; import type { WorktreeInfo } from "../../lib/api"; import { getWorktreeInfo } from "../../lib/api"; interface WorktreeFilesPanelProps { taskId: string; } /** Get status badge styling based on file status */ function getStatusStyle(status: string): { color: string; bgColor: string; label: string } { switch (status) { case "M": case "modified": return { color: "text-yellow-400", bgColor: "bg-yellow-400/10", label: "M" }; case "A": case "added": return { color: "text-green-400", bgColor: "bg-green-400/10", label: "A" }; case "D": case "deleted": return { color: "text-red-400", bgColor: "bg-red-400/10", label: "D" }; case "R": case "renamed": return { color: "text-cyan-400", bgColor: "bg-cyan-400/10", label: "R" }; case "C": case "copied": return { color: "text-purple-400", bgColor: "bg-purple-400/10", label: "C" }; case "U": case "unmerged": return { color: "text-orange-400", bgColor: "bg-orange-400/10", label: "U" }; case "?": case "untracked": return { color: "text-[#555]", bgColor: "bg-[#555]/10", label: "?" }; default: return { color: "text-[#9bc3ff]", bgColor: "bg-[rgba(117,170,252,0.1)]", label: status.charAt(0).toUpperCase() }; } } export function WorktreeFilesPanel({ taskId }: WorktreeFilesPanelProps) { const [worktreeInfo, setWorktreeInfo] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [expanded, setExpanded] = useState(false); const fetchWorktreeInfo = useCallback(async () => { try { setLoading(true); setError(null); const info = await getWorktreeInfo(taskId); setWorktreeInfo(info); } catch (e) { console.error("Failed to fetch worktree info:", e); setError(e instanceof Error ? e.message : "Failed to fetch worktree info"); } finally { setLoading(false); } }, [taskId]); useEffect(() => { fetchWorktreeInfo(); }, [fetchWorktreeInfo]); if (loading) { return (
Worktree Changes
Loading worktree info...
); } if (error) { return (
Worktree Changes
{error}
); } if (!worktreeInfo || worktreeInfo.files.length === 0) { return (
Worktree Changes
No changes in worktree
); } const { stats, files } = worktreeInfo; const displayFiles = expanded ? files : files.slice(0, 10); return (
{/* Header */}
Worktree Changes
{/* Stats */}
{stats.filesChanged} file{stats.filesChanged !== 1 ? "s" : ""} +{stats.insertions} -{stats.deletions}
{/* File list */}
{displayFiles.map((file) => { const statusStyle = getStatusStyle(file.status); return (
{/* Status badge */} {statusStyle.label} {/* File path */} {file.path} {/* Line stats */}
{file.linesAdded > 0 && ( +{file.linesAdded} )} {file.linesRemoved > 0 && ( -{file.linesRemoved} )}
); })}
{/* Show more/less button */} {files.length > 10 && (
)}
); }