import { AlertCircle, Check, ChevronDown, Download, GitBranch, Plus, RefreshCw, RotateCcw, Upload, X } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; import type { ConfirmationRequest, GitRemoteStatus } from '../types/types'; import NewBranchModal from './modals/NewBranchModal'; type GitPanelHeaderProps = { isMobile: boolean; currentBranch: string; branches: string[]; remoteStatus: GitRemoteStatus | null; isLoading: boolean; isCreatingBranch: boolean; isFetching: boolean; isPulling: boolean; isPushing: boolean; isPublishing: boolean; isRevertingLocalCommit: boolean; operationError: string | null; onRefresh: () => void; onRevertLocalCommit: () => Promise; onSwitchBranch: (branchName: string) => Promise; onCreateBranch: (branchName: string) => Promise; onFetch: () => Promise; onPull: () => Promise; onPush: () => Promise; onPublish: () => Promise; onClearError: () => void; onRequestConfirmation: (request: ConfirmationRequest) => void; }; export default function GitPanelHeader({ isMobile, currentBranch, branches, remoteStatus, isLoading, isCreatingBranch, isFetching, isPulling, isPushing, isPublishing, isRevertingLocalCommit, operationError, onRefresh, onRevertLocalCommit, onSwitchBranch, onCreateBranch, onFetch, onPull, onPush, onPublish, onClearError, onRequestConfirmation, }: GitPanelHeaderProps) { const [showBranchDropdown, setShowBranchDropdown] = useState(false); const [showNewBranchModal, setShowNewBranchModal] = useState(false); const dropdownRef = useRef(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setShowBranchDropdown(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const aheadCount = remoteStatus?.ahead ?? 0; const behindCount = remoteStatus?.behind ?? 0; const remoteName = remoteStatus?.remoteName ?? 'remote'; const anyPending = isFetching || isPulling || isPushing || isPublishing; const requestPullConfirmation = () => { onRequestConfirmation({ type: 'pull', message: `Pull ${behindCount} commit${behindCount !== 1 ? 's' : ''} from ${remoteName}?`, onConfirm: onPull, }); }; const requestPushConfirmation = () => { onRequestConfirmation({ type: 'push', message: `Push ${aheadCount} commit${aheadCount !== 1 ? 's' : ''} to ${remoteName}?`, onConfirm: onPush, }); }; const requestPublishConfirmation = () => { onRequestConfirmation({ type: 'publish', message: `Publish branch "${currentBranch}" to ${remoteName}?`, onConfirm: onPublish, }); }; const requestRevertLocalCommitConfirmation = () => { onRequestConfirmation({ type: 'revertLocalCommit', message: 'Revert the latest local commit? This removes the commit but keeps its changes staged.', onConfirm: onRevertLocalCommit, }); }; const handleSwitchBranch = async (branchName: string) => { try { const success = await onSwitchBranch(branchName); if (success) setShowBranchDropdown(false); } catch (error) { console.error('[GitPanelHeader] Failed to switch branch:', error); } }; return ( <> {/* Branch row + action buttons */}
{/* Branch selector */}
{showBranchDropdown && (
{branches.map((branch) => ( ))}
)}
{/* Action buttons */}
{remoteStatus?.hasRemote && ( <> {!remoteStatus.hasUpstream ? ( ) : ( <> {/* Fetch — always visible when remote exists */} {behindCount > 0 && ( )} {aheadCount > 0 && ( )} )} )}
{/* Inline error banner */} {operationError && (
{operationError}
)} setShowNewBranchModal(false)} onCreateBranch={onCreateBranch} /> ); }