"use client" import React, { useRef, useState } from "react" import { Button } from "@/shared/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/shared/components/ui/dialog" import { Download, FileSpreadsheet, Loader2, UploadCloud } from "lucide-react" import { toast } from "sonner" import { ImportResultsDialog } from "@/shared/components/import-results-dialog" import type { ImportDataResponse } from "@garage/api" type ImportDataButtonProps = { onImport: (file: File) => Promise onSuccess?: () => void accept?: string label?: string entityLabel?: string onDownloadSample?: () => Promise sampleFileName?: string notes?: React.ReactNode[] } const DEFAULT_NOTES: React.ReactNode[] = [ "Download the sample file and use it as a template — keep the column headers exactly as provided.", "Supported file formats: .xlsx, .xls and .csv.", "Fields marked as required in the sample must not be empty.", "Existing records will not be overwritten. Each row is imported as a new record.", "After uploading, you'll see a results summary with any rows that failed and why.", ] export function ImportDataButton({ onImport, onSuccess, accept = ".xlsx,.xls,.csv", label = "Import", entityLabel, onDownloadSample, sampleFileName, notes, }: ImportDataButtonProps) { const inputRef = useRef(null) const [stepsOpen, setStepsOpen] = useState(false) const [isImporting, setIsImporting] = useState(false) const [isDownloadingSample, setIsDownloadingSample] = useState(false) const [result, setResult] = useState(null) const [resultOpen, setResultOpen] = useState(false) const effectiveNotes = notes && notes.length > 0 ? notes : DEFAULT_NOTES const entityForCopy = entityLabel ?? "records" const handleDownloadSample = async () => { if (!onDownloadSample) return setIsDownloadingSample(true) try { const blob = await onDownloadSample() const url = URL.createObjectURL(blob) const anchor = document.createElement("a") anchor.href = url anchor.download = `${sampleFileName ?? "import-sample"}.xlsx` document.body.appendChild(anchor) anchor.click() document.body.removeChild(anchor) URL.revokeObjectURL(url) toast.success("Sample downloaded successfully") } catch (err: any) { toast.error(err?.message ?? "Failed to download sample") } finally { setIsDownloadingSample(false) } } const handleFileChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (!file) return setIsImporting(true) try { const response = await onImport(file) const data = response.data ?? { imported_count: 0, failed_count: 0, failed_rows: [] } setResult(data) setStepsOpen(false) setResultOpen(true) if (data.failed_count === 0) { onSuccess?.() } else if (data.imported_count > 0) { onSuccess?.() } } catch (err: any) { toast.error(err?.message ?? "Failed to import data") } finally { setIsImporting(false) if (inputRef.current) inputRef.current.value = "" } } return ( <> { if (isImporting) return setStepsOpen(open) }} > Import {entityForCopy.toLowerCase()} Follow these steps to import {entityForCopy.toLowerCase()} from a spreadsheet. {onDownloadSample && (

Step 1 — Download the sample file

Use it as a template so columns are recognized correctly.

)}

{onDownloadSample ? "Step 2 — Notes before you upload" : "Notes before you upload"}

    {effectiveNotes.map((note, idx) => (
  • {note}
  • ))}
{result && ( )} ) }