47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import { Button } from "@/shared/components/ui/button"
|
|
import { Download, Loader2 } from "lucide-react"
|
|
import { toast } from "sonner"
|
|
|
|
type DownloadSampleButtonProps = {
|
|
onDownload: () => Promise<Blob>
|
|
fileName?: string
|
|
label?: string
|
|
}
|
|
|
|
export function DownloadSampleButton({
|
|
onDownload,
|
|
fileName = "import-sample",
|
|
label = "Sample",
|
|
}: DownloadSampleButtonProps) {
|
|
const [isPending, setIsPending] = useState(false)
|
|
|
|
const handleDownload = async () => {
|
|
setIsPending(true)
|
|
try {
|
|
const blob = await onDownload()
|
|
const url = URL.createObjectURL(blob)
|
|
const anchor = document.createElement("a")
|
|
anchor.href = url
|
|
anchor.download = `${fileName}.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 {
|
|
setIsPending(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Button size="sm" variant="outline" disabled={isPending} onClick={handleDownload}>
|
|
{isPending ? <Loader2 className="animate-spin" /> : <Download />}
|
|
{label}
|
|
</Button>
|
|
)
|
|
} |