import { useEffect, useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { AlertTriangle, Loader2, Trash2, X } from 'lucide-react'; import { api } from '../api/client'; import { Button } from './Button'; import { useToast } from '../contexts/ToastContext'; import { formatFileSize } from '../utils/file'; interface PurgeArchivesModalProps { onClose: () => void; initialDays?: number; } const DEFAULT_DAYS = 365; export function PurgeArchivesModal({ onClose, initialDays }: PurgeArchivesModalProps) { const { t } = useTranslation(); const queryClient = useQueryClient(); const { showToast } = useToast(); const [days, setDays] = useState(initialDays ?? DEFAULT_DAYS); // #1390: matches the single-archive delete dialog's "Also remove from // statistics" checkbox. Default off — soft-delete, Quick Stats preserved. const [purgeStats, setPurgeStats] = useState(false); const [debouncedDays, setDebouncedDays] = useState(days); useEffect(() => { const handle = window.setTimeout(() => setDebouncedDays(days), 300); return () => window.clearTimeout(handle); }, [days]); const previewQuery = useQuery({ queryKey: ['archive-purge-preview', debouncedDays, purgeStats], queryFn: () => api.previewArchivePurge(debouncedDays, purgeStats), enabled: debouncedDays >= 1, }); const purgeMutation = useMutation({ mutationFn: () => api.executeArchivePurge(days, purgeStats), onSuccess: (res) => { showToast(t('archivePurge.toast.success', { count: res.deleted }), 'success'); queryClient.invalidateQueries({ queryKey: ['archives'] }); queryClient.invalidateQueries({ queryKey: ['archive-stats'] }); onClose(); }, onError: (e: Error) => showToast(e.message || t('archivePurge.toast.failed'), 'error'), }); useEffect(() => { const handleKey = (e: KeyboardEvent) => { if (e.key === 'Escape' && !purgeMutation.isPending) onClose(); }; window.addEventListener('keydown', handleKey); return () => window.removeEventListener('keydown', handleKey); }, [onClose, purgeMutation.isPending]); const preview = previewQuery.data; const count = preview?.count ?? 0; const totalBytes = preview?.total_bytes ?? 0; const canConfirm = count > 0 && !purgeMutation.isPending; return (
{t('archivePurge.description')}