"use client" import { useState, useEffect } from "react" import { useRouter } from "next/navigation" import { PageHeader } from "@/components/shared/page-header" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Card } from "@/components/ui/card" import { Plus, Trash2, ArrowLeft, FileText } from "lucide-react" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" interface LineItem { id: string description: string quantity: number unitPrice: number discountPercent: number totalPrice: number } export default function NewProposalPage() { const router = useRouter() const [title, setTitle] = useState("") const [leadId, setLeadId] = useState("") const [customerId, setCustomerId] = useState("") const [validUntil, setValidUntil] = useState("") const [taxPercent, setTaxPercent] = useState(15) const [notes, setNotes] = useState("") const [terms, setTerms] = useState("Payment due within 30 days. 50% deposit required to commence work.") const [items, setItems] = useState([]) const [leads, setLeads] = useState([]) const [customers, setCustomers] = useState([]) const [saving, setSaving] = useState(false) useEffect(() => { fetch("/api/leads?limit=100").then((r) => r.json()).then(setLeads).catch(() => {}) fetch("/api/customers?limit=100").then((r) => r.json()).then(setCustomers).catch(() => {}) }, []) const addItem = () => { setItems((prev) => [ ...prev, { id: crypto.randomUUID(), description: "", quantity: 1, unitPrice: 0, discountPercent: 0, totalPrice: 0 }, ]) } const updateItem = (id: string, field: keyof LineItem, value: string | number) => { setItems((prev) => prev.map((item) => { if (item.id !== id) return item const updated = { ...item, [field]: value } updated.totalPrice = updated.quantity * updated.unitPrice * (1 - updated.discountPercent / 100) return updated }) ) } const removeItem = (id: string) => { setItems((prev) => prev.filter((i) => i.id !== id)) } const subtotal = items.reduce((sum, i) => sum + i.totalPrice, 0) const taxAmount = subtotal * (taxPercent / 100) const total = subtotal + taxAmount const handleSubmit = async () => { if (!title) return setSaving(true) try { const res = await fetch("/api/proposals", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title, leadId: leadId || null, customerId: customerId || null, subtotal, taxPercent, taxAmount, totalAmount: total, validUntil: validUntil || null, notes: notes || null, terms: terms || null, }), }) const data = await res.json() if (!data.id) throw new Error("No id returned") for (const item of items) { await fetch(`/api/proposals/${data.id}/items`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ description: item.description, quantity: item.quantity, unitPrice: item.unitPrice, discountPercent: item.discountPercent, }), }) } router.push(`/proposals/${data.id}`) } catch (e) { console.error("Failed to create proposal", e) } finally { setSaving(false) } } const formatCurrency = (n: number) => `R${n.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` return (
setTitle(e.target.value)} placeholder="e.g. Website Redesign Quote" />
setValidUntil(e.target.value)} />
setTaxPercent(parseFloat(e.target.value) || 0)} />
{/* Line Items */}
{items.length === 0 && (

No items yet. Click "Add Item" to add services or products.

)} {items.map((item) => (
updateItem(item.id, "description", e.target.value)} placeholder="Service description..." className="h-8 text-sm" />
updateItem(item.id, "quantity", parseInt(e.target.value) || 1)} className="h-7 text-xs" />
updateItem(item.id, "unitPrice", parseFloat(e.target.value) || 0)} className="h-7 text-xs" />
updateItem(item.id, "discountPercent", parseFloat(e.target.value) || 0)} className="h-7 text-xs" />

{formatCurrency(item.totalPrice)}

))}
{/* Totals */}
Subtotal{formatCurrency(subtotal)}
VAT ({taxPercent}%){formatCurrency(taxAmount)}
Total{formatCurrency(total)}
{/* Notes & Terms */}