'use client'; import { memo, useMemo, useState } from 'react'; import { IconArrowBackUp, IconExternalLink, IconPlus, IconCircleFilled, IconMinus, IconCheck, } from '@tabler/icons-react'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@kandev/ui/tabs'; import { Tooltip, TooltipContent, TooltipTrigger } from '@kandev/ui/tooltip'; import { LineStat } from '@/components/diff-stat'; import { useAppStore } from '@/components/state-provider'; import { useOpenSessionInEditor } from '@/hooks/use-open-session-in-editor'; import { useSessionGitStatus } from '@/hooks/use-session-git-status'; import { useGitOperations } from '@/hooks/use-git-operations'; import type { FileInfo } from '@/lib/state/store'; import { FileBrowser } from '@/components/task/file-browser'; type OpenFileTab = { path: string; name: string; content: string; }; type TaskFilesPanelProps = { onSelectDiffPath: (path: string) => void; onOpenFile: (file: OpenFileTab) => void; }; const StatusIcon = ({ status }: { status: FileInfo['status'] }) => { switch (status) { case 'added': case 'untracked': return (
); case 'modified': return (
); case 'deleted': return (
); case 'renamed': return (
); default: return (
); } }; const splitPath = (path: string) => { const lastSlash = path.lastIndexOf('/'); if (lastSlash === -1) return { folder: '', file: path }; return { folder: path.slice(0, lastSlash), file: path.slice(lastSlash + 1), }; }; const TaskFilesPanel = memo(function TaskFilesPanel({ onSelectDiffPath, onOpenFile }: TaskFilesPanelProps) { const [topTab, setTopTab] = useState<'diff' | 'files'>('diff'); const activeSessionId = useAppStore((state) => state.tasks.activeSessionId); const gitStatus = useSessionGitStatus(activeSessionId); const openEditor = useOpenSessionInEditor(activeSessionId ?? null); const gitOps = useGitOperations(activeSessionId ?? null); // Convert git status files to array for display const changedFiles = useMemo(() => { if (!gitStatus?.files || Object.keys(gitStatus.files).length === 0) { return []; } return Object.values(gitStatus.files).map((file) => ({ path: file.path, status: file.status, staged: file.staged, plus: file.additions, minus: file.deletions, oldPath: file.old_path, })); }, [gitStatus]); return (
setTopTab(value as 'diff' | 'files')} className="flex-1 min-h-0"> Diff files {changedFiles.length > 0 && `(${changedFiles.length})`} All files
{changedFiles.length === 0 ? (
No changes detected
) : (
    {changedFiles.map((file) => { const { folder, file: name } = splitPath(file.path); return (
  • onSelectDiffPath(file.path)} >
    {/* Staged indicator */} {file.staged ? (
    Staged for commit
    ) : ( Stage file )}
    Discard changes Open in editor
  • ); })}
)}
{activeSessionId ? ( ) : (
No task selected
)}
); }); export { TaskFilesPanel };