1import { u as useDealership, r as reactExports, t as trpc, e as toast, j as jsxRuntimeExports, B as Button, k as Target, x as ChevronRight, _ as Calculator, D as Dialog, y as DialogContent, z as DialogHeader, E as DialogTitle, X, l as Car, K as Banknote, ay as CreditCard, aQ as Gauge, C as ChartColumn, S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem, I as Calendar, f as Badge, T as TrendingUp, h as Trophy, R as RefreshCw, g as Search } from "./index-DZUVA1tZ.js"; 2import { C as Card, a as CardHeader, b as CardTitle, c as CardContent } from "./card-C2_jI6O8.js"; 3import { I as Input } from "./input-BsBhHtex.js"; 4import { L as Label } from "./label-DkWcE3Xf.js"; 5import { T as Tabs, a as TabsList, b as TabsTrigger } from "./tabs-80iYot4p.js"; 6import { S as ScrollArea } from "./scroll-area-DhwZv3x4.js"; 7import { P as PageHeader } from "./PageHeader-BeAccEfP.js"; 8import { S as Sparkles } from "./sparkles-DmCltsY5.js"; 9import { P as Printer } from "./printer-DIgPr6gd.js"; 10import { D as DollarSign } from "./dollar-sign-DMAmZp43.js"; 11import { P as Percent } from "./percent-CyWz1J0J.js"; 12import { A as ArrowUpRight } from "./arrow-up-right-CbhoZhFr.js"; 13import { A as ArrowDownRight } from "./arrow-down-right-BcLpnoyf.js"; 14import "./useComposition-Bo7q6aoH.js"; 15import "./calendar-B8_9t0D4.js"; 16import "./format-B8OmckKX.js"; 17import "./endOfMonth-BBZWhvnk.js"; 18import "./chevron-left-BUMmw3WR.js"; 19import "./calendar-days-kCkFTmM5.js"; 20import "./download-2Lv-z89u.js"; 21const fmt = (n) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 }).format(n); 22const fmtDec = (n) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(n); 23const fmtNum = (n) => new Intl.NumberFormat("en-US").format(n); 24function VehicleSearch({ dealerId, onSelect }) { 25 const [query, setQuery] = reactExports.useState(""); 26 const [showResults, setShowResults] = reactExports.useState(false); 27 const { data: results, isLoading } = trpc.desking.searchVehicles.useQuery( 28 { dealerId, query }, 29 { enabled: query.length >= 2 } 30 ); 31 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ 32 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
33 /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), 34 /* @__PURE__ */ jsxRuntimeExports.jsx( 35 Input, 36 { 37 placeholder: "Search by stock #, VIN, or year make model...", 38 value: query, 39 onChange: (e) => { 40 setQuery(e.target.value); 41 setShowResults(true); 42 }, 43 onFocus: () => setShowResults(true), 44 className: "pl-10" 45 } 46 ) 47 ] }), 48 showResults && query.length >= 2 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute z-50 top-full mt-1 w-full bg-popover border border-border rounded-lg shadow-xl max-h-80 overflow-y-auto", children: [ 49 isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-center text-muted-foreground", children: "Searching inventory..." }), 50 results && results.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-center text-muted-foreground", children: "No vehicles found" }), 51 results?.map((v) => { 52 const price = v.sellingPrice || v.retailPrice || v.internetPrice || v.msrp || 0; 53 const cost = v.cost || v.invoicePrice || 0; 54 const photos = v.photos; 55 return /* @__PURE__ */ jsxRuntimeExports.jsxs( 56 "button", 57 { 58 className: "w-full flex items-center gap-3 p-3 hover:bg-accent/50 transition-colors text-left border-b border-border/50 last:border-0", 59 onClick: () => { 60 onSelect(v); 61 setShowResults(false); 62 setQuery(`${v.year} ${v.make} ${v.model}`); 63 }, 64 children: [ 65 photos && photos.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: photos[0], alt: "", className: "w-16 h-12 object-cover rounded" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-12 bg-muted rounded flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Car, { className: "h-5 w-5 text-muted-foreground" }) }),
66 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 67 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-medium text-sm truncate", children: [ 68 v.year, 69 " ", 70 v.make, 71 " ", 72 v.model, 73 " ", 74 v.trim || "" 75 ] }), 76 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [ 77 "Stock #", 78 v.stockId, 79 " · ", 80 v.exteriorColor || "N/A", 81 " · ", 82 v.mileage ? fmtNum(v.mileage) + " mi" : "New" 83 ] }) 84 ] }), 85 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-right", children: [ 86 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-sm", children: price > 0 ? fmt(price) : "No Price" }), 87 cost > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [ 88 "Cost: ", 89 fmt(cost) 90 ] }) 91 ] }) 92 ] 93 }, 94 v.id 95 ); 96 }) 97 ] }) 98 ] }); 99} 100function DeskingWorksheet() { 101 const { selectedDealerId } = useDealership(); 102 const dealerId = selectedDealerId || ""; 103 const [selectedVehicle, setSelectedVehicle] = reactExports.useState(null); 104 const [dealType, setDealType] = reactExports.useState("loan"); 105 const [sellingPrice, setSellingPrice] = reactExports.useState(0); 106 const [vehicleCost, setVehicleCost] = reactExports.useState(0); 107 const [tradeValue, setTradeValue] = reactExports.useState(0); 108 const [tradePayoff, setTradePayoff] = reactExports.useState(0); 109 const [tradeYear, setTradeYear] = reactExports.useState(void 0); 110 const [tradeMake, setTradeMake] = reactExports.useState(""); 111 const [tradeModel, setTradeModel] = reactExports.useState(""); 112 const [tradeMileage, setTradeMileage] = reactExports.useState(void 0); 113 const [tradeVin, setTradeVin] = reactExports.useState(""); 114 const [tradeLienholder, setTradeLienholder] = reactExports.useState(""); 115 const [showTradeEstimator, setShowTradeEstimator] = reactExports.useState(false); 116 const [downPayment, setDownPayment] = reactExports.useState(0); 117 const [rebates, setRebates] = reactExports.useState(0); 118 const [accessories, setAccessories] = reactExports.useState(0); 119 const [docFee, setDocFee] = reactExports.useState(1295); 120 const [tagFee, setTagFee] = reactExports.useState(50); 121 const [warranty, setWarranty] = reactExports.useState(0); 122 const [gap, setGap] = reactExports.useState(0); 123 const [maintenance, setMaintenance] = reactExports.useState(0); 124 const [tireWheel, setTireWheel] = reactExports.useState(0); 125 const [paintProtection, setPaintProtection] = reactExports.useState(0); 126 const [taxRate, setTaxRate] = reactExports.useState(6); 127 const [apr, setApr] = reactExports.useState(6.9); 128 const [term, setTerm] = reactExports.useState(72); 129 const [residualPercent, setResidualPercent] = reactExports.useState(55); 130 const [moneyFactor, setMoneyFactor] = reactExports.useState(125e-5); 131 const [mileageAllowance, setMileageAllowance] = reactExports.useState(12e3); 132 const [capCostReduction, setCapCostReduction] = reactExports.useState(0); 133 const { data: tradeMakes } = trpc.desking.tradeMakes.useQuery(void 0, { staleTime: 3e5 }); 134 const { data: tradeModels } = trpc.desking.tradeModels.useQuery( 135 { make: tradeMake }, 136 { enabled: !!tradeMake, staleTime: 3e5 } 137 ); 138 const { data: tradeEstimate } = trpc.desking.estimateTradeValue.useQuery( 139 { dealerId, year: tradeYear, make: tradeMake || void 0, model: tradeModel || void 0, mileage: tradeMileage }, 140 { enabled: !!tradeMake && !!tradeModel } 141 ); 142 const [creditTier, setCreditTier] = reactExports.useState(""); 143 const { data: lenderRateResult } = trpc.desking.lookupRate.useQuery( 144 { dealerId, creditTier, term }, 145 { enabled: !!dealerId && !!creditTier } 146 ); 147 const [lenderInfo, setLenderInfo] = reactExports.useState(""); 148 reactExports.useEffect(() => { 149 if (lenderRateResult && creditTier && creditTier !== "manual") { 150 const newApr = lenderRateResult.customerRate; 151 setApr(newApr); 152 setLenderInfo(`${lenderRateResult.lenderName} â Buy: ${lenderRateResult.buyRate}% + Markup â ${newApr}%`); 153 } 154 }, [lenderRateResult, creditTier]); 155 const [showAlternatives, setShowAlternatives] = reactExports.useState(false); 156 const [paymentTolerance, setPaymentTolerance] = reactExports.useState(50); 157 const saveDealMutation = trpc.desking.saveDeal.useMutation({ 158 onSuccess: () => toast.success("Deal saved successfully"), 159 onError: () => toast.error("Failed to save deal") 160 }); 161 const submitDealApproval = trpc.approvals.submitDealApproval.useMutation({ 162 onSuccess: () => toast.success("Deal submitted for GSM approval â notification sent"), 163 onError: (e) => toast.error(e.message) 164 }); 165 const [scenarios, setScenarios] = reactExports.useState([]); 166 const [showCompare, setShowCompare] = reactExports.useState(false); 167 const handleVehicleSelect = reactExports.useCallback((v) => { 168 setSelectedVehicle(v); 169 const price = v.sellingPrice || v.retailPrice || v.internetPrice || v.msrp || 0; 170 const cost = v.cost || v.invoicePrice || Math.round(price * 0.85); 171 setSellingPrice(price);
172 setVehicleCost(cost); 173 }, []); 174 const calculations = reactExports.useMemo(() => { 175 if (sellingPrice === 0) return null; 176 const tradeEquity = tradeValue - tradePayoff; 177 const fiProducts = warranty + gap + maintenance + tireWheel + paintProtection; 178 if (dealType === "loan") { 179 const subtotal = sellingPrice + accessories + docFee + fiProducts - rebates - tradeEquity - downPayment; 180 const taxableAmount = sellingPrice + accessories + docFee - rebates; 181 const salesTax = taxableAmount * (taxRate / 100) + tagFee; 182 const amountFinanced = subtotal + salesTax; 183 const monthlyRate = apr / 100 / 12; 184 const monthlyPayment = monthlyRate > 0 ? amountFinanced * monthlyRate * Math.pow(1 + monthlyRate, term) / (Math.pow(1 + monthlyRate, term) - 1) : amountFinanced / term; 185 const totalInterest = monthlyPayment * term - amountFinanced; 186 const totalCost = monthlyPayment * term; 187 const frontGross = sellingPrice - vehicleCost + accessories + docFee; 188 const reserveEstimate = amountFinanced * 0.015; 189 const backGross = fiProducts + reserveEstimate; 190 const totalGross = frontGross + backGross; 191 return { 192 dealType: "loan", 193 tradeEquity, 194 fiProducts, 195 subtotal, 196 salesTax, 197 amountFinanced, 198 monthlyPayment, 199 totalInterest, 200 totalCost, 201 frontGross, 202 backGross, 203 totalGross, 204 reserveEstimate 205 }; 206 } else { 207 const grossCapCost = sellingPrice + accessories + docFee + fiProducts; 208 const taxableAmount = sellingPrice + accessories + docFee; 209 const salesTax = taxableAmount * (taxRate / 100) + tagFee; 210 const netCapCost = grossCapCost + salesTax - rebates - tradeEquity - downPayment - capCostReduction; 211 const residualValue = sellingPrice * (residualPercent / 100); 212 const depreciation = (netCapCost - residualValue) / term; 213 const rentCharge = (netCapCost + residualValue) * moneyFactor; 214 const monthlyPayment = depreciation + rentCharge; 215 const totalCost = monthlyPayment * term + downPayment + capCostReduction; 216 const frontGross = sellingPrice - vehicleCost + accessories + docFee; 217 const backGross = fiProducts; 218 const totalGross = frontGross + backGross; 219 return { 220 dealType: "lease", 221 tradeEquity, 222 fiProducts, 223 grossCapCost, 224 netCapCost, 225 salesTax, 226 residualValue, 227 depreciation, 228 rentCharge, 229 monthlyPayment, 230 totalCost, 231 frontGross, 232 backGross, 233 totalGross 234 }; 235 } 236 }, [sellingPrice, vehicleCost, tradeValue, tradePayoff, downPayment, rebates, accessories, docFee, tagFee, taxRate, apr, term, warranty, gap, maintenance, tireWheel, paintProtection, dealType, residualPercent, moneyFactor, capCostReduction]); 237 const paymentGrid = reactExports.useMemo(() => { 238 if (!calculations || calculations.dealType !== "loan") return null; 239 const terms = [36, 48, 60, 72, 84]; 240 const rates = [apr - 2, apr - 1, apr, apr + 1, apr + 2].filter((r) => r >= 0); 241 return terms.map((t) => ({ 242 term: t, 243 payments: rates.map((r) => { 244 const monthlyRate = r / 100 / 12; 245 const payment = monthlyRate > 0 ? calculations.amountFinanced * monthlyRate * Math.pow(1 + monthlyRate, t) / (Math.pow(1 + monthlyRate, t) - 1) : calculations.amountFinanced / t; 246 return { rate: r, payment, isSelected: t === term && Math.abs(r - apr) < 0.01 }; 247 }) 248 })); 249 }, [calculations, apr, term]); 250 const { data: alternatives, isLoading: altLoading } = trpc.desking.findAlternatives.useQuery( 251 { 252 dealerId, 253 currentVehicleId: selectedVehicle?.id || 0, 254 targetPayment: calculations?.monthlyPayment || 0, 255 paymentTolerance, 256 apr, 257 term, 258 downPayment, 259 tradeEquity: tradeValue - tradePayoff, 260 taxRate, 261 docFee 262 }, 263 { enabled: showAlternatives && !!selectedVehicle && !!calculations } 264 ); 265 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6 p-4 sm:p-6", children: [
266 /* @__PURE__ */ jsxRuntimeExports.jsx( 267 PageHeader, 268 { 269 title: "Desking Worksheet", 270 description: "Structure deals, pencil payments, and find profit-maximizing alternatives", 271 children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex w-full flex-wrap items-center gap-2 sm:w-auto", children: calculations && selectedVehicle && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 272 /* @__PURE__ */ jsxRuntimeExports.jsxs( 273 Button, 274 { 275 size: "sm", 276 variant: "outline", 277 onClick: () => { 278 setScenarios((prev) => [...prev, { 279 label: `${term}mo @ ${apr}% / $${downPayment} down`, 280 term, 281 apr, 282 down: downPayment, 283 payment: Math.round(calculations.monthlyPayment), 284 gross: Math.round(calculations.totalGross), 285 vehicleYear: selectedVehicle?.year, 286 vehicleMake: selectedVehicle?.make, 287 vehicleModel: selectedVehicle?.model, 288 vehicleTrim: selectedVehicle?.trim, 289 stockNumber: selectedVehicle?.stockId, 290 sellingPrice, 291 vehicleCost, 292 downPayment, 293 tradeValue, 294 tradePayoff, 295 docFee, 296 taxRate, 297 monthlyPayment: Math.round(calculations.monthlyPayment), 298 amountFinanced: Math.round("amountFinanced" in calculations ? calculations.amountFinanced : calculations.netCapCost ?? 0), 299 frontGross: Math.round(calculations.frontGross), 300 backGross: Math.round(calculations.backGross), 301 totalGross: Math.round(calculations.totalGross), 302 dealType, 303 creditTier, 304 lenderName: lenderRateResult?.lenderName 305 }]); 306 toast.success("Scenario saved for comparison"); 307 }, 308 children: [
309 /* @__PURE__ */ jsxRuntimeExports.jsx(Target, { className: "h-3.5 w-3.5 mr-1" }), 310 " Save Scenario" 311 ] 312 } 313 ), 314 scenarios.length >= 2 && /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", variant: "outline", onClick: () => setShowCompare(true), children: [ 315 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "h-3.5 w-3.5 mr-1" }), 316 " Compare (", 317 scenarios.length, 318 ")" 319 ] }), 320 /* @__PURE__ */ jsxRuntimeExports.jsxs( 321 Button, 322 { 323 size: "sm", 324 variant: "outline", 325 onClick: () => { 326 saveDealMutation.mutate({ 327 dealerId, 328 name: `${selectedVehicle.year} ${selectedVehicle.make} ${selectedVehicle.model} - ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`, 329 vehicleId: selectedVehicle.id, 330 stockNumber: selectedVehicle.stockId, 331 vin: selectedVehicle.vin, 332 vehicleYear: parseInt(selectedVehicle.year) || 0, 333 vehicleMake: selectedVehicle.make, 334 vehicleModel: selectedVehicle.model, 335 sellingPrice, 336 vehicleCost, 337 tradeValue, 338 tradePayoff, 339 tradeYear: tradeYear || void 0, 340 tradeMake: tradeMake || void 0, 341 tradeModel: tradeModel || void 0, 342 tradeVin: tradeVin || void 0, 343 tradeMileage: tradeMileage || void 0, 344 tradeLienholder: tradeLienholder || void 0, 345 downPayment, 346 rebates, 347 docFee, 348 accessories, 349 taxRate, 350 apr, 351 term, 352 dealType, 353 monthlyPayment: calculations.monthlyPayment, 354 frontGross: calculations.frontGross, 355 backGross: calculations.backGross, 356 totalGross: calculations.totalGross, 357 warranty, 358 gap, 359 maintenancePlan: maintenance, 360 tireWheel, 361 paintProtection 362 }); 363 }, 364 disabled: saveDealMutation.isPending, 365 children: [
366 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-3.5 w-3.5 mr-1" }), 367 " Save Deal" 368 ] 369 } 370 ), 371 /* @__PURE__ */ jsxRuntimeExports.jsxs( 372 Button, 373 { 374 size: "sm", 375 variant: "outline", 376 className: "border-amber-500/30 text-amber-400 hover:bg-amber-500/10", 377 onClick: () => { 378 if (!selectedVehicle) { 379 toast.error("Select a vehicle first"); 380 return; 381 } 382 const frontGross = calculations?.frontGross ?? 0; 383 const backGross = warranty + gap + maintenance + tireWheel + paintProtection; 384 const totalGross = frontGross + backGross; 385 let approvalType = "custom"; 386 let description = ""; 387 if (tradeValue > (selectedVehicle.wholesalePrice || selectedVehicle.cost || sellingPrice * 0.8)) { 388 approvalType = "over_allowance"; 389 description = `Trade over book by $${(tradeValue - (selectedVehicle.wholesalePrice || selectedVehicle.cost || sellingPrice * 0.8)).toLocaleString()}`; 390 } else if (frontGross < 1e3) { 391 approvalType = "gross_below_min"; 392 description = `Front gross only $${frontGross.toLocaleString()} â below minimum threshold`; 393 } 394 submitDealApproval.mutate({ 395 dealerId, 396 savedDealId: void 0, 397 approvalType, 398 description: description || `Deal on ${selectedVehicle.year} ${selectedVehicle.make} ${selectedVehicle.model} needs GSM approval`, 399 vehicleYear: Number(selectedVehicle.year) || void 0, 400 vehicleMake: selectedVehicle.make || void 0, 401 vehicleModel: selectedVehicle.model || void 0, 402 stockNumber: selectedVehicle.stockNumber || selectedVehicle.stockId || void 0, 403 sellingPrice, 404 frontGross, 405 backGross, 406 totalGross, 407 monthlyPayment: calculations?.monthlyPayment ? Math.round(calculations.monthlyPayment) : void 0, 408 tradeOverAllowance: tradeValue > 0 ? Math.max(0, tradeValue - (selectedVehicle.wholesalePrice || selectedVehicle.cost || 0)) : void 0 409 }); 410 }, 411 disabled: submitDealApproval.isPending || !selectedVehicle, 412 children: [
413 /* @__PURE__ */ jsxRuntimeExports.jsx(Target, { className: "h-3.5 w-3.5 mr-1" }), 414 " Submit for Approval" 415 ] 416 } 417 ), 418 /* @__PURE__ */ jsxRuntimeExports.jsxs( 419 Button, 420 { 421 size: "sm", 422 variant: "outline", 423 onClick: async () => { 424 try { 425 const res = await fetch("/api/deal-worksheet/pdf", { 426 method: "POST", 427 headers: { "Content-Type": "application/json" }, 428 body: JSON.stringify({ 429 stockNumber: selectedVehicle?.stockNumber, 430 vin: selectedVehicle?.vin, 431 vehicleYear: selectedVehicle?.year, 432 vehicleMake: selectedVehicle?.make, 433 vehicleModel: selectedVehicle?.model, 434 vehicleTrim: selectedVehicle?.trim, 435 vehicleColor: selectedVehicle?.exteriorColor, 436 vehicleMileage: selectedVehicle?.mileage, 437 sellingPrice, 438 vehicleCost: selectedVehicle?.cost || 0, 439 tradeValue, 440 tradePayoff, 441 downPayment, 442 rebates, 443 accessories, 444 docFee, 445 warranty, 446 gap, 447 maintenancePlan: maintenance, 448 tireWheel, 449 paintProtection, 450 dealType, 451 taxRate, 452 apr, 453 term, 454 creditTier: creditTier || void 0, 455 lenderName: lenderInfo ? lenderInfo.split(" â")[0] : void 0, 456 monthlyPayment: calculations.monthlyPayment, 457 amountFinanced: calculations.amountFinanced, 458 frontGross: calculations.frontGross, 459 backGross: calculations.backGross, 460 totalGross: calculations.totalGross 461 }) 462 }); 463 if (!res.ok) throw new Error("PDF generation failed"); 464 const blob = await res.blob(); 465 const url = URL.createObjectURL(blob); 466 const a = document.createElement("a"); 467 a.href = url; 468 a.download = `deal-worksheet-${selectedVehicle?.stockNumber || "draft"}.pdf`; 469 a.click(); 470 URL.revokeObjectURL(url); 471 toast.success("PDF downloaded"); 472 } catch { 473 toast.error("Failed to generate PDF"); 474 } 475 }, 476 children: [
477 /* @__PURE__ */ jsxRuntimeExports.jsx(Calculator, { className: "h-3.5 w-3.5 mr-1" }), 478 " Export PDF" 479 ] 480 } 481 ) 482 ] }) }) 483 } 484 ), 485 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showCompare, onOpenChange: setShowCompare, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-2xl", children: [ 486 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [ 487 /* @__PURE__ */ jsxRuntimeExports.jsx(Target, { className: "h-5 w-5 text-blue-400" }), 488 "Scenario Comparison" 489 ] }) }), 490 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 491 selectedVehicle && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-muted-foreground", children: [ 492 selectedVehicle.year, 493 " ", 494 selectedVehicle.make, 495 " ", 496 selectedVehicle.model, 497 " ", 498 selectedVehicle.trim || "", 499 " â Stock #", 500 selectedVehicle.stockId 501 ] }),
502 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto rounded-lg border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full min-w-[640px] text-sm", children: [ 503 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 504 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left p-3 font-semibold text-xs uppercase", children: "Scenario" }), 505 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-center p-3 font-semibold text-xs uppercase", children: "Term" }), 506 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-center p-3 font-semibold text-xs uppercase", children: "APR" }), 507 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-center p-3 font-semibold text-xs uppercase", children: "Down" }), 508 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right p-3 font-semibold text-xs uppercase text-blue-400", children: "Payment" }),
509 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-right p-3 font-semibold text-xs uppercase text-emerald-400", children: "Total Gross" }), 510 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "p-3 w-10" }) 511 ] }) }), 512 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { className: "divide-y divide-border", children: scenarios.map((s, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "hover:bg-accent/30", children: [ 513 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3 font-medium", children: s.label }), 514 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-3 text-center font-mono", children: [ 515 s.term, 516 "mo" 517 ] }), 518 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-3 text-center font-mono", children: [ 519 s.apr, 520 "%" 521 ] }), 522 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-3 text-center font-mono", children: [ 523 "$", 524 s.down.toLocaleString() 525 ] }),
526 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-3 text-right font-mono font-bold text-blue-400", children: [ 527 "$", 528 s.payment.toLocaleString(), 529 "/mo" 530 ] }), 531 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "p-3 text-right font-mono font-bold text-emerald-400", children: [ 532 "$", 533 s.gross.toLocaleString(), 534 "/mo" 535 ] }), 536 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", variant: "ghost", className: "h-6 w-6 p-0", onClick: () => setScenarios((prev) => prev.filter((_, idx) => idx !== i)), children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-3 w-3" }) }) }) 537 ] }, i)) }) 538 ] }) }), 539 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [ 540 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", variant: "outline", onClick: () => setScenarios([]), children: "Clear All" }),
541 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [ 542 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", variant: "outline", className: "w-full sm:w-auto", onClick: async () => { 543 try { 544 const scenarioData = scenarios.map((s) => ({ 545 vehicleYear: s.vehicleYear, 546 vehicleMake: s.vehicleMake, 547 vehicleModel: s.vehicleModel, 548 vehicleTrim: s.vehicleTrim, 549 stockNumber: s.stockNumber, 550 sellingPrice: s.sellingPrice, 551 vehicleCost: s.vehicleCost, 552 downPayment: s.downPayment, 553 tradeValue: s.tradeValue || 0, 554 tradePayoff: s.tradePayoff || 0, 555 docFee: s.docFee, 556 taxRate: s.taxRate, 557 apr: s.apr, 558 term: s.term, 559 monthlyPayment: s.monthlyPayment, 560 amountFinanced: s.amountFinanced, 561 frontGross: s.frontGross, 562 backGross: s.backGross || 0, 563 totalGross: s.totalGross || s.frontGross, 564 dealType: s.dealType || "Loan", 565 creditTier: s.creditTier, 566 lenderName: s.lenderName 567 })); 568 const res = await fetch("/api/deal-comparison/pdf", { 569 method: "POST", 570 headers: { "Content-Type": "application/json" }, 571 body: JSON.stringify({ scenarios: scenarioData }) 572 }); 573 if (!res.ok) throw new Error("PDF generation failed"); 574 const blob = await res.blob(); 575 const url = URL.createObjectURL(blob); 576 const a = document.createElement("a"); 577 a.href = url; 578 a.download = `deal-comparison-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.pdf`; 579 a.click(); 580 URL.revokeObjectURL(url); 581 toast.success("Comparison PDF exported"); 582 } catch { 583 toast.error("Failed to export comparison PDF"); 584 } 585 }, children: [
586 /* @__PURE__ */ jsxRuntimeExports.jsx(Printer, { className: "h-3.5 w-3.5 mr-1" }), 587 " Export PDF" 588 ] }), 589 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", className: "w-full sm:w-auto", onClick: () => setShowCompare(false), children: "Done" }) 590 ] }) 591 ] }) 592 ] }) 593 ] }) }), 594 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ 595 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2 text-lg", children: [ 596 /* @__PURE__ */ jsxRuntimeExports.jsx(Car, { className: "h-5 w-5 text-blue-400" }), 597 "Select Vehicle from Inventory" 598 ] }) }), 599 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [ 600 /* @__PURE__ */ jsxRuntimeExports.jsx(VehicleSearch, { dealerId, onSelect: handleVehicleSelect }), 601 selectedVehicle && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 flex flex-col gap-4 roun
601ded-lg border border-accent bg-accent/30 p-4 sm:flex-row sm:items-center", children: [ 602 (() => { 603 const photos = selectedVehicle.photos; 604 return photos && photos.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: photos[0], alt: "", className: "w-24 h-18 object-cover rounded-lg" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-24 h-18 bg-muted rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Car, { className: "h-8 w-8 text-muted-foreground" }) }); 605 })(), 606 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 607 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "font-semibold text-lg", children: [ 608 selectedVehicle.year, 609 " ", 610 selectedVehicle.make, 611 " ", 612 selectedVehicle.model, 613 " ", 614 selectedVehicle.trim || "" 615 ] }), 616 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-muted-foreground", children: [ 617 "Stock #", 618 selectedVehicle.stockId, 619 " · VIN: ", 620 selectedVehicle.vin, 621 " · ", 622 selectedVehicle.exteriorColor || "N/A", 623 selectedVehicle.mileage ? ` · ${fmtNum(selectedVehicle.mileage)} mi` : " · New", 624 selectedVehicle.daysInStock ? ` · ${selectedVehicle.daysInStock} days on lot` : "" 625 ] }) 626 ] }),
627 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1 sm:text-right", children: [ 628 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "Selling" }), 629 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-bold text-lg", children: fmt(sellingPrice) }), 630 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground", children: [ 631 "Cost: ", 632 fmt(vehicleCost) 633 ] }) 634 ] }), 635 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "icon", onClick: () => { 636 setSelectedVehicle(null); 637 setSellingPrice(0); 638 setVehicleCost(0); 639 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-4 w-4" }) }) 640 ] }) 641 ] }) 642 ] }), 643 calculations && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gradient-to-r from-emerald-500/10 via-blue-500/5 to-purple-500/10 border border-emerald-500/20 rounded-xl p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-5", children: [
644 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [ 645 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-1 uppercase tracking-wider", children: "Monthly Payment" }), 646 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-3xl md:text-4xl font-bold text-emerald-400", children: fmtDec(calculations.monthlyPayment) }), 647 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: dealType === "loan" ? `${term}mo @ ${apr}% APR` : `${term}mo lease` }) 648 ] }), 649 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [ 650 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-1 uppercase tracking-wider", children: "Front Gross" }), 651 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-2xl font-bold ${calculations.frontGross >= 0 ? "text-emerald-400" : "text-red-400"}`, children: fmt(calculations.frontGross) }) 652 ] }),
653 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [ 654 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-1 uppercase tracking-wider", children: "Back Gross" }), 655 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-blue-400", children: fmt(calculations.backGross) }) 656 ] }), 657 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [ 658 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-1 uppercase tracking-wider", children: "Total Gross" }), 659 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-2xl font-bold ${calculations.totalGross >= 2e3 ? "text-emerald-400" : calculations.totalGross >= 0 ? "text-yellow-400" : "text-red-400"}`, children: fmt(calculations.totalGross) }) 660 ] }), 661 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [ 662 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mb-1 uppercase tracking-wider", children: dealType === "loan" ? "Amt Financed" : "Net Cap Cost" }),
663 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold", children: fmt(calculations.dealType === "loan" ? calculations.amountFinanced : calculations.netCapCost) }) 664 ] }) 665 ] }) }), 666 /* @__PURE__ */ jsxRuntimeExports.jsx(Tabs, { value: dealType, onValueChange: (v) => setDealType(v), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { className: "grid w-full max-w-xs grid-cols-2", children: [ 667 /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "loan", className: "flex items-center gap-2", children: [ 668 /* @__PURE__ */ jsxRuntimeExports.jsx(Banknote, { className: "h-4 w-4" }), 669 " Loan" 670 ] }), 671 /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsTrigger, { value: "lease", className: "flex items-center gap-2", children: [ 672 /* @__PURE__ */ jsxRuntimeExports.jsx(CreditCard, { className: "h-4 w-4" }), 673 " Lease" 674 ] }) 675 ] }) }), 676 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
677 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ 678 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm font-medium flex items-center gap-2", children: [ 679 /* @__PURE__ */ jsxRuntimeExports.jsx(DollarSign, { className: "h-4 w-4" }), 680 " Pricing & Trade" 681 ] }) }), 682 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ 683 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 684 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Selling Price" }), 685 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: sellingPrice || "", onChange: (e) => setSellingPrice(+e.target.value), className: "font-mono" }) 686 ] }), 687 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
688 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Vehicle Cost (Invoice)" }), 689 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: vehicleCost || "", onChange: (e) => setVehicleCost(+e.target.value), className: "font-mono" }) 690 ] }), 691 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 692 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs font-medium text-muted-foreground", children: "TRADE-IN" }), 693 /* @__PURE__ */ jsxRuntimeExports.jsxs( 694 Button, 695 { 696 size: "sm", 697 variant: showTradeEstimator ? "default" : "outline", 698 className: "h-6 text-[10px] px-2", 699 onClick: () => setShowTradeEstimator(!showTradeEstimator), 700 children: [ 701 /* @__PURE__ */ jsxRuntimeExports.jsx(Gauge, { className: "h-3 w-3 mr-1" }), 702 showTradeEstimator ? "Hide Estimator" : "Estimate Value" 703 ] 704 } 705 ) 706 ] }) }), 707 showTradeEstimator && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 bg-gradient-to-br from-purple-500/5 to-blue-500/5 border border-purple-500/20 rounded-lg space-y-3", children: [
708 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [ 709 /* @__PURE__ */ jsxRuntimeExports.jsx(ChartColumn, { className: "h-3.5 w-3.5 text-purple-400" }), 710 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-purple-400 uppercase tracking-wider", children: "Trade Value Estimator" }) 711 ] }), 712 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [ 713 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 714 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-[10px] text-muted-foreground", children: "Year" }), 715 /* @__PURE__ */ jsxRuntimeExports.jsx( 716 Input, 717 { 718 type: "number", 719 placeholder: "2021", 720 value: tradeYear || "", 721 onChange: (e) => setTradeYear(e.target.value ? parseInt(e.target.value) : void 0), 722 className: "h-7 text-xs font-mono" 723 } 724 ) 725 ] }),
726 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 727 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-[10px] text-muted-foreground", children: "Make" }), 728 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: tradeMake, onValueChange: (v) => { 729 setTradeMake(v); 730 setTradeModel(""); 731 }, children: [ 732 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select" }) }), 733 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: tradeMakes?.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m)) }) 734 ] }) 735 ] }), 736 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 737 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-[10px] text-muted-foreground", children: "Model" }),
738 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: tradeModel, onValueChange: setTradeModel, disabled: !tradeMake, children: [ 739 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select" }) }), 740 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: tradeModels?.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: m, children: m }, m)) }) 741 ] }) 742 ] }), 743 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 744 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-[10px] text-muted-foreground", children: "Mileage" }), 745 /* @__PURE__ */ jsxRuntimeExports.jsx( 746 Input, 747 { 748 type: "number", 749 placeholder: "45000", 750 value: tradeMileage || "", 751 onChange: (e) => setTradeMileage(e.target.value ? parseInt(e.target.value) : void 0), 752 className: "h-7 text-xs font-mono" 753 } 754 ) 755 ] }) 756 ] }),
757 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 758 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-[10px] text-muted-foreground", children: "VIN (optional)" }), 759 /* @__PURE__ */ jsxRuntimeExports.jsx( 760 Input, 761 { 762 placeholder: "1HGBH41JXMN109186", 763 value: tradeVin, 764 onChange: (e) => setTradeVin(e.target.value), 765 className: "h-7 text-xs font-mono" 766 } 767 ) 768 ] }), 769 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 770 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-[10px] text-muted-foreground", children: "Lienholder" }), 771 /* @__PURE__ */ jsxRuntimeExports.jsx( 772 Input, 773 { 774 placeholder: "Capital One Auto", 775 value: tradeLienholder, 776 onChange: (e) => setTradeLienholder(e.target.value), 777 className: "h-7 text-xs" 778 } 779 ) 780 ] }), 781 tradeEstimate && tradeEstimate.estimate && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-2 border-t border-purple-500/20 space-y-2", children: [
782 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 783 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "Estimated ACV" }), 784 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-lg font-bold font-mono text-purple-400", children: fmt(tradeEstimate.estimate) }) 785 ] }), 786 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 gap-2 text-center sm:grid-cols-3", children: [ 787 tradeEstimate.wholesaleAvg && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-1.5 bg-muted/30 rounded", children: [ 788 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[9px] text-muted-foreground", children: "Wholesale" }), 789 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-mono font-semibold", children: fmt(tradeEstimate.wholesaleAvg) }) 790 ] }), 791 tradeEstimate.retailAvg && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-1.5 bg-muted/30 rounded", children: [
792 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[9px] text-muted-foreground", children: "Retail" }), 793 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-mono font-semibold", children: fmt(tradeEstimate.retailAvg) }) 794 ] }), 795 tradeEstimate.salesAvg && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-1.5 bg-muted/30 rounded", children: [ 796 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[9px] text-muted-foreground", children: "Sold Avg" }), 797 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-mono font-semibold", children: fmt(tradeEstimate.salesAvg) }) 798 ] }) 799 ] }), 800 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 801 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] text-muted-foreground", children: [ 802 "Based on ", 803 tradeEstimate.compCount, 804 " comparable", 805 tradeEstimate.compCount !== 1 ? "s" : "", 806 " (", 807 tradeEstimate.method, 808 ")" 809 ] }),
810 /* @__PURE__ */ jsxRuntimeExports.jsx( 811 Button, 812 { 813 size: "sm", 814 variant: "outline", 815 className: "h-6 text-[10px] px-2 border-purple-500/30 text-purple-400 hover:bg-purple-500/10", 816 onClick: () => { 817 setTradeValue(tradeEstimate.estimate); 818 toast.success(`Trade value set to ${fmt(tradeEstimate.estimate)}`); 819 }, 820 children: "Use as ACV" 821 } 822 ) 823 ] }) 824 ] }), 825 tradeEstimate && !tradeEstimate.estimate && tradeMake && tradeModel && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground italic", children: [ 826 "No comparable data found for ", 827 tradeMake, 828 " ", 829 tradeModel 830 ] }) 831 ] }), 832 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
833 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Trade Value (ACV)" }), 834 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: tradeValue || "", onChange: (e) => setTradeValue(+e.target.value), className: "font-mono" }) 835 ] }), 836 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 837 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Trade Payoff" }), 838 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: tradePayoff || "", onChange: (e) => setTradePayoff(+e.target.value), className: "font-mono" }) 839 ] }), 840 tradeLienholder && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-muted-foreground px-2 py-1 bg-muted/30 rounded", children: [ 841 "Lienholder: ", 842 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: tradeLienholder }) 843 ] }), 844 tradeValue > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `text-sm font-medium px-2 py-1 rounded ${tradeValue - tradePayoff >= 0 ? "bg-emerald-500/10 text-emerald-400" : "bg-red-500/10 text-red-400"}`, children: [ 845 "Equity: ", 846 fmt(tradeValue - tradePayoff) 847 ] }),
848 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs font-medium text-muted-foreground", children: "CASH DOWN" }) }), 849 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 850 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Down Payment" }), 851 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: downPayment || "", onChange: (e) => setDownPayment(+e.target.value), className: "font-mono" }) 852 ] }), 853 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 854 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Rebates / Incentives" }), 855 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: rebates || "", onChange: (e) => setRebates(+e.target.value), className: "font-mono" }) 856 ] }) 857 ] }) }) 858 ] }), 859 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
860 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm font-medium flex items-center gap-2", children: [ 861 /* @__PURE__ */ jsxRuntimeExports.jsx(Calculator, { className: "h-4 w-4" }), 862 " Fees & F&I Products" 863 ] }) }), 864 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ 865 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 866 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Accessories / Add-ons" }), 867 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: accessories || "", onChange: (e) => setAccessories(+e.target.value), className: "font-mono" }) 868 ] }), 869 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 870 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Doc Fee" }),
871 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: docFee || "", onChange: (e) => setDocFee(+e.target.value), className: "font-mono" }) 872 ] }), 873 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs font-medium text-muted-foreground", children: "F&I PRODUCTS" }) }), 874 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 875 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Extended Warranty / VSC" }), 876 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: warranty || "", onChange: (e) => setWarranty(+e.target.value), className: "font-mono" }) 877 ] }), 878 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 879 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "GAP Insurance" }), 880 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: gap || "", onChange: (e) => setGap(+e.target.value), className: "font-mono" }) 881 ] }),
882 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 883 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Maintenance Plan" }), 884 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: maintenance || "", onChange: (e) => setMaintenance(+e.target.value), className: "font-mono" }) 885 ] }), 886 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 887 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Tire & Wheel" }), 888 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: tireWheel || "", onChange: (e) => setTireWheel(+e.target.value), className: "font-mono" }) 889 ] }), 890 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 891 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Paint Protection / Ceramic" }), 892 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: paintProtection || "", onChange: (e) => setPaintProtection(+e.target.value), className: "font-mono" }) 893 ] }),
894 calculations && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-500/10 text-blue-400 text-sm font-medium px-2 py-1 rounded", children: [ 895 "F&I Total: ", 896 fmt(calculations.fiProducts) 897 ] }) 898 ] }) }) 899 ] }), 900 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ 901 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-sm font-medium flex items-center gap-2", children: [ 902 /* @__PURE__ */ jsxRuntimeExports.jsx(Percent, { className: "h-4 w-4" }), 903 " ", 904 dealType === "loan" ? "Loan Terms" : "Lease Terms" 905 ] }) }), 906 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ 907 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 908 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Tax Rate (%)" }),
909 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", step: "0.1", value: taxRate, onChange: (e) => setTaxRate(+e.target.value), className: "font-mono" }) 910 ] }), 911 dealType === "loan" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 912 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 913 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Credit Tier" }), 914 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: creditTier, onValueChange: (v) => setCreditTier(v), children: [ 915 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Manual APR" }) }), 916 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 917 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "manual", children: "Manual APR" }), 918 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "tier1", children: "Tier 1 (720+)" }),
919 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "tier2", children: "Tier 2 (680-719)" }), 920 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "tier3", children: "Tier 3 (620-679)" }), 921 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "tier4", children: "Tier 4 (580-619)" }), 922 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "tier5", children: "Tier 5 (Below 580)" }) 923 ] }) 924 ] }), 925 lenderInfo && creditTier && creditTier !== "manual" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-emerald-400 mt-1 truncate", children: lenderInfo }) 926 ] }), 927 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 928 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "APR (%)" }), 929 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", step: "0.1", value: apr, onChange: (e) => { 930 setApr(+e.target.value); 931 setCreditTier("manual"); 932 }, className: "font-mono" }) 933 ] }),
934 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 935 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Term (months)" }), 936 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: String(term), onValueChange: (v) => setTerm(+v), children: [ 937 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }), 938 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 939 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "36", children: "36 months" }), 940 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "48", children: "48 months" }), 941 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "60", children: "60 months" }), 942 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "72", children: "72 months" }), 943 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "84", children: "84 months" }) 944 ] }) 945 ] }) 946 ] }) 947 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
948 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 949 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Term (months)" }), 950 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: String(term), onValueChange: (v) => setTerm(+v), children: [ 951 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }), 952 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 953 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "24", children: "24 months" }), 954 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "36", children: "36 months" }), 955 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "39", children: "39 months" }), 956 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "48", children: "48 months" }) 957 ] }) 958 ] }) 959 ] }),
960 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 961 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Residual Value (%)" }), 962 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", step: "1", value: residualPercent, onChange: (e) => setResidualPercent(+e.target.value), className: "font-mono" }) 963 ] }), 964 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 965 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Money Factor" }), 966 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", step: "0.00001", value: moneyFactor, onChange: (e) => setMoneyFactor(+e.target.value), className: "font-mono" }), 967 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: [ 968 "â ", 969 (moneyFactor * 2400).toFixed(2), 970 "% APR equivalent" 971 ] }) 972 ] }),
973 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 974 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Miles/Year" }), 975 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: String(mileageAllowance), onValueChange: (v) => setMileageAllowance(+v), children: [ 976 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }), 977 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 978 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "10000", children: "10,000 mi/yr" }), 979 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "12000", children: "12,000 mi/yr" }), 980 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "15000", children: "15,000 mi/yr" }) 981 ] }) 982 ] }) 983 ] }), 984 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
985 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Cap Cost Reduction" }), 986 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { type: "number", value: capCostReduction || "", onChange: (e) => setCapCostReduction(+e.target.value), className: "font-mono" }) 987 ] }) 988 ] }), 989 calculations && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-3 border-t space-y-2", children: [ 990 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Gross Breakdown" }), 991 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1 text-sm", children: [ 992 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 993 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: "Front Gross" }), 994 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `font-mono font-medium ${calculations.frontGross >= 0 ? "text-emerald-400" : "text-red-400"}`, children: fmt(calculations.frontGross) }) 995 ] }),
996 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 997 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: "Back Gross" }), 998 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-medium text-blue-400", children: fmt(calculations.backGross) }) 999 ] }), 1000 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between border-t pt-1", children: [ 1001 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Total Gross" }), 1002 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `font-mono font-bold ${calculations.totalGross >= 2e3 ? "text-emerald-400" : calculations.totalGross >= 0 ? "text-yellow-400" : "text-red-400"}`, children: fmt(calculations.totalGross) }) 1003 ] }) 1004 ] }) 1005 ] }) 1006 ] }) }) 1007 ] }) 1008 ] }), 1009 paymentGrid && calculations?.dealType === "loan" && /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
1010 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [ 1011 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2 text-lg", children: [ 1012 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "h-5 w-5 text-purple-400" }), 1013 " Payment Grid" 1014 ] }), 1015 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "w-fit text-xs", children: [ 1016 "Amount Financed: ", 1017 fmt(calculations.amountFinanced) 1018 ] }) 1019 ] }) }), 1020 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [ 1021 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full min-w-[620px] text-sm", children: [ 1022 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b", children: [
1023 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left py-2 px-3 text-muted-foreground text-xs", children: "TERM" }), 1024 paymentGrid[0]?.payments.map((p, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("th", { className: "text-center py-2 px-3 text-muted-foreground text-xs", children: [ 1025 p.rate.toFixed(1), 1026 "%" 1027 ] }, i)) 1028 ] }) }), 1029 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: paymentGrid.map((row) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-b border-border/50 hover:bg-muted/30", children: [ 1030 /* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "py-3 px-3 font-medium", children: [ 1031 row.term, 1032 " mo" 1033 ] }), 1034 row.payments.map((cell, ci) => /* @__PURE__ */ jsxRuntimeExports.jsx( 1035 "td", 1036 { 1037 className: `text-center py-3 px-3 font-mono cursor-pointer transition-colors ${cell.isSelected ? "bg-emerald-500/20 font-bold text-emerald-400 rounded" : "hover:bg-accent/50"}`, 1038 onClick: () => { 1039 setTerm(row.term); 1040 setApr(cell.rate); 1041 }, 1042 children: fmtDec(cell.payment) 1043 }, 1044 ci 1045 )) 1046 ] }, row.term)) }) 1047 ] }) }),
1048 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mt-3", children: "Click any cell to select that term and rate combination" }) 1049 ] }) 1050 ] }), 1051 calculations && /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ 1052 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center gap-2 text-lg", children: [ 1053 /* @__PURE__ */ jsxRuntimeExports.jsx(TrendingUp, { className: "h-5 w-5 text-amber-400" }), 1054 " Deal Breakdown" 1055 ] }) }), 1056 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [ 1057 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 text-sm", children: [ 1058 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1059 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Selling Price" }),
1060 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: fmt(sellingPrice) }) 1061 ] }), 1062 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1063 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "+ Accessories" }), 1064 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: fmt(accessories) }) 1065 ] }), 1066 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1067 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "+ Doc Fee" }), 1068 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: fmt(docFee) }) 1069 ] }), 1070 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1071 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "+ F&I Products" }), 1072 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: fmt(calculations.fiProducts) }) 1073 ] }),
1074 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1075 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "- Rebates" }), 1076 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-red-400", children: [ 1077 "-", 1078 fmt(rebates) 1079 ] }) 1080 ] }), 1081 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1082 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "- Trade Equity" }), 1083 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: `font-mono ${calculations.tradeEquity >= 0 ? "text-red-400" : "text-emerald-400"}`, children: [ 1084 calculations.tradeEquity >= 0 ? "-" : "+", 1085 fmt(Math.abs(calculations.tradeEquity)) 1086 ] }) 1087 ] }), 1088 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [ 1089 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "- Down Payment" }),
1090 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-red-400", children: [ 1091 "-", 1092 fmt(downPayment) 1093 ] }) 1094 ] }), 1095 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between border-t pt-2", children: [ 1096 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 1097 "+ Sales Tax (", 1098 taxRate, 1099 "%)" 1100 ] }), 1101 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: fmt(calculations.salesTax) }) 1102 ] }), 1103 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between font-bold border-t pt-2 text-base", children: [ 1104 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: calculations.dealType === "loan" ? "Amount Financed" : "Net Cap Cost" }), 1105 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: fmt(calculations.dealType === "loan" ? calculations.amountFinanced : calculations.netCapCost) }) 1106 ] }) 1107 ] }),
1108 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-muted/30 rounded-lg p-4 space-y-3", children: [ 1109 /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-medium text-sm flex items-center gap-2", children: [ 1110 /* @__PURE__ */ jsxRuntimeExports.jsx(Trophy, { className: "h-4 w-4 text-amber-400" }), 1111 " Gross Profit Analysis" 1112 ] }), 1113 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ 1114 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [ 1115 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "Selling Price" }), 1116 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-sm", children: fmt(sellingPrice) }) 1117 ] }), 1118 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [
1119 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "- Vehicle Cost" }), 1120 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-sm text-red-400", children: [ 1121 "-", 1122 fmt(vehicleCost) 1123 ] }) 1124 ] }), 1125 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [ 1126 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "+ Accessories + Doc" }), 1127 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-sm", children: fmt(accessories + docFee) }) 1128 ] }), 1129 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center font-medium border-t pt-2", children: [ 1130 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "= Front Gross" }), 1131 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `font-mono ${calculations.frontGross >= 0 ? "text-emerald-400" : "text-red-400"}`, children: fmt(calculations.frontGross) }) 1132 ] }) 1133 ] }),
1134 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-3 space-y-2", children: [ 1135 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [ 1136 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "F&I Products" }), 1137 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-sm", children: fmt(calculations.fiProducts) }) 1138 ] }), 1139 calculations.dealType === "loan" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [ 1140 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "+ Reserve (est.)" }), 1141 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-sm", children: fmt(calculations.reserveEstimate) }) 1142 ] }), 1143 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center font-medium border-t pt-2", children: [
1144 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "= Back Gross" }), 1145 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-400", children: fmt(calculations.backGross) }) 1146 ] }) 1147 ] }), 1148 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center text-lg font-bold", children: [ 1149 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "TOTAL GROSS" }), 1150 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `font-mono ${calculations.totalGross >= 2e3 ? "text-emerald-400" : calculations.totalGross >= 0 ? "text-yellow-400" : "text-red-400"}`, children: fmt(calculations.totalGross) }) 1151 ] }) }) 1152 ] }) }) 1153 ] }) }) 1154 ] }), 1155 selectedVehicle && calculations && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( 1156 Button, 1157 { 1158 size: "lg", 1159 className: "w-full bg-gradient-to-r from-purple-600 to-blue-600 text-white shadow-lg hover:from-purple-700 hover:to-blue-700 sm:w-auto", 1160 onClick: () => setShowAlternatives(true), 1161 children: [
1162 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-5 w-5 mr-2" }), 1163 "Find More Profitable Alternatives at ", 1164 fmtDec(calculations.monthlyPayment), 1165 "/mo", 1166 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "h-5 w-5 ml-2" }) 1167 ] 1168 } 1169 ) }), 1170 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showAlternatives, onOpenChange: setShowAlternatives, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-4xl max-h-[85vh]", children: [ 1171 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 1172 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [ 1173 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-5 w-5 text-purple-400" }), 1174 "Profit-Maximizing Alternatives" 1175 ] }), 1176 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-muted-foreground", children: [ 1177 "Vehicles with similar payments (", 1178 fmtDec((calculations?.monthlyPayment || 0) - paymentTolerance), 1179 " â ", 1180 fmtDec((calculations?.monthlyPayment || 0) + paymentTolerance), 1181 "/mo) but higher gross profit" 1182 ] }) 1183 ] }),
1184 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center", children: [ 1185 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs whitespace-nowrap", children: "Payment Tolerance:" }), 1186 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: String(paymentTolerance), onValueChange: (v) => setPaymentTolerance(+v), children: [ 1187 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-full sm:w-32", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }), 1188 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 1189 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "25", children: "± $25" }), 1190 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "50", children: "± $50" }), 1191 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "75", children: "± $75" }), 1192 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "100", children: "± $100" }),
1193 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "150", children: "± $150" }) 1194 ] }) 1195 ] }), 1196 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "text-xs", children: [ 1197 "Current Front Gross: ", 1198 calculations ? fmt(calculations.frontGross) : "$0" 1199 ] }) 1200 ] }), 1201 /* @__PURE__ */ jsxRuntimeExports.jsxs(ScrollArea, { className: "max-h-[55vh]", children: [ 1202 altLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [ 1203 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "h-6 w-6 animate-spin mx-auto mb-2" }), 1204 "Searching inventory for profitable alternatives..." 1205 ] }), 1206 alternatives && alternatives.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [ 1207 /* @__PURE__ */ jsxRuntimeExports.jsx(Target, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
1208 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "No alternatives found within the payment range." }), 1209 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs mt-1", children: "Try increasing the payment tolerance." }) 1210 ] }), 1211 alternatives && alternatives.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: alternatives.map((alt, idx) => { 1212 const grossDiff = alt.frontGross - (calculations?.frontGross || 0); 1213 const photos = alt.vehicle.photos; 1214 return /* @__PURE__ */ jsxRuntimeExports.jsxs( 1215 "div", 1216 { 1217 className: "flex flex-col gap-3 rounded-lg border border-border p-4 transition-all hover:border-emerald-500/50 hover:bg-accent/30 sm:flex-row sm:items-center sm:gap-4 cursor-pointer", 1218 onClick: () => { 1219 handleVehicleSelect(alt.vehicle); 1220 setShowAlternatives(false); 1221 toast.success(`Switched to ${alt.vehicle.year} ${alt.vehicle.make} ${alt.vehicle.model}`); 1222 }, 1223 children: [
1224 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold shrink-0 ${idx === 0 ? "bg-amber-500/20 text-amber-400" : idx === 1 ? "bg-gray-400/20 text-gray-300" : "bg-orange-500/20 text-orange-400"}`, children: idx + 1 }), 1225 photos && photos.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: photos[0], alt: "", className: "w-20 h-14 object-cover rounded shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-20 h-14 bg-muted rounded flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Car, { className: "h-5 w-5 text-muted-foreground" }) }), 1226 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 1227 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-medium text-sm truncate", children: [ 1228 alt.vehicle.year, 1229 " ", 1230 alt.vehicle.make, 1231 " ", 1232 alt.vehicle.model, 1233 " ", 1234 alt.vehicle.trim || "" 1235 ] }),
1236 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [ 1237 "Stock #", 1238 alt.vehicle.stockId, 1239 " · ", 1240 alt.vehicle.exteriorColor || "N/A", 1241 alt.vehicle.daysInStock ? ` · ${alt.vehicle.daysInStock} days` : "" 1242 ] }) 1243 ] }), 1244 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "shrink-0 text-left sm:text-center", children: [ 1245 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-mono font-semibold text-sm", children: [ 1246 fmtDec(alt.payment), 1247 "/mo" 1248 ] }), 1249 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: `text-xs font-mono ${alt.paymentDiff >= 0 ? "text-red-400" : "text-emerald-400"}`, children: [ 1250 alt.paymentDiff >= 0 ? "+" : "", 1251 fmtDec(alt.paymentDiff) 1252 ] }) 1253 ] }),
1254 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-right min-w-[100px] shrink-0", children: [ 1255 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-mono font-bold text-emerald-400", children: fmt(alt.frontGross) }), 1256 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-1", children: [ 1257 grossDiff > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUpRight, { className: "h-3 w-3 text-emerald-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowDownRight, { className: "h-3 w-3 text-red-400" }), 1258 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: `text-xs font-mono ${grossDiff > 0 ? "text-emerald-400" : "text-red-400"}`, children: [ 1259 grossDiff > 0 ? "+" : "", 1260 fmt(grossDiff) 1261 ] }) 1262 ] }) 1263 ] }) 1264 ] 1265 }, 1266 alt.vehicle.id 1267 ); 1268 }) }) 1269 ] }) 1270 ] }) }) 1271 ] }); 1272} 1273export { 1274 DeskingWorksheet as default 1275};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.