'use client'; import { useState, useEffect, useCallback, useRef } from 'react'; import { Check, Copy, ChevronUp, Download, X } from 'lucide-react'; import { distros, type DistroId } from '@/lib/data'; import { generateInstallScript } from '@/lib/generateInstallScript'; import { analytics } from '@/lib/analytics'; import { ShortcutsBar } from './ShortcutsBar'; import { AurFloatingCard } from './AurFloatingCard'; import { CommandDrawer } from './CommandDrawer'; interface CommandFooterProps { command: string; selectedCount: number; selectedDistro: DistroId; selectedApps: Set; hasAurPackages: boolean; aurAppNames: string[]; hasYayInstalled: boolean; setHasYayInstalled: (value: boolean) => void; searchQuery: string; onSearchChange: (query: string) => void; searchInputRef: React.RefObject; clearAll: () => void; selectedHelper: 'yay' | 'paru'; setSelectedHelper: (helper: 'yay' | 'paru') => void; hasUnfreePackages?: boolean; unfreeAppNames?: string[]; drawerOpen?: boolean; drawerClosing?: boolean; onDrawerOpen?: () => void; onDrawerClose?: () => void; activeShortcut?: string | null; } export function CommandFooter({ command, selectedCount, selectedDistro, selectedApps, hasAurPackages, aurAppNames, hasYayInstalled, setHasYayInstalled, searchQuery, onSearchChange, searchInputRef, clearAll, selectedHelper, setSelectedHelper, hasUnfreePackages, unfreeAppNames, drawerOpen: externalDrawerOpen, drawerClosing: externalDrawerClosing, onDrawerOpen: externalOnDrawerOpen, onDrawerClose: externalOnDrawerClose, activeShortcut, }: CommandFooterProps) { const [copied, setCopied] = useState(false); const [internalDrawerOpen, setInternalDrawerOpen] = useState(false); const [internalDrawerClosing, setInternalDrawerClosing] = useState(false); const [hasEverHadSelection, setHasEverHadSelection] = useState(false); const initialCountRef = useRef(selectedCount); const drawerOpen = externalDrawerOpen ?? internalDrawerOpen; const drawerClosing = externalDrawerClosing ?? internalDrawerClosing; useEffect(() => { if (selectedCount !== initialCountRef.current && !hasEverHadSelection) { // eslint-disable-next-line react-hooks/set-state-in-effect setHasEverHadSelection(true); } }, [selectedCount, hasEverHadSelection]); const closeDrawer = useCallback(() => { if (externalOnDrawerClose) { externalOnDrawerClose(); } else { setInternalDrawerClosing(true); setTimeout(() => { setInternalDrawerOpen(false); setInternalDrawerClosing(false); }, 250); } }, [externalOnDrawerClose]); // Close drawer on Escape useEffect(() => { if (!drawerOpen) return; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') closeDrawer(); }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [drawerOpen, closeDrawer]); const showAur = selectedDistro === 'arch' && hasAurPackages; const distroDisplayName = distros.find(d => d.id === selectedDistro)?.name || selectedDistro; const distroColor = distros.find(d => d.id === selectedDistro)?.color || 'var(--accent)'; const handleCopy = useCallback(async () => { if (selectedCount === 0) return; await navigator.clipboard.writeText(command); setCopied(true); const distroName = distros.find(d => d.id === selectedDistro)?.name || selectedDistro; analytics.commandCopied(distroName, selectedCount); setTimeout(() => setCopied(false), 3000); }, [command, selectedCount, selectedDistro]); const handleDownload = useCallback(() => { if (selectedCount === 0) return; const script = generateInstallScript({ distroId: selectedDistro, selectedAppIds: selectedApps, helper: selectedHelper, }); const isNix = selectedDistro === 'nix'; const mimeType = isNix ? 'text/plain' : 'text/x-shellscript'; const blob = new Blob([script], { type: mimeType }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = isNix ? 'configuration.nix' : `tuxmate-${selectedDistro}.sh`; a.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); const distroName = distros.find(d => d.id === selectedDistro)?.name || selectedDistro; analytics.scriptDownloaded(distroName, selectedCount); }, [selectedCount, selectedDistro, selectedApps, selectedHelper]); return ( <> {/* AUR Floating Card */} {/* Animated footer container - shows after first selection */} {hasEverHadSelection && (
{/* Shortcuts Bar */}
{/* Preview button */}
{ if (selectedCount > 0) { if (externalOnDrawerOpen) { externalOnDrawerOpen(); } else { setInternalDrawerOpen(true); } } }} > 0 ? 'text-[var(--text-primary)]' : 'text-[var(--text-muted)]'}`}> {command}
)} ); }