import { useState, useEffect } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { Calendar, Clock, X, AlertCircle, Power } from 'lucide-react'; import { api } from '../api/client'; import type { PrintQueueItemCreate } from '../api/client'; import { Card, CardContent } from './Card'; import { Button } from './Button'; import { useToast } from '../contexts/ToastContext'; interface AddToQueueModalProps { archiveId: number; archiveName: string; onClose: () => void; } export function AddToQueueModal({ archiveId, archiveName, onClose }: AddToQueueModalProps) { const queryClient = useQueryClient(); const { showToast } = useToast(); const [printerId, setPrinterId] = useState(null); const [scheduleType, setScheduleType] = useState<'asap' | 'scheduled'>('asap'); const [scheduledTime, setScheduledTime] = useState(''); const [requirePreviousSuccess, setRequirePreviousSuccess] = useState(false); const [autoOffAfter, setAutoOffAfter] = useState(false); const { data: printers } = useQuery({ queryKey: ['printers'], queryFn: () => api.getPrinters(), }); // Set default printer if only one available useEffect(() => { if (printers?.length === 1 && !printerId) { setPrinterId(printers[0].id); } }, [printers, printerId]); // Close on Escape key useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [onClose]); const addMutation = useMutation({ mutationFn: (data: PrintQueueItemCreate) => api.addToQueue(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['queue'] }); showToast('Added to print queue'); onClose(); }, onError: (error: Error) => { showToast(error.message || 'Failed to add to queue', 'error'); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!printerId) { showToast('Please select a printer', 'error'); return; } const data: PrintQueueItemCreate = { printer_id: printerId, archive_id: archiveId, require_previous_success: requirePreviousSuccess, auto_off_after: autoOffAfter, }; if (scheduleType === 'scheduled' && scheduledTime) { data.scheduled_time = new Date(scheduledTime).toISOString(); } addMutation.mutate(data); }; // Get minimum datetime (now + 1 minute) const getMinDateTime = () => { const now = new Date(); now.setMinutes(now.getMinutes() + 1); return now.toISOString().slice(0, 16); }; return (
e.stopPropagation()}> {/* Header */}

Schedule Print

{/* Form */}
{/* Archive name */}

{archiveName}

{/* Printer selection */}
{printers?.length === 0 ? (
No printers configured
) : ( )}
{/* Schedule type */}
{/* Scheduled time input */} {scheduleType === 'scheduled' && (
setScheduledTime(e.target.value)} min={getMinDateTime()} required />
)} {/* Require previous success */}
setRequirePreviousSuccess(e.target.checked)} className="rounded border-bambu-dark-tertiary bg-bambu-dark text-bambu-green focus:ring-bambu-green" />
{/* Auto power off */}
setAutoOffAfter(e.target.checked)} className="rounded border-bambu-dark-tertiary bg-bambu-dark text-bambu-green focus:ring-bambu-green" />
{/* Help text */}

{scheduleType === 'asap' ? 'Print will start as soon as the printer is idle.' : 'Print will start at the scheduled time if the printer is idle. If busy, it will wait until the printer becomes available.'}

{/* Actions */}
); }