"use client"; import { useState, useRef, useCallback, useEffect } from "react"; import { useTranslations } from "next-intl"; import { Upload, AlertTriangle, Check, X } from "lucide-react"; import { Button } from "@/components/ui/button"; import { SettingsSection, SettingItem, RadioGroup, Select } from "./settings-section"; import { importEmails, type ConflictResolution, type ImportProgress, type ImportResult } from "@/lib/email-import"; import { useAuthStore } from "@/stores/auth-store"; import { useEmailStore } from "@/stores/email-store"; import { EML_IMPORT_ACCEPT } from "@/lib/eml-import"; import { toast } from "@/stores/toast-store"; import { cn } from "@/lib/utils"; export function ImportSettings() { const t = useTranslations("settings.importer"); const { client } = useAuthStore(); const { mailboxes } = useEmailStore(); const fileRef = useRef(null); const [files, setFiles] = useState([]); const [destination, setDestination] = useState(""); const [conflict, setConflict] = useState("skip"); const [progress, setProgress] = useState(null); const [result, setResult] = useState(null); const [error, setError] = useState(null); const [importing, setImporting] = useState(false); const abortRef = useRef(null); useEffect(() => { if (mailboxes.length > 0 && !destination) { const inbox = mailboxes.find((m) => m.role === "inbox") || mailboxes[0]; if (inbox) setDestination(inbox.id); } }, [mailboxes, destination]); const folderOptions = mailboxes.map((m) => ({ value: m.id, label: m.name, })); const handleFileChange = useCallback((e: React.ChangeEvent) => { const selected = e.target.files; if (!selected || selected.length === 0) return; setError(null); setResult(null); setProgress(null); setFiles(Array.from(selected)); }, []); const handleImport = useCallback(async () => { if (!client || files.length === 0 || !destination) return; setImporting(true); setError(null); setResult(null); const controller = new AbortController(); abortRef.current = controller; try { const res = await importEmails({ client, files, destinationMailboxId: destination, conflictResolution: conflict, onProgress: (p) => setProgress({ ...p }), signal: controller.signal, }); setResult(res); if (res.imported > 0) { toast.success(t("success", { count: res.imported })); } } catch (err) { if (!controller.signal.aborted) { const msg = err instanceof Error ? err.message : t("fail"); setError(msg); toast.error(msg); } } finally { setImporting(false); abortRef.current = null; } }, [client, files, destination, conflict, t]); const handleCancel = () => { abortRef.current?.abort(); setImporting(false); }; const reset = () => { setFiles([]); setResult(null); setProgress(null); setError(null); if (fileRef.current) fileRef.current.value = ""; }; const progressPercent = progress && progress.total > 0 ? Math.round((progress.processed / progress.total) * 100) : 0; return (
{files.length > 0 && !importing && ( )}