1import { c as createLucideIcon, a as useAgentAuth, r as reactExports, t as trpc, b as toast, j as jsxRuntimeExports, U as USFlag, B as Button, L as LoaderCircle, F as FileText, d as Badge, g as ChevronRight, N as RotateCcw, C as CircleAlert, ab as FileCheck, o as RefreshCw, X, n as Building2, $ as ClipboardList, E as Eye } from './index-CNT5CkK7.js'; 2import { I as Input } from './input-Dy4-W9m0.js'; 3import { L as Label } from './label-BdZn6Q6n.js'; 4import { T as Textarea } from './textarea-B3UNOK9R.js'; 5import { C as Card, b as CardHeader, c as CardTitle, a as CardContent } from './card-CV3CzesJ.js'; 6import { S as Select, a as SelectTrigger, b as SelectValue, c as SelectContent, d as SelectItem } from './select-3x7TRCw-.js'; 7import { D as Dialog, b as DialogContent, c as DialogHeader, d as DialogTitle, k as DialogDescription, e as DialogFooter } from './useComposition-DPCJbBnn.js'; 8import { A as AgentChat } from './AgentChat-DDAj7r8S.js'; 9import { A as AcordFieldEditor } from './AcordFieldEditor-DmOR2NZ0.js'; 10import { C as Copy } from './copy-BAoxz8Jl.js'; 11import { C as CircleCheckBig } from './circle-check-big-CmJOxlC9.js'; 12import { T as Trash2 } from './trash-2-DkCMhEWr.js'; 13import { A as ArrowLeft } from './arrow-left-BTjDVb-D.js'; 14import { S as Sparkles } from './sparkles-I54sm_K8.js'; 15import { U as Upload } from './upload-BrgTKlQs.js'; 16import { I as Info } from './info-D8W5gqg6.js'; 17import { S as Save } from './save-PDl6zfI9.js'; 18import { S as Search } from './search-BQjKKf9D.js'; 19import { P as Plus } from './plus-BP2QxMPQ.js'; 20import { P as PenLine } from './pen-line-Bn1tOSLX.js'; 21import { A as ArrowRight } from './arrow-right-CECJo1mW.js'; 22import { D as Download } from './download-BMCjKajM.js'; 23import './index-BEBgmBqK.js'; 24import './index-B88B3rZe.js'; 25import './chevron-down-DFKrqu4j.js'; 26import './check-BezXvNsL.js'; 27import './chevron-up-Do8Lk9oa.js'; 28import './user-B4RG8T6t.js'; 29import './circle-check-CqW-unub.js'; 30 31/** 32 * @license lucide-react v0.453.0 - ISC 33 * 34 * This source code is licensed under the ISC license. 35 * See the LICENSE file in the root directory of this source tree. 36 */ 37 38 39const Flag = createLucideIcon("Flag", [ 40 ["path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z", key: "i9b6wo" }], 41 ["line", { x1: "4", x2: "4", y1: "22", y2: "15", key: "1cm3nv" }] 42]); 43 44const LOBS = ["P&C", "Business", "Life", "Auto", "Home", "Commercial", "Workers Comp", "Other"]; 45function camelToLabel(key) { 46 const KNOWN_LABELS = { 47 namedInsured: "Named Insured", 48 mailingAddress: "Mailing Address", 49 mailingCity: "City", 50 mailingState: "State", 51 mailingZip: "ZIP Code", 52 policyNumber: "Policy Number", 53 effectiveDate: "Effective Date", 54 expirationDate: "Expiration Date", 55 dateOfBirth: "Date of Birth", 56 dob: "Date of Birth", 57 ssn: "SSN", 58 phone: "Phone", 59 email: "Email", 60 agencyName: "Agency Name", 61 agencyAddress: "Agency Address", 62 agencyCity: "Agency City", 63 agencyState: "Agency State", 64 agencyZip: "Agency ZIP", 65 agencyPhone: "Agency Phone", 66 agencyCode: "Agency Code", 67 producerName: "Producer Name", 68 carrierName: "Carrier Name", 69 lineOfBusiness: "Line of Business", 70 glEachOccurrenceLimit: "GL Each Occurrence Limit", 71 glGeneralAggregateLimit: "GL General Aggregate Limit", 72 glProductsCompletedOpsLimit: "GL Products/Completed Ops Limit", 73 glPersonalAdvInjuryLimit: "GL Personal & Adv Injury Limit", 74 glFireDamageLimitAnyOneFire: "GL Fire Damage Limit", 75 glMedExpLimit: "GL Med Exp Limit", 76 vehicleYear: "Vehicle Year", 77 vehicleMake: "Vehicle Make", 78 vehicleModel: "Vehicle Model", 79 vehicleVin: "Vehicle VIN", 80 vehicleGarageState: "Garage State", 81 bodilyInjuryLimit: "Bodily Injury Limit", 82 propertyDamageLimit: "Property Damage Limit",
83 combinedSingleLimit: "Combined Single Limit", 84 medicalPaymentsLimit: "Medical Payments Limit", 85 uninsuredMotoristLimit: "Uninsured Motorist Limit", 86 comprehensiveDeductible: "Comprehensive Deductible", 87 collisionDeductible: "Collision Deductible", 88 locationAddress: "Location Address", 89 locationCity: "Location City", 90 locationState: "Location State", 91 locationZip: "Location ZIP", 92 buildingLimit: "Building Limit", 93 contentsLimit: "Contents Limit", 94 businessIncomeLimit: "Business Income Limit", 95 naicsCode: "NAICS Code", 96 sicCode: "SIC Code", 97 fein: "FEIN", 98 yearsInBusiness: "Years in Business", 99 numberOfEmployees: "Number of Employees", 100 annualRevenue: "Annual Revenue", 101 annualPayroll: "Annual Payroll", 102 descriptionOfOperations: "Description of Operations", 103 certificateHolder: "Certificate Holder", 104 additionalInsured: "Additional Insured", 105 waiverOfSubrogation: "Waiver of Subrogation", 106 projectDescription: "Project Description", 107 contractDate: "Contract Date", 108 formNumber: "Form Number", 109 formTitle: "Form Title" 110 }; 111 if (KNOWN_LABELS[key]) return KNOWN_LABELS[key]; 112 return key.replace(/_/g, " ").replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim(); 113} 114const VISIBLE_STEP_LABELS = [ 115 "Upload Source Docs", 116 // server step 1 117 "Upload Blank Form", 118 // server step 2 119 "Review & Complete Data", 120 // server step 3 121 "Preview & Edit", 122 // server steps 4+5 (map runs silently) 123 "Download" 124 // server steps 6+7 125]; 126function serverStepToVisible(serverStep) { 127 if (serverStep <= 3) return serverStep; 128 if (serverStep <= 5) return 4; 129 return 5; 130} 131function StepIndicator({ currentStep }) { 132 const visibleStep = serverStepToVisible(currentStep); 133 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1 flex-wrap mb-6", children: VISIBLE_STEP_LABELS.map((label, i) => { 134 const step = i + 1; 135 const isDone = step < visibleStep; 136 const isActive = step === visibleStep; 137 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
138 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex items-center gap-1.5 px-2 py-1 rounded-full text-xs font-medium transition-all ${isDone ? "bg-green-100 text-green-700" : isActive ? "bg-[var(--eps-navy-deep)] text-white" : "bg-gray-100 text-gray-400"}`, children: [ 139 isDone ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 12 }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-4 text-center", children: step }), 140 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "hidden sm:inline", children: label }) 141 ] }), 142 i < VISIBLE_STEP_LABELS.length - 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 12, className: "text-gray-300 flex-shrink-0" }) 143 ] }, step); 144 }) }); 145} 146const EXTRACTION_STEPS = [ 147 { label: "Uploading documents to secure storageâ¦", pct: 15 }, 148 { label: "Analyzing document structureâ¦", pct: 40 }, 149 { label: "Extracting insurance data fieldsâ¦", pct: 70 }, 150 { label: "Saving extracted dataâ¦", pct: 95 } 151]; 152const LOBS_EXPANDED = [ 153 "BOP (Business Owner's Policy)", 154 "Commercial General Liability", 155 "Commercial Property", 156 "Commercial Auto", 157 "Workers Compensation", 158 "Professional Liability / E&O", 159 "Umbrella / Excess", 160 "Certificate of Liability (ACORD 25)", 161 "Personal Auto", 162 "Homeowners", 163 "Life", 164 "P&C", 165 "Other" 166]; 167function Step1Upload({ onCreated }) { 168 const [clientName, setClientName] = reactExports.useState(""); 169 const [lob, setLob] = reactExports.useState("P&C"); 170 const [notes, setNotes] = reactExports.useState(""); 171 const [files, setFiles] = reactExports.useState([]); 172 const [loading, setLoading] = reactExports.useState(false); 173 const [progressStep, setProgressStep] = reactExports.useState(-1); 174 const [extractionError, setExtractionError] = reactExports.useState(null); 175 const [isPriorAcord, setIsPriorAcord] = reactExports.useState(false); 176 const [intakeDocTypes, setIntakeDocTypes] = reactExports.useState([]); 177 const [intakeIsRenewal, setIntakeIsRenewal] = reactExports.useState(false); 178 const [intakeStandardAnswers, setIntakeStandardAnswers] = reactExports.useState(true); 179 const progressTimerRef = reactExports.useRef(null); 180 const fileInputRef = reactExports.useRef(null); 181 const [isDraggingOver, setIsDraggingOver] = reactExports.useState(false); 182 const INTAKE_DOC_OPTIONS = [ 183 "Declaration page", 184 "Prior completed ACORD form", 185 "Prior application", 186 "Loss runs", 187 "Quote proposal / binder", 188 "Other" 189 ]; 190 const toggleDocType = (type) => { 191 setIntakeDocTypes( 192 (prev) => prev.includes(type) ? prev.filter((t) => t !== type) : [...prev, type] 193 ); 194 }; 195 const startProgress = () => { 196 setProgressStep(0); 197 let step = 0; 198 progressTimerRef.current = setInterval(() => { 199 step = Math.min(step + 1, EXTRACTION_STEPS.length - 1); 200 setProgressStep(step); 201 if (step >= EXTRACTION_STEPS.length - 1 && progressTimerRef.current) { 202 clearInterval(progressTimerRef.current); 203 } 204 }, 4e3); 205 }; 206 const stopProgress = () => { 207 if (progressTimerRef.current) clearInterval(progressTimerRef.current); 208 progressTimerRef.current = null; 209 }; 210 const createMutation = trpc.acordWorkflows.createAndUploadSources.useMutation({ 211 onSuccess: (data) => { 212 stopProgress(); 213 setProgressStep(EXTRACTION_STEPS.length); 214 setTimeout(() => { 215 toast.success("Source documents uploaded and data extracted!"); 216 onCreated(data.id); 217 }, 500); 218 }, 219 onError: (err) => { 220 stopProgress(); 221 setLoading(false); 222 setProgressStep(-1); 223 const msg = err.message || "Extraction failed. Please try again."; 224 setExtractionError(msg); 225 } 226 }); 227 const processDroppedFiles = reactExports.useCallback((fileList) => { 228 if (!fileList) return; 229 const accepted = Array.from(fileList).filter((f) => { 230 const ext = f.name.toLowerCase(); 231 return ext.endsWith(".pdf") || ext.endsWith(".doc") || ext.endsWith(".docx") || ext.endsWith(".png") || ext.endsWith(".jpg") || ext.endsWith(".jpeg"); 232 }); 233 if (accepted.length === 0) { 234 toast.error("Only PDF, Word, and image files are accepted"); 235 return; 236 } 237 accepted.forEach((file) => { 238 const reader = new FileReader(); 239 reader.onload = (ev) => { 240 const base64 = (ev.target?.result).split(",")[1]; 241 setFiles((prev) => [...prev, { name: file.name, base64, mimeType: file.type || "application/pdf", size: file.size }]); 242 };
243 reader.readAsDataURL(file); 244 }); 245 }, []); 246 const handleFileChange = reactExports.useCallback((e) => { 247 processDroppedFiles(e.target.files); 248 e.target.value = ""; 249 }, [processDroppedFiles]); 250 const handleDragOver = reactExports.useCallback((e) => { 251 e.preventDefault(); 252 e.stopPropagation(); 253 setIsDraggingOver(true); 254 }, []); 255 const handleDragLeave = reactExports.useCallback((e) => { 256 e.preventDefault(); 257 e.stopPropagation(); 258 setIsDraggingOver(false); 259 }, []); 260 const handleDrop = reactExports.useCallback((e) => { 261 e.preventDefault(); 262 e.stopPropagation(); 263 setIsDraggingOver(false); 264 processDroppedFiles(e.dataTransfer.files); 265 }, [processDroppedFiles]); 266 const removeFile = (idx) => setFiles((prev) => prev.filter((_, i) => i !== idx)); 267 const handleSubmit = async () => { 268 if (!clientName.trim()) { 269 toast.error("Client name is required"); 270 return; 271 } 272 if (files.length === 0) { 273 toast.error("Please upload at least one source document"); 274 return; 275 } 276 setExtractionError(null); 277 setLoading(true); 278 startProgress(); 279 const priorNote = isPriorAcord ? `[PRIOR ACORD IMPORT] SOURCE IS A COMPLETED ACORD FORM FROM A PRIOR YEAR. Extract all fields as if reading a filled insurance application â treat every pre-filled field as data to extract.${notes ? " Producer notes: " + notes : ""}` : notes; 280 createMutation.mutate({ 281 clientName: clientName.trim(), 282 lineOfBusiness: lob, 283 producerNotes: priorNote, 284 intakeDocTypes: intakeDocTypes.length > 0 ? intakeDocTypes : void 0, 285 intakeIsRenewal, 286 intakeStandardAnswersAsUsual: intakeStandardAnswers, 287 files 288 }); 289 }; 290 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3", children: [ 291 extractionError && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border border-red-200 bg-red-50 p-3 flex gap-2", children: [
292 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 16, className: "text-red-500 flex-shrink-0 mt-0.5" }), 293 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ 294 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-red-700", children: "Extraction Failed" }), 295 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-600 mt-0.5", children: extractionError }), 296 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-500 mt-1", children: "You can try again, or proceed to Step 2 and add fields manually." }) 297 ] }), 298 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setExtractionError(null), className: "text-red-400 hover:text-red-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 14 }) }) 299 ] }), 300 loading && progressStep >= 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border border-blue-200 bg-blue-50 p-3", children: [
301 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [ 302 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin text-blue-600" }), 303 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-semibold text-blue-800", children: progressStep < EXTRACTION_STEPS.length ? EXTRACTION_STEPS[progressStep].label : "Complete!" }) 304 ] }), 305 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full bg-blue-100 rounded-full h-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx( 306 "div", 307 { 308 className: "bg-blue-600 h-1.5 rounded-full transition-all duration-700", 309 style: { width: `${progressStep < EXTRACTION_STEPS.length ? EXTRACTION_STEPS[progressStep].pct : 100}%` } 310 } 311 ) }), 312 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-between mt-1", children: EXTRACTION_STEPS.map((s, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `text-xs ${i <= progressStep ? "text-blue-600 font-medium" : "text-blue-300"}`, children: i + 1 }, i)) }) 313 ] }), 314 /* @__PURE__ */ jsxRuntimeExports.jsx( 315 "button", 316 { 317 onClick: handleSubmit, 318 disabled: loading || files.length === 0 || !clientName.trim(), 319 className: "w-full py-2.5 px-4 rounded-md text-sm font-semibold flex items-center justify-center gap-2 transition-colors", 320 style: { 321 background: loading || files.length === 0 || !clientName.trim() ? "#64748b" : "#0f2d5e", 322 color: "white", 323 cursor: loading || files.length === 0 || !clientName.trim() ? "not-allowed" : "pointer", 324 opacity: 1, 325 border: "none" 326 }, 327 onMouseEnter: (e) => { 328 if (!(loading || files.length === 0 || !clientName.trim())) e.currentTarget.style.background = "#0a1f42"; 329 }, 330 onMouseLeave: (e) => { 331 if (!(loading || files.length === 0 || !clientName.trim())) e.currentTarget.style.background = "#0f2d5e"; 332 },
333 children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 334 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 16, className: "animate-spin mr-2" }), 335 "Analyzing Documentsâ¦" 336 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 337 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 16, className: "mr-2" }), 338 "Upload & Extract Data" 339 ] }) 340 } 341 ), 342 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-lg border border-slate-200 bg-slate-50 p-3 space-y-3", children: [ 343 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-semibold text-slate-700 flex items-center gap-1.5", children: [ 344 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-[#0f2d5e] text-white text-[9px] font-bold", children: "0" }), 345 "Quick Intake â helps the AI extract more accurately" 346 ] }),
347 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [ 348 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-slate-600", children: [ 349 "What documents are you uploading? ", 350 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-slate-400", children: "(select all that apply)" }) 351 ] }), 352 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1.5", children: INTAKE_DOC_OPTIONS.map((opt) => /* @__PURE__ */ jsxRuntimeExports.jsx( 353 "button", 354 { 355 type: "button", 356 onClick: () => toggleDocType(opt), 357 className: `px-2 py-0.5 rounded text-xs border transition-colors ${intakeDocTypes.includes(opt) ? "bg-[#0f2d5e] text-white border-[#0f2d5e]" : "bg-white text-slate-600 border-slate-300 hover:border-[#0f2d5e]"}`, 358 children: opt 359 }, 360 opt 361 )) }) 362 ] }), 363 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-4", children: [
364 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer", children: [ 365 /* @__PURE__ */ jsxRuntimeExports.jsx( 366 "input", 367 { 368 type: "checkbox", 369 checked: intakeIsRenewal, 370 onChange: (e) => setIntakeIsRenewal(e.target.checked), 371 className: "w-3.5 h-3.5 accent-[#0f2d5e]" 372 } 373 ), 374 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-slate-700", children: "This is a renewal" }) 375 ] }), 376 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer", children: [ 377 /* @__PURE__ */ jsxRuntimeExports.jsx( 378 "input", 379 { 380 type: "checkbox", 381 checked: intakeStandardAnswers, 382 onChange: (e) => setIntakeStandardAnswers(e.target.checked), 383 className: "w-3.5 h-3.5 accent-[#0f2d5e]" 384 } 385 ), 386 /* @__P
386URE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-slate-700", children: [ 387 "Standard yes/no answers as usual ", 388 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-slate-400", children: "(No for everything, Yes for safety plan)" }) 389 ] }) 390 ] }) 391 ] }) 392 ] }), 393 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: [ 394 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 395 /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { htmlFor: "clientName", className: "text-xs", children: [ 396 "Client Name ", 397 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" }) 398 ] }), 399 /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { id: "clientName", placeholder: "e.g. ABC Manufacturing LLC", value: clientName, onChange: (e) => setClientName(e.target.value), className: "h-8 text-sm" }) 400 ] }), 401 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
402 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-xs", children: "Line of Business" }), 403 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: lob, onValueChange: setLob, children: [ 404 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "h-8 text-sm", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, {}) }), 405 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: LOBS_EXPANDED.map((l) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: l, children: l }, l)) }) 406 ] }) 407 ] }) 408 ] }), 409 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ 410 /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { className: "text-xs", children: [ 411 "Producer Notes ", 412 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground text-xs", children: "(optional)" }) 413 ] }), 414 /* @__PURE__ */ jsxRuntimeExports.jsx( 415 Textarea, 416 { 417 placeholder: "Coverage changes, special requirements, etc.", 418 value: notes, 419 onChange: (e) => setNotes(e.target.value), 420 rows: 2, 421 className: "text-sm resize-none" 422 } 423 ) 424 ] }), 425 /* @__PURE__ */ jsxRuntimeExports.jsxs( 426 "button", 427 { 428 type: "button", 429 onClick: () => setIsPriorAcord((v) => !v), 430 className: `w-full flex items-center gap-2 rounded-lg border px-3 py-2.5 text-left transition-colors ${isPriorAcord ? "border-amber-400 bg-amber-50 text-amber-900" : "border-gray-200 bg-gray-50 text-gray-600 hover:border-gray-300"}`, 431 children: [
432 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `w-4 h-4 rounded flex-shrink-0 border-2 flex items-center justify-center transition-colors ${isPriorAcord ? "border-amber-500 bg-amber-500" : "border-gray-300 bg-white"}`, children: isPriorAcord && /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 10, className: "text-white" }) }), 433 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 434 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold", children: "ð Start from Prior ACORD (Renewal Import)" }), 435 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs opacity-70 mt-0.5", children: isPriorAcord ? "Upload a completed ACORD form from a prior year â AI will extract all filled fields automatically." : "Check this if you're uploading a completed ACORD form from a prior year to pre-populate the new workflow." }) 436 ] }) 437 ] 438 } 439 ), 440 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
441 /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { className: "text-xs", children: [ 442 isPriorAcord ? "Prior ACORD Form" : "Source Documents", 443 " ", 444 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" }) 445 ] }), 446 /* @__PURE__ */ jsxRuntimeExports.jsxs( 447 "div", 448 { 449 className: `border-2 border-dashed rounded-lg p-4 text-center cursor-pointer transition-all ${isDraggingOver ? "border-[#0f2d5e] bg-blue-50 scale-[1.01]" : isPriorAcord ? "border-amber-300 hover:border-amber-400 bg-amber-50" : "border-gray-300 hover:border-[var(--eps-navy-mid)]"}`, 450 onClick: () => fileInputRef.current?.click(), 451 onDragOver: handleDragOver, 452 onDragEnter: handleDragOver, 453 onDragLeave: handleDragLeave, 454 onDrop: handleDrop, 455 children: [ 456 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 20, className: `mx-auto mb-1 ${isDraggingOver ? "text-[#0f2d5e]" : isPriorAcord ? "text-amber-400" : "text-gray-400"}` }),
457 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-600", children: isDraggingOver ? "Drop files here" : isPriorAcord ? "Upload completed prior ACORD form" : "Drag & drop files here, or click to browse" }), 458 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400", children: isPriorAcord ? "PDF only â the completed form from last year" : "PDF, Word, images â up to 10 files" }), 459 /* @__PURE__ */ jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", multiple: true, accept: ".pdf,.doc,.docx,.png,.jpg,.jpeg", className: "hidden", onChange: handleFileChange }) 460 ] 461 } 462 ), 463 files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1.5", children: files.map((f, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 bg-gray-50 rounded-lg px-3 py-2", children: [ 464 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 14, className: "text-gray-500 flex-shrink-0" }),
465 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm flex-1 truncate", children: f.name }), 466 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-400", children: [ 467 (f.size / 1024).toFixed(0), 468 " KB" 469 ] }), 470 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => removeFile(i), className: "text-gray-400 hover:text-red-500", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 14 }) }) 471 ] }, i)) }) 472 ] }) 473 ] }); 474} 475function MissingFieldQA({ workflowId, onFieldAnswered, onBulkFieldsAnswered }) { 476 const [answeredFields, setAnsweredFields] = reactExports.useState([]); 477 const [savedAnswerLog, setSavedAnswerLog] = reactExports.useState([]); 478 const [currentAnswer, setCurrentAnswer] = reactExports.useState(""); 479 const [dismissed, setDismissed] = reactExports.useState(false); 480 const [showUpload, setShowUpload] = reactExports.useState(false); 481 const [showAnswerLog, setShowAnswerLog] = reactExports.useState(false); 482 const [lastSavedFlash, setLastSavedFlash] = reactExports.useState(null); 483 const flashTimerRef = reactExports.useRef(null); 484 const [pendingReview, setPendingReview] = reactExports.useState(null); 485 const [reviewIndex, setReviewIndex] = reactExports.useState(0); 486 const [editedReviewValue, setEditedReviewValue] = reactExports.useState(""); 487 const [uploadSummary, setUploadSummary] = reactExports.useState(null); 488 const [uploadFileCount, setUploadFileCount] = reactExports.useState(0); 489 const inputRef = reactExports.useRef(null); 490 const suppFileInputRef = reactExports.useRef(null); 491 const currentQuestionRef = reactExports.useRef(""); 492 const questionQuery = trpc.acordWorkflows.getMissingFieldQuestion.useQuery( 493 { id: workflowId, answeredFields }, 494 { enabled: !dismissed && pendingReview === null } 495 ); 496 reactExports.useEffect(() => { 497 if (questionQuery.data && !questionQuery.data.done && questionQuery.data.question) { 498 currentQuestionRef.current = questionQuery.data.question; 499 } 500 }, [questionQuery.data]); 501 const answerMutation = trpc.acordWorkflows.answerMissingField.useMutation({ 502 onSuccess: (data) => { 503 const isSkip = data.value === null; 504 setSavedAnswerLog((prev) => [...prev, { 505 key: data.fieldKey, 506 question: currentQuestionRef.current, 507 value: data.value, 508 skipped: isSkip 509 }]); 510 if (!isSkip) { 511 if (flashTimerRef.current) clearTimeout(flashTimerRef.current); 512 setLastSavedFlash({ question: currentQuestionRef.current, value: data.value }); 513 flashTimerRef.current = setTimeout(() => setLastSavedFlash(null), 2500); 514 } 515 onFieldAnswered(data.fieldKey, data.value ?? null); 516 setAnsweredFields((prev) => [...prev, data.fieldKey]); 517 setCurrentAnswer(""); 518 setTimeout(() => inputRef.current?.focus(), 100); 519 }, 520 onError: (err) => toast.error("Failed to save answer: " + err.message) 521 }); 522 const uploadMutation = trpc.acordWorkflows.uploadSupplementalDocs.useMutation({ 523 onSuccess: (data) => { 524 setShowUpload(false); 525 if (data.mergedCount > 0 && data.filledFields && data.filledFields.length > 0) { 526 setPendingReview(data.filledFields); 527 setReviewIndex(0); 528 setEditedReviewValue(data.filledFields[0]?.value ?? ""); 529 setUploadSummary({ 530 filledFields: data.filledFields, 531 stillMissingFields: data.stillMissingFields ?? [], 532 message: data.message 533 }); 534 } else { 535 setUploadSummary({ 536 filledFields: [], 537 stillMissingFields: data.stillMissingFields ?? [], 538 message: data.message 539 }); 540 toast.info(data.message); 541 questionQuery.refetch(); 542 } 543 }, 544 onError: (err) => toast.error("Upload failed: " + err.message) 545 }); 546 const handleSuppFileChange = reactExports.useCallback((e) => { 547 const selected = Array.from(e.target.files ?? []); 548 if (selected.length === 0) return; 549 setUploadFileCount(selected.length); 550 const filePromises = selected.map((file) => new Promise((resolve) => { 551 const reader = new FileReader(); 552 reader.onload = (ev) => { 553 const base64 = (ev.target?.result).split(",")[1]; 554 resolve({ name: file.name, base64, mimeType: file.type || "application/pdf" }); 555 };
556 reader.readAsDataURL(file); 557 })); 558 Promise.all(filePromises).then((files) => { 559 uploadMutation.mutate({ id: workflowId, files, answeredFields }); 560 }); 561 e.target.value = ""; 562 }, [workflowId, answeredFields, uploadMutation]); 563 const handleReviewAccept = reactExports.useCallback(() => { 564 if (!pendingReview) return; 565 const field = pendingReview[reviewIndex]; 566 if (!field) return; 567 answerMutation.mutate({ id: workflowId, fieldKey: field.key, answer: editedReviewValue || field.value }); 568 const nextIndex = reviewIndex + 1; 569 if (nextIndex >= pendingReview.length) { 570 const acceptedFields = {}; 571 pendingReview.forEach((f) => { 572 acceptedFields[f.key] = f.value; 573 }); 574 if (onBulkFieldsAnswered) onBulkFieldsAnswered(acceptedFields); 575 setAnsweredFields((prev) => Array.from(/* @__PURE__ */ new Set([...prev, ...pendingReview.map((f) => f.key)]))); 576 setPendingReview(null); 577 questionQuery.refetch(); 578 toast.success(`Accepted ${pendingReview.length} auto-filled field${pendingReview.length !== 1 ? "s" : ""}.`); 579 } else { 580 setReviewIndex(nextIndex); 581 setEditedReviewValue(pendingReview[nextIndex]?.value ?? ""); 582 } 583 }, [pendingReview, reviewIndex, editedReviewValue, workflowId, answerMutation, onBulkFieldsAnswered, questionQuery]); 584 const handleReviewReject = reactExports.useCallback(() => { 585 if (!pendingReview) return; 586 const field = pendingReview[reviewIndex]; 587 if (!field) return; 588 const nextIndex = reviewIndex + 1; 589 if (nextIndex >= pendingReview.length) { 590 setPendingReview(null); 591 questionQuery.refetch(); 592 } else { 593 setReviewIndex(nextIndex); 594 setEditedReviewValue(pendingReview[nextIndex]?.value ?? ""); 595 } 596 }, [pendingReview, reviewIndex, questionQuery]); 597 const handleSubmit = () => { 598 const q2 = questionQuery.data; 599 if (!q2 || q2.done || !q2.fieldKey) return; 600 answerMutation.mutate({ id: workflowId, fieldKey: q2.fieldKey, answer: currentAnswer }); 601 }; 602 const handleSkip = () => { 603 const q2 = questionQuery.data; 604 if (!q2 || q2.done || !q2.fieldKey) return; 605 answerMutation.mutate({ id: workflowId, fieldKey: q2.fieldKey, answer: "skip" }); 606 }; 607 if (dismissed) return null; 608 if (questionQuery.isLoading && !pendingReview) return null; 609 const q = questionQuery.data; 610 if (pendingReview !== null) { 611 const field = pendingReview[reviewIndex]; 612 const reviewProgress = reviewIndex + 1; 613 const reviewTotal = pendingReview.length; 614 const pctReview = Math.round(reviewIndex / reviewTotal * 100); 615 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 border border-amber-300 rounded-lg p-3 mb-3 space-y-2", children: [
616 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [ 617 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 618 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 13, className: "text-amber-600 flex-shrink-0" }), 619 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-amber-800", children: "Review Auto-Filled Fields" }), 620 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-amber-500", children: [ 621 "â ", 622 reviewProgress, 623 " of ", 624 reviewTotal 625 ] }) 626 ] }), 627 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => { 628 setPendingReview(null); 629 questionQuery.refetch(); 630 }, className: "text-amber-300 hover:text-amber-600", title: "Skip review", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 631 ] }),
632 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1 bg-amber-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full bg-amber-500 rounded-full transition-all", style: { width: `${pctReview}%` } }) }), 633 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-amber-700", children: [ 634 "The AI found ", 635 /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [ 636 reviewTotal, 637 " field", 638 reviewTotal !== 1 ? "s" : "" 639 ] }), 640 " in the uploaded document", 641 uploadFileCount !== 1 ? "s" : "", 642 ". Review each value before it's saved to the form." 643 ] }), 644 field && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white border border-amber-200 rounded-lg p-3 space-y-2", children: [ 645 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 646 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-gray-700", children: field.label }),
647 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs bg-amber-100 text-amber-700 px-1.5 py-0.5 rounded-full font-medium", children: "From document" }) 648 ] }), 649 /* @__PURE__ */ jsxRuntimeExports.jsx( 650 "input", 651 { 652 type: "text", 653 value: editedReviewValue, 654 onChange: (e) => setEditedReviewValue(e.target.value), 655 onKeyDown: (e) => { 656 if (e.key === "Enter") handleReviewAccept(); 657 }, 658 className: "w-full text-sm px-2.5 py-1.5 rounded border border-amber-300 bg-white focus:border-amber-500 focus:outline-none focus:ring-1 focus:ring-amber-200", 659 autoFocus: true 660 } 661 ), 662 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400", children: "Edit the value if needed, then Accept or Reject." }), 663 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 664 /* @__PURE__ */ jsxRuntimeExports.jsxs( 665 Button, 666 { 667 size: "sm", 668 onClick: handleReviewAccept, 669 disabled: answerMutation.isPending, 670 className: "flex-1 gap-1 bg-green-600 hover:bg-green-700 text-white", 671 children: [
672 answerMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 12 }), 673 "Accept" 674 ] 675 } 676 ), 677 /* @__PURE__ */ jsxRuntimeExports.jsxs( 678 Button, 679 { 680 size: "sm", 681 variant: "outline", 682 onClick: handleReviewReject, 683 disabled: answerMutation.isPending, 684 className: "flex-1 gap-1 text-red-500 border-red-200 hover:bg-red-50", 685 children: [ 686 /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 12 }), 687 "Reject" 688 ] 689 } 690 ) 691 ] }) 692 ] }) 693 ] }); 694 } 695 if (uploadSummary && !pendingReview) { 696 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 mb-3 space-y-2", children: [ 697 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
698 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 699 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 13, className: "text-blue-600 flex-shrink-0" }), 700 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-blue-800", children: "Upload Results" }) 701 ] }), 702 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setUploadSummary(null), className: "text-blue-300 hover:text-blue-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 703 ] }), 704 uploadSummary.filledFields.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 705 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-semibold text-green-700 mb-1", children: [ 706 "â Fields filled (", 707 uploadSummary.filledFields.length, 708 "):" 709 ] }), 710 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: uploadSummary.filledFields.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs bg-green-100 text-green-700 px-1.5 py-0.5 rounded-full", children: f.label }, f.key)) }) 711 ] }), 712 uploadSummary.stillMissingFields.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
713 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-semibold text-amber-700 mb-1", children: [ 714 "Still missing (", 715 uploadSummary.stillMissingFields.length, 716 "):" 717 ] }), 718 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-1", children: [ 719 uploadSummary.stillMissingFields.slice(0, 8).map((f) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs bg-amber-100 text-amber-700 px-1.5 py-0.5 rounded-full", children: f.label }, f.key)), 720 uploadSummary.stillMissingFields.length > 8 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-amber-500", children: [ 721 "+", 722 uploadSummary.stillMissingFields.length - 8, 723 " more" 724 ] }) 725 ] }) 726 ] }), 727 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", onClick: () => setUploadSummary(null), className: "w-full gap-1 bg-blue-600 hover:bg-blue-700 text-white", children: [
728 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 12 }), 729 "Continue Q&A for remaining fields" 730 ] }) 731 ] }); 732 } 733 if (!q || q.done) { 734 if (answeredFields.length > 0) { 735 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 bg-green-50 border border-green-200 rounded-lg px-3 py-2 mb-3", children: [ 736 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 14, className: "text-green-600 flex-shrink-0" }), 737 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-green-700 font-medium flex-1", children: [ 738 "All gaps filled! ", 739 answeredFields.length, 740 " field", 741 answeredFields.length !== 1 ? "s" : "", 742 " added to the form data." 743 ] }), 744 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setDismissed(true), className: "text-green-400 hover:text-green-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 745 ] }); 746 } 747 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 bg-green-50 border border-green-200 rounded-lg px-3 py-2 mb-3", children: [
748 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 14, className: "text-green-600 flex-shrink-0" }), 749 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-700 font-medium flex-1", children: "No gaps found â all priority fields were extracted from your documents. Ready to proceed!" }), 750 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setDismissed(true), className: "text-green-400 hover:text-green-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 751 ] }); 752 } 753 const progress = q.answeredCount ?? 0; 754 const total = q.totalPriority ?? 1; 755 const pct = total > 0 ? Math.round(progress / total * 100) : 100; 756 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 mb-3 space-y-2", children: [ 757 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [ 758 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
759 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 13, className: "text-blue-600 flex-shrink-0" }), 760 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-blue-800", children: "Missing Field Assistant" }), 761 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-blue-500", children: [ 762 "â ", 763 progress, 764 " of ", 765 total, 766 " gap", 767 total !== 1 ? "s" : "", 768 " filled" 769 ] }) 770 ] }), 771 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setDismissed(true), className: "text-blue-300 hover:text-blue-600 flex-shrink-0", title: "Dismiss Q&A", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 772 ] }), 773 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-1 bg-blue-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full bg-blue-500 rounded-full transition-all", style: { width: `${pct}%` } }) }), 774 savedAnswerLog.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-green-200 rounded-lg overflow-hidden", children: [
775 /* @__PURE__ */ jsxRuntimeExports.jsxs( 776 "button", 777 { 778 onClick: () => setShowAnswerLog((v) => !v), 779 className: "w-full flex items-center justify-between px-3 py-2 bg-green-50 hover:bg-green-100 transition-colors text-left", 780 children: [ 781 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5 text-xs font-semibold text-green-800", children: [ 782 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 12, className: "text-green-600" }), 783 savedAnswerLog.filter((a) => !a.skipped).length, 784 " answer", 785 savedAnswerLog.filter((a) => !a.skipped).length !== 1 ? "s" : "", 786 " saved", 787 savedAnswerLog.filter((a) => a.skipped).length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-green-500 font-normal", children: [ 788 "(", 789 savedAnswerLog.filter((a) => a.skipped).length, 790 " skipped)" 791 ] }) 792 ] }),
793 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-green-500", children: showAnswerLog ? "Hide" : "Show" }) 794 ] 795 } 796 ), 797 showAnswerLog && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-y divide-green-100 bg-white max-h-48 overflow-y-auto", children: savedAnswerLog.map((entry, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 px-3 py-2", children: [ 798 entry.skipped ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mt-0.5 flex-shrink-0 w-4 h-4 rounded-full bg-gray-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 9, className: "text-gray-400" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mt-0.5 flex-shrink-0 w-4 h-4 rounded-full bg-green-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 9, className: "text-green-600" }) }), 799 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
800 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 leading-snug truncate", children: entry.question }), 801 entry.skipped ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 italic", children: "Skipped" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-green-800 truncate", children: entry.value }) 802 ] }) 803 ] }, i)) }) 804 ] }), 805 showUpload ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white border border-blue-200 rounded-lg p-3 space-y-2", children: [ 806 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 807 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-semibold text-blue-800 flex items-center gap-1.5", children: [ 808 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 12 }), 809 "Upload Additional Documents" 810 ] }), 811 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowUpload(false), className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 812 ] }),
813 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500", children: [ 814 "Upload a W-9, prior application, property schedule, or any document that may contain the missing fields. The AI will extract answers for the remaining ", 815 total - progress, 816 " unanswered fields and ask you to review each one." 817 ] }), 818 uploadMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-2", children: [ 819 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin text-blue-600" }), 820 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-blue-700", children: [ 821 "Analyzing ", 822 uploadFileCount, 823 " document", 824 uploadFileCount !== 1 ? "s" : "", 825 " and extracting missing fieldsâ¦" 826 ] }) 827 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 828 /* @__PURE__ */ jsxRuntimeExports.jsx( 829 "input", 830 { 831 ref: suppFileInputRef, 832 type: "file", 833 multiple: true, 834 accept: ".pdf,.doc,.docx,.png,.jpg,.jpeg,.txt", 835 onChange: handleSuppFileChange, 836 className: "hidden" 837 } 838 ),
839 /* @__PURE__ */ jsxRuntimeExports.jsxs( 840 Button, 841 { 842 size: "sm", 843 onClick: () => suppFileInputRef.current?.click(), 844 className: "w-full gap-1.5 bg-blue-600 hover:bg-blue-700 text-white", 845 children: [ 846 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 13 }), 847 "Choose File(s) to Upload" 848 ] 849 } 850 ), 851 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 text-center", children: "PDF, Word, images accepted · Multiple files OK · Up to 16 MB each" }) 852 ] }) 853 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 854 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 855 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-blue-900", children: q.question }), 856 q.hint && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-600 mt-0.5", children: q.hint }) 857 ] }),
858 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 859 /* @__PURE__ */ jsxRuntimeExports.jsx( 860 "input", 861 { 862 ref: inputRef, 863 type: "text", 864 value: currentAnswer, 865 onChange: (e) => setCurrentAnswer(e.target.value), 866 onKeyDown: (e) => { 867 if (e.key === "Enter") handleSubmit(); 868 }, 869 placeholder: "Type your answerâ¦", 870 className: "flex-1 text-sm px-2.5 py-1.5 rounded border border-blue-300 bg-white focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200", 871 autoFocus: true, 872 disabled: answerMutation.isPending 873 } 874 ), 875 /* @__PURE__ */ jsxRuntimeExports.jsxs( 876 Button, 877 { 878 size: "sm", 879 onClick: handleSubmit, 880 disabled: answerMutation.isPending || !currentAnswer.trim(), 881 className: "gap-1 bg-blue-600 hover:bg-blue-700 text-white flex-shrink-0", 882 children: [
883 answerMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 12 }), 884 "Submit" 885 ] 886 } 887 ), 888 /* @__PURE__ */ jsxRuntimeExports.jsx( 889 Button, 890 { 891 size: "sm", 892 variant: "outline", 893 onClick: handleSkip, 894 disabled: answerMutation.isPending, 895 className: "text-xs text-blue-500 border-blue-200 hover:bg-blue-50 flex-shrink-0", 896 children: "Skip" 897 } 898 ) 899 ] }), 900 lastSavedFlash && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 bg-green-50 border border-green-300 rounded-lg px-3 py-2 animate-in fade-in duration-200", children: [ 901 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 13, className: "text-green-600 flex-shrink-0" }), 902 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
903 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-green-700 font-semibold", children: "Saved â " }), 904 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-green-800 font-bold truncate", children: lastSavedFlash.value }) 905 ] }) 906 ] }), 907 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between pt-0.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( 908 "button", 909 { 910 onClick: () => setShowUpload(true), 911 className: "text-xs text-blue-500 hover:text-blue-700 flex items-center gap-1 underline underline-offset-2", 912 children: [ 913 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { size: 11 }), 914 "Upload more documents to auto-fill remaining fields" 915 ] 916 } 917 ) }) 918 ] }) 919 ] }); 920} 921function Step3ReviewAndQA({ workflow, onConfirmed, onRequestBack, confirmTriggerRef, onConfirmStateChange }) { 922 const [editedData, setEditedData] = reactExports.useState(() => workflow.extractedData ?? {}); 923 const [aiExtractedKeys, setAiExtractedKeys] = reactExports.useState(() => new Set(Object.keys(workflow.extractedData ?? {}))); 924 const [fieldSources, setFieldSources] = reactExports.useState(() => workflow.fieldSources ?? {}); 925 const fieldConfidence = workflow.fieldConfidence ?? {}; 926 const [newKey, setNewKey] = reactExports.useState(""); 927 const [newValue, setNewValue] = reactExports.useState(""); 928 const [reviewerNote, setReviewerNote] = reactExports.useState(""); 929 const [loading, setLoading] = reactExports.useState(false); 930 const [isDirty, setIsDirty] = reactExports.useState(false); 931 const [savedAt, setSavedAt] = reactExports.useState(null); 932 const [autoSavedAt, setAutoSavedAt] = reactExports.useState(null); 933 const lastSavedSnapshotRef = reactExports.useRef(workflow.extractedData ?? {}); 934 const [recentlySavedKeys, setRecentlySavedKeys] = reactExports.useState(/* @__PURE__ */ new Set()); 935 const recentlySavedTimerRef = reactExports.useRef({}); 936 const [searchFilter, setSearchFilter] = reactExports.useState(""); 937 const [showLowConfOnly, setShowLowConfOnly] = reactExports.useState(false); 938 const markRecentlySaved = (keys) => { 939 setRecentlySavedKeys((prev) => { 940 const next = new Set(prev); 941 keys.forEach((k) => next.add(k)); 942 return next; 943 }); 944 keys.forEach((k) => { 945 if (recentlySavedTimerRef.current[k]) clearTimeout(recentlySavedTimerRef.current[k]); 946 recentlySavedTimerRef.current[k] = setTimeout(() => { 947 setRecentlySavedKeys((prev) => { 948 const next = new Set(prev); 949 next.delete(k); 950 return next; 951 }); 952 delete recentlySavedTimerRef.current[k]; 953 }, 3e3); 954 }); 955 }; 956 const prevExtractedRef = reactExports.useRef(null); 957 reactExports.useEffect(() => { 958 const incoming = workflow.extractedData ?? {}; 959 const prev = prevExtractedRef.current; 960 if (prev === null || JSON.stringify(prev) !== JSON.stringify(incoming)) { 961 prevExtractedRef.current = incoming; 962 if (!isDirty) { 963 setEditedData(incoming); 964 setAiExtractedKeys(new Set(Object.keys(incoming))); 965 } 966 } 967 }, [workflow.extractedData, isDirty]); 968 const saveDraftMutation = trpc.acordWorkflows.saveDraftData.useMutation({ 969 onSuccess: (_data, variables) => { 970 setIsDirty(false); 971 const now = /* @__PURE__ */ new Date(); 972 setSavedAt(now); 973 setAutoSavedAt(now); 974 lastSavedSnapshotRef.current = { ...variables.editedData }; 975 toast.success("Changes saved!", { description: "Your edits have been saved. You can continue editing or confirm when ready." }); 976 }, 977 onError: (err) => toast.error("Save failed: " + err.message) 978 }); 979 const autoSaveMutation = trpc.acordWorkflows.saveDraftData.useMutation({ 980 onSuccess: (_data, variables) => { 981 setAutoSavedAt(/* @__PURE__ */ new Date()); 982 lastSavedSnapshotRef.current = { ...variables.editedData }; 983 }, 984 onError: () => { 985 } 986 }); 987 const confirmMutation = trpc.acordWorkflows.confirmStructuredData.useMutation({ 988 onSuccess: () => { 989 toast.success("Data confirmed!"); 990 onConfirmed(); 991 }, 992 onError: (err) => { 993 toast.error(err.message);
994 setLoading(false); 995 } 996 }); 997 const reExtractMutation = trpc.acordWorkflows.reExtract.useMutation({ 998 onSuccess: (data) => { 999 const count = data.fieldCount ?? Object.keys(data.extractedData ?? {}).length; 1000 toast.success(`Re-extraction complete â ${count} fields found!`); 1001 const extracted = data.extractedData ?? {}; 1002 setEditedData(extracted); 1003 setAiExtractedKeys(new Set(Object.keys(extracted))); 1004 setIsDirty(false); 1005 prevExtractedRef.current = extracted; 1006 }, 1007 onError: (err) => toast.error("Re-extraction failed: " + err.message) 1008 }); 1009 const handleFieldChange = (key, value) => { 1010 setEditedData((prev) => ({ ...prev, [key]: value })); 1011 setIsDirty(true); 1012 }; 1013 const handleDeleteField = (key) => { 1014 setEditedData((prev) => { 1015 const n = { ...prev }; 1016 delete n[key]; 1017 return n; 1018 }); 1019 setIsDirty(true); 1020 }; 1021 const handleAddField = () => { 1022 if (!newKey.trim()) return; 1023 setEditedData((prev) => ({ ...prev, [newKey.trim()]: newValue })); 1024 setNewKey(""); 1025 setNewValue(""); 1026 setIsDirty(true); 1027 }; 1028 const [jsonView, setJsonView] = reactExports.useState(false); 1029 const [jsonEditText, setJsonEditText] = reactExports.useState(""); 1030 const [jsonError, setJsonError] = reactExports.useState(null); 1031 const [showSummaryPanel, setShowSummaryPanel] = reactExports.useState(false); 1032 const [summaryText, setSummaryText] = reactExports.useState(null); 1033 const [summaryCopied, setSummaryCopied] = reactExports.useState(false); 1034 const summaryMutation = trpc.acordWorkflows.generateUnderwritingSummary.useMutation({ 1035 onSuccess: (data) => { 1036 setSummaryText(data.summary); 1037 toast.success(`Carrier summary generated for ${data.clientName}`); 1038 }, 1039 onError: (err) => toast.error("Summary generation failed: " + err.message) 1040 }); 1041 const handleCopySummary = () => { 1042 if (!summaryText) return; 1043 navigator.clipboard.writeText(summaryText).then(() => { 1044 setSummaryCopied(true); 1045 setTimeout(() => setSummaryCopied(false), 2e3); 1046 }); 1047 }; 1048 const [showSummary, setShowSummary] = reactExports.useState(false); 1049 const isBooleanValue = (v) => v === "true" || v === "false"; 1050 const handleConfirm = () => { 1051 setShowSummary(true); 1052 }; 1053 const handleFinalConfirm = () => { 1054 setShowSummary(false); 1055 setLoading(true); 1056 confirmMutation.mutate({ id: workflow.id, editedData, reviewerNote }); 1057 }; 1058 const fieldCount = Object.keys(editedData).length; 1059 reactExports.useEffect(() => { 1060 if (confirmTriggerRef) { 1061 confirmTriggerRef.current = { confirm: handleConfirm, fieldCount, loading }; 1062 } 1063 onConfirmStateChange?.({ fieldCount, loading }); 1064 }, [fieldCount, loading, handleConfirm]); 1065 const allEntries = Object.entries(editedData); 1066 const lowConfKeys = new Set( 1067 Object.entries(fieldConfidence).filter(([k, c]) => c < 0.6 && editedData[k] !== void 0).map(([k]) => k) 1068 ); 1069 const filteredEntries = (() => { 1070 let entries = allEntries; 1071 if (showLowConfOnly) { 1072 const low = entries.filter(([k]) => lowConfKeys.has(k)); 1073 const rest = entries.filter(([k]) => !lowConfKeys.has(k)); 1074 entries = [...low, ...rest]; 1075 } 1076 if (searchFilter.trim()) { 1077 entries = entries.filter( 1078 ([k, v]) => k.toLowerCase().includes(searchFilter.toLowerCase()) || v.toLowerCase().includes(searchFilter.toLowerCase()) 1079 ); 1080 } 1081 return entries; 1082 })(); 1083 const hasFields = allEntries.length > 0; 1084 const openJsonView = () => { 1085 setJsonEditText(JSON.stringify(editedData, null, 2)); 1086 setJsonError(null); 1087 setJsonView(true); 1088 }; 1089 const applyJsonEdit = () => { 1090 try { 1091 const parsed = JSON.parse(jsonEditText); 1092 if (typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("Mu
1092st be a JSON object"); 1093 const cleaned = {}; 1094 for (const [k, v] of Object.entries(parsed)) { 1095 cleaned[k] = String(v); 1096 } 1097 setEditedData(cleaned); 1098 setIsDirty(true); 1099 setJsonError(null); 1100 setJsonView(false); 1101 } catch (e) { 1102 setJsonError(e.message); 1103 } 1104 }; 1105 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3", children: [ 1106 isDirty && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 border border-amber-300 rounded-lg px-3 py-2 flex items-center gap-2 flex-shrink-0 mb-2", children: [ 1107 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 14, className: "text-amber-600 flex-shrink-0" }), 1108 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-amber-800 flex-1", children: [ 1109 "Unsaved changes â click ", 1110 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Save Changes" }), 1111 " or ", 1112 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Confirm" }), 1113 " to proceed." 1114 ] }),
1115 /* @__PURE__ */ jsxRuntimeExports.jsxs( 1116 Button, 1117 { 1118 size: "sm", 1119 variant: "ghost", 1120 className: "text-amber-700 hover:bg-amber-100 h-6 px-2 text-xs gap-1", 1121 onClick: () => saveDraftMutation.mutate({ id: workflow.id, editedData }), 1122 children: [ 1123 saveDraftMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 11, className: "animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { size: 11 }), 1124 "Save now" 1125 ] 1126 } 1127 ) 1128 ] }), 1129 (workflow.autoFilledCount ?? 0) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-emerald-50 border border-emerald-200 rounded-lg px-3 py-2 flex items-center gap-2 flex-shrink-0", children: [ 1130 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 14, className: "text-emerald-600 flex-shrink-0" }), 1131 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-emerald-800 flex-1", children: [ 1132 /* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [ 1133 workflow.autoFilledCount, 1134 " fields auto-filled" 1135 ] }), 1136 " â agency info, producer details", 1137 workflow.intakeStandardAnswersAsUsual ? ", and standard yes/no answers" : "", 1138 " were applied automatically." 1139 ] }) 1140 ] }), 1141 ((workflow.intakeDocTypes ?? []).length >
1141 0 || workflow.intakeIsRenewal) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-1.5 flex-shrink-0", children: [ 1142 workflow.intakeIsRenewal && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex items-center gap-1 text-[10px] font-medium bg-amber-100 text-amber-800 border border-amber-300 rounded-full px-2 py-0.5", children: "ð Renewal" }), 1143 (workflow.intakeDocTypes ?? []).map((dt) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex items-center text-[10px] font-medium bg-blue-50 text-blue-700 border border-blue-200 rounded-full px-2 py-0.5", children: dt }, dt)) 1144 ] }), 1145 /* @__PURE__ */ jsxRuntimeExports.jsx( 1146 MissingFieldQA, 1147 { 1148 workflowId: workflow.id, 1149 onFieldAnswered: (key, value) => { 1150 if (value !== null) { 1151 setEditedData((prev) => { 1152 const updated = { ...prev, [key]: value }; 1153 autoSaveMutation.mutate({ id: workflow.id, editedData: updated }); 1154 return updated; 1155 }); 1156 setIsDirty(true); 1157 markRecentlySaved([key]); 1158 } 1159 }, 1160 onBulkFieldsAnswered: (fields) => { 1161 setEditedData((prev) => { 1162 const updated = { ...prev, ...fields }; 1163 autoSaveMutation.mutate({ id: workflow.id, editedData: updated }); 1164 return updated; 1165 }); 1166 markRecentlySaved(Object.keys(fields)); 1167 setFieldSources((prev) => { 1168 const updated = { ...prev }; 1169 Object.keys(fields).forEach((k) => { 1170 updated[k] = "from_document"; 1171 }); 1172 return updated; 1173 }); 1174 setIsDirty(true); 1175 } 1176 } 1177 ), 1178 (() => { 1179 const lob = (workflow.lineOfBusiness ?? "").toLowerCase(); 1180 const isCommercial = lob.includes("commercial") || lob.includes("bop") || lob.includes("business") || lob.includes("property") || lob.includes("p&c"); 1181 if (!isCommercial) return null; 1182 const clientName = workflow.clientName ?? ""; 1183 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-indigo-50 border border-indigo-200 rounded-lg px-3 py-2.5 flex items-center gap-2 flex-shrink-0", children: [
1184 /* @__PURE__ */ jsxRuntimeExports.jsx(Building2, { size: 14, className: "text-indigo-600 flex-shrink-0" }), 1185 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-indigo-800 flex-1", children: [ 1186 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Business Research:" }), 1187 " The AI can look up NAICS/SIC/GL codes, property details, and general business info to help complete this form." 1188 ] }), 1189 /* @__PURE__ */ jsxRuntimeExports.jsxs( 1190 Button, 1191 { 1192 size: "sm", 1193 variant: "outline", 1194 className: "text-xs text-indigo-600 border-indigo-300 hover:bg-indigo-100 flex-shrink-0 gap-1", 1195 onClick: () => { 1196 const query = clientName ? `Look up business info, NAICS/SIC/GL codes, and property details for: ${clientName}` : `Help me find NAICS/SIC/GL codes and property details for this commercial account`; 1197 window.dispatchEvent(new CustomEvent("acord-chat-prefill", { detail: { message: query } })); 1198 toast.info("Opening AI assistant⦠scroll down to the chat panel"); 1199 }, 1200 children: [
1201 /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { size: 11 }), 1202 "Look Up Business" 1203 ] 1204 } 1205 ) 1206 ] }); 1207 })(), 1208 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-wrap flex-shrink-0", children: [ 1209 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 bg-blue-50 border border-blue-200 rounded-lg px-3 py-1.5 flex-1 min-w-0", children: [ 1210 /* @__PURE__ */ jsxRuntimeExports.jsx(Info, { size: 13, className: "text-blue-600 flex-shrink-0" }), 1211 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-blue-800 font-medium", children: hasFields ? `${allEntries.length} field${allEntries.length !== 1 ? "s" : ""} extracted` : "No fields extracted yet â add manually below" }), 1212 hasFields && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-blue-500 ml-1", children: [ 1213 "(", 1214 aiExtractedKeys.size, 1215 " AI · ", 1216 allEntries.length - aiExtractedKeys.size, 1217 " manual)" 1218 ] }) 1219 ] }),
1220 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1.5 flex-shrink-0", children: [ 1221 /* @__PURE__ */ jsxRuntimeExports.jsx( 1222 Button, 1223 { 1224 size: "sm", 1225 variant: "outline", 1226 className: "gap-1.5 text-xs h-8 border-blue-200 text-blue-700 hover:bg-blue-50", 1227 onClick: () => reExtractMutation.mutate({ id: workflow.id }), 1228 disabled: reExtractMutation.isPending, 1229 title: "Re-run AI extraction on the uploaded documents", 1230 children: reExtractMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1231 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 11, className: "animate-spin" }), 1232 "Re-extractingâ¦" 1233 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1234 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 11 }), 1235 "Re-extract" 1236 ] }) 1237 } 1238 ),
1239 hasFields && /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", variant: "outline", className: "gap-1.5 text-xs h-8 flex-shrink-0", onClick: openJsonView, children: [ 1240 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 12 }), 1241 "View / Edit JSON" 1242 ] }), 1243 hasFields && /* @__PURE__ */ jsxRuntimeExports.jsx( 1244 Button, 1245 { 1246 size: "sm", 1247 variant: "outline", 1248 className: "gap-1.5 text-xs h-8 flex-shrink-0 border-emerald-300 text-emerald-700 hover:bg-emerald-50", 1249 onClick: () => { 1250 setShowSummaryPanel(true); 1251 setSummaryText(null); 1252 summaryMutation.mutate({ id: workflow.id }); 1253 }, 1254 disabled: summaryMutation.isPending, 1255 title: "Generate a professional carrier submission narrative from the extracted data", 1256 children: summaryMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1257 /* @__P
1257URE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 11, className: "animate-spin" }), 1258 "Generatingâ¦" 1259 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1260 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 11 }), 1261 "Carrier Summary" 1262 ] }) 1263 } 1264 ) 1265 ] }) 1266 ] }), 1267 showSummaryPanel && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-emerald-200 rounded-lg overflow-hidden flex-shrink-0", children: [ 1268 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 py-2 bg-emerald-50 border-b border-emerald-200", children: [ 1269 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 1270 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 13, className: "text-emerald-600" }), 1271 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-emerald-800", children: "Carrier Submission Narrative" }), 1272 summaryText && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-emerald-500", children: "â ready to copy" }) 1273 ] }),
1274 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 1275 summaryText && /* @__PURE__ */ jsxRuntimeExports.jsx( 1276 "button", 1277 { 1278 onClick: handleCopySummary, 1279 className: "flex items-center gap-1 text-xs text-emerald-600 hover:text-emerald-800 border border-emerald-300 rounded px-2 py-0.5 hover:bg-emerald-100 transition-colors", 1280 children: summaryCopied ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1281 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 11 }), 1282 "Copied!" 1283 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1284 /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 11 }), 1285 "Copy" 1286 ] }) 1287 } 1288 ), 1289 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowSummaryPanel(false), className: "text-emerald-400 hover:text-emerald-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) 1290 ] }) 1291 ] }),
1292 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 bg-white", children: summaryMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-4 justify-center", children: [ 1293 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 16, className: "animate-spin text-emerald-600" }), 1294 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-emerald-700", children: "Generating carrier narrative⦠(10â20 seconds)" }) 1295 ] }) : summaryText ? /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs text-gray-800 whitespace-pre-wrap leading-relaxed font-sans max-h-96 overflow-y-auto", children: summaryText }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 text-center py-4", children: "Summary will appear here once generated." }) }) 1296 ] }), 1297 hasFields && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 flex-shrink-0", children: [ 1298 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex-1", children: [
1299 /* @__PURE__ */ jsxRuntimeExports.jsx( 1300 Input, 1301 { 1302 placeholder: `Search ${allEntries.length} fieldsâ¦`, 1303 value: searchFilter, 1304 onChange: (e) => setSearchFilter(e.target.value), 1305 className: "text-sm h-8 pl-7" 1306 } 1307 ), 1308 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-gray-400", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [ 1309 /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "11", cy: "11", r: "8" }), 1310 /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m21 21-4.35-4.35" }) 1311 ] }) }), 1312 searchFilter && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600", onClick: () => setSearchFilter(""), children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 12 }) }) 1313 ] }), 1314 lowConfKeys.size > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs( 1315 "button", 1316 { 1317 onClick: () => setShowLowConfOnly((v) => !v), 1318 className: `flex items-center gap-1.5 text-xs font-semibold px-2.5 py-1 rounded-lg border transition-colors flex-shrink-0 ${showLowConfOnly ? "bg-amber-500 border-amber-500 text-white" : "bg-amber-50 border-amber-300 text-amber-700 hover:bg-amber-100"}`, 1319 title: "Show low-confidence fields first", 1320 children: [
1321 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 12 }), 1322 lowConfKeys.size, 1323 " low conf" 1324 ] 1325 } 1326 ) 1327 ] }), 1328 jsonView && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white rounded-xl shadow-2xl w-full max-w-2xl mx-4 flex flex-col", style: { maxHeight: "85vh" }, children: [ 1329 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b", children: [ 1330 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1331 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-900", children: "Edit Extracted Data as JSON" }), 1332 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: "Edit the JSON object directly. All values must be strings. Click Apply to save changes." }) 1333 ] }),
1334 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setJsonView(false), className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 16 }) }) 1335 ] }), 1336 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-hidden p-4", children: [ 1337 /* @__PURE__ */ jsxRuntimeExports.jsx( 1338 Textarea, 1339 { 1340 value: jsonEditText, 1341 onChange: (e) => { 1342 setJsonEditText(e.target.value); 1343 setJsonError(null); 1344 }, 1345 className: "font-mono text-xs h-full resize-none", 1346 style: { minHeight: "400px" }, 1347 spellCheck: false 1348 } 1349 ), 1350 jsonError && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-red-600 mt-1 flex items-center gap-1", children: [ 1351 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 11 }), 1352 "JSON error: ", 1353 jsonError 1354 ] }) 1355 ] }), 1356 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 px-4 pb-4", children: [
1357 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", className: "flex-1", onClick: () => setJsonView(false), children: "Cancel" }), 1358 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { className: "flex-1", style: { background: "var(--eps-navy-deep)", color: "white" }, onClick: applyJsonEdit, children: [ 1359 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 14, className: "mr-1.5" }), 1360 "Apply Changes" 1361 ] }) 1362 ] }) 1363 ] }) }), 1364 (() => { 1365 const lowConfKeys2 = Object.entries(fieldConfidence).filter(([k, c]) => c < 0.5 && editedData[k] !== void 0); 1366 if (lowConfKeys2.length === 0) return null; 1367 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-red-50 border border-red-200 rounded-lg px-3 py-2.5 flex gap-2 flex-shrink-0", children: [ 1368 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 14, className: "text-red-500 flex-shrink-0 mt-0.5" }), 1369 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
1370 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-semibold text-red-700 mb-1", children: [ 1371 lowConfKeys2.length, 1372 " field", 1373 lowConfKeys2.length !== 1 ? "s" : "", 1374 " need review â AI confidence is low" 1375 ] }), 1376 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-1", children: [ 1377 lowConfKeys2.slice(0, 8).map(([k]) => /* @__PURE__ */ jsxRuntimeExports.jsx( 1378 "button", 1379 { 1380 onClick: () => setSearchFilter(k), 1381 className: "text-[10px] bg-red-100 text-red-700 border border-red-200 rounded px-1.5 py-0.5 hover:bg-red-200 transition-colors", 1382 children: camelToLabel(k) 1383 }, 1384 k 1385 )), 1386 lowConfKeys2.length > 8 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] text-red-500", children: [ 1387 "+", 1388 lowConfKeys2.length - 8, 1389 " more" 1390 ] }) 1391 ] }) 1392 ] }) 1393 ] }); 1394 })(), 1395 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-y-auto border border-gray-200 rounded-lg", style: { maxHeight: "45vh", minHeight: "120px" }, children: hasFields ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1396 workflow.missingFields.length > 0 && !searchFilter && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 border-b border-amber-200 px-3 py-2", children: [
1397 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-medium text-amber-700 mb-1", children: [ 1398 "Fields not found in documents ", 1399 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-normal", children: "(click to pre-fill name)" }), 1400 ":" 1401 ] }), 1402 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: workflow.missingFields.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsx( 1403 Badge, 1404 { 1405 variant: "outline", 1406 className: "text-xs border-amber-300 text-amber-700 cursor-pointer hover:bg-amber-100", 1407 onClick: () => setNewKey(f), 1408 children: f 1409 }, 1410 f 1411 )) }) 1412 ] }), 1413 filteredEntries.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-6 text-center text-sm text-gray-400", children: [ 1414 'No fields match "', 1415 searchFilter, 1416 '"' 1417 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-sm", children: [
1418 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "sticky top-0 bg-gray-50 border-b border-gray-200 z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 1419 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left text-xs font-semibold text-gray-500 px-3 py-2 w-52", children: "Field Name" }), 1420 /* @__PURE__ */ jsxRuntimeExports.jsxs("th", { className: "text-left text-xs font-semibold text-gray-500 px-3 py-2", children: [ 1421 "Value ", 1422 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-normal text-gray-400", children: "(click to edit)" }) 1423 ] }), 1424 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "w-8" }) 1425 ] }) }), 1426 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: filteredEntries.map(([key, value]) => { 1427 const isAI = aiExtractedKeys.has(key); 1428 const isFromDoc = fieldSources[key] === "from_document"; 1429 const isRecentlySaved = recentlySavedKeys.has(key); 1430 const EPS_LOCKED_FIELDS = /* @__PURE__ */ new Set(["agencyName", "agencyAddress", "agencyCity", "agencyState", "agencyZip", "agencyPhone", "agencyCode"]); 1431 const isEpsLocked = EPS_LOCKED_FIELDS.has(key); 1432 const isLowConf = !isEpsLocked && lowConfKeys.has(key); 1433 return /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: `border-b border-gray-100 last:border-0 group transition-colors duration-700 ${isEpsLocked ? "bg-indigo-50/60" : isRecentlySaved ? "bg-green-50 border-l-2 border-l-green-400" : isLowConf ? "bg-amber-50/70 border-l-2 border-l-amber-400" : "hover:bg-blue-50/30"}`, children: [
1434 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-2 align-middle", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 flex-wrap", children: [ 1435 isEpsLocked && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-indigo-600 text-white rounded px-1 py-0.5 leading-3 flex-shrink-0", title: "Auto-filled by EPS â cannot be changed", children: "EPS" }), 1436 isAI && !isEpsLocked && (() => { 1437 const conf = fieldConfidence[key]; 1438 if (conf !== void 0) { 1439 const confPct = Math.round(conf * 100); 1440 const confColor = conf >= 0.8 ? "bg-green-500" : conf >= 0.5 ? "bg-amber-500" : "bg-red-500"; 1441 const confLabel = conf >= 0.8 ? "High" : conf >= 0.5 ? "Med" : "Low"; 1442 return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `text-[9px] font-bold ${confColor} text-white rounded px-1 py-0.5 leading-3 flex-shrink-0`, title: `AI confidence: ${confPct}%`, children: confLabel }); 1443 } 1444 return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-green-500 text-white rounded px-1 py-0.5 leading-3 flex-shrink-0", children: "AI" }); 1445 })(),
1446 isFromDoc && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-amber-500 text-white rounded px-1 py-0.5 leading-3 flex-shrink-0", title: "Extracted from supplemental document", children: "DOC" }), 1447 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-gray-700", title: key, children: camelToLabel(key) }), 1448 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] text-gray-400 font-mono", title: key, children: key }) 1449 ] }) }), 1450 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1.5 align-middle", children: isEpsLocked ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm px-2 py-1 text-indigo-800 font-medium", children: value }) : isBooleanValue(value) ? /* @__PURE__ */ jsxRuntimeExports.jsxs( 1451 "button", 1452 { 1453 onClick: () => handleFieldChange(key, value === "true" ? "false" : "true"), 1454 style: { 1455 display: "inline-flex", 1456 alignItems: "center", 1457 gap: "6px", 1458 padding: "4px 10px", 1459 borderRadius: "9999px", 1460 border: "none", 1461 cursor: "pointer", 1462 fontSize: "12px", 1463 fontWeight: "600", 1464 backgroundColor: value === "true" ? "#16a34a" : "#d1d5db", 1465 color: value === "true" ? "#ffffff" : "#374151", 1466 transition: "background-color 0.15s", 1467 minWidth: "70px", 1468 justifyContent: "center" 1469 }, 1470 children: [
1471 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { 1472 width: "12px", 1473 height: "12px", 1474 borderRadius: "50%", 1475 backgroundColor: value === "true" ? "#ffffff" : "#9ca3af", 1476 display: "inline-block", 1477 flexShrink: 0 1478 } }), 1479 value === "true" ? "Yes" : "No" 1480 ] 1481 } 1482 ) : /* @__PURE__ */ jsxRuntimeExports.jsx( 1483 "input", 1484 { 1485 type: "text", 1486 value, 1487 onChange: (e) => handleFieldChange(key, e.target.value), 1488 className: `w-full text-sm px-2 py-1 rounded border bg-white focus:outline-none focus:ring-1 transition-colors ${isLowConf ? "border-amber-300 hover:border-amber-400 focus:border-amber-500 focus:ring-amber-200" : "border-gray-200 hover:border-blue-300 focus:border-blue-500 focus:ring-blue-200"}`, 1489 placeholder: "(empty)" 1490 } 1491 ) }),
1492 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "pr-2 align-middle", children: !isEpsLocked && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => handleDeleteField(key), className: "text-gray-300 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity", title: "Remove field", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 13 }) }) }) 1493 ] }, key); 1494 }) }) 1495 ] }) 1496 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-8 text-center", children: [ 1497 /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardList, { size: 28, className: "mx-auto text-gray-300 mb-2" }), 1498 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-500", children: "No fields extracted yet" }), 1499 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 mt-1 mb-3", children: "The AI extraction returned no data. Click below to retry extraction from the uploaded documents." }), 1500 /* @__PURE__ */ jsxRuntimeExports.jsx( 1501 Button, 1502 { 1503 size: "sm", 1504 variant: "outline", 1505 className: "gap-1.5 border-blue-300 text-blue-700 hover:bg-blue-50", 1506 onClick: () => reExtractMutation.mutate({ id: workflow.id }), 1507 disabled: reExtractMutation.isPending,
1508 children: reExtractMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1509 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 13, className: "animate-spin" }), 1510 "Re-extractingâ¦" 1511 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1512 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 13 }), 1513 "Re-run AI Extraction" 1514 ] }) 1515 } 1516 ) 1517 ] }) }), 1518 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sticky bottom-0 bg-white border-t border-gray-200 pt-3 pb-2 space-y-2 z-20 shadow-[0_-2px_8px_rgba(0,0,0,0.06)]", children: [ 1519 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [ 1520 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs font-semibold text-gray-600 flex items-center gap-1.5", children: [ 1521 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { size: 12, className: "text-blue-500" }), 1522 "Add New Field" 1523 ] }),
1524 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 items-center", children: [ 1525 /* @__PURE__ */ jsxRuntimeExports.jsx( 1526 "input", 1527 { 1528 type: "text", 1529 placeholder: "Field name (e.g. namedInsured)", 1530 value: newKey, 1531 onChange: (e) => setNewKey(e.target.value), 1532 className: "w-48 text-sm px-2 py-1.5 rounded border border-gray-200 bg-white hover:border-blue-300 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200" 1533 } 1534 ), 1535 /* @__PURE__ */ jsxRuntimeExports.jsx( 1536 "input", 1537 { 1538 type: "text", 1539 placeholder: "Value", 1540 value: newValue, 1541 onChange: (e) => setNewValue(e.target.value), 1542 onKeyDown: (e) => { 1543 if (e.key === "Enter") handleAddField(); 1544 }, 1545 className: "flex-1 text-sm px-2 py-1.5 rounded border border-gray-200 bg-white hover:border-blue-300 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200" 1546 } 1547 ),
1548 /* @__PURE__ */ jsxRuntimeExports.jsxs( 1549 Button, 1550 { 1551 size: "sm", 1552 onClick: handleAddField, 1553 disabled: !newKey.trim(), 1554 className: "gap-1 bg-blue-600 hover:bg-blue-700 text-white flex-shrink-0", 1555 children: [ 1556 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { size: 13 }), 1557 "Add" 1558 ] 1559 } 1560 ) 1561 ] }) 1562 ] }), 1563 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ 1564 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 1565 /* @__PURE__ */ jsxRuntimeExports.jsx( 1566 Button, 1567 { 1568 variant: "outline", 1569 size: "sm", 1570 onClick: () => saveDraftMutation.mutate({ id: workflow.id, editedData }), 1571 disabled: !isDirty || saveDraftMutation.isPending, 1572 className: "flex-1 gap-1.5 border-green-300 text-green-700 hover:bg-green-50",
1573 children: saveDraftMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1574 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin" }), 1575 "Savingâ¦" 1576 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1577 /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { size: 14 }), 1578 "Save Changes" 1579 ] }) 1580 } 1581 ), 1582 savedAt && !isDirty && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-green-600 flex items-center gap-1", children: [ 1583 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 12 }), 1584 "Saved ", 1585 savedAt.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) 1586 ] }), 1587 isDirty && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-amber-600 flex items-center gap-1", children: [
1588 /* @__PURE__ */ jsxRuntimeExports.jsx(PenLine, { size: 12 }), 1589 "Unsaved changes" 1590 ] }) 1591 ] }), 1592 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [ 1593 autoSavedAt ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-blue-600 flex items-center gap-1", children: [ 1594 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 11, className: "text-blue-500" }), 1595 "Auto-saved ", 1596 autoSavedAt.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" }) 1597 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400", children: "Auto-save active" }), 1598 isDirty && Object.keys(lastSavedSnapshotRef.current).length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs( 1599 "button", 1600 { 1601 onClick: () => { 1602 setEditedData({ ...lastSavedSnapshotRef.current }); 1603 setIsDirty(false); 1604 toast.info("Restored to last saved version"); 1605 }, 1606 className: "text-xs text-gray-500 hover:text-gray-700 flex items-center gap-1 underline underline-offset-2", 1607 children: [
1608 /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 11 }), 1609 "Restore last save" 1610 ] 1611 } 1612 ) 1613 ] }) 1614 ] }) 1615 ] }), 1616 showSummary && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white rounded-xl shadow-2xl w-full max-w-2xl mx-4 flex flex-col", style: { maxHeight: "85vh" }, children: [ 1617 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b", children: [ 1618 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1619 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-900", children: "Review Before Confirming" }), 1620 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 mt-0.5", children: [ 1621 Object.keys(editedData).length, 1622 " fields will be confirmed and locked for ACORD form population." 1623 ] }) 1624 ] }),
1625 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowSummary(false), className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 16 }) }) 1626 ] }), 1627 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-3", children: [ 1628 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-3 mb-4", children: [ 1629 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 rounded-lg p-3 text-center", children: [ 1630 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-blue-700", children: Object.keys(editedData).length }), 1631 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-600 mt-0.5", children: "Total Fields" }) 1632 ] }), 1633 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-green-50 rounded-lg p-3 text-center", children: [ 1634 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-green-700", children: aiExtractedKeys.size }),
1635 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-600 mt-0.5", children: "AI Extracted" }) 1636 ] }), 1637 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-purple-50 rounded-lg p-3 text-center", children: [ 1638 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-purple-700", children: Object.keys(editedData).length - aiExtractedKeys.size }), 1639 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-purple-600 mt-0.5", children: "Manually Added" }) 1640 ] }) 1641 ] }), 1642 /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-sm border border-gray-200 rounded-lg overflow-hidden", children: [ 1643 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [ 1644 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left text-xs font-semibold text-gray-500 px-3 py-2 w-52", children: "Field" }),
1645 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left text-xs font-semibold text-gray-500 px-3 py-2", children: "Value" }), 1646 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left text-xs font-semibold text-gray-500 px-3 py-2 w-16", children: "Source" }) 1647 ] }) }), 1648 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: Object.entries(editedData).map(([k, v]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "border-t border-gray-100 hover:bg-gray-50", children: [ 1649 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-1.5 font-mono text-xs text-gray-700 break-all", children: k }), 1650 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-1.5 text-xs text-gray-900", children: isBooleanValue(v) ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { 1651 display: "inline-block", 1652 padding: "1px 8px", 1653 borderRadius: "9999px", 1654 fontSize: "11px", 1655 fontWeight: 600, 1656 backgroundColor: v === "true" ? "#dcfce7" : "#f3f4f6", 1657 color: v === "true" ? "#166534" : "#374151" 1658 }, children: v === "true" ? "Yes" : "No" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "break-all", children: v || /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400 italic", children: "empty" }) }) }),
1659 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-1.5", children: aiExtractedKeys.has(k) ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-green-500 text-white rounded px-1 py-0.5", children: "AI" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-purple-500 text-white rounded px-1 py-0.5", children: "Manual" }) }) 1660 ] }, k)) }) 1661 ] }) 1662 ] }), 1663 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 px-4 pb-4 pt-3 border-t", children: [ 1664 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", className: "flex-1", onClick: () => setShowSummary(false), children: "Back to Edit" }), 1665 /* @__PURE__ */ jsxRuntimeExports.jsx( 1666 Button, 1667 { 1668 className: "flex-1 gap-1.5", 1669 style: { backgroundColor: "#1a2e4a", color: "#ffffff" }, 1670 onClick: handleFinalConfirm, 1671 disabled: loading || confirmMutation.isPending, 1672 children: loading || confirmMutation.isPending ? /* @__P
1672URE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1673 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin" }), 1674 "Confirmingâ¦" 1675 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1676 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 14 }), 1677 "Confirm & Continue to Step 4" 1678 ] }) 1679 } 1680 ) 1681 ] }) 1682 ] }) }) 1683 ] }); 1684} 1685function Step2BlankFormUpload({ workflow, onUploaded }) { 1686 const [file, setFile] = reactExports.useState(null); 1687 const [expectedForm, setExpectedForm] = reactExports.useState(""); 1688 const [loading, setLoading] = reactExports.useState(false); 1689 const [isDraggingOver2, setIsDraggingOver2] = reactExports.useState(false); 1690 const fileInputRef = reactExports.useRef(null); 1691 const processFile2 = (f) => { 1692 const isValidType = f.name.toLowerCase().endsWith(".pdf") || f.name.toLowerCase().endsWith(".docx") || f.name.toLowerCase().endsWith(".doc"); 1693 if (!isValidType) { 1694 toast.error("Please upload a PDF or Word document (.docx)"); 1695 return; 1696 } 1697 const reader = new FileReader(); 1698 reader.onload = (ev) => { 1699 const base64 = (ev.target?.result).split(",")[1]; 1700 let mimeType = f.type; 1701 if (!mimeType) { 1702 const lower = f.name.toLowerCase(); 1703 if (lower.endsWith(".docx")) mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; 1704 else if (lower.endsWith(".doc")) mimeType = "application/msword"; 1705 else mimeType = "application/pdf"; 1706 } 1707 setFile({ name: f.name, base64, mimeType }); 1708 }; 1709 reader.readAsDataURL(f); 1710 }; 1711 const handleDragOver2 = (e) => { 1712 e.preventDefault(); 1713 e.stopPropagation(); 1714 setIsDraggingOver2(true); 1715 }; 1716 const handleDragLeave2 = (e) => { 1717 e.preventDefault(); 1718 e.stopPropagation(); 1719 setIsDraggingOver2(false); 1720 }; 1721 const handleDrop2 = (e) => { 1722 e.preventDefault(); 1723 e.stopPropagation(); 1724 setIsDraggingOver2(false); 1725 const dropped = e.dataTransfer.files?.[0]; 1726 if (dropped) processFile2(dropped); 1727 }; 1728 const uploadMutation = trpc.acordWorkflows.uploadAndValidateOfficialForm.useMutation({ 1729 onSuccess: (data) => { 1730 const label = data.formTitle || data.formNumber || file?.name || "form"; 1731 toast.success(`â Blank form uploaded: ${label}`); 1732 onUploaded(); 1733 }, 1734 onError: (err) => { 1735 toast.error(err.message || "Upload failed â please try again"); 1736 setLoading(false); 1737 } 1738 }); 1739 const handleFileChange = (e) => { 1740 const f = e.target.files?.[0]; 1741 if (f) processFile2(f); 1742 e.target.value = ""; 1743 }; 1744 const handleUpload = () => { 1745 if (!file) { 1746 toast.error("Please select a PDF or Word document to upload"); 1747 return; 1748 } 1749 setLoading(true); 1750 uploadMutation.mutate({ 1751 id: workflow.id, 1752 fileName: file.name, 1753 base64: file.base64, 1754 mimeType: file.mimeType, 1755 expectedFormNumber: expectedForm.trim() || void 0, 1756 producerConfirmsCorrectForm: true 1757 }); 1758 }; 1759 const useTemplateMutation = trpc.acordWorkflows.useFormTemplate.useMutation({ 1760 onSuccess: (data) => { 1761 toast.success(`â Loaded from library: ${data.formTitle}`); 1762 onUploaded(); 1763 }, 1764 onError: (err) => toast.error(err.message || "Template not available") 1765 }); 1766 const { data: libraryForms, isLoading: libraryLoading } = trpc.acordWorkflows.listFormLibrary.useQuery(); 1767 const suggested = workflow.suggestedForm; 1768 const suggestedInLibrary = suggested && libraryForms?.find((f) => f.formNumber === suggested.formNumber); 1769 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-5", children: [ 1770 suggested && suggested.formNumber && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-amber-50 border border-amber-300 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
1771 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex items-center justify-center w-7 h-7 rounded-full bg-amber-500 text-white text-xs font-bold", children: "AI" }) }), 1772 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 1773 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-semibold text-amber-900 mb-0.5", children: [ 1774 "Suggested Form: ACORD ", 1775 suggested.formNumber, 1776 " â ", 1777 suggested.formTitle 1778 ] }), 1779 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-800 leading-relaxed", children: suggested.reason }), 1780 suggestedInLibrary ? /* @__PURE__ */ jsxRuntimeExports.jsx( 1781 "button", 1782 { 1783 onClick: () => useTemplateMutation.mutate({ id: workflow.id, formNumber: suggested.formNumber }), 1784 disabled: useTemplateMutation.isPending, 1785 className: "mt-2 inline-flex items-center gap-1.5 text-xs font-semibold bg-amber-600 hover:bg-amber-700 text-white px-3 py-1.5 rounded-md transition-colors disabled:opacity-50",
1786 children: useTemplateMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1787 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 11, className: "animate-spin" }), 1788 "Loadingâ¦" 1789 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1790 /* @__PURE__ */ jsxRuntimeExports.jsx(FileCheck, { size: 11 }), 1791 "Use ACORD ", 1792 suggested.formNumber, 1793 " from Library" 1794 ] }) 1795 } 1796 ) : /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-amber-700 mt-1.5 italic", children: [ 1797 "ACORD ", 1798 suggested.formNumber, 1799 " is not in your library yet â upload the blank form below to use it." 1800 ] }) 1801 ] }) 1802 ] }) }), 1803 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-3", children: [ 1804 /* @__PURE__ */ jsxRuntimeExports.jsx(Info, { size: 16, className: "text-blue-600 flex-shrink-0 mt-0.5" }),
1805 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-blue-800", children: [ 1806 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium mb-1", children: "Upload the blank form you need completed" }), 1807 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Upload any blank PDF form â ACORD forms, carrier applications, or any other insurance form. The AI will use the extracted data to fill in the blanks, then ask you one question at a time for anything that couldn't be found automatically." }) 1808 ] }) 1809 ] }), 1810 libraryLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-400 py-2", children: [ 1811 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin" }), 1812 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Loading saved formsâ¦" }) 1813 ] }) : libraryForms && libraryForms.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 1814 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-gray-700 mb-2", children: "Saved Forms Library" }),
1815 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-2", children: libraryForms.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsxs( 1816 "button", 1817 { 1818 onClick: () => useTemplateMutation.mutate({ id: workflow.id, formNumber: f.formNumber }), 1819 disabled: useTemplateMutation.isPending, 1820 className: "border rounded-lg p-3 text-left hover:border-blue-400 hover:bg-blue-50 transition-colors disabled:opacity-50", 1821 children: [ 1822 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-bold text-gray-800", children: [ 1823 "ACORD ", 1824 f.formNumber 1825 ] }), 1826 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 mt-0.5 leading-snug", children: f.formTitle }), 1827 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [ 1828 f.fieldCount, 1829 " fields · ", 1830 f.uploadedBy 1831 ] }) 1832 ] 1833 }, 1834 f.id 1835 )) }),
1836 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 mt-1.5", children: "Or upload a new form below to add it to the library" }) 1837 ] }) : null, 1838 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [ 1839 /* @__PURE__ */ jsxRuntimeExports.jsxs(Label, { children: [ 1840 "Form Number ", 1841 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground text-xs", children: "(optional â auto-detected from PDF)" }) 1842 ] }), 1843 /* @__PURE__ */ jsxRuntimeExports.jsx( 1844 Input, 1845 { 1846 placeholder: "e.g. 27, 125, 126, 130, 140 â leave blank for non-ACORD forms", 1847 value: expectedForm, 1848 onChange: (e) => setExpectedForm(e.target.value) 1849 } 1850 ) 1851 ] }), 1852 /* @__PURE__ */ jsxRuntimeExports.jsxs( 1853 "div", 1854 { 1855 className: "border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-all", 1856 style: { 1857 borderColor: isDraggingOver2 ? "#0f2d5e" : file ? "#16a34a" : "#d1d5db", 1858 background: isDraggingOver2 ? "#eff6ff" : file ? "#f0fdf4" : "#fafafa", 1859 transform: isDraggingOver2 ? "scale(1.01)" : void 0 1860 }, 1861 onClick: () => fileInputRef.current?.click(), 1862 onDragOver: handleDragOver2, 1863 onDragEnter: handleDragOver2, 1864 onDragLeave: handleDragLeave2, 1865 onDrop: handleDrop2, 1866 children: [
1867 /* @__PURE__ */ jsxRuntimeExports.jsx(FileCheck, { size: 32, className: "mx-auto mb-2", style: { color: isDraggingOver2 ? "#0f2d5e" : file ? "#16a34a" : "#9ca3af" } }), 1868 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium", style: { color: isDraggingOver2 ? "#0f2d5e" : file ? "#15803d" : "#4b5563" }, children: isDraggingOver2 ? "Drop form here" : file ? file.name : "Drag & drop blank form here, or click to browse" }), 1869 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs mt-1", style: { color: isDraggingOver2 ? "#0f2d5e" : file ? "#16a34a" : "#9ca3af" }, children: file && !isDraggingOver2 ? "â File ready â click Upload below" : "PDF or .docx accepted · ACORD forms, carrier apps, or custom forms · Word docs auto-converted" }), 1870 /* @__PURE__ */ jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: ".pdf,.docx,.doc,application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document", className: "hidden", onChange: handleFileChange }) 1871 ] 1872 } 1873 ), 1874 file && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500", children: [
1875 /* @__PURE__ */ jsxRuntimeExports.jsx(FileCheck, { size: 13, className: "text-green-600" }), 1876 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-green-700 font-medium", children: file.name }), 1877 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setFile(null), className: "ml-auto text-gray-400 hover:text-red-500 text-xs underline", children: "Remove" }) 1878 ] }), 1879 /* @__PURE__ */ jsxRuntimeExports.jsx( 1880 Button, 1881 { 1882 onClick: handleUpload, 1883 disabled: loading || !file, 1884 className: "w-full font-semibold", 1885 style: { background: file ? "#1a2e4a" : void 0, color: file ? "white" : void 0 }, 1886 children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1887 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 16, className: "animate-spin mr-2" }), 1888 "Uploading formâ¦" 1889 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 1890 /* @__PURE__ */ jsxRuntimeExports.jsx(FileCheck, { size: 16, className: "mr-2" }), 1891 "Upload Blank Form & Continue" 1892 ] }) 1893 } 1894 ), 1895 !file && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-center text-gray-400", children: "Select a PDF above to enable upload" }) 1896 ] }); 1897} 1898function Step4MapFieldsSilent({ workflow, onMapped }) { 1899 const autoTriggered = reactExports.useRef(false); 1900 const mapMutation = trpc.acordWorkflows.mapFields.useMutation({ 1901 onSuccess: () => onMapped(), 1902 onError: (err) => { 1903 console.error("[MapFields silent] error:", err.message); 1904 onMapped(); 1905 } 1906 }); 1907 reactExports.useEffect(() => { 1908 if (autoTriggered.current) return; 1909 autoTriggered.current = true; 1910 if (workflow.mapping) { 1911 onMapped(); 1912 return; 1913 } 1914 mapMutation.mutate({ id: workflow.id }); 1915 }, [workflow.id]); 1916 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-4 py-10 text-center", children: [ 1917 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 32, className: "text-blue-600 animate-spin" }), 1918 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1919 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-gray-700", children: "Preparing your formâ¦" }), 1920 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 mt-1", children: "Matching extracted data to form fields. This takes about 15 seconds." }) 1921 ] }) 1922 ] }); 1923} 1924function Step5Preview({ workflow, onPreviewed, onGoBackToEdit }) { 1925 const [loading, setLoading] = reactExports.useState(false); 1926 const [generatingFinal, setGeneratingFinal] = reactExports.useState(false); 1927 const [hasPreview, setHasPreview] = reactExports.useState(workflow.hasPreview); 1928 const [previewKey, setPreviewKey] = reactExports.useState(Date.now()); 1929 const autoTriggered = reactExports.useRef(false); 1930 const originalFields = reactExports.useMemo(() => workflow.extractedData ?? {}, [workflow.id]); 1931 const [editedFields, setEditedFields] = reactExports.useState(originalFields); 1932 const [isSaving, setIsSaving] = reactExports.useState(false); 1933 const saveDraftMutation = trpc.acordWorkflows.saveDraftData.useMutation({ 1934 onSuccess: () => { 1935 toast.success("Changes saved!"); 1936 setIsSaving(false); 1937 }, 1938 onError: (err) => { 1939 toast.error(err.message); 1940 setIsSaving(false); 1941 } 1942 }); 1943 const mapFieldsMutation = trpc.acordWorkflows.mapFields.useMutation({ 1944 onError: (err) => toast.error("Re-mapping failed: " + err.message) 1945 }); 1946 const previewMutation = trpc.acordWorkflows.generatePreview.useMutation({ 1947 onSuccess: () => { 1948 setHasPreview(true); 1949 setPreviewKey(Date.now()); 1950 toast.success("Preview updated!"); 1951 setLoading(false); 1952 }, 1953 onError: (err) => { 1954 toast.error(err.message); 1955 setLoading(false); 1956 } 1957 }); 1958 const generateFinalMutation = trpc.acordWorkflows.generateCompleted.useMutation({ 1959 onSuccess: () => { 1960 toast.success("Final form generated!"); 1961 setGeneratingFinal(false); 1962 onPreviewed(); 1963 }, 1964 onError: (err) => { 1965 toast.error(err.message); 1966 setGeneratingFinal(false); 1967 } 1968 }); 1969 const reExtractMutation = trpc.acordWorkflows.reExtract.useMutation({ 1970 onSuccess: () => { 1971 toast.success("Data re-extracted! Refresh to see updated fields."); 1972 }, 1973 onError: (err) => toast.error(err.message) 1974 }); 1975 const handleSaveAndRefresh = async () => { 1976 setIsSaving(true); 1977 try { 1978 await saveDraftMutation.mutateAsync({ id: workflow.id, editedData: editedFields }); 1979 await mapFieldsMutation.mutateAsync({ id: workflow.id }); 1980 setLoading(true); 1981 previewMutation.mutate({ id: workflow.id }); 1982 } catch { 1983 setIsSaving(false); 1984 } 1985 }; 1986 const handleGenerateFinal = () => { 1987 setGeneratingFinal(true); 1988 generateFinalMutation.mutate({ id: workflow.id }); 1989 }; 1990 const handleGenerate = () => { 1991 setLoading(true); 1992 previewMutation.mutate({ id: workflow.id }); 1993 }; 1994 const iframeProxyUrl = `/api/acord-workflow-preview?id=${workflow.id}&type=preview&t=${previewKey}`; 1995 const fallbackUrl = workflow.previewPdfUrl ?? iframeProxyUrl; 1996 reactExports.useEffect(() => { 1997 if (autoTriggered.current) return; 1998 if (hasPreview) return; 1999 autoTriggered.current = true; 2000 setLoading(true); 2001 previewMutation.mutate({ id: workflow.id }); 2002 }, [workflow.id]); 2003 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: !hasPreview ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 2004 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-5 flex flex-col items-center gap-3 text-center", children: [
2005 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 28, className: "text-blue-600 animate-spin" }), 2006 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-blue-800", children: [ 2007 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold mb-1", children: "Generating Preview PDFâ¦" }), 2008 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Filling your ACORD form with the mapped data. This may take 15â30 seconds." }) 2009 ] }) 2010 ] }), 2011 !loading && /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: handleGenerate, disabled: loading, className: "w-full", style: { background: "var(--eps-navy-deep)", color: "white" }, children: [ 2012 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 16, className: "mr-2" }), 2013 "Retry Generate Preview PDF" 2014 ] }) 2015 ] }) : ( 2016 /* ââ Top/Bottom: PDF preview (top) + field editor (bottom) ââ */ 2017 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-4", children: [
2018 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [ 2019 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2020 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-semibold text-gray-700 flex items-center gap-1.5", children: [ 2021 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 14, className: "text-blue-600" }), 2022 " PDF Preview" 2023 ] }), 2024 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2025 loading && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-blue-600 flex items-center gap-1", children: [ 2026 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 11, className: "animate-spin" }), 2027 " Refreshingâ¦" 2028 ] }), 2029 /* @__PURE__ */ jsxRuntimeExports.jsxs("a", { href: fallbackUrl, target: "_blank", rel: "noopener noreferrer", className: "text-xs text-gray-400 hover:text-gray-600 flex items-center gap-1", children: [
2030 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 11, className: "rotate-[-45deg]" }), 2031 " Open in tab" 2032 ] }) 2033 ] }) 2034 ] }), 2035 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-gray-200 rounded-lg overflow-hidden bg-gray-50", style: { height: 700 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx( 2036 "iframe", 2037 { 2038 src: `${iframeProxyUrl}#toolbar=1&navpanes=0&scrollbar=1`, 2039 className: "w-full h-full", 2040 title: "ACORD Form Preview", 2041 style: { border: "none" } 2042 }, 2043 previewKey 2044 ) }) 2045 ] }), 2046 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx( 2047 AcordFieldEditor, 2048 { 2049 outputType: workflow.formNumber === "25" ? "acord_25" : workflow.formNumber === "140" ? "acord_140" : "acord_125", 2050 originalFields, 2051 editedFields, 2052 onChange: setEditedFields, 2053 onSave: () => { 2054 setIsSaving(true); 2055 saveDraftMutation.mutate({ id: workflow.id, editedData: editedFields }); 2056 }, 2057 onGeneratePdf: handleSaveAndRefresh, 2058 isSaving: isSaving || saveDraftMutation.isPending || mapFieldsMutation.isPending, 2059 isGenerating: loading || previewMutation.isPending, 2060 isExtracting: reExtractMutation.isPending, 2061 hasDocs: true 2062 } 2063 ) }),
2064 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 pt-1", children: [ 2065 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", className: "flex-1 text-gray-600 text-sm", onClick: onGoBackToEdit, children: [ 2066 /* @__PURE__ */ jsxRuntimeExports.jsx(PenLine, { size: 13, className: "mr-1.5" }), 2067 "Back to Edit" 2068 ] }), 2069 /* @__PURE__ */ jsxRuntimeExports.jsx( 2070 Button, 2071 { 2072 onClick: handleGenerateFinal, 2073 disabled: generatingFinal || loading, 2074 className: "flex-1 text-sm", 2075 style: { background: "var(--eps-navy-deep)", color: "white" }, 2076 children: generatingFinal ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2077 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 13, className: "animate-spin mr-1.5" }), 2078 "Generatingâ¦" 2079 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2080 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 13, className: "mr-1.5" }), 2081 "Generate Final" 2082 ] }) 2083 } 2084 ) 2085 ] }) 2086 ] }) 2087 ) }); 2088} 2089function Step6Generate({ workflow, onGenerated }) { 2090 const [loading, setLoading] = reactExports.useState(false); 2091 const previewIframeUrl = reactExports.useMemo(() => `/api/acord-workflow-preview?id=${workflow.id}&type=preview&t=${Date.now()}`, [workflow.id]); 2092 const generateMutation = trpc.acordWorkflows.generateCompleted.useMutation({ 2093 onSuccess: () => { 2094 toast.success("Completed form generated!"); 2095 onGenerated(); 2096 }, 2097 onError: (err) => { 2098 toast.error(err.message); 2099 setLoading(false); 2100 } 2101 }); 2102 const handleGenerate = () => { 2103 setLoading(true); 2104 generateMutation.mutate({ id: workflow.id }); 2105 }; 2106 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-5", children: [ 2107 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-green-50 border border-green-200 rounded-lg p-4 flex gap-3", children: [
2108 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 16, className: "text-green-600 flex-shrink-0 mt-0.5" }), 2109 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-green-800", children: [ 2110 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium mb-1", children: "Ready to generate the completed form" }), 2111 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [ 2112 "This creates the final review-ready draft. ", 2113 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "This is not a submission" }), 2114 " â review with your client before submitting to the carrier." 2115 ] }) 2116 ] }) 2117 ] }), 2118 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 rounded-lg p-4 space-y-2", children: [ 2119 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-700", children: "Form Summary" }), 2120 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm", children: [
2121 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: "Client:" }), 2122 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: workflow.clientName }), 2123 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: "Form:" }), 2124 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: workflow.formTitle ?? "â" }), 2125 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: "Line:" }), 2126 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: workflow.lineOfBusiness ?? "â" }), 2127 workflow.mappingSummary && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2128 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-500", children: "Fields filled:" }), 2129 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-green-600", children: workflow.mappingSummary.filled }) 2130 ] }) 2131 ] }) 2132 ] }), 2133 workflow.previewPdfUrl && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
2134 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-gray-700 flex items-center gap-1.5", children: [ 2135 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 14, className: "text-blue-600" }), 2136 " Preview â Review filled fields before generating" 2137 ] }), 2138 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-gray-200 rounded-lg overflow-hidden", style: { height: 520 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx( 2139 "iframe", 2140 { 2141 src: previewIframeUrl, 2142 className: "w-full h-full", 2143 title: "ACORD Form Preview" 2144 }, 2145 workflow.id 2146 ) }) 2147 ] }), 2148 /* @__PURE__ */ jsxRuntimeExports.jsx( 2149 Button, 2150 { 2151 onClick: handleGenerate, 2152 disabled: loading, 2153 className: "w-full", 2154 style: { background: "var(--eps-navy-deep)", color: "white" }, 2155 children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2156 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 16, className: "animate-spin mr-2" }), 2157 "Generatingâ¦" 2158 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2159 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 16, className: "mr-2" }), 2160 "Generate Completed Form" 2161 ] }) 2162 } 2163 ) 2164 ] }); 2165} 2166function Step7Download({ workflow, onCloned }) { 2167 const { data: downloadData } = trpc.acordWorkflows.getDownloadUrl.useQuery( 2168 { id: workflow.id }, 2169 { enabled: !!workflow.completedPdfUrl } 2170 ); 2171 const [showViewer, setShowViewer] = reactExports.useState(false); 2172 const pdfUrl = downloadData?.url ?? workflow.completedPdfUrl ?? null; 2173 const iframeProxyUrl = reactExports.useMemo(() => `/api/acord-workflow-preview?id=${workflow.id}&type=completed&t=${Date.now()}`, [workflow.id]); 2174 const [showCloneDialog, setShowCloneDialog] = reactExports.useState(false); 2175 const [cloneClientName, setCloneClientName] = reactExports.useState(""); 2176 const cloneMutation = trpc.acordWorkflows.cloneWorkflow.useMutation({ 2177 onSuccess: (data) => { 2178 toast.success(`Renewal workflow created for ${data.clientName ?? "client"}`); 2179 setShowCloneDialog(false); 2180 setCloneClientName(""); 2181 if (onCloned) onCloned(data.id); 2182 }, 2183 onError: (err) => toast.error(err.message) 2184 }); 2185 const [showAdditionalForms, setShowAdditionalForms] = reactExports.useState(false); 2186 const [selectedFormIds, setSelectedFormIds] = reactExports.useState([]); 2187 const [generatedForms, setGeneratedForms] = reactExports.useState([]); 2188 const [failedForms, setFailedForms] = reactExports.useState([]); 2189 const [parallelPreview, setParallelPreview] = reactExports.useState(null); 2190 const [flagNoteInput, setFlagNoteInput] = reactExports.useState(""); 2191 const [showFlagNote, setShowFlagNote] = reactExports.useState(false); 2192 const flagForm = (formNumber, note) => { 2193 setGeneratedForms((prev) => prev.map( 2194 (f) => f.formNumber === formNumber ? { ...f, flagged: true, reviewNote: note } : f 2195 )); 2196 setParallelPreview((prev) => prev && prev.formNumber === formNumber ? { ...prev } : prev); 2197 setShowFlagNote(false); 2198 setFlagNoteInput(""); 2199 toast.success(`ACORD ${formNumber} flagged for review`); 2200 }; 2201 const unflagForm = (formNumber) => { 2202 setGeneratedForms((prev) => prev.map( 2203 (f) => f.formNumber === formNumber ? { ...f, flagged: false, reviewNote: void 0 } : f 2204 )); 2205 toast(`ACORD ${formNumber} flag removed`); 2206 }; 2207 const { data: libraryForms, isLoading: libraryLoading } = trpc.acordWorkflows.listFormLibrary.useQuery( 2208 void 0, 2209 { enabled: showAdditionalForms } 2210 ); 2211 const generateAdditionalMutation = trpc.acordWorkflows.generateAdditionalForms.useMutation({ 2212 onSuccess: (data) => { 2213 setGeneratedForms((prev) => [...prev, ...data.succeeded]); 2214 setFailedForms((prev) => [...prev, ...data.failed]); 2215 setSelectedFormIds([]); 2216 if (data.succeeded.length > 0) toast.success(`Generated ${data.succeeded.length} additional form${data.succeeded.length !== 1 ? "s" : ""}`); 2217 if (data.failed.length > 0) toast.error(`${data.failed.length} form${data.failed.length !== 1 ? "s" : ""} failed to generate`); 2218 }, 2219 onError: (err) => toast.error(err.message) 2220 }); 2221 const toggleFormSelection = (id) => { 2222 setSelectedFormIds((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]); 2223 }; 2224 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 2225 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-green-50 border border-green-200 rounded-lg p-5 text-center", children: [
2226 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 40, className: "mx-auto text-green-500 mb-2" }), 2227 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-green-800 mb-1", children: "ACORD Form Completed!" }), 2228 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-green-700", children: [ 2229 "Your completed ", 2230 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: workflow.formTitle ?? "ACORD form" }), 2231 " for ", 2232 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: workflow.clientName }), 2233 " is ready." 2234 ] }) 2235 ] }), 2236 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 border border-amber-200 rounded-lg p-3 flex gap-2", children: [ 2237 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 14, className: "text-amber-600 flex-shrink-0 mt-0.5" }), 2238 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-amber-800", children: [ 2239 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Review-ready draft only." }), 2240 " Please review all fields with your client before submitting to the carrier." 2241 ] }) 2242 ] }), 2243 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 2244 pdfUrl && /* @__PURE__ */ jsxRuntimeExports.jsxs( 2245 Button, 2246 { 2247 variant: "outline", 2248 className: "flex-1 gap-1.5", 2249 onClick: () => setShowViewer((v) => !v), 2250 children: [
2251 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 14 }), 2252 showViewer ? "Hide Preview" : "View PDF" 2253 ] 2254 } 2255 ), 2256 downloadData && /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: downloadData.url, download: downloadData.fileName, target: "_blank", rel: "noopener noreferrer", className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { className: "w-full gap-1.5", style: { background: "var(--eps-navy-deep)", color: "white" }, children: [ 2257 /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { size: 14 }), 2258 "Download PDF" 2259 ] }) }), 2260 workflow.completedPdfUrl && /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: workflow.completedPdfUrl, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", title: "Open in new tab", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 14 }) }) }) 2261 ] }), 2262 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
2263 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2264 Button, 2265 { 2266 variant: "outline", 2267 size: "sm", 2268 className: "flex-1 gap-1.5 text-blue-700 border-blue-200 hover:bg-blue-50", 2269 onClick: () => setShowCloneDialog(true), 2270 children: [ 2271 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 13 }), 2272 "Start Renewal" 2273 ] 2274 } 2275 ), 2276 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2277 Button, 2278 { 2279 variant: "outline", 2280 size: "sm", 2281 className: "flex-1 gap-1.5 text-purple-700 border-purple-200 hover:bg-purple-50", 2282 onClick: () => setShowAdditionalForms((v) => !v), 2283 children: [ 2284 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { size: 13 }), 2285 showAdditionalForms ? "Hide" : "Generate Additional Forms" 2286 ] 2287 } 2288 ) 2289 ] }), 2290 showViewer && pdfUrl && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 rounded-lg overflow-hidden", children: [
2291 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 border-b border-gray-200 px-3 py-2 flex items-center justify-between", children: [ 2292 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-gray-600", children: downloadData?.fileName ?? "Completed ACORD Form" }), 2293 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShowViewer(false), className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 14 }) }) 2294 ] }), 2295 /* @__PURE__ */ jsxRuntimeExports.jsx( 2296 "iframe", 2297 { 2298 src: `${iframeProxyUrl}#toolbar=1&navpanes=0`, 2299 className: "w-full", 2300 style: { height: "600px" }, 2301 title: "Completed ACORD Form" 2302 } 2303 ) 2304 ] }), 2305 showAdditionalForms && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-purple-200 rounded-lg bg-purple-50 p-4 space-y-3", children: [ 2306 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
2307 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2308 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-purple-900", children: "Generate Additional Forms" }), 2309 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-purple-700 mt-0.5", children: "Select forms from the library to fill with this workflow's extracted data" }) 2310 ] }), 2311 selectedFormIds.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { className: "bg-purple-600 text-white text-xs", children: [ 2312 selectedFormIds.length, 2313 " selected" 2314 ] }) 2315 ] }), 2316 libraryLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-4 justify-center text-purple-600", children: [ 2317 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 16, className: "animate-spin" }), 2318 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "Loading libraryâ¦" }) 2319 ] }) : !libraryForms || libraryForms.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-purple-700 text-center py-4", children: "No forms in library. Ask an admin to upload blank ACORD forms." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1.5 max-h-48 overflow-y-auto", children: libraryForms.map((form) => /* @__PURE__ */ jsxRuntimeExports.jsxs( 2320 "label", 2321 { 2322 className: `flex items-center gap-3 px-3 py-2 rounded-lg cursor-pointer transition-colors ${selectedFormIds.includes(form.id) ? "bg-purple-100 border border-purple-300" : "bg-white border border-gray-200 hover:border-purple-200"}`, 2323 children: [
2324 /* @__PURE__ */ jsxRuntimeExports.jsx( 2325 "input", 2326 { 2327 type: "checkbox", 2328 checked: selectedFormIds.includes(form.id), 2329 onChange: () => toggleFormSelection(form.id), 2330 className: "accent-purple-600" 2331 } 2332 ), 2333 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 2334 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-gray-800 truncate", children: [ 2335 "ACORD ", 2336 form.formNumber 2337 ] }), 2338 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 truncate", children: form.formTitle }) 2339 ] }), 2340 (form.fieldCount ?? 0) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-400 flex-shrink-0", children: [ 2341 form.fieldCount, 2342 " fields" 2343 ] }) 2344 ] 2345 }, 2346 form.id 2347 )) }),
2348 /* @__PURE__ */ jsxRuntimeExports.jsx( 2349 Button, 2350 { 2351 className: "w-full gap-1.5", 2352 style: { background: "var(--eps-navy-deep)", color: "white" }, 2353 disabled: selectedFormIds.length === 0 || generateAdditionalMutation.isPending, 2354 onClick: () => generateAdditionalMutation.mutate({ id: workflow.id, formLibraryIds: selectedFormIds }), 2355 children: generateAdditionalMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2356 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin" }), 2357 "Generating ", 2358 selectedFormIds.length, 2359 " form", 2360 selectedFormIds.length !== 1 ? "s" : "", 2361 "â¦" 2362 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2363 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { size: 14 }), 2364 "Generate ", 2365 selectedFormIds.length > 0 ? `${selectedFormIds.length} Selected Form${selectedFormIds.length !== 1 ? "s" : ""}` : "Selected Forms" 2366 ] }) 2367 } 2368 ), 2369 generatedForms.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-1", children: [
2370 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-purple-900", children: "â Ready to Download" }), 2371 generatedForms.map((f, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs( 2372 "div", 2373 { 2374 className: `flex flex-col gap-1 px-3 py-2 rounded-lg border ${f.flagged ? "bg-red-50 border-red-300" : "bg-white border-green-200"}`, 2375 children: [ 2376 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2377 f.flagged ? /* @__PURE__ */ jsxRuntimeExports.jsx(Flag, { size: 13, className: "text-red-500 flex-shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { size: 13, className: "text-green-600 flex-shrink-0" }), 2378 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 2379 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [ 2380 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-gray-800", children: [ 2381 "ACORD ", 2382 f.formNumber 2383 ] }),
2384 f.flagged && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-semibold text-red-600 bg-red-100 px-1.5 py-0.5 rounded", children: "â Needs Review" }) 2385 ] }), 2386 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 truncate", children: f.formTitle }) 2387 ] }), 2388 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [ 2389 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2390 "button", 2391 { 2392 onClick: () => setParallelPreview({ url: f.url, fileName: f.fileName, formNumber: f.formNumber }), 2393 className: "flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 px-2 py-1 rounded border border-blue-200 hover:border-blue-400 bg-blue-50 hover:bg-blue-100 transition-colors", 2394 title: "Preview filled PDF", 2395 children: [
2396 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 11 }), 2397 "Preview" 2398 ] 2399 } 2400 ), 2401 f.flagged ? /* @__PURE__ */ jsxRuntimeExports.jsxs( 2402 "button", 2403 { 2404 onClick: () => unflagForm(f.formNumber), 2405 className: "flex items-center gap-1 text-xs text-red-600 hover:text-red-800 px-2 py-1 rounded border border-red-200 hover:border-red-400 bg-red-50 hover:bg-red-100 transition-colors", 2406 title: "Remove flag", 2407 children: [ 2408 /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 11 }), 2409 "Unflag" 2410 ] 2411 } 2412 ) : /* @__PURE__ */ jsxRuntimeExports.jsxs( 2413 "a", 2414 { 2415 href: f.url, 2416 download: f.fileName, 2417 target: "_blank", 2418 rel: "noopener noreferrer", 2419 className: "flex items-center gap-1 text-xs text-green-600 hover:text-green-800 px-2 py-1 rounded border border-green-200 hover:border-green-400 bg-green-50 hover:bg-green-100 transition-colors", 2420 children: [
2421 /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { size: 11 }), 2422 "Download" 2423 ] 2424 } 2425 ) 2426 ] }) 2427 ] }), 2428 f.flagged && f.reviewNote && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-red-700 pl-5 italic", children: [ 2429 "â", 2430 f.reviewNote, 2431 "â" 2432 ] }) 2433 ] 2434 }, 2435 i 2436 )) 2437 ] }), 2438 failedForms.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1 pt-1", children: [ 2439 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-red-700", children: "Failed to Generate" }), 2440 failedForms.map((f, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 bg-red-50 border border-red-200 rounded-lg", children: [ 2441 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 13, className: "text-red-500 flex-shrink-0" }),
2442 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 2443 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm font-medium text-red-800", children: [ 2444 "ACORD ", 2445 f.formNumber 2446 ] }), 2447 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-600 truncate", children: f.error }) 2448 ] }) 2449 ] }, i)) 2450 ] }) 2451 ] }), 2452 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showCloneDialog, onOpenChange: (open) => !open && setShowCloneDialog(false), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [ 2453 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 2454 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Start Renewal Workflow" }), 2455 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "This will create a new workflow pre-populated with all extracted data from this workflow, marked as a renewal. You can then upload new documents to update any changed information." }) 2456 ] }),
2457 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-3 space-y-3", children: [ 2458 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2459 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Client Name for Renewal" }), 2460 /* @__PURE__ */ jsxRuntimeExports.jsx( 2461 Input, 2462 { 2463 className: "mt-1.5", 2464 placeholder: workflow.clientName ?? "Client name", 2465 value: cloneClientName, 2466 onChange: (e) => setCloneClientName(e.target.value) 2467 } 2468 ), 2469 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-1", children: "Leave blank to keep the same client name" }) 2470 ] }), 2471 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-blue-800", children: [ 2472 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "What gets copied:" }), 2473 " All extracted data, field confidence scores, line of business, and standard answer preferences. The new workflow starts at Step 1 so you can upload updated renewal documents." 2474 ] }) }) 2475 ] }),
2476 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 2477 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setShowCloneDialog(false), children: "Cancel" }), 2478 /* @__PURE__ */ jsxRuntimeExports.jsx( 2479 Button, 2480 { 2481 onClick: () => cloneMutation.mutate({ id: workflow.id, newClientName: cloneClientName || void 0 }), 2482 disabled: cloneMutation.isPending, 2483 style: { background: "var(--eps-navy-deep)", color: "white" }, 2484 children: cloneMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2485 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin mr-1" }), 2486 "Creatingâ¦" 2487 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2488 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 14, className: "mr-1" }), 2489 "Start Renewal" 2490 ] }) 2491 } 2492 ) 2493 ] }) 2494 ] }) }), 2495 parallelPreview && (() => { 2496 const previewForm = generatedForms.find((f) => f.formNumber === parallelPreview.formNumber); 2497 const isFlagged = previewForm?.flagged ?? false; 2498 return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: !!parallelPreview, onOpenChange: (open) => { 2499 if (!open) { 2500 setParallelPreview(null); 2501 setShowFlagNote(false); 2502 setFlagNoteInput(""); 2503 } 2504 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "max-w-5xl w-full h-[90vh] flex flex-col p-0 gap-0", children: [
2505 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { className: `px-4 py-3 border-b flex-shrink-0 ${isFlagged ? "border-red-300 bg-red-50" : "border-gray-200"}`, children: [ 2506 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 2507 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2508 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2509 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { className: "text-base", children: [ 2510 "ACORD ", 2511 parallelPreview.formNumber, 2512 " â Preview" 2513 ] }), 2514 isFlagged && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-semibold text-red-600 bg-red-100 px-1.5 py-0.5 rounded flex items-center gap-1", children: [ 2515 /* @__PURE__ */ jsxRuntimeExports.jsx(Flag, { size: 10 }), 2516 "â Flagged for Review" 2517 ] }) 2518 ] }),
2519 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: parallelPreview.fileName }), 2520 isFlagged && previewForm?.reviewNote && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-red-700 mt-1 italic", children: [ 2521 "â", 2522 previewForm.reviewNote, 2523 "â" 2524 ] }) 2525 ] }), 2526 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2527 isFlagged ? /* @__PURE__ */ jsxRuntimeExports.jsxs( 2528 Button, 2529 { 2530 size: "sm", 2531 variant: "outline", 2532 className: "gap-1.5 text-red-600 border-red-300 hover:bg-red-50", 2533 onClick: () => unflagForm(parallelPreview.formNumber), 2534 children: [ 2535 /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 12 }), 2536 "Remove Flag" 2537 ] 2538 } 2539 ) : /* @__PURE__ */ jsxRuntimeExports.jsxs( 2540 Button, 2541 { 2542 size: "sm", 2543 variant: "outline", 2544 className: "gap-1.5 text-orange-600 border-orange-300 hover:bg-orange-50", 2545 onClick: () => setShowFlagNote((v) => !v), 2546 children: [
2547 /* @__PURE__ */ jsxRuntimeExports.jsx(Flag, { size: 12 }), 2548 "Flag for Review" 2549 ] 2550 } 2551 ), 2552 /* @__PURE__ */ jsxRuntimeExports.jsx( 2553 "a", 2554 { 2555 href: parallelPreview.url, 2556 download: parallelPreview.fileName, 2557 target: "_blank", 2558 rel: "noopener noreferrer", 2559 children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { size: "sm", className: "gap-1.5", style: { background: "var(--eps-navy-deep)", color: "white" }, children: [ 2560 /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { size: 13 }), 2561 "Download" 2562 ] }) 2563 } 2564 ), 2565 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", variant: "ghost", onClick: () => { 2566 setParallelPreview(null); 2567 setShowFlagNote(false); 2568 setFlagNoteInput(""); 2569 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 15 }) }) 2570 ] }) 2571 ] }),
2572 showFlagNote && !isFlagged && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex gap-2 items-start", children: [ 2573 /* @__PURE__ */ jsxRuntimeExports.jsx( 2574 "input", 2575 { 2576 autoFocus: true, 2577 type: "text", 2578 placeholder: "Optional: describe what needs correctionâ¦", 2579 value: flagNoteInput, 2580 onChange: (e) => setFlagNoteInput(e.target.value), 2581 onKeyDown: (e) => { 2582 if (e.key === "Enter") flagForm(parallelPreview.formNumber, flagNoteInput); 2583 if (e.key === "Escape") { 2584 setShowFlagNote(false); 2585 setFlagNoteInput(""); 2586 } 2587 }, 2588 className: "flex-1 text-sm border border-orange-300 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-orange-400" 2589 } 2590 ), 2591 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2592 Button, 2593 { 2594 size: "sm", 2595 className: "gap-1 bg-orange-500 hover:bg-orange-600 text-white flex-shrink-0", 2596 onClick: () => flagForm(parallelPreview.formNumber, flagNoteInput), 2597 children: [
2598 /* @__PURE__ */ jsxRuntimeExports.jsx(Flag, { size: 11 }), 2599 "Confirm Flag" 2600 ] 2601 } 2602 ), 2603 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", variant: "ghost", className: "flex-shrink-0", onClick: () => { 2604 setShowFlagNote(false); 2605 setFlagNoteInput(""); 2606 }, children: "Cancel" }) 2607 ] }) 2608 ] }), 2609 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 bg-gray-100", children: /* @__PURE__ */ jsxRuntimeExports.jsx( 2610 "iframe", 2611 { 2612 src: `${parallelPreview.url}#toolbar=1&navpanes=0&scrollbar=1`, 2613 className: "w-full h-full border-0", 2614 title: `ACORD ${parallelPreview.formNumber} Preview` 2615 } 2616 ) }), 2617 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `px-4 py-2 border-t flex-shrink-0 ${isFlagged ? "border-red-200 bg-red-50" : "border-gray-200 bg-gray-50"}`, children: isFlagged ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-red-700", children: [
2618 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "â Flagged for manual review." }), 2619 " This form will not be included in the final submission until the flag is cleared." 2620 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-amber-700", children: [ 2621 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Review-ready draft only." }), 2622 " Verify all fields with your client before submitting to the carrier." 2623 ] }) }) 2624 ] }) }); 2625 })() 2626 ] }); 2627} 2628function WorkflowView({ workflowId, onBack, isAdmin }) { 2629 const utils = trpc.useUtils(); 2630 const { data: workflow, isLoading, refetch } = trpc.acordWorkflows.get.useQuery({ id: workflowId }); 2631 const [backToStep2, setBackToStep2] = reactExports.useState(false); 2632 const [showUnsavedDialog, setShowUnsavedDialog] = reactExports.useState(false); 2633 const pendingBackRef = reactExports.useRef(null); 2634 const [step2IsDirty, setStep2IsDirty] = reactExports.useState(false); 2635 const step2ConfirmRef = reactExports.useRef(null); 2636 const [confirmState, setConfirmState] = reactExports.useState({ fieldCount: 0, loading: false }); 2637 const [showResetDialog, setShowResetDialog] = reactExports.useState(false);
2638 const [resetTargetStep, setResetTargetStep] = reactExports.useState("1"); 2639 const setStepMutation = trpc.acordWorkflows.setStep.useMutation({ 2640 onSuccess: () => { 2641 setBackToStep2(false); 2642 refetch(); 2643 }, 2644 onError: (err) => toast.error(err.message) 2645 }); 2646 const resetStepMutation = trpc.acordWorkflows.setStep.useMutation({ 2647 onSuccess: () => { 2648 setShowResetDialog(false); 2649 toast.success(`Workflow reset to Step ${resetTargetStep}`); 2650 refetch(); 2651 }, 2652 onError: (err) => toast.error(err.message) 2653 }); 2654 const handleStepComplete = () => { 2655 setBackToStep2(false); 2656 refetch(); 2657 }; 2658 const handleRequestBack = (isDirty) => { 2659 setStep2IsDirty(isDirty); 2660 if (isDirty) { 2661 pendingBackRef.current = onBack; 2662 setShowUnsavedDialog(true); 2663 } else { 2664 onBack(); 2665 } 2666 }; 2667 if (isLoading) { 2668 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 24, className: "animate-spin text-gray-400" }) }); 2669 } 2670 if (!workflow) { 2671 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center py-16 text-gray-500", children: "Workflow not found" }); 2672 } 2673 const wf = workflow; 2674 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 2675 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
2676 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2677 Button, 2678 { 2679 variant: "ghost", 2680 size: "sm", 2681 onClick: () => { 2682 const isStep3Active = wf.step === 3 || backToStep2; 2683 if (isStep3Active) { 2684 handleRequestBack(step2IsDirty); 2685 } else { 2686 onBack(); 2687 } 2688 }, 2689 className: "text-gray-500", 2690 children: [ 2691 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { size: 14, className: "mr-1" }), 2692 "Back" 2693 ] 2694 } 2695 ), 2696 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2697 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold", children: wf.clientName }), 2698 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500", children: [ 2699 wf.lineOfBusiness, 2700 " · ", 2701 wf.formTitle ?? "Form TBD" 2702 ] }) 2703 ] }), 2704 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
2705 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-xs", children: wf.status.replace(/_/g, " ") }), 2706 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsxs( 2707 Button, 2708 { 2709 variant: "outline", 2710 size: "sm", 2711 className: "text-xs border-amber-300 text-amber-700 hover:bg-amber-50", 2712 onClick: () => setShowResetDialog(true), 2713 children: [ 2714 /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { size: 12, className: "mr-1" }), 2715 "Reset Step" 2716 ] 2717 } 2718 ) 2719 ] }) 2720 ] }), 2721 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showResetDialog, onOpenChange: setShowResetDialog, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [ 2722 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 2723 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Reset Workflow Step" }), 2724 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogDescription, { children: [ 2725 "Move ",
2726 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: wf.clientName }), 2727 " back to a specific step. This is useful when a step got stuck or needs to be re-done. Step-specific data (e.g. uploaded form, mapping) will be preserved but the workflow will re-enter that step." 2728 ] }) 2729 ] }), 2730 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-2", children: [ 2731 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium mb-2 block", children: "Target Step" }), 2732 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: resetTargetStep, onValueChange: setResetTargetStep, children: [ 2733 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select step" }) }), 2734 /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [ 2735 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "1", children: "Step 1 â Upload Source Documents" }),
2736 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "2", children: "Step 2 â Upload Blank Form" }), 2737 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "3", children: "Step 3 â Review & Complete Data" }), 2738 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "4", children: "Step 4 â Map Fields" }), 2739 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "5", children: "Step 5 â Preview PDF" }), 2740 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "6", children: "Step 6 â Generate Final PDF" }), 2741 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: "7", children: "Step 7 â Download Completed Form" }) 2742 ] }) 2743 ] }) 2744 ] }), 2745 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 2746 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setShowResetDialog(false), children: "Cancel" }), 2747 /* @__PURE__ */ jsxRuntimeExports.jsx( 2748 Button, 2749 { 2750 variant: "destructive", 2751 disabled: resetStepMutation.isPending, 2752 onClick: () => resetStepMutation.mutate({ id: workflowId, step: parseInt(resetTargetStep) }),
2753 children: resetStepMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2754 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin mr-1" }), 2755 "Resettingâ¦" 2756 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2757 "Reset to Step ", 2758 resetTargetStep 2759 ] }) 2760 } 2761 ) 2762 ] }) 2763 ] }) }), 2764 /* @__PURE__ */ jsxRuntimeExports.jsx(StepIndicator, { currentStep: wf.step }), 2765 wf.policySummary && wf.step >= 2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg border border-blue-200 bg-blue-50 p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [ 2766 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0 mt-0.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "text-blue-600", children: [
2767 /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }), 2768 /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 16v-4M12 8h.01" }) 2769 ] }) }), 2770 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 2771 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-blue-800 mb-1.5", children: "AI Document Summary" }), 2772 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-blue-900 whitespace-pre-wrap leading-relaxed", children: wf.policySummary }) 2773 ] }) 2774 ] }) }), 2775 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ 2776 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-base", children: [ 2777 "Step ", 2778 serverStepToVisible(wf.step), 2779 ": ", 2780 VISIBLE_STEP_LABELS[serverStepToVisible(wf.step) - 1] 2781 ] }) }), 2782 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [ 2783 wf.step === 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(Step1Upload, { onCreated: (id) => { 2784 utils.acordWorkflows.list.invalidate(); 2785 refetch(); 2786 } }), 2787 wf.step === 2 && !backToStep2 && /* @__PURE__ */ jsxRuntimeExports.jsx(Step2BlankFormUpload, { workflow: wf, onUploaded: handleStepComplete }),
2788 (wf.step === 3 || backToStep2) && /* @__PURE__ */ jsxRuntimeExports.jsx( 2789 Step3ReviewAndQA, 2790 { 2791 workflow: wf, 2792 onRequestBack: handleRequestBack, 2793 confirmTriggerRef: step2ConfirmRef, 2794 onConfirmStateChange: setConfirmState, 2795 onConfirmed: () => { 2796 if (backToStep2) { 2797 setStepMutation.mutate({ id: wf.id, step: 4 }); 2798 } else { 2799 handleStepComplete(); 2800 } 2801 } 2802 }, 2803 `step3-${wf.id}` 2804 ), 2805 showUnsavedDialog && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white rounded-xl shadow-xl p-6 max-w-sm w-full mx-4 space-y-4", children: [ 2806 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ 2807 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { size: 20, className: "text-amber-500 flex-shrink-0 mt-0.5" }),
2808 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2809 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-900", children: "Unsaved Changes" }), 2810 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 mt-1", children: "You have unsaved edits to the extracted data. If you leave now, your changes will be lost." }) 2811 ] }) 2812 ] }), 2813 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 justify-end", children: [ 2814 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", onClick: () => setShowUnsavedDialog(false), children: "Stay & Save" }), 2815 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", variant: "destructive", onClick: () => { 2816 setShowUnsavedDialog(false); 2817 pendingBackRef.current?.(); 2818 }, children: "Leave Without Saving" }) 2819 ] }) 2820 ] }) }), 2821 wf.step === 4 && !backToStep2 && /* @__PURE__ */ jsxRuntimeExports.jsx( 2822 Step4MapFieldsSilent, 2823 { 2824 workflow: wf, 2825 onMapped: () => setStepMutation.mutate({ id: wf.id, step: 5 }) 2826 } 2827 ), 2828 wf.step === 5 && !backToStep2 && /* @__PURE__ */ jsxRuntimeExports.jsx( 2829 Step5Preview, 2830 { 2831 workflow: wf, 2832 onPreviewed: () => setStepMutation.mutate({ id: wf.id, step: 6 }), 2833 onGoBackToEdit: () => setBackToStep2(true) 2834 } 2835 ), 2836 wf.step === 6 && !backToStep2 && /* @__PURE__ */ jsxRuntimeExports.jsx(Step6Generate, { workflow: wf, onGenerated: handleStepComplete }), 2837 wf.step === 7 && !backToStep2 && /* @__PURE__ */ jsxRuntimeExports.jsx(Step7Download, { workflow: wf, onCloned: (newId) => { 2838 onBack(); 2839 setTimeout(() => { 2840 }, 100); 2841 } }) 2842 ] }) 2843 ] }),
2844 (wf.step === 3 || backToStep2) && /* @__PURE__ */ jsxRuntimeExports.jsx( 2845 "button", 2846 { 2847 onClick: () => step2ConfirmRef.current?.confirm(), 2848 disabled: confirmState.loading, 2849 style: { 2850 width: "100%", 2851 padding: "16px 24px", 2852 backgroundColor: confirmState.loading ? "#6b7280" : "#1a2e4a", 2853 color: "#ffffff", 2854 border: "none", 2855 borderRadius: "8px", 2856 fontSize: "16px", 2857 fontWeight: "600", 2858 cursor: confirmState.loading ? "not-allowed" : "pointer", 2859 display: "flex", 2860 alignItems: "center", 2861 justifyContent: "center", 2862 gap: "8px", 2863 boxShadow: "0 2px 8px rgba(0,0,0,0.3)", 2864 marginTop: "8px" 2865 }, 2866 children: confirmState.loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 2867 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 18, className: "animate-spin", style: { color: "#ffffff" } }), 2868 "Confirmingâ¦" 2869 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
2870 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 18, style: { color: "#ffffff" } }), 2871 confirmState.fieldCount > 0 ? `Confirm ${confirmState.fieldCount} Fields & Continue to Step 4` : "Continue to Upload ACORD Form" 2872 ] }) 2873 } 2874 ) 2875 ] }); 2876} 2877function AcordAgentChat({ agentName }) { 2878 const chatMutation = trpc.acordWorkflows.chatAssist.useMutation(); 2879 const [prefillMessage, setPrefillMessage] = reactExports.useState(void 0); 2880 reactExports.useEffect(() => { 2881 const handler = (e) => { 2882 const detail = e.detail; 2883 if (detail?.message) setPrefillMessage(detail.message); 2884 }; 2885 window.addEventListener("acord-chat-prefill", handler); 2886 return () => window.removeEventListener("acord-chat-prefill", handler); 2887 }, []); 2888 const handleSend = async (message, history) => { 2889 const result = await chatMutation.mutateAsync({ 2890 message, 2891 history: history.map((m) => ({ role: m.role, content: m.content })), 2892 producerName: agentName ?? "Unknown" 2893 }); 2894 return result.reply; 2895 }; 2896 return /* @__PURE__ */ jsxRuntimeExports.jsx( 2897 AgentChat, 2898 { 2899 title: "ACORD Forms Assistant", 2900 greeting: `Hi ${agentName ?? "there"}! I can help with ACORD form fields, NAICS/SIC/GL codes, business info lookups, and best practices. What do you need help with?`, 2901 quickPrompts: [ 2902 "What fields are required on ACORD 125?", 2903 "Look up NAICS and SIC codes for a restaurant", 2904 "What GL class code applies to a roofing contractor?",
2905 "What information do I need for a workers comp application?" 2906 ], 2907 prefillMessage, 2908 onPrefillConsumed: () => setPrefillMessage(void 0), 2909 onSend: handleSend, 2910 isPending: chatMutation.isPending 2911 } 2912 ); 2913} 2914function FormLibraryManager() { 2915 const utils = trpc.useUtils(); 2916 const { data: libraryForms, isLoading } = trpc.acordWorkflows.listFormLibrary.useQuery(); 2917 const [deleteLibId, setDeleteLibId] = reactExports.useState(null); 2918 const [replaceId, setReplaceId] = reactExports.useState(null); 2919 const [replaceFile, setReplaceFile] = reactExports.useState(null); 2920 const deleteMut = trpc.acordWorkflows.deleteFormLibraryEntry.useMutation({ 2921 onSuccess: (data) => { 2922 toast.success(`Deleted: ${data.formTitle}`); 2923 setDeleteLibId(null); 2924 utils.acordWorkflows.listFormLibrary.invalidate(); 2925 }, 2926 onError: (err) => toast.error(err.message) 2927 }); 2928 const replaceMut = trpc.acordWorkflows.replaceFormLibraryEntry.useMutation({ 2929 onSuccess: (data) => { 2930 toast.success(`Updated: ${data.formTitle} (${data.fieldCount} fields)`); 2931 setReplaceId(null); 2932 setReplaceFile(null); 2933 utils.acordWorkflows.listFormLibrary.invalidate(); 2934 }, 2935 onError: (err) => toast.error(err.message) 2936 }); 2937 const handleReplace = async () => { 2938 if (!replaceId || !replaceFile) return; 2939 const reader = new FileReader(); 2940 reader.onload = (e) => { 2941 const base64 = (e.target?.result).split(",")[1]; 2942 let replaceMimeType = replaceFile.type; 2943 if (!replaceMimeType) { 2944 const lower = replaceFile.name.toLowerCase(); 2945 if (lower.endsWith(".docx")) replaceMimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; 2946 else if (lower.endsWith(".doc")) replaceMimeType = "application/msword"; 2947 else replaceMimeType = "application/pdf"; 2948 } 2949 replaceMut.mutate({ id: replaceId, fileName: replaceFile.name, base64, mimeType: replaceMimeType }); 2950 }; 2951 reader.readAsDataURL(replaceFile); 2952 }; 2953 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 2954 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
2955 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2956 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-base font-semibold", style: { color: "var(--eps-navy-deep)" }, children: "ð ACORD Form Library" }), 2957 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Blank forms saved here are auto-selected for new workflows. Admins can delete or replace any entry." }) 2958 ] }), 2959 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: "text-xs", children: [ 2960 libraryForms?.length ?? 0, 2961 " form", 2962 libraryForms?.length !== 1 ? "s" : "" 2963 ] }) 2964 ] }), 2965 isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 py-8 justify-center text-gray-400", children: [ 2966 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 18, className: "animate-spin" }), 2967 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: "Loading libraryâ¦" }) 2968 ] }) : !libraryForms || libraryForms.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12 border-2 border-dashed border-gray-200 rounded-xl", children: [
2969 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 36, className: "mx-auto text-gray-300 mb-3" }), 2970 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 font-medium", children: "No forms in library yet" }), 2971 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-400 mt-1", children: "Forms are automatically saved here when uploaded during a workflow" }) 2972 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-gray-200 rounded-xl overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-sm", children: [ 2973 /* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "bg-gray-50 border-b border-gray-200", children: [ 2974 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-4 py-2.5 font-semibold text-gray-600 text-xs uppercase tracking-wide", children: "Form" }), 2975 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-4 py-2.5 font-semibold text-gray-600 text-xs uppercase tracking-wide hidden sm:table-cell", children: "Fields" }),
2976 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-4 py-2.5 font-semibold text-gray-600 text-xs uppercase tracking-wide hidden md:table-cell", children: "Uploaded By" }), 2977 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "text-left px-4 py-2.5 font-semibold text-gray-600 text-xs uppercase tracking-wide hidden md:table-cell", children: "Date" }), 2978 /* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-4 py-2.5" }) 2979 ] }) }), 2980 /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { className: "divide-y divide-gray-100", children: libraryForms.map((f) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "hover:bg-gray-50", children: [ 2981 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ 2982 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-7 h-7 rounded-md bg-blue-50 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(FileCheck, { size: 14, className: "text-blue-600" }) }),
2983 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 2984 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-gray-800", children: f.formTitle }), 2985 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-400", children: [ 2986 "ACORD ", 2987 f.formNumber 2988 ] }) 2989 ] }) 2990 ] }) }), 2991 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-3 text-gray-500 hidden sm:table-cell", children: (f.fieldCount ?? 0) > 0 ? `${f.fieldCount} fields` : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-300", children: "â" }) }), 2992 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-3 text-gray-500 hidden md:table-cell", children: f.uploadedBy }), 2993 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-3 text-gray-400 text-xs hidden md:table-cell", children: new Date(f.createdAt).toLocaleDateString() }), 2994 /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 justify-end", children: [
2995 /* @__PURE__ */ jsxRuntimeExports.jsxs( 2996 Button, 2997 { 2998 size: "sm", 2999 variant: "outline", 3000 className: "text-xs h-7 px-2", 3001 onClick: () => { 3002 setReplaceId(f.id); 3003 setReplaceFile(null); 3004 }, 3005 children: [ 3006 /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 11, className: "mr-1" }), 3007 "Replace" 3008 ] 3009 } 3010 ), 3011 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3012 Button, 3013 { 3014 size: "sm", 3015 variant: "outline", 3016 className: "text-xs h-7 px-2 text-red-600 hover:text-red-700 hover:border-red-300", 3017 onClick: () => setDeleteLibId(f.id), 3018 children: [ 3019 /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { size: 11, className: "mr-1" }), 3020 "Delete" 3021 ] 3022 } 3023 ) 3024 ] }) }) 3025 ] }, f.id)) }) 3026 ] }) }), 3027 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: deleteLibId !== null, onOpenChange: (open) => !open && setDeleteLibId(null), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [
3028 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 3029 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Remove from Library?" }), 3030 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "This removes the blank form from the library. Existing completed workflows are not affected. Producers will need to re-upload this form manually for future workflows." }) 3031 ] }), 3032 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 3033 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setDeleteLibId(null), children: "Cancel" }), 3034 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3035 Button, 3036 { 3037 variant: "destructive", 3038 onClick: () => deleteLibId && deleteMut.mutate({ id: deleteLibId }), 3039 disabled: deleteMut.isPending, 3040 children: [ 3041 deleteMut.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin mr-1" }) : null, 3042 "Remove" 3043 ] 3044 } 3045 ) 3046 ] }) 3047 ] }) }), 3048 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: replaceId !== null, onOpenChange: (open) => { 3049 if (!open) { 3050 setReplaceId(null); 3051 setReplaceFile(null); 3052 } 3053 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [
3054 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 3055 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Replace Form PDF" }), 3056 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Upload a new blank PDF to replace the current version in the library. The form number will remain the same; only the file is updated." }) 3057 ] }), 3058 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-3", children: [ 3059 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "New Blank PDF" }), 3060 /* @__PURE__ */ jsxRuntimeExports.jsx( 3061 Input, 3062 { 3063 type: "file", 3064 accept: ".pdf,application/pdf", 3065 className: "mt-1.5", 3066 onChange: (e) => setReplaceFile(e.target.files?.[0] ?? null) 3067 } 3068 ), 3069 replaceFile && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-green-600 mt-1.5", children: [ 3070 "â ", 3071 replaceFile.name, 3072 " selected" 3073 ] }) 3074 ] }),
3075 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 3076 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => { 3077 setReplaceId(null); 3078 setReplaceFile(null); 3079 }, children: "Cancel" }), 3080 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3081 Button, 3082 { 3083 onClick: handleReplace, 3084 disabled: !replaceFile || replaceMut.isPending, 3085 style: { background: "var(--eps-navy-deep)", color: "white" }, 3086 children: [ 3087 replaceMut.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin mr-1" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { size: 14, className: "mr-1" }), 3088 replaceMut.isPending ? "Uploadingâ¦" : "Replace" 3089 ] 3090 } 3091 ) 3092 ] }) 3093 ] }) }) 3094 ] }); 3095} 3096function AcordFormsAgentPage() { 3097 const { agent } = useAgentAuth(); 3098 const [activeWorkflowId, setActiveWorkflowId] = reactExports.useState(null); 3099 const [deleteId, setDeleteId] = reactExports.useState(null); 3100 const [mainTab, setMainTab] = reactExports.useState("workflows"); 3101 const utils = trpc.useUtils(); 3102 const isAdmin = agent?.isAdmin === true; 3103 const { data: workflows, isLoading, refetch } = trpc.acordWorkflows.list.useQuery({ limit: 50, offset: 0 }); 3104 const deleteMutation = trpc.acordWorkflows.delete.useMutation({ 3105 onSuccess: () => { 3106 toast.success("Workflow deleted"); 3107 setDeleteId(null); 3108 utils.acordWorkflows.list.invalidate(); 3109 }, 3110 onError: (err) => toast.error(err.message) 3111 }); 3112 const [showIntakeLinkDialog, setShowIntakeLinkDialog] = reactExports.useState(false); 3113 const [intakeClientName, setIntakeClientName] = reactExports.useState(""); 3114 const [intakeClientEmail, setIntakeClientEmail] = reactExports.useState(""); 3115 const [intakeLob, setIntakeLob] = reactExports.useState(""); 3116 const [generatedIntakeLink, setGeneratedIntakeLink] = reactExports.useState(null); 3117 const createIntakeLinkMutation = trpc.acordIntake.createLink.useMutation({ 3118 onSuccess: (data) => { 3119 const url = `${window.location.origin}/acord-intake?token=${data.token}`; 3120 setGeneratedIntakeLink(url); 3121 }, 3122 onError: (err) => toast.error(err.message) 3123 }); 3124 const [announcementSent, setAnnouncementSent] = reactExports.useState(false); 3125 trpc.sendAcordAnnouncement.useMutation({ 3126 onSuccess: (data) => { 3127 setAnnouncementSent(true); 3128 toast.success(`Announcement sent to ${data.sent}/${data.total} producers!`); 3129 }, 3130 onError: (err) => toast.error(`Failed to send: ${err.message}`) 3131 }); 3132 if (activeWorkflowId) { 3133 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-5xl mx-auto px-4 py-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[1fr_320px] gap-6 items-start", children: [
3134 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(WorkflowView, { workflowId: activeWorkflowId, onBack: () => { 3135 setActiveWorkflowId(null); 3136 refetch(); 3137 }, isAdmin }) }), 3138 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lg:sticky lg:top-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(AcordAgentChat, { agentName: agent?.agentName }) }) 3139 ] }) }); 3140 } 3141 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-5xl mx-auto px-4 py-6 space-y-6", children: [ 3142 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3143 /* @__PURE__ */ jsxRuntimeExports.jsxs("h1", { className: "text-2xl font-bold", style: { fontFamily: "'Playfair Display', serif", color: "var(--eps-navy-deep)" }, children: [ 3144 /* @__PURE__ */ jsxRuntimeExports.jsx(USFlag, { size: 18 }), 3145 " ACORD Forms & Applications" 3146 ] }), 3147 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "AI-powered ACORD form completion â upload source docs, AI extracts & fills official forms, download completed PDFs" }) 3148 ] }), 3149 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1 border-b border-gray-200", children: [
3150 /* @__PURE__ */ jsxRuntimeExports.jsx( 3151 "button", 3152 { 3153 onClick: () => setMainTab("workflows"), 3154 className: `px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors ${mainTab === "workflows" ? "border-[var(--eps-navy-deep)] text-[var(--eps-navy-deep)]" : "border-transparent text-gray-500 hover:text-gray-700"}`, 3155 children: "Workflows" 3156 } 3157 ), 3158 isAdmin && /* @__PURE__ */ jsxRuntimeExports.jsx( 3159 "button", 3160 { 3161 onClick: () => setMainTab("library"), 3162 className: `px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors ${mainTab === "library" ? "border-[var(--eps-navy-deep)] text-[var(--eps-navy-deep)]" : "border-transparent text-gray-500 hover:text-gray-700"}`, 3163 children: "Form Library" 3164 } 3165 ) 3166 ] }), 3167 mainTab === "library" && isAdmin ? /* @__PURE__ */ jsxRuntimeExports.jsx(FormLibraryManager, {}) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 3168 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 items-start", children: [
3169 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ 3170 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-2 rounded-xl p-4", style: { borderColor: "var(--eps-navy-mid)" }, children: [ 3171 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold mb-3", style: { color: "var(--eps-navy-deep)" }, children: "ð Start New ACORD Form Workflow" }), 3172 /* @__PURE__ */ jsxRuntimeExports.jsx( 3173 Step1Upload, 3174 { 3175 onCreated: (id) => { 3176 utils.acordWorkflows.list.invalidate(); 3177 setActiveWorkflowId(id); 3178 } 3179 } 3180 ) 3181 ] }), 3182 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-dashed border-blue-300 rounded-xl p-4 bg-blue-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ 3183 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
3184 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-blue-900", children: "ð Client Intake Link" }), 3185 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-700 mt-0.5", children: "Send clients a link to fill in their own information" }) 3186 ] }), 3187 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3188 Button, 3189 { 3190 size: "sm", 3191 variant: "outline", 3192 className: "gap-1.5 border-blue-300 text-blue-700 hover:bg-blue-100", 3193 onClick: () => { 3194 setShowIntakeLinkDialog(true); 3195 setGeneratedIntakeLink(null); 3196 }, 3197 children: [ 3198 /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 13 }), 3199 "Create Link" 3200 ] 3201 } 3202 ) 3203 ] }) }), 3204 /* @__PURE__ */ jsxRuntimeExports.jsx(AcordAgentChat, { agentName: agent?.agentName }) 3205 ] }),
3206 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ 3207 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-base font-semibold", style: { color: "var(--eps-navy-deep)" }, children: "Workflow Status Dashboard" }), 3208 !isLoading && workflows && workflows.length > 0 && (() => { 3209 const wfList = workflows; 3210 const inProgress = wfList.filter((w) => w.step < 7).length; 3211 const completed = wfList.filter((w) => w.step === 7).length; 3212 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [ 3213 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 text-center", children: [ 3214 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-blue-700", children: inProgress }), 3215 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-600 mt-0.5", children: "In Progress" }) 3216 ] }),
3217 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-green-50 border border-green-200 rounded-lg p-3 text-center", children: [ 3218 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-green-700", children: completed }), 3219 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-600 mt-0.5", children: "Completed" }) 3220 ] }), 3221 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-3 text-center", children: [ 3222 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-2xl font-bold text-gray-700", children: wfList.length }), 3223 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: "Total" }) 3224 ] }) 3225 ] }); 3226 })(), 3227 isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 20, className: "animate-spin text-gray-400" }) }) : !workflows || workflows.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12 border-2 border-dashed border-gray-200 rounded-xl", children: [
3228 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 36, className: "mx-auto text-gray-300 mb-3" }), 3229 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 font-medium", children: "No workflows yet" }), 3230 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-400 mt-1", children: "Fill out the form on the left to start your first workflow" }) 3231 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: workflows.map((wf) => /* @__PURE__ */ jsxRuntimeExports.jsxs( 3232 "div", 3233 { 3234 className: "flex items-center gap-3 bg-white border border-gray-200 rounded-lg px-4 py-3 hover:border-[var(--eps-navy-mid)] transition-colors cursor-pointer group", 3235 onClick: () => setActiveWorkflowId(wf.id), 3236 children: [ 3237 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${wf.step === 7 ? "bg-green-100" : "bg-blue-100"}`, children: wf.step === 7 ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { size: 16, className: "text-green-600" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { size: 16, className: "text-blue-600" }) }),
3238 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ 3239 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 flex-wrap", children: [ 3240 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium truncate", children: wf.clientName }), 3241 wf.intakeDocTypes?.includes("client_intake") && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-violet-600 text-white rounded px-1 py-0.5 leading-3 flex-shrink-0", title: "Created from client intake form", children: "INTAKE" }), 3242 wf.intakeIsRenewal && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] font-bold bg-teal-600 text-white rounded px-1 py-0.5 leading-3 flex-shrink-0", title: "Renewal workflow", children: "RENEWAL" }) 3243 ] }), 3244 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500", children: [ 3245 wf.formTitle ?? "Form TBD", 3246 " · ", 3247 wf.lineOfBusiness 3248 ] }) 3249 ] }),
3250 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [ 3251 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", className: `text-xs ${wf.step === 7 ? "border-green-300 text-green-700" : wf.step >= 5 ? "border-blue-300 text-blue-700" : "border-gray-300 text-gray-600"}`, children: [ 3252 "Step ", 3253 wf.step, 3254 "/7" 3255 ] }), 3256 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 hidden sm:block", children: new Date(wf.updatedAt).toLocaleDateString() }), 3257 /* @__PURE__ */ jsxRuntimeExports.jsx( 3258 "button", 3259 { 3260 onClick: (e) => { 3261 e.stopPropagation(); 3262 setDeleteId(wf.id); 3263 }, 3264 className: "text-gray-300 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity", 3265 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { size: 14 }) 3266 } 3267 ),
3268 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "text-gray-400" }) 3269 ] }) 3270 ] 3271 }, 3272 wf.id 3273 )) }) 3274 ] }) 3275 ] }), 3276 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: deleteId !== null, onOpenChange: (open) => !open && setDeleteId(null), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [ 3277 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 3278 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Delete Workflow?" }), 3279 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "This will permanently delete this ACORD form workflow and all associated files. This cannot be undone." }) 3280 ] }), 3281 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 3282 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => setDeleteId(null), children: "Cancel" }), 3283 /* @__PURE__ */ jsxRuntimeExports.jsxs( 3284 Button, 3285 { 3286 variant: "destructive", 3287 onClick: () => deleteId && deleteMutation.mutate({ id: deleteId }), 3288 disabled: deleteMutation.isPending, 3289 children: [
3290 deleteMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin mr-1" }) : null, 3291 "Delete" 3292 ] 3293 } 3294 ) 3295 ] }) 3296 ] }) }), 3297 /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open: showIntakeLinkDialog, onOpenChange: (open) => { 3298 if (!open) { 3299 setShowIntakeLinkDialog(false); 3300 setGeneratedIntakeLink(null); 3301 setIntakeClientName(""); 3302 setIntakeClientEmail(""); 3303 setIntakeLob(""); 3304 } 3305 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { children: [ 3306 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [ 3307 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Create Client Intake Link" }), 3308 /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: "Generate a secure link to send your client. They can fill in their own information, which youâll use to start their ACORD workflow." }) 3309 ] }), 3310 !generatedIntakeLink ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-3 space-y-3", children: [
3311 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3312 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Client Name (optional)" }), 3313 /* @__PURE__ */ jsxRuntimeExports.jsx( 3314 Input, 3315 { 3316 className: "mt-1.5", 3317 placeholder: "John Smith", 3318 value: intakeClientName, 3319 onChange: (e) => setIntakeClientName(e.target.value) 3320 } 3321 ) 3322 ] }), 3323 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3324 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Client Email (optional)" }), 3325 /* @__PURE__ */ jsxRuntimeExports.jsx( 3326 Input, 3327 { 3328 className: "mt-1.5", 3329 type: "email", 3330 placeholder: "[email protected]", 3331 value: intakeClientEmail, 3332 onChange: (e) => setIntakeClientEmail(e.target.value) 3333 } 3334 ) 3335 ] }),
3336 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 3337 /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { className: "text-sm font-medium", children: "Line of Business (optional)" }), 3338 /* @__PURE__ */ jsxRuntimeExports.jsxs(Select, { value: intakeLob, onValueChange: setIntakeLob, children: [ 3339 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "mt-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Select type of insurance" }) }), 3340 /* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: LOBS.map((lob) => /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItem, { value: lob, children: lob }, lob)) }) 3341 ] }) 3342 ] }), 3343 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "The link will expire in 7 days." }) 3344 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-3 space-y-3", children: [ 3345 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-green-50 border border-green-200 rounded-lg p-3", children: [
3346 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs font-semibold text-green-800 mb-1", children: "â Intake link created!" }), 3347 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-700", children: "Share this link with your client. It expires in 7 days and can only be used once." }) 3348 ] }), 3349 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ 3350 /* @__PURE__ */ jsxRuntimeExports.jsx( 3351 Input, 3352 { 3353 readOnly: true, 3354 value: generatedIntakeLink, 3355 className: "text-xs font-mono" 3356 } 3357 ), 3358 /* @__PURE__ */ jsxRuntimeExports.jsx( 3359 Button, 3360 { 3361 size: "sm", 3362 variant: "outline", 3363 onClick: () => { 3364 navigator.clipboard.writeText(generatedIntakeLink); 3365 toast.success("Link copied to clipboard!"); 3366 }, 3367 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 13 }) 3368 } 3369 ) 3370 ] }),
3371 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500", children: "You can also open the link to preview the form your client will see." }), 3372 /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: generatedIntakeLink, target: "_blank", rel: "noopener noreferrer", className: "text-xs text-blue-600 hover:underline", children: "Preview form â" }) 3373 ] }), 3374 /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [ 3375 /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: () => { 3376 setShowIntakeLinkDialog(false); 3377 setGeneratedIntakeLink(null); 3378 setIntakeClientName(""); 3379 setIntakeClientEmail(""); 3380 setIntakeLob(""); 3381 }, children: "Close" }), 3382 !generatedIntakeLink && /* @__PURE__ */ jsxRuntimeExports.jsx( 3383 Button, 3384 { 3385 onClick: () => createIntakeLinkMutation.mutate({ 3386 clientName: intakeClientName || void 0, 3387 clientEmail: intakeClientEmail || void 0, 3388 lineOfBusiness: intakeLob || void 0 3389 }), 3390 disabled: createIntakeLinkMutation.isPending, 3391 style: { background: "var(--eps-navy-deep)", color: "white" }, 3392 children: createIntakeLinkMutation.isPending ? /* @__P
3392URE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 3393 /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { size: 14, className: "animate-spin mr-1" }), 3394 "Creatingâ¦" 3395 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 3396 /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14, className: "mr-1" }), 3397 "Generate Link" 3398 ] }) 3399 } 3400 ) 3401 ] }) 3402 ] }) }) 3403 ] }) 3404 ] }); 3405} 3406 3407export { AcordFormsAgentPage as default };
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.