"use client" import { useState, useRef } from "react" import { useRouter } from "next/navigation" import { toast } from "sonner" import { Select } from "@/components/ui/select" import { Camera, X, Loader2 } from "lucide-react" const CATEGORIES = [ { value: "general", label: "General" }, { value: "plumbing", label: "Plumbing" }, { value: "electrical", label: "Electrical" }, { value: "hvac", label: "HVAC" }, { value: "appliance", label: "Appliance" }, { value: "structural", label: "Structural" }, { value: "pest", label: "Pest" }, ] const PRIORITIES = [ { value: "low", label: "Low" }, { value: "medium", label: "Medium" }, { value: "high", label: "High" }, { value: "emergency", label: "Emergency" }, ] export function MaintenanceForm({ properties, tenants, request }: { properties: any[]; tenants: any[]; request?: any }) { const router = useRouter() const [loading, setLoading] = useState(false) const [error, setError] = useState("") const [selectedPropertyId, setSelectedPropertyId] = useState(request?.property_id ?? "") const [photos, setPhotos] = useState(request?.images ?? []) const [uploading, setUploading] = useState(false) const fileRef = useRef(null) async function handlePhotoUpload(e: React.ChangeEvent) { const files = Array.from(e.target.files ?? []) if (!files.length) return if (photos.length + files.length > 5) { toast.error("Max 5 photos"); return } setUploading(true) const uploaded: string[] = [] for (const file of files) { if (file.size > 5 * 1024 * 1024) { toast.error(`${file.name} is too large (max 5MB)`); continue } const uploadData = new FormData() uploadData.append("file", file) uploadData.append("scope", "maintenance") const res = await fetch("/api/upload", { method: "POST", body: uploadData }) if (!res.ok) { toast.error(`Failed to upload ${file.name}`); continue } const { url } = await res.json() uploaded.push(url) } setPhotos((prev) => [...prev, ...uploaded]) setUploading(false) if (fileRef.current) fileRef.current.value = "" } function removePhoto(url: string) { setPhotos((prev) => prev.filter((p) => p !== url)) } const propertyOptions = [ { value: "", label: "Select property…" }, ...properties.map((p: any) => ({ value: p.id, label: p.name })), ] const units = properties.find((p: any) => p.id === selectedPropertyId)?.units ?? [] const unitOptions = [ { value: "", label: "No specific unit" }, ...units.map((u: any) => ({ value: u.id, label: `Unit ${u.unit_number}` })), ] const tenantOptions = [ { value: "", label: "No tenant" }, ...tenants.map((t: any) => ({ value: t.id, label: `${t.first_name} ${t.last_name}` })), ] const cls = "w-full rounded-lg border border-white/10 bg-white/5 px-4 py-2.5 text-sm text-white placeholder-white/30 outline-none ring-indigo-500 transition focus:border-indigo-500/50 focus:ring-1" const lbl = "mb-1.5 block text-sm font-medium text-white/70" async function handleSubmit(e: React.FormEvent) { e.preventDefault() setLoading(true) setError("") const formData = new FormData(e.currentTarget) const body = { property_id: formData.get("property_id"), unit_id: formData.get("unit_id") || undefined, tenant_id: formData.get("tenant_id") || undefined, title: formData.get("title"), description: formData.get("description"), category: formData.get("category"), priority: formData.get("priority"), assigned_to: formData.get("assigned_to") || undefined, estimated_cost: formData.get("estimated_cost") ? Number(formData.get("estimated_cost")) : undefined, images: photos, } const res = await fetch( request ? `/api/maintenance/${request.id}` : "/api/maintenance", { method: request ? "PATCH" : "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) } ) const data = await res.json() setLoading(false) if (!res.ok) { setError(typeof data.error === "string" ? data.error : "Something went wrong") return } toast.success(request ? "Request updated" : "Maintenance request created") router.push(`/maintenance/${data.id}`) router.refresh() } return (
{error && (
{error}
)}