import { useEffect, useState } from "react"; import type { MouseEvent } from "react"; import { Upload, Loader2 } from "lucide-react"; import { Form, useRefresh, useTranslate } from "ra-core"; import { Link } from "react-router"; import { Alert, AlertDescription } from "@/components/ds/ui/alert"; import { Button } from "@/components/ds/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ds/ui/dialog"; import { FormToolbar } from "@/components/ds/admin/simple-form"; import { FileInput } from "@/components/ds/admin/file-input"; import { FileField } from "@/components/ds/admin/file-field"; import { usePapaParse } from "../misc/usePapaParse"; import type { ContactImportSchema } from "./useContactImport"; import { useContactImport } from "./useContactImport"; import * as sampleCsv from "./contacts_export.csv?raw"; export const ContactImportButton = () => { const [modalOpen, setModalOpen] = useState(false); const translate = useTranslate(); const handleOpenModal = () => { setModalOpen(true); }; const handleCloseModal = () => { setModalOpen(false); }; return ( <> ); }; const SAMPLE_URL = `data:text/csv;name=crm_contacts_sample.csv;charset=utf-8,${encodeURIComponent( sampleCsv.default, )}`; type ContactImportModalProps = { open: boolean; onClose(): void; }; export function ContactImportDialog({ open, onClose, }: ContactImportModalProps) { const refresh = useRefresh(); const translate = useTranslate(); const processBatch = useContactImport(); const { importer, parseCsv, reset } = usePapaParse({ batchSize: 10, processBatch, }); const [file, setFile] = useState(null); useEffect(() => { if (importer.state === "complete") { refresh(); } }, [importer.state, refresh]); const handleFileChange = (file: File | null) => { setFile(file); }; const startImport = () => { if (!file) return; parseCsv(file); }; const handleClose = () => { reset(); onClose(); }; const handleReset = (e: MouseEvent) => { e.preventDefault(); reset(); }; return (
{translate("crm.contact.import.title")} {translate("crm.contact.import.description")}
{importer.state === "running" && (
{translate("crm.contact.import.running")}
{translate("crm.contact.import.status", { count: importer.importCount, total: importer.rowCount, errors: importer.errorCount, })} {importer.remainingTime !== null && ( <> {" "} {translate("crm.contact.import.remaining_time", { time: millisecondsToTime(importer.remainingTime), })} .{" "} )}
)} {importer.state === "error" && ( {translate("crm.contact.import.error")} )} {importer.state === "complete" && ( {translate("crm.contact.import.complete", { count: importer.importCount, errors: importer.errorCount, })} )} {importer.state === "idle" && ( <> {translate("crm.contact.import.template_hint")} {" "} )}
{importer.state === "idle" ? ( ) : ( )}
); } function millisecondsToTime(ms: number) { const seconds = Math.floor((ms / 1000) % 60); const minutes = Math.floor((ms / (60 * 1000)) % 60); return `${minutes}m ${seconds}s`; }