Files

100 lines
3.3 KiB
TypeScript
Raw Permalink Normal View History

"use client"
import { useRef, useState } from "react"
import { useRouter } from "next/navigation"
import { toast } from "sonner"
import { FileText, Upload, ExternalLink, Loader2 } from "lucide-react"
import { setLeaseDocument } from "@/app/actions/esign"
export function LeaseDocument({
leaseId,
documentUrl,
canWrite,
}: {
leaseId: string
documentUrl: string | null
canWrite: boolean
}) {
const router = useRouter()
const inputRef = useRef<HTMLInputElement>(null)
const [uploading, setUploading] = useState(false)
async function onPick(e: React.ChangeEvent<HTMLInputElement>) {
const file = e.target.files?.[0]
if (!file) return
if (!/\.(pdf|docx?)$/i.test(file.name)) {
toast.error("Upload a PDF or Word document")
if (inputRef.current) inputRef.current.value = ""
return
}
setUploading(true)
try {
const fd = new FormData()
fd.append("file", file)
fd.append("scope", "documents")
const res = await fetch("/api/upload", { method: "POST", body: fd })
if (!res.ok) {
const j = await res.json().catch(() => ({}))
throw new Error(j?.error || "Upload failed")
}
const { url } = (await res.json()) as { url: string }
await setLeaseDocument(leaseId, url)
toast.success(documentUrl ? "Lease document replaced" : "Lease document attached")
router.refresh()
} catch (err) {
toast.error(err instanceof Error ? err.message : "Upload failed")
} finally {
setUploading(false)
if (inputRef.current) inputRef.current.value = ""
}
}
return (
<div className="rounded-xl border border-white/[0.06] bg-[#16161f] p-5">
<div className="flex items-center justify-between gap-3">
<div className="flex min-w-0 items-center gap-2 text-sm font-medium text-white">
<FileText className="h-4 w-4 shrink-0 text-indigo-400" />
{documentUrl ? "Lease document" : "No lease document yet"}
</div>
{documentUrl && (
<a
href={documentUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex shrink-0 items-center gap-1 text-xs text-indigo-400 transition hover:text-indigo-300"
>
View <ExternalLink className="h-3.5 w-3.5" />
</a>
)}
</div>
{!documentUrl && (
<p className="mt-1.5 text-xs text-white/40">Upload the lease PDF to enable sending it for e-signature.</p>
)}
{canWrite && (
<div className="mt-3">
<input
ref={inputRef}
type="file"
accept=".pdf,.doc,.docx"
onChange={onPick}
disabled={uploading}
className="hidden"
id={`lease-doc-${leaseId}`}
/>
<label
htmlFor={`lease-doc-${leaseId}`}
className={`inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-white/10 px-3 py-1.5 text-xs font-medium text-white/70 transition hover:bg-white/[0.06] hover:text-white ${
uploading ? "pointer-events-none opacity-50" : ""
}`}
>
{uploading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Upload className="h-3.5 w-3.5" />}
{documentUrl ? "Replace document" : "Upload lease document"}
</label>
</div>
)}
</div>
)
}