import { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { Loader2, Archive, Trash2, FileBox, Clock, Upload, ChevronDown, ChevronUp } from 'lucide-react'; import { pendingUploadsApi } from '../api/client'; import type { PendingUpload, ProjectListItem } from '../api/client'; import { api } from '../api/client'; import { Card, CardContent, CardHeader } from './Card'; import { Button } from './Button'; import { useToast } from '../contexts/ToastContext'; import { ConfirmModal } from './ConfirmModal'; import { formatFileSize } from '../utils/file'; function formatTimeAgo(dateStr: string): string { const date = new Date(dateStr); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / 60000); if (diffMins < 1) return 'Just now'; if (diffMins < 60) return `${diffMins}m ago`; const diffHours = Math.floor(diffMins / 60); if (diffHours < 24) return `${diffHours}h ago`; const diffDays = Math.floor(diffHours / 24); return `${diffDays}d ago`; } interface PendingUploadItemProps { upload: PendingUpload; projects: ProjectListItem[]; onArchive: (id: number, data?: { tags?: string; notes?: string; project_id?: number }) => void; onDiscard: (id: number) => void; isArchiving: boolean; isDiscarding: boolean; } function PendingUploadItem({ upload, projects, onArchive, onDiscard, isArchiving, isDiscarding, }: PendingUploadItemProps) { const [expanded, setExpanded] = useState(false); const [tags, setTags] = useState(upload.tags || ''); const [notes, setNotes] = useState(upload.notes || ''); const [projectId, setProjectId] = useState(upload.project_id); const [showDiscardConfirm, setShowDiscardConfirm] = useState(false); return (

{upload.filename}

{formatFileSize(upload.file_size)} · {formatTimeAgo(upload.uploaded_at)} {upload.source_ip && ( <> · from {upload.source_ip} )}
{/* Discard Confirmation Modal */} {showDiscardConfirm && ( { onDiscard(upload.id); setShowDiscardConfirm(false); }} onCancel={() => setShowDiscardConfirm(false)} /> )} {/* Expanded details for adding tags/notes/project */} {expanded && (
setTags(e.target.value)} placeholder="e.g., functional, prototype, gift" className="w-full bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-md px-3 py-2 text-white placeholder-bambu-gray text-sm" />